Clap On Lamp

Pages
Contributors: ShawnHymel
Favorited Favorite 3

Introduction

Perhaps you remember an “As Seen on TV” product known as “The Clapper” in the 1980s and 1990s. The TV commercials could be seen on almost every channel. The premise was simple: a 120 VAC relay would control power to appliances and respond to two sharp noises, specifically two claps. We’re going to make our own version of this, but instead of controlling any appliance, we will operate a lamp chain using a servo.

Required Materials

You can complete this project with parts from the SparkFun Inventor’s Kit v4.0 and a Sound Detector board. Specifically, you will need:

Tools Needed:

Suggested Reading

If you aren’t familiar with the following concepts, we recommend checking out these tutorials before continuing:

What is an Arduino?

What is this 'Arduino' thing anyway?

Installing Arduino IDE

A step-by-step guide to installing and testing the Arduino software on Windows, Mac, and Linux.

Hobby Servo Tutorial

Servos are motors that allow you to accurately control the rotation of the output shaft, opening up all kinds of possibilities for robotics and other projects.

Hardware Assembly

Lamp Assembly

To start, we’ll attach the servo to the lamp first. If you want to protect your lamp’s finish, wrap some electrical tape around the post, covering about a 3-inch section.

Wrapping electrical tape around lamp

Use a screwdriver to tighten the hose clamp around the post about 1 inch above the base. Note that you may need to adjust the position of the servo later so that it can effectively pull the chain. Leave a small gap on one side.

Attaching hose clamp to lamp

Thread two zip ties through the gap in the hose clamp

Pulling zip ties through hose clamp

Carefully pull the zip ties around the servo on either side of the flange. Pull the zip ties tight (you may need to use a set of needle-nose pliers).

Pulling zip ties through hose clamp

Tighten the hose clamp as needed and cut the ends of the zip ties.

Cut ends of zip ties

Using a screw, attach a servo arm to the servo’s shaft. Make sure that the arm can rotate from pointing directly up to directly down, rotating away from the lamp’s post. We’ll use that motion to pull the lamp’s chain.

Put servo arm on servo

Straighten out a paper clip, and bend a hook in one end using needle-nose pliers.

Bending paper clip

With the servo arm facing up, thread the hook through the outermost hole in the servo arm. Hold the other end of the paper clip up to the chain, and bend the paper clip so that it hooks onto the chain.

Attach other end of paper clip to chain

Try rotating the servo to make sure that the chain is pulled fully to switch the lamp. This may require readjusting a second paper clip hook so that the chain is pulled successfully on each rotation.

Make sure that the servo pulls the chain

Circuit Diagram

Using jumper wires, connect the components as shown in the diagram below.

Clap on lamp Fritzing diagram

Having a hard time seeing the circuit? Click on the image for a closer look.

Programming

Note: This example assumes you are using the latest version of the Arduino IDE on your desktop. If this is your first time using Arduino, please review our tutorial on installing the Arduino IDE.

Copy and paste the following code in the Arduino IDE. Click Upload to send your compiled code to the Arduino.

language:c
/**
 * Clap On Light
 * Date: November 9, 2017
 * Author: Shawn Hymel (SparkFun Electronics)
 * 
 * Connect a servo to a lamp chain/switch to turn it on and off
 * with two successive claps (or other loud noises).
 * 
 * To complete this project, you will need parts from the
 * SparkFun Inventor's Kit v4.0: 
 * https://www.sparkfun.com/products/14265 as well as a sound
 * detector board: https://www.sparkfun.com/products/14262 along
 * with a lamp, electrical tape, hose clamp, zip ties, and a
 * paper clip.
 * 
 * This sketch was written by SparkFun Electronics, with lots of
 * help from the Arduino community. This code is completely free
 * for any use.
 */

#include <Servo.h>

// Pins
const int SERVO_PIN = 9;
const int SOUND_PIN = A0;

// Constants
const int THRESHOLD = 30;                           // Raw ADC
const unsigned long TIMEOUT = 500;                  // ms
const unsigned long TIME_BETWEEN_PULSES_MIN = 300;  // ms
const unsigned long TIME_BETWEEN_PULSES_MAX = 1000; // ms
const int PULSE_MIN = 40;                           // ms
const int PULSE_MAX = 300;                          // ms
const int SERVO_WAIT = 1000;                        // ms
const int SERVO_CCW = 0;                            // deg
const int SERVO_CW = 180;                           // deg

// Globals
unsigned long last_pulse_time = 0;
Servo servo;

void setup() {

  Serial.begin(9600);

  servo.attach(SERVO_PIN);
  servo.write(SERVO_CW);

  pinMode(SOUND_PIN, INPUT);
}

void loop() {

  // Look for pulse and take time it occured
  unsigned long pulse_length = readPulse(SOUND_PIN, THRESHOLD, TIMEOUT);
  if ( (pulse_length >= PULSE_MIN) && 
       (pulse_length <= PULSE_MAX) ) {
    unsigned long pulse_time = millis();
    Serial.println(pulse_time - last_pulse_time);

    // Check time between this pulse and the last one we saw
    if ( (pulse_time - last_pulse_time >= TIME_BETWEEN_PULSES_MIN) &&
         (pulse_time - last_pulse_time <= TIME_BETWEEN_PULSES_MAX) ) {
      Serial.println("Clap on!");
      pullChain();
    }

    last_pulse_time = pulse_time;
  }
}

// If the analog value is above the threshold, wait for it to
// drop below the threshold and return the time it was above
// the threshold. Return 0 if it's not above the threshold, and
// return the timeout value if it stays above the threshold for
// too long.
unsigned long readPulse(int pin, int threshold, unsigned long timeout) {

  unsigned long t = 0;

  // If above the threshold, wait for value to drop below it
  if ( analogRead(pin) >= threshold ) {
    unsigned long timestamp = millis();
    while ( (analogRead(pin) >= threshold) &&
            (millis() < timestamp + timeout) );
    t = millis() - timestamp;
  }

  return t;
}

// Pull the lamp chain by moving the servo far counterclockwise,
// wait 500 ms, and then move it far clockwise.
void pullChain() {
  servo.write(SERVO_CCW);
  delay(SERVO_WAIT);
  servo.write(SERVO_CW);
  delay(SERVO_WAIT);
}

What You Should See

Clap twice near the sound detector with a pause of about ½ second between claps. The servo should activate and pull the chain to switch the light on. Clap twice again, and the lamp should turn off.

Clap twice to switch the lamp!

Resources and Going Further

The example code and circuit diagram for the Clap On Lamp project can be found on GitHub.

Challenges

  1. Right now, the program looks for any two sharp, successive noises. This could mean tapping the table near the sensor, sneezing or even just talking. See if you can modify the code to be more restrictive about what’s considered a “clap.” Can you have the servo activate only on clap sounds?
  2. Replace the sound detector sensor with another sensor, like a photocell. Have the lamp activate whenever another type of threshold is reached, such as getting too dark in a room.
  3. Write a computer program that looks for the local sunrise and sunset data on the internet and sends a command to the Arduino (e.g., over Serial) to turn the light on at sunset and off at sunrise.

Need some inspiration for your next project? Check out some of these related tutorials:

Mario the Magician's Magical Lapel Flower

A guest tutorial from the astonishingly talented Mario the Magician showing how to put together your own servo-controlled lapel flower.

Spectacle Example: Super Mario Bros. Diorama

A study in building an animated diorama (with sound!) using Spectacle electronics.