Clap switch on an Arduino Uno
A KY-038 sound sensor: clap and the lamp toggles. A clap is a burst of pulses on D0, and A0 barely moves, because there is no amplifier. The whole build, an Arduino Uno and 3 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Beginner About 15 minutes to build and run. Runs in your browser. Free, and no account needed.
The parts retail for about $31. On Mokxi they're free.
Step by step, with the wiring and the common mistakes: Arduino Sound Sensor (KY-038): Clap Switch
What you'll learn
- Reading a digital sensor output on a pin
- Toggling state on a rising edge
- Ignoring a noisy burst with a quiet time
- What an unamplified microphone gives the ADC
- Difficulty: Beginner
- Time: About 15 minutes
- Board: Arduino Uno R3
- Parts: 5
How it works
The KY-038 has a microphone and a comparator. When the sound passes the level set by its trimmer, the D0 output goes high. The sketch watches D0 on pin 2, and each clap flips a yellow LED on pin 9 between on and off.
One clap is not one clean pulse. It is a burst of many pulses in a tenth of a second. So the sketch acts on the first rising edge and then ignores D0 for 300 ms. It also reports the lowest and highest A0 reading once a second.
Parts list
5 parts, plus the jumper wires. They retail for about $31; on Mokxi they're free.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Half breadboard
- 1 × Sound sensor, KY-038
- 1 × Resistor, 220 ΩIn Starter Kit, Claw Machine Kit, Halloween Prop Kit.
- 1 × LED, yellowIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
Kits that can build it
These 2 starter kits have every part in the circuit. Each kit's page lists what else it can build.
Wiring table
Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.
| Part and pin | Connects to |
|---|---|
| Resistor, 220 Ω pin 1 | Arduino Uno R3 pin 9 |
| Sound sensor, KY-038 pin DO | Arduino Uno R3 pin 2 |
| Sound sensor, KY-038 pin VCC | Arduino Uno R3 pin 5V |
| Sound sensor, KY-038 pin GND | Arduino Uno R3 pin GND |
| LED, yellow pin C | Arduino Uno R3 pin GND |
| Sound sensor, KY-038 pin AO | Arduino Uno R3 pin A0 |
| LED, yellow pin A | Resistor, 220 Ω pin 2 |
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Clap switch: clap once and the lamp comes on, clap again and it goes off.
//
// pin 2 the KY-038's D0 A0 its A0
// pin 9 the lamp, through 220 ohm to GND
// + -> 5 V, G -> GND
//
// The KY-038 has no amplifier. Its microphone's signal is a few millivolts on
// top of half the supply, and the comparator on the board lets D0 go high on
// every instant that signal pokes above the trimmer. So a clap is not one
// clean high on D0: it is a burst of dozens of pulses over a tenth of a
// second, and a sketch that toggles on every rising edge toggles dozens of
// times.
//
// # Latch the first edge, then stop listening
//
// The fix is the same one a pushbutton needs: take the first rising edge and
// ignore D0 for a while after it. 300 ms is longer than any clap rings and
// shorter than two claps in a row.
//
// # And what A0 says
//
// Once a second the sketch prints the lowest and highest A0 it saw. In a quiet
// room they are the same number, about 512. Drag the level slider up and even
// "very loud" moves them by only a few counts either side: that is what an
// unamplified microphone gives a 10-bit ADC. The clap button is the thing that
// reaches the trimmer.
const int SOUND_DO = 2;
const int SOUND_AO = A0;
const int LAMP = 9;
const unsigned long QUIET_MS = 300;
bool lampOn = false;
bool wasHigh = false;
unsigned long lastClap = 0;
int lowest = 1023;
int highest = 0;
unsigned long lastReport = 0;
void setup() {
pinMode(SOUND_DO, INPUT);
pinMode(LAMP, OUTPUT);
digitalWrite(LAMP, LOW);
Serial.begin(115200);
Serial.println("Mokxi Arduino Uno: clap switch");
Serial.println("press clap on the sensor");
}
void loop() {
unsigned long now = millis();
bool high = digitalRead(SOUND_DO) == HIGH;
if (high && !wasHigh && now - lastClap > QUIET_MS) {
lastClap = now;
lampOn = !lampOn;
digitalWrite(LAMP, lampOn ? HIGH : LOW);
Serial.println(lampOn ? "clap: lamp on" : "clap: lamp off");
}
wasHigh = high;
int level = analogRead(SOUND_AO);
if (level < lowest) {
lowest = level;
}
if (level > highest) {
highest = level;
}
if (now - lastReport >= 1000) {
lastReport = now;
Serial.print("A0 over the last second: ");
Serial.print(lowest);
Serial.print(" to ");
Serial.println(highest);
lowest = 1023;
highest = 0;
}
}
Code walkthrough
The key functions of the sketch, and what each one does.
setup sketch.ino
Makes pin 2 an input for the sensor and pin 9 an output for the lamp, turns the lamp off, and opens the serial monitor at 115200 baud. The lamp starts off, so the first clap turns it on.
void setup() {
pinMode(SOUND_DO, INPUT);
pinMode(LAMP, OUTPUT);
digitalWrite(LAMP, LOW);
Serial.begin(115200);
Serial.println("Mokxi Arduino Uno: clap switch");
Serial.println("press clap on the sensor");
}loop sketch.ino
Looks for D0 going from low to high, and only accepts it if more than QUIET_MS has passed since the last clap. If so it flips lampOn and writes the lamp pin. It also tracks the lowest and highest A0 reading and prints them every second.
void loop() {
unsigned long now = millis();
bool high = digitalRead(SOUND_DO) == HIGH;
if (high && !wasHigh && now - lastClap > QUIET_MS) {
lastClap = now;
lampOn = !lampOn;
digitalWrite(LAMP, lampOn ? HIGH : LOW);
Serial.println(lampOn ? "clap: lamp on" : "clap: lamp off");
}
wasHigh = high;
int level = analogRead(SOUND_AO);
if (level < lowest) {
lowest = level;
}
if (level > highest) {
highest = level;
}
if (now - lastReport >= 1000) {
lastReport = now;
Serial.print("A0 over the last second: ");
Serial.print(lowest);
Serial.print(" to ");
Serial.println(highest);
lowest = 1023;
highest = 0;
}
// ... 1 more lines in the editorTroubleshooting
The usual mistakes with this circuit, and the fix for each.
- One clap toggles the lamp several times This project
RaiseQUIET_MSso it is longer than the burst from one clap. - The lamp never reacts This project
Turn the trimmer on the KY-038 until the board's own lamp lights on a clap, and check D0 goes to pin 2. - A0 barely changes even for loud sounds This project
That is normal. The microphone has no amplifier, so A0 only moves a few counts around 512. - The digital output is on all the time or never. The pot sets the threshold, and the sensor is only a microphone with a comparator. Sound sensor
Turn the pot until the DO LED just goes out in quiet, then a clap will trip it. Use the AO pin and analogRead for a level rather than a clean on or off. - Analog readings sit at a middle value and look flat, so it seems dead. A loudness change is small and fast. Sound sensor
Sample many readings quickly and take the peak minus the low. Power the module at 3.3 V or 5 V to match your ADC range, and keep it away from motor noise. - The LED is dim, burns out, or the pin reads wrong because the resistor value is off. Resistor
Read the color bands again. A 220 ohm to 330 ohm resistor suits a typical LED on 5 V. 10k is a common pull-up or pull-down value. Check with a multimeter if unsure. - A pull-up or pull-down resistor is missing, so the input floats and reads random values. Resistor
Tie the input to 5 V or ground through about 10k. Or use INPUT_PULLUP and wire the switch to ground. - The LED does not light, or it lights once and then dies. LED
LEDs have polarity. The longer leg (anode) goes toward the positive side. Always add a series resistor, about 220 ohms to 1 k ohm on a 5 V pin.
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.