Sonic Screwdriver Plug Socket Controller

If you’ve seen the hit British TV series Doctor Who, then you’ll be familiar with the sonic screwdriver – a piece of alien technology that can open locks, summon spacecraft and control almost any equipment.

Sounds pretty exciting, right!

Whilst summoning spacecraft is a bit above my paygrade, I decided to build my own sonic screwdriver to control electronic equipment in my house such as lights, hair dryers and 3D printers.

To do this, I hacked the remote control from a wireless plug socket and turned my sonic screwdriver into the controller. This allowed me to turn on or off anything plugged into a mains socket. Needless to say, a fair bit of mischief ensued!

Bill of Materials

Here are the materials I used to create the sonic screwdriver (excluding 3D prints)

1 x ATtiny85 microcontroller

1 x 433 MHz radio transmitter

1 x 433 MHz remote control plug socket with receiver

3 x 470 Ohm resistor

1 x Step-up voltage regulator 0.5V to 5V

3 x Yellow LED

1 x AA battery

3D Prints

The sonic screwdriver 3D prints are split down the middle so that they will breakaway into two halves and give access to the electronics inside.

For some additional decoration and a much-needed splash of colour, I added a black conical section onto the front and a yellow conical section onto the back.

The main blue section was very challenging to print and I had to modify my 3D printing setup a little bit to get anything close to a decent result – more on that in the “Lessons Learned” section below.

The actual 3D modelling was very challenging too as the sonic screwdriver is quite an organic shape – it’s made up of curved surfaces in every direction and there is only one line of symmetry. Therefore, no 2D sketch can fully represent the body of the sonic screwdriver as it is inherently 3D.

To overcome this challenge, I found it easiest to start with a big rectangle of material and cut away at it until I got the finished shape, much like a sculptor would with a block of marble. In my head, I found it a lot easier to incrementally subtract the bits which didn’t look screwdriver shaped, rather than try and imagine it and create the full 3D model in one step.

This is counter intuitive as 3D printing is an additive process, but the computer modelling can be done the opposite way by using a subtractive method.

If you’d like to dive in and view the 3D model in Fusion 360, you can go here: https://a360.co/2HQuYGX

Circuit Diagram

The circuitry for this project required a custom PCB, mainly so that the electronics could be as compact as possible.

On a similar note, I chose to use an ATtiny85 because it packs a lot of power into a small form factor. I think even a little Arduino like the Pro Mini would have been a bit too big to fit inside the sonic screwdriver so the ATtiny85 was pretty much my only option.

These size constraints also lead to a difficult choice in how to power the sonic screwdriver circuitry. Whilst three AA batteries in series would give a healthy 4.5V to work with, they would simply be too bulky. Therefore, I had to go with just one AA battery at 1.5V and then use a step-up voltage regulator to get out 5V.

I’ve never used a step-up voltage regulator before, but I was very pleased with the results – it was easy to use and did exactly what I expected!

A final consideration for the circuitry was to reduce power consumption as I knew that the casing would just be glued together. Ideally, the battery should last for several years so that I never need to replace it.

To achieve this, I chose to wire the push-to-make button so that power is only drawn from the battery when the switch is pressed.

When the switch is not pressed, the circuit is broken and there is no way for electricity to flow. Therefore, the circuit only uses power for the short time that the button is pressed, it is not constantly drawing power 24/7.

Code

I’ll admit that I stole the code for controlling the plug sockets from another blog I stumbled across many years ago. I tried to find it again to credit the author, but with no luck. If you’re reading this and you wrote this code, get in touch!

***EDIT: A kind person commented on the above youtube video with the original blog where I sourced the code for this project. You can now visit the original blog post here. ***

The author of this code recorded the radio signals needed to turn the plug sockets on and off, and even gave some useful functions to playback these signals in one line of code with the “simulate_button” routine.

The only clever thing about my adaptation of this code is that, as mentioned in the above section on circuitry, the ATtiny85 is only powered up when the button is pressed.

Therefore, it doesn’t have any code in the loop() because everything is executed once on startup when the button is pressed. When the button is released, the ATtiny85 loses power and shuts down.

To allow the turning on and off of plug sockets, the ATtiny85 must send an ON signal when the button is first pressed, but next time the button is pressed it must send an OFF signal.

To keep track of the last signal sent, the EEPROM on board the ATtiny85 is used to permanently store the plug socket on/off state, even when the ATtiny85 is powered down.

This allows the alternation between on and off signals with each subsequent button press.


#include <EEPROM.h>

