Saving presets to EEPROM

I need to save three presets (A, B & C) to EEPROM. My attempts so far allow me to save preset "A" but nothing more. All presets save to RAM without issue. Any help much appreciated...

#include "TM1637.h"  // include TM1637 library
#include <EEPROM.h>

#define CLK   2  // define TM1637 clock pin
#define DIO   3  // define TM1637 data pin

// initialize the TM1637 library
TM1637 tm1637(CLK, DIO);

//buttons for preset selection
//last 2 digits of tm1637 display (0-99)
#define UP    4  // define up button pin
#define DN    5  // define down button pin

//button for "A" "b" or "C" selection
//1st digit of TM1637 display
const int btn = 6;

//button to save settings
const int Sv = 9;
int buttonState = 0;

int num = 0, prev_num = 1;
int let = 0, prev_let = 1;
int i = 0, prev_i = 1;


const unsigned int numReadings = 3;
int storedValues[numReadings];
int Saves[numReadings];

int address1 = 0;
int address2 = 1;
int address3 = 2; // preset A


void setup() {
  Serial.begin(9600);
  pinMode(btn, INPUT);
  pinMode(UP, INPUT);
  pinMode(DN, INPUT);
  pinMode(Sv, INPUT);

  // initialize the TM1637 display
  tm1637.init();
  // set display brightness (from 0 to 7)
  tm1637.set(3);

  EEPROM.get(address1, Saves[let]);
  EEPROM.get(address2, Saves[let]);
  EEPROM.get(address3, Saves[let]); // preset A
}

void loop ()
{

  if (num != prev_num)
  { // if the displayed (current) number was changed
    prev_num = num;   // save current value of 'num'
    // print all data
    Serial.println(Saves[let]);
    tm1637.display(2, num / 10 % 10); // print tens digit
    tm1637.display(3, num % 10);     // print ones digit
    delay(200);  // wait 200 milliseconds
  }

  if (let != prev_let)
  { // if the displayed (current) number was changed
    prev_let = let;   // save current value of 'let'
    // print all data
    tm1637.display(0, (let + 10));  //this gives me 10, 11 & 12 (A,b & C)

    delay(200);  // wait 200 milliseconds
  }

  if (i != prev_i)
  { // if the displayed (current) number was changed
    prev_i = i;   // save current value of 'let'
    delay(200);  // wait 200 milliseconds
  }

  if ( digitalRead(UP) )
  { // if the UP button is presses
    num++;         // increment 'num'
    if (num > 99) //99
      num = 0;
  }

  if ( digitalRead(DN) )
  { // if the DN button is presses
    num--;        // decrement 'num'
    if (num < 0)
      num = 99; //99
  }

  if ( digitalRead(btn) )
  { // if the btn button is presses
    let++;         // increment 'let'
    if (let > 2) // >= 3
      let = 0;
      num = Saves[let];
      
    Serial.println(Saves[let]);
    tm1637.display(2, Saves[let] / 10 % 10); // print tens digit
    tm1637.display(3, Saves[let] % 10);     // print ones digit
       
    delay(100);
  }
  buttonState = digitalRead(Sv);
  if (buttonState == HIGH)
  {
    Saves[let] = num;
    i++;
    if (let > 2) // >= 3
      let = 0;
  }
   switch (let) {
    case 0:
    EEPROM.update(address3, Saves[let]); // preset A
    break;
    case 1:
    EEPROM.update(address2, Saves[let]);
    break;
    case 2:
    EEPROM.update(address1, Saves[let]);
    break;
  }

}

You should reserve more space to store an integer. E.g.,

int address1 = 0;
int address2 = sizeof(int);
int address3 = 2 * sizeof(int);
1 Like

An int data type (Saves declared int[]) takes 2 bytes. Your addresses are 1 byte apart.

Try with (8 bit AVR):

int address1 = 0;
int address2 = 2;
int address3 = 4; 

With some processors the int data type is 4 bytes so the addresses need to be 4 bytes apart.

