using single button to toggle states and writing and reading to eprom

I have a project that uses a single momentary button to toggle between different modes. I have the change/state working well thanks to some ingenious code posted by That1guy99 (thank you). Now I'm trying to store the current mode's value in the Arduino's eeprom (so when Arduino powers down then up again it will be in the same mode). When I run the program, I get double digits of the same mode value - i.e. instead of 3, I get 33 using the serial monitor. I can figure out why? is there something that I'm missing? Following is my current sketch:

/* mark biasotti - adapted from That1guy99 example on Forum
 *  how to use a single momentary to toggle sequentially between different
 *  states. A tricolor led with common anode is switched from off to 4 different colors
 *  depending on how many button depresses. Then current led color mode (Mode) is stored
 *  and when ardruino is powered down and then up again, current mode and Led color illuminates
 */

#include <EEPROM.h>
int switchPin = 2;              // switch is connected to pin 2
int greenled = 3;               // green led pin
int redled = 4;                 // red led pin
int blueled = 5;                // blue led pin

int val;                        // variable for reading the pin status
int val2;                       // variable for reading the delayed status
int buttonState;                // variable to hold the button state
int Mode = 0;                   // What mode is the light in?

void setup() {
  pinMode(switchPin, INPUT);    // Set the switch pin as input
  pinMode(greenled, OUTPUT);
  pinMode(redled, OUTPUT);
  pinMode(blueled, OUTPUT);
  buttonState = digitalRead(switchPin);   // read the initial state
  Serial.begin(9600);           // for debug
}

void loop() {
Serial.print(Mode);
  val = digitalRead(switchPin);        // read input value and store it in val
  delay(10);                           // 10 milliseconds is a good amount of time
  val2 = digitalRead(switchPin);       // read the input again to check for bounces
  if (val == val2) {                   // make sure we got 2 consistant readings!
    if (val != buttonState) {          // the button state has changed!
      if (val == LOW) {                // check if the button is pressed
        if (Mode == 0) {
          Mode = 1;
          EEPROM.write(100, Mode);     // store mode to eeprom
          digitalWrite(greenled, LOW); // green led on (common anode + tri-led so pin low means led is on)
          digitalWrite(redled, HIGH);
          digitalWrite(blueled, HIGH);
        } else {
          if (Mode == 1) {
            Mode = 2;
            EEPROM.write(100, Mode);
            digitalWrite(greenled, HIGH);
            digitalWrite(redled, LOW);
            digitalWrite(blueled, HIGH);
          } else {
            if (Mode == 2) {
              Mode =3;
              EEPROM.write(100, Mode);
            } else {
              if (Mode == 3) {
                Mode = 4;
                EEPROM.write(100, Mode);
                digitalWrite(greenled, HIGH);
                digitalWrite(redled, HIGH);
                digitalWrite(blueled, LOW);
              } else {
                if (Mode == 4) {
                  Mode = 0;
                  EEPROM.write(100, Mode);
                  digitalWrite(greenled, HIGH);
                  digitalWrite(redled, HIGH);
                  digitalWrite(blueled, HIGH);
                }
              }
            }
          }
        }
      }
    }
    buttonState = val;            // save the new state in our variable
  }
  EEPROM.update(100, Mode);       // while looping store current mode ONLY if different that currently stored address.
  Serial.println(Mode);
}

In your main loop you have:

