FC-04 Sound sensor for 3 claps

I’m working on a clap clap light switch sensor for a school project. The FC-04 sensor is working, however it is picking up my voice and other background sounds to turning on the light. I tried adjusting the potentiometer however it still reacts to other non-clap sounds.

Is there a way to change the code to a clap pattern to fix this? e.g. clap (pause), clap. clap.

Here is the site tutorial that I’m following:

Here is the code:

#define signalToRelayPin 13
#define sensorPin 2

int lastSoundValue;
int soundValue;
long lastNoiseTime = 0;
long currentNoiseTime = 0;
long lastLightChange = 0;
int relayStatus = HIGH;

void setup() {
  pinMode(sensorPin, INPUT);
  pinMode(signalToRelayPin, OUTPUT);


}

void loop() {
  soundValue = digitalRead(sensorPin);
  currentNoiseTime = millis();

  if (soundValue == 1) { // if there is currently a noise

    if (
      (currentNoiseTime > lastNoiseTime + 200) && // to debounce a sound occurring in more than a loop cycle as a single noise
      (lastSoundValue == 0) &&  // if it was silent before
      (currentNoiseTime < lastNoiseTime + 800) && // if current clap is less than 0.8 seconds after the first clap
      (currentNoiseTime > lastLightChange + 1000) // to avoid taking a third clap as part of a pattern
    ) {

      relayStatus = !relayStatus;
      digitalWrite(signalToRelayPin, relayStatus);
      lastLightChange = currentNoiseTime;
     }

     lastNoiseTime = currentNoiseTime;
  }

  lastSoundValue = soundValue;
}

As per the tutorial I’m using an:

  • Arduino UNO
  • FC-04 sound sensor
  • 5V relay

I agree this sensor does not sense only claps but rather sound in general. A clap sensor would require a circuit sensor that filters out low frequencies and lets high frequency of a clap sound pass through.

Here is some code that will sense 3 claps.

#define signalToRelayPin 10
#define sensorPin 2

int lastSoundValue;
bool soundValue;
long lastNoiseTime = 0;
long currentNoiseTime = 0;
int relayStatus = LOW;


long lastChangeTime[3]  = { 1, 2, 3 };            // clap history array
int idx = 0;                                      // current index pointer in clap history
int idxOrder[3][3] = {{0,1,2}, {1,2,0}, {2,0,1}}; // index order for tracking noise history

void setup() {
  pinMode(sensorPin, INPUT);
  pinMode(signalToRelayPin, OUTPUT);
  digitalWrite(signalToRelayPin, relayStatus);
  Serial.begin(9600);
}

void loop() {
  soundValue = digitalRead(sensorPin);
  currentNoiseTime = millis();


  if ( currentNoiseTime > lastNoiseTime + 200 ) { // debounce
    if ( lastSoundValue != soundValue ){          // if sound state has changed store the time and state.
      lastNoiseTime = currentNoiseTime;
      lastSoundValue = soundValue;
      if ( soundValue == 1 ){
        lastChangeTime[idx] = currentNoiseTime;
        idx++;
        if ( idx > 2 ){
          idx=0;
        }
        printArr();
        findPattern();
      }
    }
  }
}

// Print timings
void printArr(){
  Serial.println("===================================");
  for (int i = 0; i < 3; i++){
    Serial.print (lastChangeTime[i]);
    Serial.print(", ");
  }
  Serial.println("");
}

void findPattern(){
  // scan the history array for silence pattern:
  // sound; 1 second silence; sound; 500ms silence; sound;
  long silence1 = lastChangeTime[idxOrder[idx][1]] - lastChangeTime[idxOrder[idx][0]];
  Serial.print ("Silence1: "); Serial.println(silence1);
  Serial.print ("idx1/idx2: ");  Serial.print(idxOrder[idx][1]); Serial.print("/"); Serial.println(idxOrder[idx][0]);
  if (silence1 > 750 && silence1 < 1250){
    long silence2 = lastChangeTime[idxOrder[idx][2]] - lastChangeTime[idxOrder[idx][1]]; 
    Serial.print ("Silence2: "); Serial.println(silence2);
    Serial.print ("idx1/idx2: ");  Serial.print(idxOrder[idx][2]); Serial.print("/"); Serial.println(idxOrder[idx][1]);
    if ( silence2 > 350 && silence2 < 650){
      relayStatus = !relayStatus;
      digitalWrite(signalToRelayPin, relayStatus);
      Serial.println("light change");  
    }  
  }
}

Thank you