analog microphone/Using it/09. A clap switch
Using it · 09 of 10

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

A clap switch
After a clap
Window
none
TK01
off
Switches
0
The sketch has measured the quiet room: about 14 mV peak to peak. It fires at that plus 200 mV. Press run for a second and a half of a room.

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.

mic_clap_switch.ino
/*
  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.

When it does not work

One clap turns it on and off again.

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.

It switches when I talk or put a cup down.

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.

It never switches, however hard I clap.

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.

It ignores claps it heard fine a minute ago.

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.

Where this goes next

Six symptoms, and where to look first for each.

When a reading is wrong

Edit this page — content/books/analog-microphone/a-clap-switch.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

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.

Browse Modules and blocks on the forum