The offices next to Elmwood's must be wondering what we've been up to over the last couple of days. They would have heard sudden bursts of applause, then giggling, then more applause, and so on. There is, I can now reveal, a very good reason for this odd behaviour.
We've been testing Verbal Machines' Hand Clap Sensor VM-CLAP1. While it might look a bit like a cheap “noise detector” board, VM-CLAP1 has a bunch of clever signal processing built in so that almost all background noise is filtered out. Only handclaps or finger snaps will make the sensor trigger, and will do so over a range of a few metres.
We tried it with a speaker blaring right next to the microphone, and it could still pick out our handclaps over the noise. Really short percussive sounds like sharp snare hits might confuse the VM-CLAP1, but the board makes audio control of your electronic projects much simpler.
VM-Clap1 is really easy to set up, with only three connections:
I've written a couple of Arduino demos to show off what the VM-CLAP1 can do. The first is a very simple “clap twice for on, clap twice for off” script that switches the built-in LED on and off. Flashing LED_BUILTIN is no big deal, but choose a different pin, add a coffee maker and a Power Switch Tail II, and you've got a clappuccino machine!
Wiring is as follows:
And here's the code for Arduino:
/* Verbal Machines VM-CLAP1 sensor test clap twice within ¼ second to turn Arduino LED on or off by scruss - 2017-06 for Elmwood Electronics - https://elmwood.to/ Sensor wiring: OUT → Arduino Pin 2 (use INPUT_PULLUP) PWR → 5V or 3.3V GND → GND */ #define CLAPIN 2 // pin must be interrupt-capable #define CLAP_DELAY 250 // max gap between claps to trigger volatile boolean clap = false; // clap detected state boolean led_state = false; // LED on/off state unsigned long clap_time, last_clap_time = 0; // clap time records void setup() { pinMode(CLAPIN, INPUT_PULLUP); pinMode(LED_BUILTIN, OUTPUT); // control built-in LED by clapping Serial.begin(57600); Serial.println("# Clap sensor test ..."); attachInterrupt( // register Interrupt Service Routine (ISR): digitalPinToInterrupt(CLAPIN), // pin to watch for interrupt heard_clap, // void function to call on interrupt FALLING // trigger interrupt on HIGH → LOW change ); } void loop() { digitalWrite(LED_BUILTIN, led_state); // set LED based on clap status if (clap) { // we heard a clap from ISR clap = false; // make sure we don't trigger again too soon last_clap_time = clap_time; // store old clap time clap_time = millis(); // note current clap time if (clap_time - last_clap_time < CLAP_DELAY) { // if two claps heard in ¼ s: Serial.println("clap clap!"); // notify led_state = !led_state; // and switch LED state } else { Serial.println("clap!"); // notify of only one clap } } } void heard_clap() { clap = true; // just set clap state in ISR }
The next demo is a "clapometer", where we use an Adafruit NeoPixel Stick - 8 x WS2812 5050 RGB LED as the indicator. The faster you clap, the more LEDs light up - and in different colours, too!
Wiring is as follows:
You'll need to install the Adafruit NeoPixel Arduino Library to use the code:
/* Verbal Machines VM-CLAP1 sensor test clapometer with neopixel output by scruss - 2017-06 for Elmwood Electronics - https://elmwood.to/ Sensor wiring ("open collector"): OUT → Arduino Pin 2 PWR → 5V GND → GND 8 Neoxpixel strip on Arduino pin 6 */ #define CLAPIN 2 // pin must be interrupt-capable #define CLAP_INTERVAL 600 // time over which claps are counted #define MAX_COUNT 7 // max claps to count #define NEOPIN 6 // 8 px strip on pin 6 #define NUMPIXELS 8 // 0 ..7 // this is a colour table of pleasing(ish) HSV hues: unsigned long hues[] = {0x7F0000, // 0 degree hue 0x7F5F00, // 45 deg 0x407F00, // 90 ... 0x007F40, // 135 0x007F7F, // 180 0x00407F, // 225 0x40007F, // 270 0x7F005F // 315 }; #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> #endif volatile boolean clap = false; // clap detected state unsigned long clap_times[MAX_COUNT]; // clap time records int array_pos = 0; // index of current time record int clap_count = 0; // count of claps within CLAP_INTERVAL unsigned long current_time = 0; int i, j = 0; Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, NEOPIN, NEO_GRB + NEO_KHZ800); void setup() { pinMode(CLAPIN, INPUT_PULLUP); Serial.begin(57600); Serial.println("# Clapometer ..."); pixels.begin(); for (i = 0; i < NUMPIXELS; i++) { // turn all pixels off pixels.setPixelColor(i, 0); } pixels.show(); attachInterrupt( // register Interrupt Service Routine (ISR): digitalPinToInterrupt(CLAPIN), // pin to watch for interrupt heard_clap, // void function to call on interrupt FALLING // trigger interrupt on HIGH → LOW change ); } void loop() { if (clap) { // we heard a clap from ISR clap = false; // make sure we don't trigger again too soon clap_times[array_pos] = millis(); array_pos++; if (array_pos == MAX_COUNT) { array_pos = 0; } } current_time = millis(); clap_count = 0; for (i = 0; i < MAX_COUNT ; i++) { if (current_time - clap_times[i] <= CLAP_INTERVAL) { clap_count++; } } // set neopixels to clap count in right hue for (i = 0; i <= clap_count ; i++) { pixels.setPixelColor(i, hues[i]); } if (clap_count < NUMPIXELS) { // blank any unused pixels for (i = clap_count + 1; i < NUMPIXELS ; i++) { pixels.setPixelColor(i, 0); } } pixels.show(); Serial.print("clap count: "); Serial.println(clap_count); delay(10); } void heard_clap() { clap = true; // just set clap state in ISR }
Have fun with your new 👏-enhanced projects!
Stewart would like to thank/blame Brent Marshall and Anna Humphrey for the idea of the "clappuccino" machine.