multiple mcp23017 and EEPROM

I’m pretty new to arduino’s and programming, but i’m a fast learner. I’m pretty proud of what I have achieved so far just by trying and making mistakes.
Right now I have written a code for sending input/output information to 3x MCP23017 which is pretty straigth forward. I’m using the <Adafruit_MCP23017.h> for this.
The GPA ports are inputs with momentary pushbuttons and the GPB’s are outputs toggled by the momentary buttons to drive relays (push once is on, push again off). I need those 3 expanders because I need 24 ins and 24 outs to drive the relays (with a transistor array since the coils are 24v).
So far so good and it’s working as expected. 8)
Now I want to write and read the last states of the GPB outputs (and maybe some memories) so that it comes back to the last state after power down. So I guess I need to write and read the i2c state for that, but i’m lost on what code to use and where to put it.

The only really a bit usefull information is in this topic, but it’s 5 years old: https://forum.arduino.cc/index.php?topic=291470.0
Could someone please help me with this?
I’m also wondering if the onboard EEPROM (uno) will be enough for this or maybe it’s a good idea to use an external EEPROM using i2c.

code.txt (24.2 KB)

Why do you want to read the port multiplexer output pins ? The status of the pins has been set previously by the Arduino, so the logical place to record their status at the time these have been explicitly set. Or maybe I have misunderstood something about your set up.

The other thing is that there is a lot of repetition in your code:

. . .
  //Condition Relay 34
  if (reading34 == HIGH && previous34 == LOW && millis() - time > debounce) {
    if (state34 == HIGH)
      state34 = LOW;
    else
      state34 = HIGH;
    time = millis();
  }

  //Condition Relay 35
  if (reading35 == HIGH && previous35 == LOW && millis() - time > debounce) {
    if (state35 == HIGH)
      state35 = LOW;
    else
      state35 = HIGH;
    time = millis();
  }
. . .

simply using a function may reduce it a lot. Maybe looking at arrays for say stateZZ etc. would help also.

The EEPROM has a limited lifetime (number of write operations - say 100,000 per cell) so it should not be used for rapidly changing values. Maybe this does not apply here ?

6v6gt: Why do you want to read the port multiplexer output pins ? The status of the pins has been set previously by the Arduino, so the logical place to record their status at the time these have been explicitly set. Or maybe I have misunderstood something about your set up.

The other thing is that there is a lot of repetition in your code:

. . .
  //Condition Relay 34
  if (reading34 == HIGH && previous34 == LOW && millis() - time > debounce) {
    if (state34 == HIGH)
      state34 = LOW;
    else
      state34 = HIGH;
    time = millis();
  }

 //Condition Relay 35  if (reading35 == HIGH && previous35 == LOW && millis() - time > debounce) {    if (state35 == HIGH)      state35 = LOW;    else      state35 = HIGH;    time = millis();  } . . .




simply using a function may reduce it a lot. Maybe looking at arrays for say stateZZ etc. would help also.

The EEPROM has a limited lifetime (number of write operations - say 100,000 per cell) so it should not be used for rapidly changing values. Maybe this does not apply here ?

Simply said, I want to save the output states of the MCP GPB ports so that after power down it remembers those states. The 100.000 operations per cell is no problem at all, I knew about that. It would even surprise me if it would get to 10.000 operations after a year. So that's not going to be a problem. The code needs cleaning up indeed. To me this whole thing with coding is new and so I was already happy to get this far, learning everyday, sometimes even in my sleep. :) Maybe I will cut most of the code first to have a simple version with just 2 ins/outs on one mcp. That might be easier to start with and build from there.

instead of writing directly to the GP port, create a sub-function that is passed the value and a port ID (chip, port). that sub-function writes the value to both the port and an EEPROM location.

on startup, a separate sub-function reads each EEPROM value for each port and writes the value to the port.

you need to use arrays and for loops