void loop() 
{
    Serial.print(Mode);

.
.
.

    
    EEPROM.update(100, Mode);       // while looping store current mode ONLY if different that currently stored address.
    Serial.println(Mode);

You print '3' and then print '3\n'; will show up as '33' on screen.

Okay I see. Thanks for that. Forgot to take that out. I'm still left with the problem of where do I put my Mode = EEPROM.read(100);? I'm thinking at the beginning of the loop? :

/* mark biasotti - adapted from That1guy99 example on Forum
 *  how to use a single momentary to toggle sequentially between different
 *  states. A tricolor led with common anode is switched from off to 4 different colors
 *  depending on how many button depresses. Then current led color mode (Mode) is stored
 *  and when ardruino is powered down and then up again, current mode and Led color illuminates
 */

#include <EEPROM.h>
int switchPin = 2;              // switch is connected to pin 2
int greenled = 3;               // green led pin
int redled = 4;                 // red led pin
int blueled = 5;                // blue led pin

int val;                        // variable for reading the pin status
int val2;                       // variable for reading the delayed status
int buttonState;                // variable to hold the button state
int Mode = 0;                   // What mode is the light in?

void setup() {
  pinMode(switchPin, INPUT);    // Set the switch pin as input
  pinMode(greenled, OUTPUT);
  pinMode(redled, OUTPUT);
  pinMode(blueled, OUTPUT);
  buttonState = digitalRead(switchPin);   // read the initial state
  Serial.begin(9600);           // for debug
}

void loop() {
   Mode = EEPROM.read(100);
  val = digitalRead(switchPin);        // read input value and store it in val
  delay(10);                           // 10 milliseconds is a good amount of time
  val2 = digitalRead(switchPin);       // read the input again to check for bounces
  if (val == val2) {                   // make sure we got 2 consistant readings!
    if (val != buttonState) {          // the button state has changed!
      if (val == LOW) {                // check if the button is pressed
        if (Mode == 0) {
          Mode = 1;
          EEPROM.write(100, Mode);     // store mode to eeprom
          digitalWrite(greenled, LOW); // green led on (common anode + tri-led so pin low means led is on)
          digitalWrite(redled, HIGH);
          digitalWrite(blueled, HIGH);
        } else {
          if (Mode == 1) {
            Mode = 2;
            EEPROM.write(100, Mode);
            digitalWrite(greenled, HIGH);
            digitalWrite(redled, LOW);
            digitalWrite(blueled, HIGH);
          } else {
            if (Mode == 2) {
              Mode =3;
              EEPROM.write(100, Mode);
            } else {
              if (Mode == 3) {
                Mode = 4;
                EEPROM.write(100, Mode);
                digitalWrite(greenled, HIGH);
                digitalWrite(redled, HIGH);
                digitalWrite(blueled, LOW);
              } else {
                if (Mode == 4) {
                  Mode = 0;
                  EEPROM.write(100, Mode);
                  digitalWrite(greenled, HIGH);
                  digitalWrite(redled, HIGH);
                  digitalWrite(blueled, HIGH);
                }
              }
            }
          }
        }
      }
    }
    buttonState = val;            // save the new state in our variable
  }
  EEPROM.update(100, Mode);       // while looping store current mode ONLY if different that currently stored address.
  Serial.println(Mode);
}

Why not read it in setup() to get the value, set mode and then enter the loop()?

Think I got it solved. I did a little cleanup and correction and moved the digital writes to the LEDs out of the button press loop. Seems to work now. Now I know it could be written more efficiently. Any ideas?

/* mark biasotti - adapted from That1guy99 example on Forum
    how to use a single momentary to toggle sequentially between different
    states. A tricolor led with common anode is switched from off to 4 different colors
    depending on how many button depresses. Then current led color mode (Mode) is stored
    and when ardruino is powered down and then up again, current mode and Led color illuminates
*/

#include <EEPROM.h>
int switchPin = 2;              // switch is connected to pin 2
int greenled = 3;               // green led pin
int redled = 4;                 // red led pin
int blueled = 5;                // blue led pin

int val;                        // variable for reading the pin status
int val2;                       // variable for reading the delayed status
int buttonState;                // variable to hold the button state
int Mode = 0;                   // What mode is the light in?

void setup() {
  pinMode(switchPin, INPUT);    // Set the switch pin as input
  pinMode(greenled, OUTPUT);
  pinMode(redled, OUTPUT);
  pinMode(blueled, OUTPUT);
  buttonState = digitalRead(switchPin);   // read the initial state
  Serial.begin(9600);           // for debug
}

void loop() {
  int address = EEPROM.read(100);
  Serial.println(address);
  Mode = address;
  val = digitalRead(switchPin);        // read input value and store it in val
  delay(10);                           // 10 milliseconds is a good amount of time
  val2 = digitalRead(switchPin);       // read the input again to check for bounces
  if (val == val2) {                   // make sure we got 2 consistant readings!
    if (val != buttonState) {          // the button state has changed!
      if (val == LOW) {                // check if the button is pressed
        if (Mode == 0) {
          Mode = 1;
          EEPROM.write(100, Mode);     // store mode to eeprom
        } else {
          if (Mode == 1) {
            Mode = 2;
          } else {
            if (Mode == 2) {
              Mode = 3;
              EEPROM.write(100, Mode);
            } else {
              if (Mode == 3) {
                Mode = 4;
                EEPROM.write(100, Mode);
              } else {
                if (Mode == 4) {
                  Mode = 0;
                  EEPROM.write(100, Mode);
                }
              }
            }
          }
        }
      }
    }
    buttonState = val;            // save the new state in our variable
    EEPROM.update(100, Mode);       // while looping store current mode ONLY if different that currently stored address.
  }
  if (Mode == 0) {                // all leds off
    digitalWrite(greenled, HIGH);
    digitalWrite(redled, HIGH);
    digitalWrite(blueled, HIGH);
  }
  if (Mode == 1) {
    digitalWrite(greenled, LOW); // green led on (common anode + tri-led so pin low means led is on)
    digitalWrite(redled, HIGH);
    digitalWrite(blueled, HIGH);
  }
  if (Mode == 2) {               // red led on
    digitalWrite(greenled, HIGH);
    digitalWrite(redled, LOW);
    digitalWrite(blueled, HIGH);   
  }
  if (Mode == 4) {
    digitalWrite(greenled, HIGH);  // Blue led on
    digitalWrite(redled, HIGH);
    digitalWrite(blueled, LOW);
  }
}
/code]