And use EEPROM.put() to save the values instead of EEPROM.update(). The update function only writes 1 byte. The put function writes the number of bytes in the data type (2 [or 4] for int).
The put function calls update so only write if the data changes.
See the EEPROM reference.

1 Like

Ok.... I have changed to

int address1 = 0;
int address2 = 2;
int address3 = 4;

and used EEPROM.put() instead of EEPROM.update().
However, I get exactly the same result as before.

I’d suggest you write a simple program to save values to eeprom and read them back .( worth looking at examples)
On your sketch add some print statements to see what you actually are saving and reading back , which will identify any other errors .

Dont forget , as said, on some processors β€œint” is 4 bytes , or others only two . Adjust your addressing as needed.

1 Like

What Arduino board are you using (that information should have been included in the OP)?

1 Like

Thanks everyone!
I'm using a Teensy 2
The reason being I want to use midi eventually

You are reading all three into the same place in the array.

You want each one in a separate place:

  EEPROM.get(address1, Saves[0]);
  EEPROM.get(address2, Saves[1]);
  EEPROM.get(address3, Saves[2]); // preset A
1 Like

A big thanks to all these examples from everyone.
I realise now the int is two bytes and this change was necessary...

int address1 = 0;
int address2 = 2;
int address3 = 4;

Thank you @jfjlaros and @groundFungus
This change was necessary also...

EEPROM.get(address1, Saves[0]);
  EEPROM.get(address2, Saves[1]);
  EEPROM.get(address3, Saves[2]); // preset A

Thanks @johnwasser I also found that I had to alter this accordingly...

case 0:
    EEPROM.put(address3, Saves[2]); // preset A
    break;
    case 1:
    EEPROM.put(address2, Saves[1]);
    break;
    case 2:
    EEPROM.put(address1, Saves[0]);
    break;

One thing puzzles me that would be great to fix. For a preset to be saved I must cycle past that preset. How could I fix this so that a preset is saved on each press of the save button?

Look at the state change detection method to see how to perform an action only when the button state changes from, say, HIGH to LOW. The level is not important, it is the transition between one state and the other.

This example modified from the tutorial shows how to save the presets to EEPROM each time the button is pressed.

/*
   The circuit:
   - pushbutton attached to pin 2 from ground
   - the internal pullup on pin 2 is enabled
   - LED attached from pin 13 to ground (or use the built-in LED on most
    Arduino boards)
*/

#include <EEPROM.h>

// this constant won't change:
const byte  buttonPin = 12;    // the pin that the pushbutton is attached to

// Variables will change:

int address3 = 0;
int address2 = 2;
int address1 = 4;

int Saves[3];

void setup()
{
   // initialize the button pin as a input:
   pinMode(buttonPin, INPUT_PULLUP);
   // initialize the LED as an output:
   Serial.begin(9600);
   Serial.println(F("save the presets to EEPROM each time the button is pressed."));
}

void loop()
{
   static boolean lastButtonState = 0;     // previous state of the button
   static unsigned long timer = 0;
   unsigned long interval = 20;
   if (millis() - timer >= interval)
   {
      timer = millis();

      // read the pushbutton input pin:
      bool buttonState = digitalRead(buttonPin);  // current state of the button

      // compare the buttonState to its previous state
      if (buttonState != lastButtonState)
      {
         // if the state has changed, increment the counter
         if (buttonState == LOW)
         {
            // if the current state is LOW then the button went from off to on:
            Serial.println(F("Saving presets to EEPROM"));
            EEPROM.put(address3, Saves[2]); // preset A
            EEPROM.put(address2, Saves[1]);
            EEPROM.put(address1, Saves[0]);
         }
         lastButtonState = buttonState;
      }
   }
}
1 Like

Very much appreciated @groundFungus.
I will work with that example.

@groundFungus I'm guessing that incorporating your code means I drop the Switch Case?

What was the switch case there for? It looks like you were using it to iterate through the array to save the individual array elements. It is much more efficient to use the for loop.

I'm also guessing you don't mean like this?

#include "TM1637.h"  // include TM1637 library
#include <EEPROM.h>

#define CLK   2  // define TM1637 clock pin
#define DIO   3  // define TM1637 data pin

