Last active
December 14, 2017 09:09
-
-
Save ShawnHymel/3e0ed5e48fb34c9745f19e13469cfcd0 to your computer and use it in GitHub Desktop.
Clap On Light
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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