Remembering multiple states using EEPROM

Hello! I'm developing a 3 button on/off system using an attiny84 for channel switching with low signal relays. I'm having some trouble getting the 3rd button to remember the state. The behavior is as follows:

Channel 1: works as intended.
Channel 2: works but also links to channel 3.
Channel 3: wont update unless channel 2 is updated.

Here is my code so far.

#include <EEPROM.h>

/* ATTINY24/44/84 PINS */

/* VCC          1|O     |14     GND */
/* SWTIP (SW1)  2|      |13     RELAY1 PIN1-  */
/* SWRING (SW2) 3|      |12     RELAY1 PIN10+ */
/* RESET        4|      |11     RELAY1 PIN1-  */
/* LED1         5|      |10     RELAY1 PIN10+ */
/* LED2         6|      |9      RELAY2 PIN1-  */
/* LED3         7|      |8      RELAY2 PIN10+ */

/*+ = BYPASS */
/*- = ENGAGE */

// arduino pins

//# define buttonPin 0
//# define buttonPin2 1
//# define ledPin 2
//# define ledPin2 3
//# define ledPin3 4
//# define engage 5
//# define bypass 6
//# define engage2 7
//# define bypass2 8
//# define engage3 9
//# define bypass3 10

// attiny pins (clockwise)

# define buttonPin 10
# define buttonPin2 9
# define ledPin 8
# define ledPin2 7
# define ledPin3 6
# define engage 0
# define bypass 1
# define engage2 2
# define bypass2 3
# define engage3 4
# define bypass3 5

int effectstate;
int effectstate2;
int effectstate3;

int buttonState = HIGH;
int buttonState2 = HIGH;

int lastButtonState = HIGH;
int lastbuttonState2 = HIGH;

//timing
long lastDebounceTime = 0;
long debounceDelay = 50;
long pressedat = 0;
long pressedat2 = 0;
long longpress = 500;
long relaytime = 40;

void setup() {

  //sw pins
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);

  //wait for pullup
  delay(25);

  //led pins
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);

  //relay pins
  pinMode(engage, OUTPUT);
  pinMode(bypass, OUTPUT);
  pinMode(engage2, OUTPUT);
  pinMode(bypass2, OUTPUT);
  pinMode(engage3, OUTPUT);
  pinMode(bypass3, OUTPUT);

  //read eeprom state
  checkeffectstate();
  checkeffectstate2();
  checkeffectstate3();

}

void loop() {

  unsigned long now = millis();
  int reading = digitalRead(buttonPin);
  int reading2 = digitalRead(buttonPin2);

  if (reading != lastButtonState) {

    lastDebounceTime = now;

  }

  if (reading2 != lastbuttonState2) {

    lastDebounceTime = now;

  }

  //sw3
  if ((now - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      if (reading2 != buttonState2) {

        buttonState = reading;
        buttonState2 = reading2;

        if (buttonState == LOW && buttonState2 == LOW) {

          togglestate3();
          pressedat2 = now;
          pressedat = now;

        } else {

          if ((now - pressedat) > longpress) {
            if ((now - pressedat2) > longpress) {

              togglestate3();

            }
          }
        }
      }
    }
  }


  //sw2
  if ((now - lastDebounceTime) > debounceDelay) {

    if (reading2 != buttonState2) {

      buttonState2 = reading2;

      if (buttonState2 == LOW) {

        togglestate2();
        pressedat2 = now;

      } else {
        
        if ((now - pressedat2) > longpress) {

          togglestate2();

        }
      }
    }
  }

  //sw1
  if ((now - lastDebounceTime) > debounceDelay) {

    if (reading != buttonState) {

      buttonState = reading;

      if (buttonState == LOW) {

        togglestate();
        pressedat = now;

      } else {

        if ((now - pressedat) > longpress) {

          togglestate();

        }
      }
    }
  }

  EEPROM.update(0, effectstate);
  EEPROM.update(2, effectstate2);
  EEPROM.update(4, effectstate3);

  lastButtonState = reading;
  lastbuttonState2 = reading2;

}

void togglestate() {

  effectstate = !effectstate;

  if (effectstate) {
    digitalWrite(ledPin, HIGH);
    digitalWrite(engage, HIGH);
    delay(relaytime);
    digitalWrite(engage, LOW);
  } else {
    digitalWrite(ledPin, LOW);
    digitalWrite(bypass, HIGH);
    delay(relaytime);
    digitalWrite(bypass, LOW);
  }

}

void togglestate2() {

  effectstate2 = !effectstate2;

  if (effectstate2) {
    digitalWrite(ledPin2, HIGH);
    digitalWrite(engage2, HIGH);
    delay(relaytime);
    digitalWrite(engage2, LOW);
  } else {
    digitalWrite(ledPin2, LOW);
    digitalWrite(bypass2, HIGH);
    delay(relaytime);
    digitalWrite(bypass2, LOW);
  }

}

void togglestate3() {

  effectstate3 = !effectstate3;

  if (effectstate3) {
    digitalWrite(ledPin3, HIGH);
    digitalWrite(engage3, HIGH);
    delay(relaytime);
    digitalWrite(engage3, LOW);
  } else {
    digitalWrite(ledPin3, LOW);
    digitalWrite(bypass3, HIGH);
    delay(relaytime);
    digitalWrite(bypass3, LOW);
  }

}

void checkeffectstate() {

  effectstate = EEPROM.read(0);

  //effect1 on
  if (effectstate) {
    digitalWrite(ledPin, HIGH);
    digitalWrite(engage, HIGH);
    delay(relaytime);
    digitalWrite(engage, LOW);

    //effect1 off
  } else {
    digitalWrite(ledPin, LOW);
    digitalWrite(bypass, HIGH);
    delay(relaytime);
    digitalWrite(bypass, LOW);
  }

}

void checkeffectstate2() {

  effectstate2 = EEPROM.read(2);

  //effect2 on
  if (effectstate2) {
    digitalWrite(ledPin2, HIGH);
    digitalWrite(engage2, HIGH);
    delay(relaytime);
    digitalWrite(engage2, LOW);

    //effect2 off
  } else {
    digitalWrite(ledPin2, LOW);
    digitalWrite(bypass2, HIGH);
    delay(relaytime);
    digitalWrite(bypass2, LOW);
  }

}

void checkeffectstate3() {

  effectstate3 = EEPROM.read(4);

  //effect3 on
  if (effectstate3) {
    digitalWrite(ledPin3, HIGH);
    digitalWrite(engage3, HIGH);
    delay(relaytime);
    digitalWrite(engage3, LOW);

    //effect3 off
  } else {
    digitalWrite(ledPin3, LOW);
    digitalWrite(bypass3, HIGH);
    delay(relaytime);
    digitalWrite(bypass3, LOW);
  }

}

I included the arduino pin definitions to troubleshoot and to see how the code works. I'm accomplishing the 3rd button press by linking two diodes tied to it between switches 1/2. Here is the schematic.

For now I'm using LEDs to monitor the relay pulses. You can omit them to save time.

Any ideas?

EEPROM.read(), update() & write() functions are intended for use with single byte variable types.

Integers are 2 bytes on most AVR Arduino devices.

Given you are only storing a binary value, I suggest using a different variable type such as boolean.

Alternatively you can use EEPROM.get() and put() - these work with multibyte variables.

1 Like

All helpers know the shape of an UNO and the shape of a breadboard. Reading it is the job for a detective trying to solve a murder mystery.
Schematics, can be made using pen and paper, is preferred. That's how circuitries should be opresented.

Changing read() to get() seems to have worked. Thank you for the tip!

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