Incorrect long value stored to EEPROM

Hi, I am trying to write a long called master to the EEPROM. I have followed the example but I cannot figure out why it is not working. I have tested it by setting master equal to 1514 in the setup then running the code. Once I remove setting master = 1514, the eeprom reads 65570. I was wondering if someone could tell me what I am doing wrong.

Here is the code for writing the master variable to the EEPROM:

  byte four = (master & 0xFF);
  byte three = ((master >> 8) & 0xFF);
  byte two = ((master >> 16) & 0xFF);
  byte one = ((master >> 24) & 0xFF);

  EEPROM.write(Master, four);
  EEPROM.write(Master + 10, three);
  EEPROM.write(Master + 20, two);
  EEPROM.write(Master + 30, one);

Here is the code for writing what is stored in the EEPROM to the variable:

  long four = EEPROM.read(Master);
  long three = EEPROM.read(Master + 10);
  long two = EEPROM.read(Master + 20);
  long one = EEPROM.read(Master + 30);

  master = (((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF));

I really appreciate any help!
Thank you,
James

Please post a complete program showing the problem, An EEPROM location and a variable with virtually the same name is surely a recipe for disaster

This works for me

#include <EEPROM.h>

long out;
long in;
byte eepromStart = 0;

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  randomSeed(analogRead(A1));
  for (int x = 0; x < 8; x++)
  {
    out = random(123456);
    Serial.println(out);
    save();
    load();
    Serial.println(in);
    Serial.println();
  }
}

void loop()
{
}

void save()
{
  byte four = (out & 0xFF);
  byte three = ((out >> 8) & 0xFF);
  byte two = ((out >> 16) & 0xFF);
  byte one = ((out >> 24) & 0xFF);
  EEPROM.write(eepromStart, four);
  EEPROM.write(eepromStart + 10, three);
  EEPROM.write(eepromStart + 20, two);
  EEPROM.write(eepromStart + 30, one);
}

void load()
{
  long four = EEPROM.read(eepromStart);
  long three = EEPROM.read(eepromStart + 10);
  long two = EEPROM.read(eepromStart + 20);
  long one = EEPROM.read(eepromStart + 30);
  in = (((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF));
}

You could, of course use EEPROM.put() and EEPROM.get() for an easier life

Here is the complete code that applies to this situation. I shortened it down so you didn't have to scroll through 1000+ lines. I tried to bold anything that was important.

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <EEPROM.h>
#include <ESP8266WebServer.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>


//   VARIABLE DEFINITIONS   //
[b]long master;
uint8_t Master = 0;[/b]
uint8_t NameC[11] /*= {4095, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}*/;
uint8_t Code[11] = {4096, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
uint8_t A_C[11] = {4096, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};


unsigned long currentTime = millis();
unsigned long previousTime = 0;
const long timeoutTime = 2000;
String header;

void setup() {
  Serial.begin(9600);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println(".");
  WiFi.config(ip, gateway, subnet);
  Serial.println("Successfully Connected");
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_FS
      type = "filesystem";
    }
    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      Serial.println("Auth Failed");
    } else if (error == OTA_BEGIN_ERROR) {
      Serial.println("Begin Failed");
    } else if (error == OTA_CONNECT_ERROR) {
      Serial.println("Connect Failed");
    } else if (error == OTA_RECEIVE_ERROR) {
      Serial.println("Receive Failed");
    } else if (error == OTA_END_ERROR) {
      Serial.println("End Failed");
    }
  });
  ArduinoOTA.begin();

  server.begin();


  EEPROM.begin(4096);


  [b]variableUpdate();[/b]
  //master = 1514;
}

void loop() {
  //ArduinoOTA.handle();

  WiFiClient client = server.available();
  if (client) {                             // If a new client connects,
    Serial.println("Client Connected");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    currentTime = millis();
    previousTime = currentTime;
    while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected
      currentTime = millis();
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            Serial.print("HEADER:");
            Serial.println(header);

            [b]getHeader();
            eepromUpdate();[/b]

            // Display the HTML web page
            client.println("<div class='tab'><button class='tablinks active' onclick=\"openTab(event, 'Codes'); lastTab('Codes')\">Codes</button>");
            client.println("<button class='tablinks' onclick=\"openTab(event, 'Fingerprints'); lastTab('Fingerprints')\">Fingerprints</button></div>");

            //CODES TABLE
            client.println("<div id='Codes' class='tabcontent' style='display:block'><h2>Codes</h2><table align='center';><col width='20%'><col width='25%'><col width='25%'><col width='20%'>");
            client.println("<tr><th>Code ID</th><th>Name</th><th>Code</th><th>Active</th></tr>");
            client.print("<tr><td>0</td><td>MASTER</th><td>");
            client.print([b]master[/b]);
            client.println("</td><td><input type='checkbox' checked disabled /></td></tr>");
            for (int x = 1; x <= 10; x++) {
              client.print("<tr><td>");
              client.print(x);
              client.print("</td><td>");
              client.print(nameC[x]);
              client.print("</td><td>");
              client.print(code[x]);
              client.println("</td><td>");
              if (a_C[x] == 1) {
                client.print("<input type='checkbox' checked onclick=\"window.location.assign('/c");
                client.print(x);
                client.println("/0')\"/></td></tr>");
              } else {
                client.print("<input type='checkbox' onclick=\"window.location.assign('/c");
                client.print(x);
                client.println("/1')\"/></td></tr>");
              }
            }
            client.println("</table></div>");



            client.println("</body></html>");

            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

[b]void variableUpdate()[/b] {

  long four = EEPROM.read(Master);
  long three = EEPROM.read(Master + 100);
  long two = EEPROM.read(Master + 200);
  long one = EEPROM.read(Master + 300);

  master = (((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF));
}

[b]void eepromUpdate()[/b] {

  //EEPROM.write(Master, master);
  byte four = (master & 0xFF);
  byte three = ((master >> 8) & 0xFF);
  byte two = ((master >> 16) & 0xFF);
  byte one = ((master >> 24) & 0xFF);

  EEPROM.write(Master, four);
  EEPROM.write(Master + 100, three);
  EEPROM.write(Master + 200, two);
  EEPROM.write(Master + 300, one);

  delay(500);
  EEPROM.commit();
  delay(500);

}

I appreciate your willingness to help out!!
Thank you,
James

The code in reply #2 exhibits the stated problem?

Yes.

That code doesn't compile.

uint8_t Master = 0;

Master will overflow with +300.

void eepromUpdate() {

  //EEPROM.write(Master, master);
  byte four = (master & 0xFF);
  byte three = ((master >> 8) & 0xFF);
  byte two = ((master >> 16) & 0xFF);
  byte one = ((master >> 24) & 0xFF);

  EEPROM.write(Master, four);
  EEPROM.write(Master + 100, three);
  EEPROM.write(Master + 200, two);
  EEPROM.write(Master + 300, one);

  delay(500);
  EEPROM.commit();
  delay(500);

}

This code is an extremely shortened version of my actual code because of the character limit. Below I have attached the complete code. There are four different tabs, that is why there are four documents below. Thank you for any help!!

REMOD.ino (18.2 KB)

eepromUpdate.ino (941 Bytes)

getHeader.ino (594 Bytes)

variableUpdate.ino (818 Bytes)

@cattledog What do you mean by this?
I apologize because I am still quite a newbie

cattledog:
Master will overflow with +300.

Thank you for your help!!

jamescross449:
@cattledog What do you mean by this?
I apologize because I am still quite a newbie
Thank you for your help!!

he means, 'uint8_t' causes variable to overflow, with any value above 255

1. (assume UNO) You have a 32-bit number: 0x12345678 (305 419 896 decimal) which can be broken into 4-byte data: 0x12, 0x34, 0x56, and 0x78. You want to store these 4 bytes data into 4 different EEPROM locations which are: 0 (0x0000), 10 (0x000A), 20 (0x0014), and 30 (0x001E); where, lower byte will be stored into low-order location -- meaning 0x78 wil be stored into location with address 0 (Fig-1).

eeproms.png
Figure-1: Conceptual view of EEPROM of ATmega328P MCU

2. Let us break the given 32-bit number into 4 discrete bytes.
(1) Using shift and AND operators

long y = 0x12345678;
byte one = (byte) y &0x000000FF;  //0x78
byte two = (byte) (y>>8) &0x000000FF; //0x56
byte three = (byte)(y>>16)&0x000000FF; //0x34
byte four = (byte)(y>>24)&0x000000FF; //0x12

(2) Using union structure

union
{
    long x;
    byte myByte[4];  //myByte[0] will contain 0x78
}data;
data.x = 0x12345678;   //do this initialization in the setup() function

3. Write operation

int memLoc =0;
EEPROM.write(memLoc, one);
or
EEPROM.write(memLoc, data.myByte[0]);
........................................................

4. Read oeration

byte x0 = EEPROM.read(memLoc);  
Serial.println(x0, HEX);    //Serial Monitor should show: 56
......................................................................

5. Combining the 4-byte data to get 32-bit
(1) using shift operator

long x = (long)(x3<<24)|(long)(x2<<16)|(long)(x1<<8)|(long)x0;
Serial.print(x, HEX);     //Serial Moniotr should show: 12345678

(2) Using union structure

union
{
    long x;
    byte myData[4];
}myData;

myData.myData[0] = EEPROM.read(memLoc);
............................................................

Serial.print(myData.x, HEX);      //Serial Monitor should show: 12345678

Note: EEPROM.put() and EEPROM.get() methods work only for contiguous memory locations; but, you have specified locations not touching each other (Fig-1).

eeproms.png

I apologize but I realized that I forgot to mention that I am using a NodeMCU ESP8266 which has 4096 bytes of EEPROM.

Would this cause any issues with the above code?

Thanks,
James

No, except that you have to include the following lines in the sketch if using NodeMCU. Edit:

1. EEPROM.begin(512); in the setup() function in order to allocate 512 byte space as EEPROM.

2. EEPROM.commit(); at the end of write command.

3. EEPROM.end(); to release the emulated EEPROM back to the flash.

Hi,
How did you get this far with your code before having this problem?
Did you write your code in stages and get each stage working correctly before writing the next stage?
Then combining the stages ONE at a TIME, making sure the addition works before adding the next?

You should have some code where you are JUST writing and reading data to and from the EEPROM.

Tom... :slight_smile:

//uint8_t Master = 0;
uint16_t Master = 0;

Did you change this variable to an int?