loop and variable initialisation error? Servo motor/piezo

Hi,
The end goal is for a piezo to listen for knocks and move an object (a statue of Tinky-Winky) attached to a servo motor. I'm writing this incrementally - so I know that this code does not fully perform the above described, but I am stuck with 3 things.

As soon as I power the arduino, the light comes on and the statue begins to move - no knocks required.

  1. I have initialised number of valid knocks at 1. As (1%5 == 0) should return FALSE I am not sure why the spinCondition1 function is initialised without any knocks.

  2. I am having trouble exiting the spinCondition1 loop. At the moment I am just incrementing the numOfValidKnocks so it fails to meet the condition. It exits the function, but until I can find another way it infinitely loops and the statue twitches.

  3. It's showing me knocks, when there are no knocks. Why? (code and output of the monitor below)

     #include <Servo.h>
     Servo myServo;
    
     const int piezo = A0;
     const int yellowLed = 3;
     const int resetButton = 2;
    
     int knockDetect;
     int resetTrigger;
    
     int numOfValidKnocks = 1;
    
     const int quietKnock = 1;
     const int loudKnock = 5;
     
//all you're doing here is setting a state to test later
     boolean locked = true;
    
    
    void setup() {
      myServo.attach(9);
      pinMode (yellowLed, OUTPUT);
      pinMode (resetButton, INPUT);
      
      Serial.begin(9600);

      myServo.write(0);
      Serial.print("Tinky Sits at 0");
      
    }


void loop() {
 //if a knock detcted is between a range turn on yellow light

  knockDetect = analogRead(piezo);
  turnOnYellowLight(knockDetect);
  spinCondition1(numOfValidKnocks);
  

}

//-------function time-------//

 boolean turnOnYellowLight(int value){
  knockDetect = analogRead(piezo);
    if(value > quietKnock && value < loudKnock){
        digitalWrite(yellowLed, HIGH);
        Serial.print("valid knock value is ");
        Serial.println(value);
     //without this num of valid knocks never increments, and spin tinky never called
        numOfValidKnocks ++;
        Serial.print("num of valid knocks is ");
         Serial.print(numOfValidKnocks);
      }
  }

  boolean spinCondition1(int value) {
      if(numOfValidKnocks %5 == 0){
      spinTinky(numOfValidKnocks);
    //you have this here to break the loop - otherwise just calls spinTinky and never allows more knocks to be detected
      numOfValidKnocks ++;
    //return; (why doesn't this work?)
       } else {
          return;
        }
    }

  boolean spinTinky (int value){
      Serial.println("tinky has spun 90*");
      //when you do this, it jerks around forever as you increment num of valid knocks
      myServo.write(90);
      delay(2000);
      myServo.write(0);
      
    }

This is what is what is outputted in the serial monitor when I power up the arduino. Changing the value of high and low knock has no effect. (I understand why it increments on it's own once it's initially started, I just don't understand why it starts without knocks)

Tinky Sits at 0valid knock value is 2
num of valid knocks is 2valid knock value is 2
num of valid knocks is 3valid knock value is 3
num of valid knocks is 4valid knock value is 3
num of valid knocks is 5tinky has spun 90*
valid knock value is 4
num of valid knocks is 7valid knock value is 4
num of valid knocks is 8valid knock value is 2
num of valid knocks is 9valid knock value is 4
num of valid knocks is 10tinky has spun 90*
valid knock value is 2
num of valid knocks is 12valid knock value is 4
num of valid knocks is 13valid knock value is 2
num of valid knocks is 14valid knock value is 2
num of valid knocks is 15tinky has spun 90*
      pinMode (resetButton, INPUT);

How IS this switch wired?

  knockDetect = analogRead(piezo);

The analogRead() function does NOT detect knocks.

 boolean turnOnYellowLight(int value){
  knockDetect = analogRead(piezo);
    if(value > quietKnock && value < loudKnock){
        digitalWrite(yellowLed, HIGH);

Why do you read the sensor again, and then not use the value read?

        numOfValidKnocks ++;

So, I knock on Monday afternoon, and nothing happens. I knock again on Thursday morning. Nothing happens. Over the course of a week, I keep banging on the sensor. Eventually, I've banged on it enough, and tinky winky tinkles all over the place. Is that what REALLY should happen?

  boolean spinCondition1(int value) {

Why does this function take a value that it never uses?

      numOfValidKnocks ++;

Why on earth are you unconditionally incrementing this variable in a function called unconditionally?

    //return; (why doesn't this work?)

Because you commented it out.

@OP

The problem that I am sensing is here:

if(value > quietKnock && value < loudKnock)

1. The argument of if() structure is evaluated to true even the A0-pin is tied to 0V. It is because the set value of quietKnock is 1; whereas, the error count of the ADC is 2 LSB (and hence the A0 = knockDetect = piezo = value). As a result, the variable value assumes 2 (or 3) and the argument of if() structure becomes true. So, change the setting value of quietKnock at 3 (the safe side); everything should be OK!

2. Also, think re-structuring the given single if() structure as nested one:

if(value>quietKnock)
{
   if(value<loudKnock)
   {
        //do job
   }
}

@PaulS
Thanks
I thought my spinCondition1 function was taking numOfValidKnocks as a value - or have I got the type of function wrong?

For the analogread(piezo) - Do you mean in this code?

As for the commented out return statement - It doesn't work when it's commented in - I am struggling to exit the loop here. I have added another if statement to the function, but to no avail.

Thank in advance!

  boolean spinCondition1(int value) {
      if(numOfValidKnocks %5 == 0){
      spinTinky(numOfValidKnocks);
    //you have this here to break the loop - otherwise just calls spinTinky and never allows more knocks to be detected
      numOfValidKnocks ++;
    
       } if(numOfValidKnocks %5 != 0) {
          return;
          Serial.print("number of valid knocks cannot be divided by 5");
        }
    }

@Golam

You were right - there was something off with the piezo value - I can't just increase it randomly but a range of 6-9 seems to work..I'm confused but I'll just keep going for now.

There was a problem with the modulo division - it wasn't evaluating properly to true or false. Do you know if it's an issue with the function type I used?

1. Why have you declared these functions: turnOnYellowLight(knockDetect);
spinCondition1(numOfValidKnocks); as boolean and not void. The affects are different.

2. Think, if the following two are the same (the affects are different).

void spinCondition1(int value)
{
   if (numOfValidKnocks % 5 == 0)
  {

and

void spinCondition1(int value)
{
  byte n1 = (value % 5);
  if (n1 == 0);//(numOfValidKnocks % 5 == 0)
  {