Here is a "stripped down version" of a sketch I used to replicate the Clap On, Clap Off lamp switch we had in the 1980's. It works with the KY-038 sound sensor module you currently have. You will need to install the VirtualDelay Library.
The sound sensor module is very sensitive. A quarter turn of the potentiometer around the "sweet spot" makes a huge difference. Too sensitive, and the digital output is constantly high. If it's not sensitive enough, then you have to physically "tap" the microphone to get a high/low transition out of it.
Please note: This sketch uses delay() which is "blocking code" and it's use is usually not recommended.
#include "avdweb_VirtualDelay.h"
byte clapCounter = 0;
const byte soundSensorPin = 2;
const unsigned long loopDelay = 1;
const unsigned long clapCounterDelay = 400;
unsigned long clapCounterTimerDuration = 1000;
unsigned long previousMillis = 0;
void setup(){
pinMode(LED_BUILTIN, OUTPUT);
}
void loop(){
// Timer object.
static VirtualDelay clapCounterTimer;
// Get the current time.
unsigned long currentMillis = millis();
// Check for a clapping sound (1 ms works good). If too much time
// elapses here, you could miss the "beginning" of the clap.
if(myTimer1(loopDelay, currentMillis) == 1){
// Clap detected.
if(digitalRead(soundSensorPin) == 1){
clapCounter += 1;
// When the first the clap is detected, start a timer
// to reset the clap counter to 0 after 1 second.
if(clapCounter == 1){
clapCounterTimer.start(clapCounterTimerDuration);
}
// Delay execution of the loop. 400 ms works good.
delay(clapCounterDelay);
// If a second clap is detected, toggle the LED ON/OFF.
if(clapCounter > 1){
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
}
}
// Reset the clap counter to 0 after 1 second. If
// you don't do this, you could clap once, wait a
// minute, then clap again and the LED will change state.
if(clapCounterTimer.elapsed()){
clapCounter = 0;
}
}
// Clap loop timer.
byte myTimer1(unsigned long loopDelay, unsigned long currentMillis){
if(currentMillis - previousMillis >= loopDelay){previousMillis += loopDelay;return 1;}
else{return 0;}
}