A clap switch
A TK01 XL LED that toggles on a clap. The sketch measures the quiet swing at start-up, fires when a 50 ms window swings 200 mV more than that, and then stops listening for 300 ms. Without that pause a clap's own ringing and echo switch the lamp straight back off.
The threshold comes from the room
A number copied from someone else's sketch is wrong on your desk. Their board rests at a different level, their converter wanders differently, and their room is louder or quieter. So the sketch starts by listening: for one second it measures the swing, window after window, and keeps the biggest. That is the quiet swing, from reading it on an ESP32.
The threshold is the quiet swing plus 200 mV. From the earlier figures' rough sizes, talking a metre away swings SIGNAL by about 15 mV and a raised voice close by by about 150, while a clap at arm's length swings it by more than a volt. 200 mV sits in the gap. Your room may want more.
One clap, one switch
Pick Listen straight away and run the room. A clap does not stop when your hands do: it rings on, and the echo from the walls arrives a few tens of milliseconds later. Both land in the next window, which is still over the line, so the switch fires again and turns the lamp back off. From the chair the clap did nothing.
Pick Ignore 300 ms. After each switch the sketch stops listening for 300 ms, six windows, and by then the clap has died away. Each clap is one switch. That pause is called a lockout, and it is the same idea as the debounce a push button needs.
Wiring the LED
The TK01 XL LED needs two wires, as in its own book: GND to GND, and SIGNAL to D9 on an Uno, GPIO 4 on an ESP32, GPIO 5 on an ESP32-S3, GP15 on a Pico. They are the pins the ambient light sensor's night light uses. On the ESP32-S3, GPIO 4 is the microphone, which is why the LED is on GPIO 5.
Running it
Open the serial monitor at 115200 and press reset. Keep quiet for the first second while it measures; it prints the threshold it chose. Clap once, a hand's length or two from the capsule, and the LED comes on; clap again and it goes off. A knock on the desk the block sits on does the same. That is not a fault: a knock is a loud, low sound, exactly what this block hears best.
The code
The quiet swing from the previous sketch, a threshold a fixed margin above it, and a TK01 XL LED that toggles each time a 50 ms window crosses it. After each switch it ignores the microphone for 300 ms.
/*
Analog Microphone - a clap switch TK27 / /p/tk27
Wiring, the TK27. Count from the square pad, parts up, header at
the bottom:
GND -> GND
VCC -> 5V on an Uno; 3V3 on an ESP32, ESP32-S3 or Pico
NC -> nothing (unconnected on the board)
SIGNAL -> A0 on an Uno, GPIO 34 on an ESP32, GPIO 4 on an
ESP32-S3, GP26 on a Raspberry Pi Pico
The TK01 XL LED, counted the same way:
GND -> GND
NC -> nothing (both of its NC pins)
SIGNAL -> D9 on an Uno, GPIO 4 on an ESP32, GPIO 5 on an
ESP32-S3, GP15 on a Raspberry Pi Pico
Arduino IDE
Tools > Board your board, e.g. Arduino Uno
Tools > Port the one that appears when you plug in
Tools > USB CDC On Boot Enabled (ESP32-S3 only)
No library needed.
*/
// The analog pin SIGNAL is wired to.
// Uno: A0. ESP32: 34. ESP32-S3: 4. Pico: 26.
const int MIC_PIN = A0;
// The TK01's SIGNAL. Uno: 9. ESP32: 4. ESP32-S3: 5. Pico: 15.
const int LED_PIN = 9;
// Uno and Pico only: the ADC's full scale, in mV.
// Uno: 5000. Pico: 3300.
const float FULL_SCALE_MV = 5000.0;
const unsigned long WINDOW_MS = 50;
const unsigned long CALIBRATE_MS = 1000;
const float CLAP_MARGIN_MV = 200; // how much louder than quiet
const unsigned long LOCKOUT_MS = 300; // deaf after each switch
float thresholdMv;
bool lampOn = false;
float readMilliVolts() {
#if defined(ARDUINO_ARCH_ESP32)
return analogReadMilliVolts(MIC_PIN); // calibrated in the chip
#else
return analogRead(MIC_PIN) * FULL_SCALE_MV / 1023.0;
#endif
}
// Highest minus lowest over one window, in mV.
float swingMilliVolts() {
float lo = 100000;
float hi = -1;
unsigned long start = millis();
while (millis() - start < WINDOW_MS) {
float mv = readMilliVolts();
if (mv < lo) lo = mv;
if (mv > hi) hi = mv;
}
return hi - lo;
}
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
delay(500);
Serial.println("Measuring the quiet swing. Keep quiet...");
float quiet = 0;
unsigned long start = millis();
while (millis() - start < CALIBRATE_MS) {
float s = swingMilliVolts();
if (s > quiet) quiet = s;
}
thresholdMv = quiet + CLAP_MARGIN_MV;
Serial.print("Clap above ");
Serial.print(thresholdMv, 0);
Serial.println(" mV");
}
void loop() {
float swing = swingMilliVolts();
if (swing > thresholdMv) {
lampOn = !lampOn;
digitalWrite(LED_PIN, lampOn ? HIGH : LOW);
Serial.print(swing, 0);
Serial.println(lampOn ? " mV on" : " mV off");
delay(LOCKOUT_MS); // let the clap and its echo die away
}
}CLAP_MARGIN_MV sets how loud a clap has to be; LOCKOUT_MS sets how long it stops listening. Set LOCKOUT_MS to 0 to see the double switch the figure shows. Keep quiet for the first second while it measures the room.
The same clap switch in MicroPython: the quiet swing at start-up, a threshold a fixed margin above it, and a TK01 that toggles on each crossing, then ignores the microphone for 300 ms.
"""
Analog Microphone - a clap switch, MicroPython TK27 / /p/tk27
Wiring, the TK27. Count from the square pad, parts up, header at
the bottom:
GND -> GND
VCC -> 3V3 (never 5V: a loud sound takes SIGNAL up to VCC)
NC -> nothing (unconnected on the board)
SIGNAL -> GPIO 34 on an ESP32, GPIO 4 on an ESP32-S3,
GP26 on a Raspberry Pi Pico
The TK01 XL LED, counted the same way:
GND -> GND
NC -> nothing (both of its NC pins)
SIGNAL -> GPIO 4 on an ESP32, GPIO 5 on an ESP32-S3,
GP15 on a Raspberry Pi Pico
Thonny
Run > Configure interpreter MicroPython (ESP32) or
MicroPython (Raspberry Pi Pico)
Save it to the board as main.py to run it on every power-up.
Nothing to install: machine, sys and time are built in.
"""
import sys
import time
from machine import ADC, Pin
# The GPIO number SIGNAL is wired to. ESP32: 34. ESP32-S3: 4. Pico: 26.
MIC_PIN = 4
# The TK01's SIGNAL. ESP32: 4. ESP32-S3: 5. Pico: 15.
LED_PIN = 5
WINDOW_MS = 50
CALIBRATE_MS = 1000
CLAP_MARGIN_MV = 200 # how much louder than quiet
LOCKOUT_MS = 300 # deaf after each switch
adc = ADC(Pin(MIC_PIN))
ESP = sys.platform == "esp32" # ESP32 and ESP32-S3
if ESP:
adc.atten(ADC.ATTN_11DB) # the full range, to about 3.1 V
led = Pin(LED_PIN, Pin.OUT)
def read_millivolts():
if ESP:
return adc.read_uv() / 1000 # calibrated in the chip
return adc.read_u16() * 3300 / 65535
def swing_millivolts():
lo = 100000
hi = -1
start = time.ticks_ms()
while time.ticks_diff(time.ticks_ms(), start) < WINDOW_MS:
mv = read_millivolts()
lo = min(lo, mv)
hi = max(hi, mv)
return hi - lo
time.sleep_ms(500)
print("Measuring the quiet swing. Keep quiet...")
quiet = 0
start = time.ticks_ms()
while time.ticks_diff(time.ticks_ms(), start) < CALIBRATE_MS:
quiet = max(quiet, swing_millivolts())
threshold = quiet + CLAP_MARGIN_MV
print("Clap above %.0f mV" % threshold)
lamp_on = False
while True:
swing = swing_millivolts()
if swing > threshold:
lamp_on = not lamp_on
led.value(1 if lamp_on else 0)
print("%.0f mV %s" % (swing, "on" if lamp_on else "off"))
time.sleep_ms(LOCKOUT_MS) # let the clap and its echo dieThere is no Uno here: an Uno cannot run MicroPython. The prompts appear in Thonny's shell. Stop it with Ctrl-C; the LED stays as it was, so switch it off in the shell with led.value(0).
When it does not work
The clap's second window was still over the threshold and the lockout is too short, or was removed. Keep LOCKOUT_MS at 300 or more. In a room with hard walls and little furniture the echo lasts longer; 500 ms is still quick enough to feel instant.
The margin is too small for your room. Raise CLAP_MARGIN_MV from 200 to 400 or more. A cup on a hard desk is a knock, and this block hears knocks nearly as well as claps: that is its band, not a fault. Moving the block away from the desk helps.
Print the swing with the previous article's sketch and clap. If the swing jumps by hundreds of millivolts, lower CLAP_MARGIN_MV below that jump. If it does not move at all, check the wiring by counting from the square pad, and check MIC_PIN.
Something made a sound during the quiet second at start-up, so the quiet swing, and the threshold above it, came out large. The sketch prints the threshold it chose: if it is far above what a clap reads, press reset and keep quiet for the first second.
Edit this page — content/books/analog-microphone/a-clap-switch.mdx
Questions about this product
See what other owners have asked, and read their solutions.
Analog Microphone
Loading discussions…
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.