failing to exit a switch case early.

Hello all,
I am trying to exit a switch case early by using a button and failing miserably. I've spent hours :confused: tweaking the program and double checking hardware.

Can anyone help me figure out why this program seems to ignore my attempts to exit the switch case when I press the resetBtn?

Any help would be appreciated.

const byte buzzer = 11;
const byte beepCycles = 16;
const byte resetBtn = A2;
byte beepCount = 0;
byte state = 0;
bool turnOn = true;
unsigned long waitStart;
unsigned long shortPeriod = 500;
unsigned long longPeriod = 5000;
unsigned long currentTime;

void setup()
{
  pinMode(buzzer, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(resetBtn,INPUT_PULLUP);
  //digitalWrite(ledPin, HIGH);
  //digitalWrite(resetBtn, HIGH);
  waitStart = millis();
}

void loop()
{
  switch (state)
  {
    case 0:
      currentTime = millis();
      digitalRead(resetBtn);
      if(resetBtn==LOW){                    // this is where i am trying to exit the switch case
          state = 2;
          //digitalWrite(13, HIGH);
          break;
        }
      if (currentTime - waitStart >= shortPeriod && turnOn==true)
      {
        tone(buzzer,5000);
        waitStart = currentTime;
        beepCount++;
        state = 1;
        turnOn=false;
        if (beepCount == beepCycles)
        {
          state = 2;
        }
      }
      break;
      
    case 1:
      currentTime = millis();
      digitalRead(resetBtn);
      if(resetBtn==LOW){                    // this is where i am trying to exit the switch case
          state = 2;
          //digitalWrite(13, HIGH);
          break;
        }
      if (currentTime - waitStart >= shortPeriod && turnOn==false)
      {
        noTone(buzzer);
        waitStart = currentTime;
        beepCount++;
        state = 0;
        turnOn=true;
        if (beepCount == beepCycles)
        {
          state = 2;
        }
      }
      break;
      
    case 2:
      break;
  }
}

Show us a good schematic of your circuit.
Show us a good image of your ‘actual’ wiring.
Give links to components.
Posting images:
https://forum.arduino.cc/index.php?topic=519037.0


This does nothing as it is written.

. . .
digitalRead(resetBtn);
. . .

Pin, the magic word for today is "Pin".

You can prevent so much trouble by using the term "Pin" in a variable name that is for a pin.
For example:

const byte buzzerPin = 11;
const byte resetButtonPin = A2;

This is the reference for digitalRead(): digitalRead() - Arduino Reference.
That functions returns something.

int the_returned_value_which_is_high_or_low = digitalRead( a_pin_of_the_arduino_board);

I did not look at the functionality of your code yet.

Read up on digitalRead()

Problem is, your program does nothing when it enters state 2. So it likely does enter state 2, it's just that it stays there doing nothing.

You have put 'break' within the if loop in Case 0 and Case 2 so it will not exit if the if loop is not true

Thank you for everyone's input.
I was trying, unsuccessfully, to modify a portion of an existing program. I went back and rewrote the whole thing as a series of if statements. Everything is working as expected.

Here is the functional program I ended up with. I understand this goes nowhere and just stops. The variable alarmVal is controlled elsewhere. This is only a small 'chunk' I was trying to debug.

/*
* The purpose of this is to beep a set number of times. At any point, if the 
* resetBtn is pushed, the program is to stop beeping and reset the alarmVal to 0.
* It may not be elegant, but it works as intended. 
*/

const byte buzzer = 11;     //peizo buzzer pin
const byte beepCycles = 16; //beeps * 2
const byte resetBtn = A2;   //resetBtn pin
byte beepCount = 0;         //initial beep count
int alarmVal = 1;           //initial value for testing
bool turnOn = true;         //initial value for testing
unsigned long waitStart;
unsigned long shortPeriod = 500;
unsigned long longPeriod = 5000;
unsigned long currentTime;

void setup()
{
  pinMode(buzzer, OUTPUT);
  pinMode(resetBtn,INPUT_PULLUP);
  waitStart = millis();
}

void loop(){

  if(alarmVal==1){                                
    currentTime = millis();                   
    bool value = digitalRead(resetBtn);         //save state of resetBtn
    if(value==LOW){                             //if Btn pressed
      alarmVal=0;                               //reset alarmVal
      noTone(buzzer);                           //turn off buzzer
    }
    if (currentTime - waitStart >= shortPeriod){   //timer conditions for tone cycle
        tone(buzzer,5000);                         //initial buzzer 
        waitStart = currentTime;                   //save value for next loop
        beepCount++;                               //increment beepCount
        alarmVal = 2;                              //set alarmVal for noTone cycle
        if (beepCount == beepCycles){              //if all cycles are complete
          alarmVal = 0;                            //reset alarmVal
        }
    }
  }
      
  if(alarmVal==2){                                 //rinse and repeat...
    currentTime = millis();
    bool value = digitalRead(resetBtn);
    if(value==LOW){                    
      alarmVal = 0;
      noTone(buzzer);
    }
    if (currentTime - waitStart >= shortPeriod){
        noTone(buzzer);
        waitStart = currentTime;
        beepCount++;
        alarmVal = 1;
        if (beepCount == beepCycles)
        {
          alarmVal = 0;
        }
    }      
  }
}

To make it elegant, pull different functionality apart and use common software techniques.

Instead of thinking in code, you can also think in data streams that flow through the Arduino. The resetButton creates a stream of data (it is pressed or it is not pressed). To get that data stream into the loop(), use digitalRead() just once at the beginning of the loop(). You check the resetButton twice in the loop(), then that data stream has to split into two streams, that makes no sense.

Read about the Final State Machine: The Finite State Machine | Majenko Technologies.

I like to use software-millis-timers in a more seperated way. For example my millis_single_delay.ino. Combining millis() with a Finite State Machine is my millis_and_finite_state_machine.ino.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.