#define PAYLOAD_SIZE 48
 
#define DATA_PIN  0
#define VCC_PIN   3
#define GND_PIN   4
#define LED_PIN   1
 
#define PULSE_WIDTH_SMALL  500

int channel_num = 1;
int button_num = 1;
int state = 0;
 
// Button ID (payload1) values.  There are 4 values for 4 channels, organised as
// ch1_btn1, ch1_btn2, ch1_btn3, ch1_btn4, ch2_btn1, etc.
long buttons[] = {
  859124533L,
  861090613L,
  892547893L,
  1395864373L,
  859124563L,
  861090643L,
  892547923L,
  1395864403L,
  859125043L,
  861091123L,
  892548403L,
  1395864883L,
  859132723L,
  861098803L,
  892556083L,
  1395872563L  
};
 
void setup()
{
  pinMode(DATA_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);

   state = EEPROM.read(0);

   if(state == 0)
   {
      state = 1;
   }
   else
   {
      state = 0;
   }

   EEPROM.write(0, state);
   
   for(int i = 0; i < 5; i++)
   {
      simulate_button(1, 1, state);
   }
}

void loop()
{
 
}

 
void sendData(long payload1, long payload2)
{
  // Turn on the radio. A3=GND, A5=Vcc, A4=data)
  digitalWrite(GND_PIN, LOW);
  digitalWrite(VCC_PIN, HIGH);
  digitalWrite(DATA_PIN, HIGH);
  digitalWrite(LED_PIN, HIGH);
  
  // Send a preamble of 13 ms low pulse
  digitalWrite(DATA_PIN, LOW);
  for (int ii = 0; ii < 26; ii++)
  {
    delayMicroseconds(PULSE_WIDTH_SMALL);
  }
  digitalWrite(LED_PIN, LOW);
  
  // send sync pulse : high for 0.5 ms
  digitalWrite(DATA_PIN, HIGH);
  delayMicroseconds(PULSE_WIDTH_SMALL);
  digitalWrite(DATA_PIN, LOW);
  
  // Now send the digits.  
  // We send a 1 as a state change for 1.5ms, and a 0 as a state change for 0.5ms
  long mask = 1;
  char state = HIGH;
  long payload = payload1;
  for (int jj = 0; jj < PAYLOAD_SIZE; jj++)
  {
    if (jj == 32)
    {
      payload = payload2;
      mask = 1;
    }
    
    char bit = (payload & mask) ? 1 : 0;
    mask <<= 1;
      
    state = !state;
    digitalWrite(DATA_PIN, state);
  
    delayMicroseconds(PULSE_WIDTH_SMALL);  
    if (bit)
    {
      delayMicroseconds(PULSE_WIDTH_SMALL);  
      delayMicroseconds(PULSE_WIDTH_SMALL);  
    }
  }
}
 
void simulate_button(int channel, int button, int on)
{
  long payload1 = buttons[(channel - 1) * 4 + (button - 1)];
  long payload2 = on? 13107L : 21299L; //if on is true: send on character, if off is false: send off character
  
  //Serial.println(payload1);
  //Serial.println(payload2);
 
  // Send the data 6 times
  for (int ii = 0; ii < 10; ii++)
  {
    sendData(payload1, payload2);
  }
  
  // turn off the radio
  digitalWrite(VCC_PIN, LOW);
}
 


Lessons Learned

There is only one major lesson learned in this project and that was from trying to print the two casing halves for the sonic screwdriver body.

As the casings were not self-supporting geometries, they needed lots of support material to stop the print collapsing in on itself.

By default, my slicing software (Ultimaker Cura) uses zig-zag shape supports without a raft.

Unfortunately, when I printed with these settings, the printer head would occasionally knock into the supports and pull them off. This isn’t a problem with the bed level or height, it’s to do with the lack of bed adhesion the supports had. Even a tiny knock from the printer head and they broke away!

I found the solution was to add a raft and to change the shape of the supports from “zigzag” to “grid” this gave them a lot of extra strength and increased bed adhesion.

This meant when the printer head occasionally scraped across the top of the supports during printing, they held steady and resulted in a successful print.

Project Compete

Thanks for stopping by to read about this sonic screwdriver project. I hope you enjoyed finding out about it as much as I enjoyed making it. If you’ve got any questions or thoughts, feel free to leave a comment!

I’m off to run around my house a bit more and turn the lights on and off… have a lovely day wherever you are and I hope to see you again back here at Hartley Hacks in the future.

Happy sonic screwdrivering,

Robin

Leave a Reply