user16832: I have this double clap sensor code written, it seems it would work but it seems to trigger the double clap even on a single clap, any ideas?
int soundSensor = A1;
int relay = A2;
int relay2 = A3;
int relay3 = A4;
int relay4 = A5;
int claps = 0;
long detectionSpanInitial = 0;
long detectionSpan = 0;
boolean clapState = false;
int doubleClap = 0;


//Light sensor 
int photocellPin = A0;     // the cell and 10K pulldown are connected to a0
int LEDbrightness;       

//int delayValue = 100;
int photoSensor = 0;

// sound sample
const int sampleWindow = 50; // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;

//other
boolean isRelaysOn = false;
void setup() {
  pinMode(soundSensor, INPUT);
  pinMode(relay, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);
  turnRelayOff();
  Serial.begin(9600);
}

boolean state = false;
boolean lastState = true;
boolean lightTurnedItOff = false;
void loop() {

  /////////////
  // photo sensor
  //////////////////// 

  photoSensor = analogRead(photocellPin) > 623;

  /////////////
  // clap sensor
  /////////////////////
  double sensorState = getSoundLevel();
  Serial.println(sensorState);
  double threshold = .2;


  if (sensorState > threshold)
  {
    if (claps == 0)
    {
      detectionSpanInitial = detectionSpan = millis();
      claps++;
    }
    else if (claps > 0 && millis()-detectionSpan >= 50)
    {
      detectionSpan = millis();
      claps++;
      Serial.println(" CLAP ADDED!!!!");
    }
  }



  if (millis()-detectionSpanInitial >= 400){

    if (claps == 2)
    {
      claps++;
      doubleClap = 1 - doubleClap;
      state = !state;
      Serial.println("TWO claps!");

      if(lastState == state ){
        relayControl(doubleClap);
        lastState = !lastState;
      }
    }
    claps = 0;
  }

  if(isRelaysOn == true && photoSensor == 1){
    turnRelayOff();
    lightTurnedItOff = true;
  }
  if(isRelaysOn == true && photoSensor == 0 && lightTurnedItOff == true){
    turnRelayOn();
    lightTurnedItOff = false;
  }

}

void relayControl(int doubleClap){
  /////////////
  // relay control
  /////////////////////

  if(doubleClap == 1){ 
    turnRelayOn();
    Serial.println("on");
    isRelaysOn = true;

  }
  else{ 
    turnRelayOff();
    Serial.println("off");
    isRelaysOn = false;
  }; 


}

void turnRelayOn(){
  int delayAmount = 100;
  digitalWrite(relay, LOW);
  delay(delayAmount);
  digitalWrite(relay2, LOW);
  delay(delayAmount);
  digitalWrite(relay3, LOW);
  delay(delayAmount);
  digitalWrite(relay4, LOW);
  delay(100);
  digitalWrite(relay4, HIGH);
  delay(100);
  digitalWrite(relay4, LOW);
}

void turnRelayOff(){
  digitalWrite(relay, HIGH);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, HIGH);
  digitalWrite(relay4, HIGH);
}

double getSoundLevel(){

  unsigned long startMillis= millis();  // Start of sample window
  unsigned int peakToPeak = 0;   // peak-to-peak level

  unsigned int signalMax = 0;
  unsigned int signalMin = 1024;

  // collect data for 50 mS
  while (millis() - startMillis < sampleWindow)
  {
    sample = analogRead(soundSensor);
    if (sample < 1024)  // toss out spurious readings
    {
      if (sample > signalMax)
      {
        signalMax = sample;  // save just the max levels
      }
      else if (sample < signalMin){
        signalMin = sample;  // save just the min levels
      }
    }
  }
  peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
  double volts = (peakToPeak * 3.3) / 1024;  // convert to volts

  return volts;
}

Serial monitor:

0.02
  0.02
  0.02
  0.02
  0.01
  0.01
  2.20
  0.30  CLAP ADDED!!!!
  0.13
  0.09
  0.04
  0.02
  0.02
  0.01
  0.02 TWO claps! on
  1.11
  0.06
  0.05
  0.07
  0.15
  0.10
  0.03
  0.10
  0.06
  0.03
  0.04
  0.06


user12010: If your first clap rings for more than 50ms, the program counts it as a second clap.  After detecting a clap, you need to wait for the sound to die down before you start listening for a second clap.

user1186: What you probably want to track is something more like:

high sound period of highMin to highMax ms 
low sound period of lowMin to lowMax ms 
high sound period of highMin to highMax ms 
low sound period of at least lowDone ms (no max needed)

Anything not meeting those time bounds is not two claps, reset state and timers.  If you get to the end of the fourth step, accept as two claps.
I have not tested timing of claps to estimate the periods needed; you need to tweak that with the hardware you are actually using; for example, different microphones may ring for different times after a sharp clap impulse.
States could be:

waiting for start of first clap (sample until > threshold) 
waiting for end of first clap (sample until < threshold or timeout)
waiting for start of second clap (sample until > threshold or timeout)
waiting for end of second clap (sample until < threshold or timeout)
got second clap


16832: <p>I have this double clap sensor code written, it seems it would work but it seems to trigger the double clap even on a single clap, any ideas?</p>