// initialize the TM1637 library
TM1637 tm1637(CLK, DIO);

//buttons for preset selection
//last 2 digits of tm1637 display (0-99)
#define UP    4  // define up button pin
#define DN    5  // define down button pin

//button for "A" "b" or "C" selection
//1st digit of TM1637 display
const int btn = 6;

//button to save settings
const int Sv = 9;
int buttonState = 0;
int lastButtonState = 0;     // previous state of the button


int num = 0, prev_num = 1;
int let = 0, prev_let = 1;
int i = 0, prev_i = 1;


const unsigned int numReadings = 3;
int storedValues[numReadings];
int Saves[numReadings];
//int Saves [3];
int address1 = 0;
int address2 = 2;
int address3 = 4; // preset A


void setup() {
  Serial.begin(9600);
  pinMode(btn, INPUT);
  pinMode(UP, INPUT);
  pinMode(DN, INPUT);
  pinMode(Sv, INPUT);

  // initialize the TM1637 display
  tm1637.init();
  // set display brightness (from 0 to 7)
  tm1637.set(3);

  EEPROM.get(address1, Saves[0]);
  EEPROM.get(address2, Saves[1]);
  EEPROM.get(address3, Saves[2]); // preset A
  Serial.println(F("save the presets to EEPROM each time the button is pressed."));
}

void loop ()
{

  if (num != prev_num)
  { // if the displayed (current) number was changed
    prev_num = num;   // save current value of 'num'
    // print all data
    Serial.println(Saves[let]);
    tm1637.display(2, num / 10 % 10); // print tens digit
    tm1637.display(3, num % 10);     // print ones digit
    delay(200);  // wait 200 milliseconds
  }

  if (let != prev_let)
  { // if the displayed (current) number was changed
    prev_let = let;   // save current value of 'let'
    // print all data
    tm1637.display(0, (let + 10));  //this gives me 10, 11 & 12 (A,b & C)

    delay(200);  // wait 200 milliseconds
  }

  if (i != prev_i)
  { // if the displayed (current) number was changed
    prev_i = i;   // save current value of 'let'
    delay(200);  // wait 200 milliseconds
  }

  if ( digitalRead(UP) )
  { // if the UP button is presses
    num++;         // increment 'num'
    if (num > 99) //99
      num = 0;
  }

  if ( digitalRead(DN) )
  { // if the DN button is presses
    num--;        // decrement 'num'
    if (num < 0)
      num = 99; //99
  }

  if ( digitalRead(btn) )
  { // if the btn button is presses
    let++;         // increment 'let'
    if (let > 2) // >= 3
      let = 0;
    num = Saves[let];


    Serial.println(Saves[let]);
    tm1637.display(2, Saves[let] / 10 % 10); // print tens digit
    tm1637.display(3, Saves[let] % 10);     // print ones digit

    delay(100);
  }
      static boolean lastButtonState = 0;     // previous state of the button
   static unsigned long timer = 0;
   unsigned long interval = 20;
   if (millis() - timer >= interval)
   {
      timer = millis();

      // read the pushbutton input pin:
      bool buttonState = digitalRead(Sv);  // current state of the button

      // compare the buttonState to its previous state
      if (buttonState != lastButtonState)
      {
         // if the state has changed, increment the counter
         if (buttonState == HIGH)
         {
            // if the current state is LOW then the button went from off to on:
            Serial.println(F("Saving presets to EEPROM"));
            EEPROM.put(address3, Saves[2]); // preset A
            EEPROM.put(address2, Saves[1]);
            EEPROM.put(address1, Saves[0]);
         }
         lastButtonState = buttonState;
      }
   }
}

I've tried rewiring the button for active low input and changed to INPUT_PULLUP but this doesn't work at all

Wire the Sv switch to ground.

Set the pinMode for the Sv pin to INPUT_PULLUP.

Check the switch for active LOW.

With those changes, this code saves to EEPROM on each button press.

#include "TM1637.h"  // include TM1637 library
#include <EEPROM.h>

#define CLK   2  // define TM1637 clock pin
#define DIO   3  // define TM1637 data pin