I would be very very inclined to re-write that with switch...case so as not to end up knee deep in ifs.

                }
              }
            }
          }
        }
      }
    }

@blackfin

The reason the eprom read is not in void setup is that the arduino never goes dead but is planned to go into low-power mode. Actually this will be eventually be an ATTiny in a consumer product.

@Willpatel_Kendmirez

Yeah, I agree with you and I might do that. The button depress will be very infrequent and because of that, the if statements will be run only occasionally. I want to figure this part of my sketch out first then write the main routine.

It looks a bit cleaner. Does it work? I used your logic but have to say that the Serial.println() of mode at each loop is going to slow stuff down. Might want to move it inside the switch loop...

/* mark biasotti - adapted from That1guy99 example on Forum
 *  how to use a single momentary to toggle sequentially between different
 *  states. A tricolor led with common anode is switched from off to 4 different colors
 *  depending on how many button depresses. Then current led color mode (Mode) is stored
 *  and when ardruino is powered down and then up again, current mode and Led color illuminates
 */

#include <EEPROM.h>
const int switchPin = 2;              // switch is connected to pin 2
const int greenled = 3;               // green led pin
const int redled = 4;                 // red led pin
const int blueled = 5;                // blue led pin

#define INVALID         -1
#define BTN_READ_INTVL  10
#define PASS_1          0
#define PASS_2          1

int val;                        // variable for reading the pin status
int val2;                       // variable for reading the delayed status
int buttonState;                // variable to hold the button state
int Mode = 0;                   // What mode is the light in?

#define LEDS_OFF        0x00
#define GREEN_LED       0x01
#define RED_LED         0x02
#define BLUE_LED        0x04

void setup() 
{
    pinMode(switchPin, INPUT);    // Set the switch pin as input
    pinMode(greenled, OUTPUT);
    pinMode(redled, OUTPUT);
    pinMode(blueled, OUTPUT);
    buttonState = digitalRead(switchPin);   // read the initial state
    Serial.begin(9600);           // for debug
    
}

