Nirit Altony
Published © CC BY-NC-SA

We Built a Clap-Controlled Nightlight to Beat the Dark

A kid-friendly Arduino nightlight that responds to claps, changes colors, and turned bedtime fear into bedtime fun

BeginnerFull instructions provided1 hour31
We Built a Clap-Controlled Nightlight to Beat the Dark

Things used in this project

Story

Read more

Schematics

photo-2026-04-06-13-15-30_cf0X0Whe6Q.jpg

Code

Untitled file

C/C++
/*
 * Clap-Activated Smart Nightlight
 * 
 * This project uses a microphone sensor to detect loud, sudden noises (like a clap)
 * and toggles an LED (or relay) on and off. It uses a peak-to-peak amplitude detection
 * algorithm over a small time window to filter out normal ambient noise.
 * 
 * PIN CONNECTIONS:
 * // Microphone AOUT -> A0 (Analog output for software thresholding)
 * // Microphone VCC  -> 5V
 * // Microphone GND  -> GND
 * // LED Anode (+)   -> D3 (via 220-ohm resistor)
 * // LED Cathode (-) -> GND
 * 
 * Note: If your microphone module only has a DOUT (Digital Out) pin, you can connect
 * it to a digital pin and adjust the onboard potentiometer, but using AOUT provides
 * better software control and debugging.
 */

// --- Pin Definitions ---
const int MIC_PIN = A0;   // Analog input from the microphone
const int LED_PIN = 3;    // Digital output to the LED (or relay)

// --- Configuration Parameters ---
// Adjust this threshold based on your Serial Monitor readings.
// A normal room might have an amplitude of 10-30. A clap might spike to 100-500.
const int CLAP_THRESHOLD = 150; 

// Time window (in milliseconds) to measure the sound peak-to-peak amplitude
const int SAMPLE_WINDOW = 50; 

// Debounce delay to prevent a single clap from triggering multiple times (echoes)
const unsigned long DEBOUNCE_DELAY = 500; 

// --- State Variables ---
bool ledState = false;             // Current state of the light
unsigned long lastClapTime = 0;    // Timestamp of the last detected clap

void setup() {
  // Initialize Serial Monitor for debugging
  Serial.begin(115200);
  while (!Serial) { ; } // Wait for serial port to connect
  
  Serial.println("--- Clap-Activated Smart Nightlight Starting ---");
  
  // Configure pins
  pinMode(MIC_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  
  // Fail-safe default: Ensure light is OFF at startup
  digitalWrite(LED_PIN, LOW);
}

void loop() {
  unsigned long startMillis = millis(); // Start of sample window
  int signalMax = 0;
  int signalMin = 1024;
  
  // Collect data for the duration of the SAMPLE_WINDOW (50ms)
  while (millis() - startMillis < SAMPLE_WINDOW) {
    int sample = analogRead(MIC_PIN);
    
    // Validate sensor reading (0-1023 for standard 10-bit ADC)
    if (sample < 0 || sample > 1023) {
      continue; // Skip invalid readings
    }
    
    // Find the max and min values in this window
    if (sample > signalMax) {
      signalMax = sample;
    }
    if (sample < signalMin) {
      signalMin = sample;
    }
  }
  
  // Calculate peak-to-peak amplitude
  int peakToPeak = signalMax - signalMin;
  
  // Check if the amplitude exceeds our clap threshold
  if (peakToPeak > CLAP_THRESHOLD) {
    unsigned long currentTime = millis();
    
    // Check debounce timer to ignore echoes or prolonged noises
    if (currentTime - lastClapTime > DEBOUNCE_DELAY) {
      // Valid clap detected! Toggle the LED state
      ledState = !ledState;
      digitalWrite(LED_PIN, ledState ? HIGH : LOW);
      
      // Update the last clap timestamp
      lastClapTime = currentTime;
      
      // Debug output for state change
      Serial.print("*** CLAP DETECTED! *** Amplitude: ");
      Serial.print(peakToPeak);
      Serial.print(" | Light is now: ");
      Serial.println(ledState ? "ON" : "OFF");
    } else {
      // Debug output for ignored echo
      Serial.print("Ignored echo. Amplitude: ");
      Serial.println(peakToPeak);
    }
  }
  
  // Optional: Print ambient noise levels occasionally for calibration
  // Uncomment the lines below to see continuous readings (can be spammy)
  /*
  static unsigned long lastPrint = 0;
  if (millis() - lastPrint > 500) {
    Serial.print("Ambient Amplitude: ");
    Serial.println(peakToPeak);
    lastPrint = millis();
  }
  */
}

Credits

Nirit Altony
1 project • 1 follower

Comments