// initialize the TM1637 library
TM1637 tm1637(CLK, DIO);

//buttons for preset selection
//last 2 digits of tm1637 display (0-99)
#define UP    4  // define up button pin
#define DN    5  // define down button pin

//button for "A" "b" or "C" selection
//1st digit of TM1637 display
const int btn = 6;

//button to save settings
const int Sv = 12; //9;
int buttonState = 0;
int lastButtonState = 0;     // previous state of the button


int num = 0, prev_num = 1;
int let = 0, prev_let = 1;
int i = 0, prev_i = 1;


const unsigned int numReadings = 3;
int storedValues[numReadings];
int Saves[numReadings];
//int Saves [3];
int address1 = 0;
int address2 = 2;
int address3 = 4; // preset A


void setup()
{
   Serial.begin(9600);
   pinMode(btn, INPUT);
   pinMode(UP, INPUT);
   pinMode(DN, INPUT);
   pinMode(Sv, INPUT_PULLUP);  // ***** input pullup

   // initialize the TM1637 display
   tm1637.init();
   // set display brightness (from 0 to 7)
   tm1637.set(3);

   EEPROM.get(address1, Saves[0]);
   EEPROM.get(address2, Saves[1]);
   EEPROM.get(address3, Saves[2]); // preset A
   Serial.println(F("save the presets to EEPROM each time the button is pressed."));
}

void loop ()
{

   if (num != prev_num)
   {
      // if the displayed (current) number was changed
      prev_num = num;   // save current value of 'num'
      // print all data
      Serial.println(Saves[let]);
      tm1637.display(2, num / 10 % 10); // print tens digit
      tm1637.display(3, num % 10);     // print ones digit
      delay(200);  // wait 200 milliseconds
   }

   if (let != prev_let)
   {
      // if the displayed (current) number was changed
      prev_let = let;   // save current value of 'let'
      // print all data
      tm1637.display(0, (let + 10));  //this gives me 10, 11 & 12 (A,b & C)

      delay(200);  // wait 200 milliseconds
   }

   if (i != prev_i)
   {
      // if the displayed (current) number was changed
      prev_i = i;   // save current value of 'let'
      delay(200);  // wait 200 milliseconds
   }

   if ( digitalRead(UP) )
   {
      // if the UP button is presses
      num++;         // increment 'num'
      if (num > 99) //99
         num = 0;
   }

   if ( digitalRead(DN) )
   {
      // if the DN button is presses
      num--;        // decrement 'num'
      if (num < 0)
         num = 99; //99
   }

   if ( digitalRead(btn) )
   {
      // if the btn button is presses
      let++;         // increment 'let'
      if (let > 2) // >= 3
         let = 0;
      num = Saves[let];


      Serial.println(Saves[let]);
      tm1637.display(2, Saves[let] / 10 % 10); // print tens digit
      tm1637.display(3, Saves[let] % 10);     // print ones digit

      delay(100);
   }
   static boolean lastButtonState = 0;     // previous state of the button
   static unsigned long timer = 0;
   unsigned long interval = 50;
   if (millis() - timer >= interval)
   {
      timer = millis();

      // read the pushbutton input pin:
      bool buttonState = digitalRead(Sv);  // current state of the button
      
      // compare the buttonState to its previous state
      if (buttonState != lastButtonState)
      {
         // if the state has changed, increment the counter
         if (buttonState == LOW) // ****** button active LOW
         {
            // if the current state is LOW then the button went from off to on:
            Serial.println(F("Saving presets to EEPROM"));
            EEPROM.put(address3, Saves[2]); // preset A
            EEPROM.put(address2, Saves[1]);
            EEPROM.put(address1, Saves[0]);
         }
         lastButtonState = buttonState;
      }
   }
}
1 Like

Absolutely followed your directions and she's not saving at all I'm sorry to say. I'll keep tricking with it.

Wouldn't hurt to post your current code.

1 Like

@dougp Just using @groundFungus code posted above. It prints

But doesn't save to the EEPROM for me.
I'll post @groundFungus code here to be clear...