int ReadButton( void )
{
    unsigned long
        timeNow;
    static unsigned long
        timeButton = millis();
    static byte
        statePass = 0;
    static int
        lastButton;
    int
        nowButton;
    

    timeNow = millis();
    if( (timeNow - timeButton) < BTN_READ_INTVL )
        return INVALID;

    timeButton = timeNow;
    switch( statePass )
    {
        case    PASS_1:
            lastButton = digitalRead(switchPin);
            statePass = PASS_2;            
        break;
        
        case    PASS_2:
            statePass = PASS_1;
            nowButton = digitalRead(switchPin);
            //if same on successive reads we see a difference, return the level we just saw
            //otherwise return "invalid" (-1)
            if( nowButton != lastButton )
                return( nowButton );
            else
                return INVALID;                
        break;
        
    }//switch
    
}//ReadButton

void WriteLEDs( byte Lights )
{
    //low means led is on
    digitalWrite(greenled, (Lights & GREEN_LED)?LOW:HIGH); 
    digitalWrite(redled, (Lights & RED_LED)?LOW:HIGH);
    digitalWrite(blueled, (Lights & BLUE_LED)?LOW:HIGH);    
    
}//WriteLEDs

void loop() 
{           
    if( ReadButton() == LOW )
    {
        switch( Mode )
        {
            case    0:
                Mode = 1;
                EEPROM.write(100, Mode);     // store mode to eeprom
                WriteLEDs( GREEN_LED );
            break;
            
            case    1:
                Mode = 2;
                EEPROM.write(100, Mode);
                WriteLEDs( RED_LED );
            break;
                    
            case    2:
                Mode = 3;
                EEPROM.write(100, Mode);                
            break;

            case    3:
                Mode = 4;
                EEPROM.write(100, Mode);
                WriteLEDs( BLUE_LED );
            break;
            
            case    4:
                Mode = 0;
                EEPROM.write(100, Mode);
                WriteLEDs( LEDS_OFF );
            break;
            
        }//switch
    }//if

    EEPROM.update(100, Mode);       // while looping store current mode ONLY if different that currently stored address.
    Serial.println(Mode);
    
}//loop

mbiasotti:
@blackfin

The reason the eprom read is not in void setup is that the arduino never goes dead but is planned to go into low-power mode. Actually this will be eventually be an ATTiny in a consumer product.
....

If you do not power down the Arduino (or ATtiny) there is no need so save to EEPROM. All RAM content (i. e. all your global and local variables) is preserved in all sleep modes.

I know that void loop () is harmful to run in a continuous loop
although EEPROM.update (100, Mode); can we design used void setup?

EEPROM.write (100, Mode);
How does eeprom distinguish it written 4 times with the same code?

3 color led lighting with one button
can we adapt eeprom recording
friends can you help

how to register a sample code if you have time please help

const int button = 4; // start:
const int led2 = 9; // exit:
const int led3 = 10; // button
int butonium = 0; // set location:
int value = 0;

void setup ()

pinMode(buton, INPUT);   // start :
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT); 


void loop ()


  button = digitalRead (button);
if ((button == HIGH) && (value == 0)) // button bast: // // button state variable:
{
digitalWrite (led2, LOW);
digitalWrite (led3, HIGH);
value = 1;
delay (10);
}
if ((button == LOW) && (value == 1)) // // Button left:
{
value = 2;
delay (10);
}
if ((button == HIGH) && (value == 2)) // button bast:
{
digitalWrite (led2, HIGH);
digitalWrite (led3, LOW);
value = 3;
delay (10);
}
if ((button == LOW) && (value == 3)) // // Button left:
{
value = 4;
delay (10);
}
if ((button == HIGH) && (value == 4)) // // Button bast:
{
digitalWrite (led2, LOW);
digitalWrite (led3, LOW);
value = 5;
delay (10);
}
if ((button == LOW) && (value == 5)) // // Button left:
{
value = 0;
delay (10);
}


}
}

