Looping switch case until button press

Hello,

A question about looping inside a switch case scenario.
I saw some tutorials and topics on this and other forums about it but it just couldn’t work.

Idea: I have 1 button that I want to use to go through a switch case menu.
Only when I press the button, the next case in the switch has to loop,
until then I want the case itself to loop.
In this code, the switch runs through it until it reaches the last one and stops there.
I tried some if / else if statements, one button menu’s and other ideas but I’m lost.
In the code I only display the first case, the second and further cases are copies.

Goal: Use the switch case to receive a signal, display a measurement every 1 / 2 secs,
and Most importantly: - I want to loop through custom buzzer and led signals. -
The custom ‘receiving signals’ are quite simple but I don’t know how to isolate just that and keep the rest the same…

Greets!

#include "Arduino.h"
#include <Wire.h>               // BMP280 + LCD screen
#include <LiquidCrystal_I2C.h>  //LCD screen
#include <SPI.h>                //NRF24L01
#include "RF24.h"               //NRF24L01
#include "i2c.h"                //BMP280 sensor 
#include "i2c_BMP280.h"         //BMP280 sensor 
#include <OneButton.h>
#include <MenuBackend.h>
#define NRF24L01_PIN_CE 4    //D4
#define NRF24L01_PIN_CS 10   //D10

const int menuButton = 3;
int menu = 0;
boolean isPressed = false; 
float temperature;
float pascal; 
int pascal2;

// leds met int voor hernoeming + buzzers
int led2 = 8;
int led1 = A0;
//int led2 = A1;
int led3 = A2; 
int led4 = A3; 

const int buzzer = 6;         //-> Transistor naar buzzer

LiquidCrystal_I2C lcd(0x27, 20, 4);
BMP280 bmp280;
RF24 myRadio (4, 10);

const int timeout = 1000;       //define timeout of 10 sec
//char menuOption = 0;             //menu option!
long time0;

struct package                   //NRF24L01 input
{
  int id = 0;
  float temperature = 0.0;
  char  text[100] = "empty";  //?
};
byte addresses[][6] = {"0"};
typedef struct package Package;
Package data;


//******************************************************************************************************** initialise & bmp test

void setup()
{
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(menuButton, INPUT_PULLUP);
  //pinMode(nextButton, INPUT_PULLUP);

  lcd.begin(20, 4);
  lcd.init();     // initialize the lcd
  lcd.backlight();

  Serial.begin(115200);   //(9600) is standard
  while (!Serial) ;       //whait for signal
  Serial.println("Lets Begin!");
  Serial.print("\n Probe BMP280: ");
  if (bmp280.initialize()) Serial.println("Sensor found");
  else
  {
    Serial.println("Sensor missing");
    while (1) {
      lcd.setCursor(2, 3); lcd.print("Sensor fout");
    }
  }
  // onetime-measure:
  bmp280.setEnabled(0);
  bmp280.triggerMeasurement();

  myRadio.begin();
  myRadio.setChannel(115);
  myRadio.setPALevel(RF24_PA_MAX);
  myRadio.setDataRate( RF24_250KBPS ) ;
  myRadio.openReadingPipe(1, addresses[0]);
  myRadio.startListening();
}


//*********************************************************************************************************   Button Function - Menu

void loop()
{
  if (digitalRead(menuButton) == LOW && isPressed == false ) //button is pressed AND this is the first digitalRead() that the button is pressed
  {
    isPressed = true;  //set to true, so this code will not run again until button released
    menudisplay(); // a call to a separate function that performs the switch statement and subsequent evoked code

    menu++; // this is done after the doSwitchStatement(), so case 0 will be executed on the first button press
        if (menu > 3) {
      menu = 0;
    }
    //menu = (menu+ 1) % 4; // does the same, without if-statement
  } else if (digitalRead(menuButton) == HIGH)
  {
    isPressed = false; //button is released, variable reset
  }
}
void menudisplay() {
  switch (menu) {
    case 0:

      Serial.println("Case 0");
      if ( myRadio.available())
      {
        while (myRadio.available())
        {
          myRadio.read( &data, sizeof(data) );
        }
        digitalWrite(buzzer, HIGH);             //RECEIVING SIGNALL 
        delay(1000);
        digitalWrite(buzzer, LOW);             //This is what I want to change.
        digitalWrite(led1, HIGH);              // All the other stuff has to be the same :)
        delay(200);                        // Only the number on the lcd screen about the menu that i'm in hehe
        digitalWrite(led1, LOW);
        digitalWrite(led2, HIGH);
        delay(200);
        digitalWrite(led2, LOW);
      }

      //else
      //{lcd.setCursor(0,0); lcd.print("X");        Wanneer de NRF geen signaal meer krijgt - pas de tijd nog aan!
      //}

      bmp280.awaitMeasurement();
      delay(1000);       //5 sec  - hoe vaak meet de sensor
      //float temperature;
      bmp280.getTemperature(temperature);

      //float pascal;
      bmp280.getPressure(pascal);
      //int pascal2;
      pascal2 = pascal / 100;
      //float SLpressure_mB = (((pascal) / pow((1 - ((float)(1)) / 44330), 5.255)) / 100.0);      //-> Accurate meting 2 dec.
      bmp280.triggerMeasurement();


      //lcd.clear();  //ziet er mooier uit - pas op dat er verder niets veranderd
      lcd.setCursor(0, 0); lcd.print("****************[V1]"); //lcd.setCursor(0, 1); lcd.print("|"); lcd.setCursor(0, 2); lcd.print("|");
      lcd.setCursor(0, 3); lcd.print("______[Menu:1]_____>"); //lcd.setCursor(19, 1); lcd.print("|"); lcd.setCursor(19, 2); lcd.print("|");
      lcd.setCursor(1, 1); lcd.print("Temp: "); lcd.print(temperature); lcd.print(" C");
      lcd.setCursor(1, 2); lcd.print("Druk: "); lcd.print(pascal2); lcd.print(" mB");
//*********************************************************************************************************

//case 1: ... 
//case: 2...
//case: 3...
}
}

Code is not complete

J-M-L:
Code is not complete

That is because it exceeds the 9000 char. range.
case 1 / 2 / 3 are copy's. The only difference is the lcd.print menu and the receiving signal to the LEDs and buzzers.
I hope this explains it.

derkpestman:
That is because it exceeds the 9000 char. range.
case 1 / 2 / 3 are copy's. The only difference is the lcd.print menu and the receiving signal to the LEDs and buzzers.
I hope this explains it.

well unless there is a bug in the code we don't see... for example do you have "break" at the end of each case ?

why don't you craft a small code without the radio etc and just one button and the LCD to try this out ?

J-M-L:
well unless there is a bug in the code we don't see... for example do you have "break" at the end of each case ?

why don't you craft a small code without the radio etc and just one button and the LCD to try this out ?

The problem isn't a bug because the code works, but it just circles trough the menu's until it stops at menu 4/ case 3. I simply wonder if I have to use the switch case statement with the pushbutton to circle through the outputs(buzzer + leds options) or are there other options available. (I commented in the code what I wanted to change in the case 0)
The problem lies at the beginning of the void loop because there is where all the magic happens :slight_smile:
Thanks for reading.

This sounds like a super simple state machine. Assume you want each button push to just cycle once to the next menu, which would be continuously displayed, even after the button is released, right?

Isn’t this as simple as (pseudo code)

void loop () {
   if (Detect_button_press()) {
      // do the Increment menu thing
   }
   menudisplay();
}

You would need to add appropriate debouncing on Detect_button_press().

I don’t think the isPressed flag is gaining you anything in your original code

sorry I don't get what's the problem...