Clap On Lamp

Pages
Contributors: Shawn Hymel
Favorited Favorite 8

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 1/2 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!