EEPROM - how to get and store values

I know there are a few posts already submitted to the fourms about this topic, but it would be nice if someone could clarify it for me.

(here is an attempt I have made which doesn't work)

code:

#include <EEPROM.h>

int score = 0;

void setup() 
{
    Serial.begin(9600);
    score = EEPROM.get(score);
}

void loop() 
{
    score += 1;
    EEPROM.write(score);
}

Study this link before you use EEPROM.

You only can do about 100,000 writes to a memory location, only write to a location when needed.

EEPROM.read() & EEPROM.write() only work with single byte variables.

It you are dealing with an "int" which is 2 bytes (on an Uno for example), then you should use...

EEPROM.get(address, data)

and

EEPROM.put(address, data)

Note that address is the address you want to write to in the EEPROM, and data is your variable.

Also, as @LarryD says... be careful writing to the EPPROM in loop, as it has a limited number of write cycles.

That's likely used up the quota on that location in your EEPROM. You'd likely see >100,000 writes of unique values in succession in the first second of running that sketch. If you want to continue testing with that, put a delay(1000) in the loop, and change your address to 1(because location 0 is most likely toast).

is there a way I could use update() to fix this issue?

k, thx for the explanation ill keep that in mind

i'm using a mega board

Ok cool..Reason I asked is that some Arduinos don't have EEPROM built in so the approach required is slightly different, and some have larger (4 byte) int variables... Mega is all good. See post #3 for the commands required.

No ... update will save some writes if the value hasn't changed... but in your sketch for example it will be constantly changing.

You shouldn't need to write to the EEPROM every loop. What are you trying to achieve?

loop( ) runs over and over, never stops.

loop( ) executes in just a few micro seconds.

At these speeds, if you increment your variable and write to the EEPROM, your EEPROM will soon go dead.

Only update EEPROM when it is absolutely necessary, example if/when the power is removed.

Here is code for a load sensor. I use the on chip EE of the Atmega328. You should be able to pick out the EE code

/*
2022-09-01
    v001

2022-09-06	v002	Added display and display calculations.

2022-09-15	v003	(open) add tare and gScale inputs and calculations.
2022-10-18  v005.1  Tare (K1) and scale (K2) function.
					Scale has no display prompt simply put the 200gr
					on the loadcell then press K2.
_____________________________________________________________________

HX711 device prove out code.
Reads the HX711 Raw data. Developed using YZC-133 Load Cell

HX711 outputs 24 bits:   -8,388,608 to 8,388,607

"filler" code converts the 24 bit two's compliment value
to a 32 bit two's compliment value, which the compiler understands.

https://www.exploringbinary.com/twos-complement-converter/

Notes on YZC-133 5kg
	Rated Output: 1.0 ±  0.15mV / V
	if Vexcitation = 4.07V
	5kg = 1mv * 4.07 = 4.07mv = 5kg.

	@gain = 128 then we are using only 1/5 of our range.
	8,388,607 *4.07 / 20 = ± 1,707,081
*/

/*
	Pin Assignments:
		2 	Input			HX711 Data Pin
		3 	Output  		HX711 Clock Pin
		8 	Input Pullup 	Initiate Tare
		9 	Input Pullup 	Initiate gScale (pgm assumes gScale is based on 200mg mass)
*/

#define uint unsigned int
#define int32 int32_t
#define uint32 uint32_t

#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <EEPROM.h>

//#define period 3000
#define I2C_ADDRESS 0x3C
#define _pin_data 2
#define _pin_slk 3
#define _pin_tare 9    // K1
#define _pin_gScale 8  // K2
#define _countsTOoz 7.054792
#define gTOoz 28.3     //  28 grams / oz
#define period 3000

/*
#define gTareMinLimit 50000
#define gTareMaxLimit 60000
#define g200MinLimit 130000
#define g200MaxLimit 140000
*/

SSD1306AsciiWire oled;

//-- Declare Globals ------------------------------------------------------------

const int32_t g200CountInit = 133000;  // counts at 200 grams
const int32_t g000CountInit = 56000;
int32_t g000Count;
int32_t g200Count;  // counts at 200 grams

uint g000length = sizeof(g000Count);
byte gEEbaseAddress = 0;

uint32_t gStartMillis;
uint32_t gCurrentMillis;
char disp[14];
uint widthDisp;

//-- Function Prototpyes ------------------------------------------------------------

int32_t getValue(void);
void oledInit(void);

//-------------------------------------------------------------------------------
void setup() {
  pinMode(_pin_data, INPUT);
  pinMode(_pin_slk, OUTPUT);
  pinMode(_pin_tare, INPUT_PULLUP);
  pinMode(_pin_gScale, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, 0);  // force ED off else it flickers sometimes

  oledInit();

  // if EEPROM has not been written to, save default values.
  byte value = EEPROM.read(0);
  if (value != 11) {
    EEPROM.put(gEEbaseAddress, 11);
    EEPROM.put(gEEbaseAddress + 1, g000CountInit);
    EEPROM.put(gEEbaseAddress + g000length + 1, g200CountInit);

    // initialize counts on very first startup (when EEPROM empty)
    g000Count = g000CountInit;
    g200Count = g200CountInit;
  } else {
    g000Count = EEPROM.get(gEEbaseAddress + 1, g000Count);
    g200Count = EEPROM.get(gEEbaseAddress + g000length + 1, g200Count);
  }

  oled.clear();
  oled.print("  setup v005.1");
  delay(3000);
  oled.setCursor(2 * 8, 0);
  oled.print(g000Count);
  oled.clearToEOL();
  oled.setCursor(2 * 8, 2);
  oled.print(g200Count);
  delay(1000);

  oled.SSD1306Ascii::setCursor(1 * 8, 0);
  oled.print("grams = ");

  oled.SSD1306Ascii::setCursor(1 * 8, 2);
  oled.print("ounces = ");

}  // --- setup ---------------------------------------------------------------------


//------------------------------------------------------------------------------------

void loop() {

  gCurrentMillis = millis();
  if (gCurrentMillis - gStartMillis >= period) {  //cannot use "millis()" in if statement
    gStartMillis = gCurrentMillis;

    int32_t measCounts = getValue();
    // calculations:
    float weightGrams = (200.0 / (g200Count - g000Count)) * (measCounts - g000Count);
    float weightOz = (7.054792 / (g200Count - g000Count)) * (measCounts - g000Count);
    

    //dtostrf(float_value, min_width, num_digits_after_decimal, where_to_store_string)
    dtostrf(weightGrams, 3, 1, disp);
    uint dispLengthChar = strlen(disp);
    uint widthDispPix = oled.fieldWidth(dispLengthChar);
    oled.setCursor(8 * 8, 0);  // should be after units.
    oled.clearToEOL();
    oled.setCursor( 120 - widthDispPix, 0); //dispLengthChar * 8, 0);
    oled.print(weightGrams);

    dtostrf(weightOz, 3, 1, disp);
    dispLengthChar = strlen(disp);
    widthDispPix = oled.fieldWidth(dispLengthChar);
    oled.setCursor(9 * 8, 2);  // should be after units.
    oled.clearToEOL();
    oled.setCursor( 120 - widthDispPix, 2); //dispLengthChar * 8, 0);
    oled.print(weightOz);


/*
we now have:
	display width in pixels
	width of data in pixels
	width of data in characters

	What to do:
		format right hand justification - 8 pixels = 120 pixels

*/

 }
  // Tare function: ---------------------------------------------

  if (digitalRead(_pin_tare) == 0) {
    delay(20);
    if (digitalRead(_pin_tare) == 0) {
      oled.print("... reading tare");
      g000Count = getValue();
      EEPROM.put(gEEbaseAddress + 1, g000Count);
    }
  }

  if (digitalRead(_pin_gScale) == 0) {
    delay(20);
    if (digitalRead(_pin_gScale) == 0) {
      oled.print("... reading Scale");
      g200Count = getValue();
      EEPROM.put(gEEbaseAddress + g000length + 1, g200Count);
    }
  }




  // Scale function: --------------------------------------------
  /*
	if (   digitalRead(_pin_gScale) == 0){
		delay(100);
		if ( digitalRead(_pin_gScale) == 0){ 
			oled.clear();
			oled.print("place 200g on Scale, press again to continue");
      
      // wait up to 10 seconds for _pin_Scale to go low

      
      if( digitalRead(_pin_gScale) == 1)

      delay(5000);  // else pin might still be low
			while(_pin_gScale) {
			}
			g200Count = getValue();
			EEPROM.put( gEEbaseAddress + g000length + 1, g200Count);
		}	
	}

*/
  // ------------------------------------------------------------

}  // --- loop ------------------------------------------------



//--- Functions ----------------------------------------------------------------------

int32 getValue() {
  byte data[3];
  while (digitalRead(_pin_data)) {}  // wait for data pin to go low.

  for (byte j = 3; j--;) {
    for (char i = 8; i--;) {
      digitalWrite(_pin_slk, HIGH);
      bitWrite(data[j], i, digitalRead(_pin_data));
      digitalWrite(_pin_slk, LOW);
    }
  }

  // add 25th clock pulse to put next reading at gain 128
  //  logic analyzer shows no delay is req'd to meet HX711 input req.
  digitalWrite(_pin_slk, HIGH);
  digitalWrite(_pin_slk, LOW);

  // Replicate the most significant bit to pad out a 32-bit signed integer
  uint filler;
  if (data[2] & 0x80) {
    filler = 0xFF;
  } else {
    filler = 0x00;
  }

  // Construct a 32-bit signed integer
  int32 value = (static_cast<unsigned int32>(filler) << 24
                 | static_cast<unsigned int32>(data[2]) << 16
                 | static_cast<unsigned int32>(data[1]) << 8
                 | static_cast<unsigned int32>(data[0]));

  return value;
}


void oledInit(void) {
  Wire.begin();
  Wire.setClock(100000L);

  oled.begin(&Adafruit128x32, I2C_ADDRESS);

  oled.setFont(ZevvPeep8x16);  // Screen = 4 (0,2,4,6) lines X 16 characters (0 to 15)
  uint widthDisp = oled.displayWidth();

  oled.clear();
  oled.displayRemap(true);    // rotate display 180 deg.


}

// --- eof ------------------------------------------------------------------

uh, alr (i'll test it later when I have time)

You've already been pointed here once, but...

i'd also like to thank LarryD, red_car and camsysca for helping me out. (they gave me a lot of info about this topic)

thx for helping me understand this topic.

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