Having trouble with a program to set Modes

I am going to be using this to measure the angle on a faceting machine using a pot.

The end program has three modes:

  1. RUN this is the default and will display the angle, and have a way to set the current angle so when you approach it it will set a buzzer
  2. Calibrate this will ask the user to set the POT to 0 degrees and take a reading, then set the pot to 90 degrees and take a reading. This will calibrate the machine
  3. Settings This allows the user to change defaults for things like timeout when in calibrate or settings and after that time it defaults to run, and some other settings
    The first thing I am trying is a modified debounce program to read the input of a switch, debounce it, and change the mode from run to calibrate to settings.
    I tried to use “Run” “Calibrate” and “Settings” as the modes, but I was getting an error, (I forget the error) so I switched the state to 1, 2, and 3 and then am going to program things to happen when in that state.

Eventually there will be output to a display, but to get it working I am setting 3 leds one for each mode.
I also left a led for the state of the button

BUT
I when I run it, the state of the button stays high and the led for run mode stays

on 

/*
  CHANGE MODES

first debounce the switch 
  Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
  press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's a
  minimum delay between toggles to debounce the circuit (i.e. to ignore noise).

  created 21 Nov 2006
  by David A. Mellis
  modified 30 Aug 2011
  by Limor Fried
  modified 28 Dec 2012
  by Mike Walters
  modified 30 Aug 2016
  by Arturo Guadalupi
  modified nov 17 2021 
  Ted Wilson to change modes 
*/

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;           // the number of the pushbutton pin
const int ledpinrun = 13;          // pin 13 is led for run state 
const int ledpincalibrate = 12;    // pin 12 is led for calibrate state 
const int ledpinsettings = 11;     // pin 11 is led for settings state
const int ledpin = 10;             // pin 10 is led for button is high or low  


// Variables will change:
int ledstaterun = HIGH;        // set led state run to high 
int ledstatecalibrate = LOW; // set led state calibrate to low 
int ledstatesettings = LOW;  // set led state settings to low 
int newmode = 1;           // set new mode to run  mode 1 is run, 2 is calibrate, 3 is settings
int currentmode =1;       // set the current mode to Run 
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin
int ledState = HIGH;         // the current state of the outout 

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledpinrun, OUTPUT);
  pinMode(ledpincalibrate, OUTPUT);
  pinMode(ledpinsettings, OUTPUT);
  pinMode(ledpin, OUTPUT);

  // set initial led states
     digitalWrite(ledpinrun, ledstaterun);
    digitalWrite (ledpincalibrate, ledstatecalibrate);
    digitalWrite (ledpinsettings, ledstatesettings);
    digitalWrite (ledpin,ledState);

}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;
      // change the if the state has changed to high 
  
      if (buttonState == HIGH) {
        ledState = !ledState;
 
       if (currentmode == 1) {
            newmode = 2;
            ledstaterun = LOW;
            ledstatecalibrate = HIGH;
            ledstatesettings = LOW; }
  
         else if (currentmode == 2) {
             newmode = 3;
              ledstaterun = LOW;
            ledstatecalibrate = LOW;
            ledstatesettings = HIGH;}
  
         else {newmode = 1;
            ledstaterun = HIGH;
            ledstatecalibrate = LOW;
            ledstatesettings = LOW;}
     
       // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;   
      // set the mode 
 currentmode = newmode;   
        }
    }
  }
  
  // set the LEDs:
    digitalWrite(ledpinrun, ledstaterun);
    digitalWrite (ledpincalibrate, ledstatecalibrate);
    digitalWrite (ledpinsettings, ledstatesettings);
    digitalWrite (ledpin,ledState);
  
}

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

Do you have a pulldown resistor on your button? If not, it'll float when not pressed and give you unreliable results.

Yes there is a pull down resistor, per the setup in the original debounce program

If i run the original program it works

If i comment out tne code i added to change modes it does not

Sorry about that.
Should i repost the code?

I tried to edit my original post to follow the rules, but as a newbe I am not sure i got it right

Edit your first post and select the whole of the sketch then click the </> icon in the to add the code tags and then save the post

I just edited my original post

Thanks. See how much easier the code is to read in the scrolling window and to copy with just one click

