Retrofit Remote Light Switch V2 – A Success!

After the failure of version 1 of my light switch controller (find more about that here), I am delighted to say that version 2 was a success! I was so pleased with how it all turned out that I created a full project video. I’ve never made a project video before, so I hope you like it!

Since this project actually works, I will use this post to document the components, programming and wiring I used, along with some lessons I learned along the way. If you feel I’ve missed anything out, just let me know in the comments. Let’s get stuck in…

 

Bill of Materials

Here are all the materials I used to create the light switch, excluding 3D prints.

1 x Pro Micro (Arduino Compatible)

1 x 9V battery

1 x DC barrel jack

1 x 9V battery holder with DC barrel jack connector

2 x SG90 micro servo (9 gram)

1 x LM393 sound sensor/microphone

1 x 7805 voltage regulator (5V)

12 x M2 bolts (6mm long) with nuts

3D Prints

The 3D prints are composed of several components which you can see in the above picture. The components are:

1) Baseplate: this is the green bit which screws onto the light switch. It provides a structure for all of the other components to sit on.

2) Servo connector: these are the orange bits on the end of the servo arms, designed to add strength and extra reach to the servo arms.

3) Side add-ons: these are the white components in the picture – they house the battery, electronics and microphones. There are two versions – one has no holes in the bottom, whilst the other has holes in the bottom which match those in the 9V battery holder so it can be screwed in.

You can download all of the 3D print files here:

Circuit Diagram

The circuit works as follows: firstly, the 9V battery is regulated down to 5V by the 7805 voltage regulator. This regulated 5V supply powers the two SG90 servos and the Pro Micro.

The servos are controlled using signal wires from pin 5 and pin 6 – one wire to each servo.

The sound sensor is powered by setting pin 2 on the Pro Micro HIGH and pin 4 LOW. Pin 3 is an input which is triggered when a certain sound threshold is detected by the LM383 Microphone/sound sensor.

To alter the sound threshold, there is a twisty potentiometer on the microphone which you adjust with a screwdriver. In the video below, I adjusted the threshold too low and it triggers continuously, causing a very tame strobe party.

Microphone Sensitivity is Key (Light Switch Robot)

 

Code

The code is fairly short, but is made a little more complicated by two things.

1) The servos are mirror images therefore, to turn the light on, the left servo must rotate clockwise whilst the right servo must go anticlockwise. This means the ‘destination’ position of each servo will be different for on and off.

2) The servo start positions are a weird angle due to ‘twitching’ which you can read about in ‘Lessons Learned’ further down in this article. For now though, all you need to know is that the servos had to start in a certain position – 92 degrees for the right servo, and 100 degrees for the left servo.

Without further ado, here is the code. I have commented it as best as I can but if you have any more questions, feel free to ask them in the comments.

#include <Servo.h>

Servo servoRight;       // create an object for the righthand servo
Servo servoLeft;        // create an object for the lefthand servo

const int rightStart = 92;    // variable to store the start servo positions
const int leftStart = 100;

const int twistAngle = 55;    // The angle the servos will twist to flick the light

int rightOn = rightStart - twistAngle;     // The angle required for the right servo to turn the light on
int leftOn = leftStart + twistAngle;       // The angle required for the left servo to turn the light on

int rightOff = rightStart + twistAngle;    // The angle required for the right servo to turn the light off
int leftOff = leftStart - twistAngle;      // The angle required for the left servo to turn the light off

int micPin = 3;             // Input pin for the microphone signal. It's only on/off, based on a threshold
boolean on = false;

void setup() 
{
    pinMode(4, OUTPUT);
    digitalWrite(4, LOW);     // GND for the microphone

    pinMode(2, OUTPUT);
    digitalWrite(2, HIGH);    // +5V for the microphone

    servoRight.attach(6);     // Right servo is pin 6 (must be a PWM pin!)
    servoLeft.attach(5);

    servoLeft.write(leftStart);       // Move servos to their start position on power up
    servoRight.write(rightStart);     // Really, they should be in the start positions anyway.
}

void loop() 
{
    boolean val = digitalRead(micPin);       // If the microphone sound level passes the threshold

    if(val == HIGH)
    { 
        if(on) // If the light is on...
        {
             Serial.println("Turning Off");
             servoOff();                     // Routine/method to turn the light off
             on = false;                     // Now the light is off
             delay(300);
        }
        else // If the light is off...
        {
             Serial.println("Turning On");
             servoOn();                      // routine/method to turn the light on
             on = true;                      // The light is now on.
             delay(300);
        }
     }
}

void servoOn()
{
    int rightPos = rightStart;
    int leftPos = leftStart;

    while(rightPos > rightOn)                   // Move the right servo from 'rightStart' to 'rightOn'
    {                                           // Move the left servo from 'leftStart' to 'leftOn'
        servoRight.write(rightPos);
        servoLeft.write(leftPos); 
        rightPos--;                             // rightPos is decreasing in angle 
        leftPos++;                              // leftPos is increasing in angle - remember, they're mirrored
       delay(5);
    }

    while(rightPos < rightStart)                // Move the servos back to their original position
    {
        servoRight.write(rightPos); 
        servoLeft.write(leftPos); 
        rightPos++;                // They now go the other way - rightPos increases, leftPos decreases
        leftPos--;
        delay(5);
    }

}

void servoOff()      // This is the exact opposite of the above servoOn() routine
{
    int rightPos = rightStart;
    int leftPos = leftStart;

    while(rightPos < rightOff) { servoRight.write(rightPos); servoLeft.write(leftPos); rightPos++; leftPos--; delay(5); } while(rightPos > rightStart)
    {
        servoRight.write(rightPos);
        servoLeft.write(leftPos); 
        rightPos--; 
        leftPos++;
        delay(5);
    }
}

Lessons Learned – Servo Twitching

I had not realised this before, but when you first provide power to a servo, it twitches/moves to a ‘start’ position. However, in this project, the twitch causes the light switch to flick on/off which is not exactly ideal…

The solution I found is to take the little white servo arm off and rotate it so that the ‘start’ position the servo twitches to is perfectly level with the light switch.

As this perfectly-level position above the switch is the position the servo is left in when the power is turned off, when I turn it back on, it tries to twitch but is already in its ‘start’ position. This means there is no longer any twitch.

A weird thing is that the ‘start’ position it twitches to is not a servo rotation of 0 degrees. It’s some weird value like 92 degrees. This means that the servo must rest in this ‘start’ position so it had to always return to a 92 degrees position.

You’ll see in the code above that the righthand servo has a rest position called ‘rightStart’ of 92 degrees. This is the position it naturally twitches to when powered on. As the lefthand servo is a mirror of the righthand one, its start position, called ‘leftStart’ is 100 degrees.

This took me a little while to get my head around but really wasn’t a big deal once I got it sussed.

What fun!

I really had fun creating this project and enjoyed making the video too. It definitely feels like an accomplished project which I have something to show for at the end. This makes me happy.

I hope you enjoyed it too – if you have any questions or comments I’d love to hear them.

Until next time, happy hacking,

Robin

Leave a Reply