#include "TM1637.h"  // include TM1637 library
#include <EEPROM.h>

#define CLK   2  // define TM1637 clock pin
#define DIO   3  // define TM1637 data pin

// initialize the TM1637 library
TM1637 tm1637(CLK, DIO);

//buttons for preset selection
//last 2 digits of tm1637 display (0-99)
#define UP    4  // define up button pin
#define DN    5  // define down button pin

//button for "A" "b" or "C" selection
//1st digit of TM1637 display
const int btn = 6;

//button to save settings
const int Sv = 12; //9;
int buttonState = 0;
int lastButtonState = 0;     // previous state of the button


int num = 0, prev_num = 1;
int let = 0, prev_let = 1;
int i = 0, prev_i = 1;


const unsigned int numReadings = 3;
int storedValues[numReadings];
int Saves[numReadings];
//int Saves [3];
int address1 = 0;
int address2 = 2;
int address3 = 4; // preset A


void setup()
{
   Serial.begin(9600);
   pinMode(btn, INPUT);
   pinMode(UP, INPUT);
   pinMode(DN, INPUT);
   pinMode(Sv, INPUT_PULLUP);  // ***** input pullup

   // initialize the TM1637 display
   tm1637.init();
   // set display brightness (from 0 to 7)
   tm1637.set(3);

   EEPROM.get(address1, Saves[0]);
   EEPROM.get(address2, Saves[1]);
   EEPROM.get(address3, Saves[2]); // preset A
   Serial.println(F("save the presets to EEPROM each time the button is pressed."));
}

void loop ()
{

   if (num != prev_num)
   {
      // if the displayed (current) number was changed
      prev_num = num;   // save current value of 'num'
      // print all data
      Serial.println(Saves[let]);
      tm1637.display(2, num / 10 % 10); // print tens digit
      tm1637.display(3, num % 10);     // print ones digit
      delay(200);  // wait 200 milliseconds
   }

   if (let != prev_let)
   {
      // if the displayed (current) number was changed
      prev_let = let;   // save current value of 'let'
      // print all data
      tm1637.display(0, (let + 10));  //this gives me 10, 11 & 12 (A,b & C)

      delay(200);  // wait 200 milliseconds
   }

   if (i != prev_i)
   {
      // if the displayed (current) number was changed
      prev_i = i;   // save current value of 'let'
      delay(200);  // wait 200 milliseconds
   }

   if ( digitalRead(UP) )
   {
      // if the UP button is presses
      num++;         // increment 'num'
      if (num > 99) //99
         num = 0;
   }

   if ( digitalRead(DN) )
   {
      // if the DN button is presses
      num--;        // decrement 'num'
      if (num < 0)
         num = 99; //99
   }

   if ( digitalRead(btn) )
   {
      // if the btn button is presses
      let++;         // increment 'let'
      if (let > 2) // >= 3
         let = 0;
      num = Saves[let];


      Serial.println(Saves[let]);
      tm1637.display(2, Saves[let] / 10 % 10); // print tens digit
      tm1637.display(3, Saves[let] % 10);     // print ones digit

      delay(100);
   }
   static boolean lastButtonState = 0;     // previous state of the button
   static unsigned long timer = 0;
   unsigned long interval = 50;
   if (millis() - timer >= interval)
   {
      timer = millis();

      // read the pushbutton input pin:
      bool buttonState = digitalRead(Sv);  // current state of the button
      
      // compare the buttonState to its previous state
      if (buttonState != lastButtonState)
      {
         // if the state has changed, increment the counter
         if (buttonState == LOW) // ****** button active LOW
         {
            // if the current state is LOW then the button went from off to on:
            Serial.println(F("Saving presets to EEPROM"));
            EEPROM.put(address3, Saves[2]); // preset A
            EEPROM.put(address2, Saves[1]);
            EEPROM.put(address1, Saves[0]);
         }
         lastButtonState = buttonState;
      }
   }
}

Just to mention again if it makes any difference @groundFungus , I'm using a Teensy 2 for this project. Pin 12 appears to be A9 on the Teensy but I've tried your code using pin 9 and pin 12 and it makes no difference.