inconsistent return function

Hello,

I am relatively new to arduino and wrote this code for a clap activated servo with 2 claps activating the servo.

I made an integer: int clapDetection() to record a clap and determine if its correct by returning a value: either CLAP_DETECTED or NO_CLAP.

This in turn is read by an other integer: int clapSequence() that starts counting the claps and determining the right amount before returning an output: WRONG_NUMBER or FINAL_DETECTED or NO_CLAP.

And then this is read by an if function: if (clapSequence() == FINAL_DETECTED) that toggles the servo.

My problem is that the returned outputs aren’t always read by the following function, giving me a really inconsistent system.
The large amount of serial.prints are there for me to find the source of the problem but I can’t see where I messed up.

Here is the code:

#include <Servo.h>
Servo myServo;
const int toggleLED = 6;
const int clapLED1 = 8;
const int clapLED2 = 7;
const int mic = A0;
const int thresholdPot = A1;

//mic and potentiometer inpput integers
int threshold;
int thresholdPotVal;
int micVal;

//integers for determining ambient noise levels
int bufferSize = 6;    //times to record mic values for storing in buffer array
int buffer[6];       //stored mic values
int total;           //total equals the added previous mic values for dividing after to get an average
int average;         //the average ambient noise level
int loopIteration = 0; //loop variable to update ambient noise levels in the buffer array

//clap detection
int toggleOutput = 1;  //output variable: 1 turns servo in one direction, -1 turns servo in other direction
int detectClaps;       //
int totalClaps = 2;    //total claps before output
int clapNumber = 0;    //determines what clap we are at
int clapFadeTime = 150;  //time span of each clap
int clapTime = 3000;   //time between claps

const int CLAP_DETECTED = 0, NO_CLAP = 1, WRONG_NUMBER = 2, FINAL_DETECTED = 3;

void setup() {
  Serial.begin(9600);
  pinMode(toggleLED, OUTPUT);
  pinMode(clapLED1, OUTPUT);
  pinMode(clapLED2, OUTPUT);


}

void loop() {
  initialize();
  runDetector();
}

//determine ambient noise levels at program start (runs once)
void initialize() {
  for(int i=0; i<bufferSize; i++) {
    readMic();

    buffer[i] = micVal;
    total = total+micVal;
    average = (total/(i+1));

    Serial.print("Ambient noise level: ");
    Serial.print(average);
    Serial.print("    Total (6 prev readings): ");
    Serial.print(total); 
    Serial.print("    Current value: ");
    Serial.print(micVal); 
    Serial.print("    Offset: ");
    Serial.println(micVal-average);
  }
}

//run detector in a constant loop
void runDetector() {
  while(true) { //enables a infinite loop

    clapSequence();

    //toggles output when right combination is detected
    if (clapSequence() == FINAL_DETECTED) {
      Serial.print("Output toggled: ");
      Serial.println(toggleOutput);
      digitalWrite(clapLED1, HIGH);
      digitalWrite(clapLED2, HIGH);
      digitalWrite(toggleLED, HIGH);

      if(toggleOutput == 1){
        myServo.attach(9);
        myServo.write(160);
        delay (150);
        myServo.write(90);
        delay (500);
        myServo.detach(); 
      }
      else if(toggleOutput == -1) {
        myServo.attach(9);
        myServo.write(20);
        delay (150);
        myServo.write(90);
        delay (500);
        myServo.detach(); 
      }
      digitalWrite(clapLED1, LOW);
      digitalWrite(clapLED2, LOW);
      digitalWrite(toggleLED, LOW);
    }
  }
}

//determines what state the clap sequence is at (final clap detected, wrong number of claps or no claps)
int clapSequence() {

  clapDetection();

  if (clapDetection() == CLAP_DETECTED) {
    clapNumber = 1;
    Serial.print("Clap detected - CLAP: ");
    Serial.println(clapNumber);

    for(int i = 0; i < clapTime; i++) {
      if(clapDetection() == CLAP_DETECTED) {
        clapNumber ++;
        Serial.print("Clap detected - CLAP: ");
        Serial.print(clapNumber);
        Serial.print("   clapTime: ");
        Serial.println(i);
      }
      if (clapNumber == 1) {
        digitalWrite(clapLED1, HIGH);
      }
      if (clapNumber == 2) {
        digitalWrite(clapLED2, HIGH);
      }
    }
    if (clapNumber < totalClaps || clapNumber > totalClaps) {
      clapNumber = 0;
      digitalWrite(clapLED1, LOW);
      digitalWrite(clapLED2, LOW);
      Serial.println("WRONG CLAP NUMBER");
      return WRONG_NUMBER;
    }
    else if (clapNumber == totalClaps) {
      toggleOutput *= -1;
      Serial.println("FINAL DETECTED");
      return FINAL_DETECTED;
    }
  }
  else if (clapDetection() == NO_CLAP) {
    clapNumber = 0;
    Serial.println("BAD CLAP END");
    return NO_CLAP;
  }
}

//a function that detects the claps
int clapDetection() {

  thresholdPotVal = analogRead(thresholdPot);
  threshold = map(thresholdPotVal, 0, 1023, 10, 70);
  readMic();

  if (micVal > (average+threshold)) {
    Serial.println();
    Serial.print("< Clap Pt.1   MicValue: ");
    Serial.print(micVal);
    Serial.print("   Threshold: ");
    Serial.print(threshold);

    delay (clapFadeTime);

    //update ambient noise levels
    readMic();
    total = (total - buffer[loopIteration]) + micVal; 
    average = (total/bufferSize);
    buffer[loopIteration] = micVal;
    loopIteration = (loopIteration+1)%bufferSize;

    Serial.print("   MicValue2: ");
    Serial.print(micVal);
    Serial.print("   Average: ");
    Serial.println(average);

    if (micVal < (average+8)) {
      Serial.print("< Clap Pt.2   MicValue: ");
      Serial.println(micVal);
      return CLAP_DETECTED;
    }
    else if (micVal >= (average+8)) {
      while (micVal >= (average+8)) {
        readMic();
        Serial.print("< BAD CLAP    MicValue: ");
        Serial.println(micVal);
        Serial.println("CONSTANT HIGH SOUND");
      }
      return NO_CLAP;
    }
  }
}

void readMic() {
  micVal = analogRead(mic);
}

Touix103:
My problem is that the returned outputs aren't always read by the following function, giving me a really inconsistent system.

It is very inconsistent on your system that you are calling clapSequence(); twice:

  • first time calling ==> throw away any return value, seems of no interest
  • second time calling ==> process the return value

Your original code:

    clapSequence();

    //toggles output when right combination is detected
    if (clapSequence() == FINAL_DETECTED) {

Maybe you wanted to code this instead:

    int result= clapSequence();

    //toggles output when right combination is detected
    if (result == FINAL_DETECTED) {

THANK YOU!

That was the solution. You just saved me from a huge headache.

I made an integer: int clapDetection()

That's NOT an integer. It is a function!