Read byte and time into EEPROM, then display with a comma between the time and the value?

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. Budget is $20? I thought this was a simple thing, but struggling hard. Already sunk 22 hours into this.

You still don't use a delimiter.

"programStartTime" is always 0.

The only way this could possibly work would be a timeout after sending the last digit .- on the reiver you would try to find that timeout. But you don't do that, either. (Not to mention that would be a quite unstable aproach)

will send a varying number of characters. why not try coding that to send to Serial Monitor, and look at what you get, before routing it to another processor?

Because that is just a sample of data being sent. I don't get why everyone keeps trying to alter and the emulated/sample data.

That part works. It's storing/reading it into EEPROM that I'm having trouble with.

What do you think it does?

There is no delimiter in the actual data being sent. So I cannot add one to the sample data.

Because that's what I can see from reduced programs...

Nope, quite clearly set in setup(), and updated on display. Not the problem.

Not the problem, but you receive an int, "convert" it to a byte, then write it to EEPROM, and increment address by size of int. Try using sizeof() on the actual variables you're working with, to avoid a future nasty bug?

This probably should have been millis() - programStartTime.

#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);
  programStartTime = millis(); // Record program start time

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

void loop()
{
  if (Serial.available())
  {
    int receivedData = Serial.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);
    }
  }

  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));
  }
}

And? Same result?

With the displayEEPROMData() functions in there, I'm getting... well nothing now. Supposed to print out some initial EEPROM positions. Was spitting out zeros. Idk, I'm pretty burnt out.

#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);
  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 (Serial.available())
  {
    int receivedData = Serial.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));
  }
}

Added while (!Serial); after Serial.begin.

Serial monitor:

EEPROM:
1: 0, 0
2: 0, 0
3: 0, 0
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
18: 0, 0
19: 0, 0
20: 0, 0

Your last code works fine for me... I cleared the EEPROM. Then, each character sent is put in, with the timestamp before it. This is on a Nano, mind you, and the characters are coming from Serial Monitor, but that shouldn't matter.

EEPROM:
1: 5170, 52
2: 9186, 53
3: 20908, 54
4: 26445, 55
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
18: 0, 0
19: 0, 0
20: 0, 0

What times are those? Seems not right.

milliseconds since program start.

Whenever I send new data...

// Uno send

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

void loop() {}

The display on the receive program does not... happen.

Just stays with what was printed from setup.

You've got an Uno sending data, but Serial Monitor displaying - this is a Leondardo - one of the serial ports should be Serial1, no?
Guess I need to see how you've got things connected, then.
UnoSerial to?
Leonardo Serial to?
Leonardo Serial1 to?
Any software serial on top of this?

1 Like