Can you post your wiring diagram, or a schematic.

You need to make sure that the button has some form of pull up/down resistor.. if not then when it is not being pressed its state is undefined.

Ok...so your code does my head in... it is seriously way too complex for what it is trying to do.

It doesn't work, because...

int lastButtonState = LOW;  

therefore.. this

  if (reading!= lastButtonState)
  {
    lastDebounceTime = millis();
  }

can only happen when reading is HIGH.

BUT.. it keeps happening while reading is HIGH... so

    lastDebounceTime 

keeps getting reset...

until the button is released... then this can becomes true

  if ((millis() - lastDebounceTime) > debounceDelay)

but now reading must be LOW, so...

    if (reading != buttonState)

can never be true...

In other words... your logic to toggle the pin state is never true.

Thanks

You say it is to complex for what i want to do

How can i make it simple?

Looks like you started with the example Debounce sketch... you should compare your code to that example, side by side.

This line is in the wrong place.

  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;

It needs to be after this line...

  // set the LED:
  digitalWrite(ledPin, ledState);

I got it working after changing the initial state to high.
this got the read of button working

then I ran into a problem not setting the leds so only one was on at a time it went from state 3 to state 1

I had left out resetting some of the variables

and I found some } that were out of place.

this version is now working as I wanted it to work.

thanks for all of the help
I auto formatted this in the tool and used the </> to put it in this reply



/*
  CHANGE MODES ver 1 make leds light

  first debounce the switch
  Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
  press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's a
  minimum delay between toggles to debounce the circuit (i.e. to ignore noise).

  created 21 Nov 2006
  by David A. Mellis
  modified 30 Aug 2011
  by Limor Fried
  modified 28 Dec 2012
  by Mike Walters
  modified 30 Aug 2016
  by Arturo Guadalupi
  modified nov 17 2021
  Ted Wilson to change modes
*/

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;           // the number of the pushbutton pin
const int ledpinrun = 13;          // pin 13 is led for run state
const int ledpincalibrate = 12;    // pin 12 is led for calibrate state
const int ledpinsettings = 11;     // pin 11 is led for settings state
const int ledpin = 10;             // pin 10 is led for button is high or low


// Variables will change:
int ledstaterun = HIGH;        // set led state run to high
int ledstatecalibrate = LOW; // set led state calibrate to low
int ledstatesettings = LOW;  // set led state settings to low
int newmode = 1;            // set new mode to run  mode 1 is run, 2 is calibrate, 3 is settings
int currentmode = 1;      // set the current mode to Run
int buttonState;             // the current reading from the input pin
int lastButtonState = HIGH;   // the previous reading from the input pin
int ledState = HIGH;         // the current state of the outout

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledpinrun, OUTPUT);
  pinMode(ledpincalibrate, OUTPUT);
  pinMode(ledpinsettings, OUTPUT);
  pinMode(ledpin, OUTPUT);

  // set initial led states
  digitalWrite(ledpinrun, ledstaterun);
  digitalWrite (ledpincalibrate, ledstatecalibrate);
  digitalWrite (ledpinsettings, ledstatesettings);
  digitalWrite (ledpin, ledState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);
  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:
  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;
      // change the if the state has changed to high

      if (buttonState == HIGH) {
        ledState = !ledState;

        if (currentmode == 1) {
          newmode = 2;
          ledstaterun = LOW;
          ledstatecalibrate = HIGH;
          ledstatesettings = LOW;
        }

        else if (currentmode == 2) {
          newmode = 3;
          ledstaterun = LOW;
          ledstatecalibrate = LOW;
          ledstatesettings = HIGH;
        }

        else {
          newmode = 1;   // the state must be 3 so change it to 1
          ledstaterun = HIGH;
          ledstatecalibrate = LOW;
          ledstatesettings = LOW;
        }
      }
    }
  }
  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
  // set the mode
  currentmode = newmode;

  // set the LEDs:
  digitalWrite(ledpinrun, ledstaterun);
  digitalWrite (ledpincalibrate, ledstatecalibrate);
  digitalWrite (ledpinsettings, ledstatesettings);
  digitalWrite (ledpin, ledState);
}