<pre class="lang-c prettyprint-override"><code>int soundSensor = A1;
int relay = A2;
int relay2 = A3;
int relay3 = A4;
int relay4 = A5;
int claps = 0;
long detectionSpanInitial = 0;
long detectionSpan = 0;
boolean clapState = false;
int doubleClap = 0;


//Light sensor 
int photocellPin = A0;     // the cell and 10K pulldown are connected to a0
int LEDbrightness;       

//int delayValue = 100;
int photoSensor = 0;

// sound sample
const int sampleWindow = 50; // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;

//other
boolean isRelaysOn = false;
void setup() {
  pinMode(soundSensor, INPUT);
  pinMode(relay, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);
  turnRelayOff();
  Serial.begin(9600);
}

boolean state = false;
boolean lastState = true;
boolean lightTurnedItOff = false;
void loop() {

  /////////////
  // photo sensor
  //////////////////// 

  photoSensor = analogRead(photocellPin) &gt; 623;

  /////////////
  // clap sensor
  /////////////////////
  double sensorState = getSoundLevel();
  Serial.println(sensorState);
  double threshold = .2;


  if (sensorState &gt; threshold)
  {
    if (claps == 0)
    {
      detectionSpanInitial = detectionSpan = millis();
      claps++;
    }
    else if (claps &gt; 0 &amp;&amp; millis()-detectionSpan &gt;= 50)
    {
      detectionSpan = millis();
      claps++;
      Serial.println(" CLAP ADDED!!!!");
    }
  }



  if (millis()-detectionSpanInitial &gt;= 400){

    if (claps == 2)
    {
      claps++;
      doubleClap = 1 - doubleClap;
      state = !state;
      Serial.println("TWO claps!");

      if(lastState == state ){
        relayControl(doubleClap);
        lastState = !lastState;
      }
    }
    claps = 0;
  }

  if(isRelaysOn == true &amp;&amp; photoSensor == 1){
    turnRelayOff();
    lightTurnedItOff = true;
  }
  if(isRelaysOn == true &amp;&amp; photoSensor == 0 &amp;&amp; lightTurnedItOff == true){
    turnRelayOn();
    lightTurnedItOff = false;
  }

}

void relayControl(int doubleClap){
  /////////////
  // relay control
  /////////////////////

  if(doubleClap == 1){ 
    turnRelayOn();
    Serial.println("on");
    isRelaysOn = true;

  }
  else{ 
    turnRelayOff();
    Serial.println("off");
    isRelaysOn = false;
  }; 


}

void turnRelayOn(){
  int delayAmount = 100;
  digitalWrite(relay, LOW);
  delay(delayAmount);
  digitalWrite(relay2, LOW);
  delay(delayAmount);
  digitalWrite(relay3, LOW);
  delay(delayAmount);
  digitalWrite(relay4, LOW);
  delay(100);
  digitalWrite(relay4, HIGH);
  delay(100);
  digitalWrite(relay4, LOW);
}

void turnRelayOff(){
  digitalWrite(relay, HIGH);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, HIGH);
  digitalWrite(relay4, HIGH);
}

double getSoundLevel(){

  unsigned long startMillis= millis();  // Start of sample window
  unsigned int peakToPeak = 0;   // peak-to-peak level

  unsigned int signalMax = 0;
  unsigned int signalMin = 1024;

  // collect data for 50 mS
  while (millis() - startMillis &lt; sampleWindow)
  {
    sample = analogRead(soundSensor);
    if (sample &lt; 1024)  // toss out spurious readings
    {
      if (sample &gt; signalMax)
      {
        signalMax = sample;  // save just the max levels
      }
      else if (sample &lt; signalMin){
        signalMin = sample;  // save just the min levels
      }
    }
  }
  peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
  double volts = (peakToPeak * 3.3) / 1024;  // convert to volts

  return volts;
}
</code></pre>

<p>Serial monitor:</p>

<blockquote>
  <p>0.02
  0.02
  0.02
  0.02
  0.01
  0.01
  2.20
  0.30  CLAP ADDED!!!!
  0.13
  0.09
  0.04
  0.02
  0.02
  0.01
  0.02 TWO claps! on
  1.11
  0.06
  0.05
  0.07
  0.15
  0.10
  0.03
  0.10
  0.06
  0.03
  0.04
  0.06</p>
</blockquote>
 12010: <p>If your first clap rings for more than 50ms, the program counts it as a second clap.  After detecting a clap, you need to wait for the sound to die down before you start listening for a second clap.</p>
 1186: <p>What you probably want to track is something more like:</p>

<ul>
<li>high sound period of highMin to highMax ms </li>
<li>low sound period of lowMin to lowMax ms </li>
<li>high sound period of highMin to highMax ms </li>
<li>low sound period of at least lowDone ms (no max needed)</li>
</ul>

<p>Anything not meeting those time bounds is not two claps, reset state and timers.  If you get to the end of the fourth step, accept as two claps.</p>

<p>I have not tested timing of claps to estimate the periods needed; you need to tweak that with the hardware you are actually using; for example, different microphones may ring for different times after a sharp clap impulse.</p>

<p>States could be:</p>

<ul>
<li>waiting for start of first clap (sample until > threshold) </li>
<li>waiting for end of first clap (sample until &lt; threshold or timeout)</li>
<li>waiting for start of second clap (sample until > threshold or timeout)</li>
<li>waiting for end of second clap (sample until &lt; threshold or timeout)</li>
<li>got second clap</li>
</ul>
