Skip to content

Instantly share code, notes, and snippets.

@ShawnHymel
Last active December 14, 2017 09:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ShawnHymel/3e0ed5e48fb34c9745f19e13469cfcd0 to your computer and use it in GitHub Desktop.
Save ShawnHymel/3e0ed5e48fb34c9745f19e13469cfcd0 to your computer and use it in GitHub Desktop.
Clap On Light
/**
* 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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment