-1

I have bytes of natural numbers 1-60 coming in at random times:

Example of send data

// Uno send

void setup() {
  Serial.begin(9600);
  
  int integersToSend[] = {1, 22, 30, 4, 50};
  for (int i = 0; i < 5; i++) 
  {
    Serial.print(integersToSend[i]);  // send as characters
    delay(1000);
  }
}

void loop() {}

I want to log the time (any time format) and what value was received into EEPROM:

#include <EEPROM.h>

const int timeRefreshDisplay = 30000;
const int EEPROM_SIZE = 100; // Define size of EEPROM available
int addr = 0; // EEPROM address pointer

unsigned long programStartTime;

void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600); // Initialize Serial1 for data input
  programStartTime = millis(); // Record program start time
}

void loop()
{
  if (Serial1.available())
  {
    int receivedData = Serial1.read();

    if (receivedData != 0 && receivedData <= 60)
    {
      byte receivedValue = receivedData; // Convert?

      // Calculate the timestamp based on program start time
      unsigned long currentTime = programStartTime + millis();

      // Store the received timestamp and value in EEPROM
      EEPROM.put(addr, currentTime);
      addr += sizeof(unsigned long);
      EEPROM.put(addr, receivedValue);
      addr += sizeof(int);
    }
  }

  if (millis() - programStartTime >= timeRefreshDisplay)
  {
    programStartTime = millis();
    displayEEPROMData();
  }
}

void displayEEPROMData() {
  // Display all positions stored in EEPROM
  Serial.println("EEPROM:");

  for (int i = 0; i < EEPROM_SIZE; i += sizeof(unsigned long) + sizeof(int)) {
    if (i >= EEPROM_SIZE) {
      i = 0; // Start reading from the beginning when reaching the end of EEPROM
    }

    unsigned long timestamp;
    int value;
    EEPROM.get(i, timestamp);
    EEPROM.get(i + sizeof(unsigned long), value);

    // Display position data with timestamp in HH:MM:SS format
    Serial.print(String(i / (sizeof(unsigned long) + sizeof(int)) + 1) + ": ");
    Serial.println(String(timestamp) + ", " + String(value));
  }
}

Serial monitor

EEPROM:
1: 17330, 22272
2: 101, 27943
3: 4143972352, 116
4: 0, 0
5: 0, 0
6: 0, 0
7: 0, 0
8: 0, 0
9: 0, 0
10: 0, 0
11: 0, 0
12: 0, 0
13: 0, 0
14: 0, 0
15: 0, 0
16: 0, 0
17: 0, 0

I'm not quite sure how it is reading data into EEPROM. That has to be where the issue is. I just don't know how to fix it. I tried clearing out the memory:

    #include <EEPROM.h>
    
    
    void setup() {
       // initialize the LED pin as an output.
       pinMode(13, OUTPUT);
    
       for (int i = 0 ; i < 22; i++) /*EEPROM.length()*/ 
          EEPROM.write(i, 0);
    
       // turn the LED on when we're done
       digitalWrite(13, HIGH);
    }
    
    void loop() {}

Serial monitor again

EEPROM:
1: 0, 0
2: 0, 0
3: 0, 0
4: 0, 4
5: 70, 1
6: 22, 3
7: 230, 2
8: 182, 4
9: 134, 50
10: 234, 49
11: 209, 50
12: 213, 50
13: 185, 51
14: 189, 48
15: 161, 52
16: 137, 53
17: 140, 48

I'm using a Leonardo to receive.

3
  • An EEPROM cell can tolerate only a limited number of write cycles. You should be very careful when writing to it continuously in the loop(). You are writing 2 associated data items to the EEPROM per cycle. It would be better to use a struct to pack the two items and do the write operation in one go using the put() method. For unpacking, use the get() method.
    – 6v6gt
    Sep 10, 2023 at 10:02
  • It could be that you have already damaged some EEPROM cells by exceeding the write cycle limit. You could start at say cell 100 instead of cell 0 to see if the results are more consistent. Hovever, don't allow the code to write endlessly to the EEPROM and remember that an unwritten to EEPROM cell is '1' filled.
    – 6v6gt
    Sep 10, 2023 at 13:07
  • My EEPROM library supports update which will only write if there is a change. Try using that. Also you can use FRAM and have unlimited R/W cycles.
    – Gil
    Sep 11, 2023 at 2:08

1 Answer 1

0

This works.

#include <EEPROM.h>

const int EEPROM_SIZE = 100; // Define size of EEPROM available
int addr = 0; // EEPROM address pointer

unsigned long programStartTime;

void setup()
{
  Serial.begin(9600);
  while (!Serial);
    Serial1.begin(9600);

  programStartTime = millis(); // Record program start time

  // Initialize EEPROM data
  //  for (int i = 0; i < EEPROM_SIZE; i++) {
  //    EEPROM.write(i, 0);
  //  }
  displayEEPROMData();
}

void loop()
{
  if (Serial1.available())
  {
    int receivedData = Serial1.read();

    if (receivedData >= 1 && receivedData <= 60)
    {
      byte receivedValue = static_cast<byte>(receivedData); // Convert to byte

      // Calculate the timestamp based on program start time
      unsigned long currentTime = millis() - programStartTime;

      // Store the received timestamp and value in EEPROM
      EEPROM.put(addr, currentTime);
      addr += sizeof(currentTime);
      EEPROM.put(addr, receivedValue);
      addr += sizeof(receivedValue);

      displayEEPROMData();
    }
  }

  if (addr >= EEPROM_SIZE) {
    addr = 0; // Wrap around if the EEPROM is full
  }

}

void displayEEPROMData() {
  // Display all positions stored in EEPROM
  Serial.println("EEPROM:");

  for (int i = 0; i < EEPROM_SIZE; i += sizeof(unsigned long) + sizeof(byte)) {
    unsigned long timestamp;
    byte value;
    EEPROM.get(i, timestamp);
    EEPROM.get(i + sizeof(timestamp), value);

    // Display position data with timestamp in HH:MM:SS format
    Serial.print(String(i / (sizeof(unsigned long) + sizeof(byte)) + 1) + ": ");
    Serial.println(String(timestamp) + ", " + String(value));
  }
}
2
  • Well done, answering your own question, really. For future visitors including your future self in some weeks, you might extend your answer with some explanation what was wrong. Comparing source code shows the result, but not the way to it. Sep 11, 2023 at 5:44
  • You appear to have another problem that you are sending integers (int datatype) from a Uno to the receiver. An int is represented as two bytes on the Uno. On the receiver you are getting individual bytes but making no attempt to collect pairs of these to reconstruct the original int.
    – 6v6gt
    Sep 13, 2023 at 8:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.