nzmxp:
I know that void loop () is harmful to run in a continuous loop

That seems to make no sense whatsoever! :roll_eyes:

the code i added
When pressed twice, the leds light up alternately

LEDs turn off when pressed 3 times

3 in my drawing I canceled the led

i tried to adapt rgb led here

adaptation may sound silly
compiled code did not show error

but i didn't upload

     #include <EEPROM.h>  
const int button = 4; // start:
const int led2 = 9; // exit:
const int led3 = 10; // button
int butonium = 0; // set location:
int value = 0;
byte Mode = 0; 


void setup ()

pinMode(buton, INPUT);   // start :
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);


void loop ()


  button = digitalRead (button);
if ((button == HIGH) && (value == 0)) // button bast: // // button state variable:
{
 Mode = 1;
                EEPROM.write(100, Mode); 
digitalWrite (led2, LOW);
digitalWrite (led3, HIGH);
value = 1;
delay (10);
}
if ((button == LOW) && (value == 1)) // // Button left:
{
value = 2;
delay (10);
}
if ((button == HIGH) && (value == 2)) // button bast:
{
 Mode = 2;
                EEPROM.write(100, Mode);
digitalWrite (led2, HIGH);
digitalWrite (led3, LOW);
value = 3;
delay (10);
}
if ((button == LOW) && (value == 3)) // // Button left:
{
value = 4;
delay (10);
}
if ((button == HIGH) && (value == 4)) // // Button bast:
{
 Mode = 3;
                EEPROM.write(100, Mode);
digitalWrite (led2, LOW);
digitalWrite (led3, LOW);
value = 5;
delay (10);
}
if ((button == LOW) && (value == 5)) // // Button left:
{
value = 0;
delay (10);
}

 EEPROM.update(100, Mode); 
}
}

sample kode

    void setup ()

pinMode(buton, INPUT);   // start :
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
 EEPROM. read ( Mode = 1,Mode =2 ,Mode =3)

nzmxp:
sample kode

    void setup ()

pinMode(buton, INPUT);  // start :
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
EEPROM. read ( Mode = 1,Mode =2 ,Mode =3)

Does not compile. And your EEPROM.read will not do what you think it does.

when we save the buttons to the eeproma
Is it possible to edit the code without reading
for button

recent locations
if we register to eeproma by making the address separately
Adaptive of
without confusing addresses

sampling
eeprom write (0, led2)
eeprom write (1, led3)
eeprom write (2, ledoff)

![](http://<a target=)">

@nzmxp

It's not clear what you want to achieve. Do you want to save the mode to EEPROM?

hi

sorry
there is not much narration with google translate

I want to adapt it to the written code
3 times the key press in the picture above
LED2
led 3
led closed

example, arduino should keep the last cut in power failure

I want to keep the last record saved every time only one button is pressed, we have already pressed three times in total.

const int button = 4; // start:
const int led2 = 9; // exit:
const int led3 = 10; // button
int butonium = 0; // set location:
int value = 0;

void setup ()

pinMode(buton, INPUT);   // start :
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);


void loop ()


  button = digitalRead (button);
if ((button == HIGH) && (value == 0)) // button bast: // // button state variable:
{
digitalWrite (led2, LOW);
digitalWrite (led3, HIGH);
value = 1;
delay (10);
}
if ((button == LOW) && (value == 1)) // // Button left:
{
value = 2;
delay (10);
}
if ((button == HIGH) && (value == 2)) // button bast:
{
digitalWrite (led2, HIGH);
digitalWrite (led3, LOW);
value = 3;
delay (10);
}
if ((button == LOW) && (value == 3)) // // Button left:
{
value = 4;
delay (10);
}
if ((button == HIGH) && (value == 4)) // // Button bast:
{
digitalWrite (led2, LOW);
digitalWrite (led3, LOW);
value = 5;
delay (10);
}
if ((button == LOW) && (value == 5)) // // Button left:
{
value = 0;
delay (10);
}


}
}