Countdown with Eprom

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const uint32_t INITIAL_READING =
2870000UL; // Displays 28700.00
const uint32_t MAX_READING =
99999900UL; // Displays 999999.00
const uint16_t RECORD_MAGIC =
0xA55A;
uint32_t reading;
uint32_t currentSequence = 0;
int currentSlot = -1;
// Information stored in EEPROM
struct SavedRecord {
uint32_t sequence;
uint32_t reading;uint16_t magic;
uint16_t checksum;
};
uint16_t calculateChecksum(uint32_t
sequence, uint32_t savedReading) {
uint32_t value = sequence ^
savedReading ^ 0xA55A5A5UL;
value ^= value >> 16;
return static_cast<uint16_t>(value);
}
bool isValidRecord(const SavedRecord
&record) {
return record.magic ==
RECORD_MAGIC &&
record.reading >=
INITIAL_READING &&
record.reading <= MAX_READING
&&record.checksum ==
calculateChecksum(record.sequence,
record.reading);
}
int getNumberOfSlots() {
return EEPROM.length() /
sizeof(SavedRecord);
}
void loadLastReading() {
SavedRecord record;
bool validReadingFound = false;
int numberOfSlots = getNumberOfSlots();
// Search EEPROM for the most recently
saved valid reading
for (int slot = 0; slot < numberOfSlots;
slot++) {int address = slot *
sizeof(SavedRecord);
EEPROM.get(address, record);
if (isValidRecord(record)) {
bool isNewer =
!validReadingFound ||
static_cast<int32_t>(record.sequence -
currentSequence) > 0;
if (isNewer) {
reading = record.reading;
currentSequence = record.sequence;
currentSlot = slot;
validReadingFound = true;
}
}
}// Use the initial value only if EEPROM
has no saved reading
if (!validReadingFound) {
reading = INITIAL_READING;
currentSequence = 0;
currentSlot = -1;
}
}
void saveReading() {
int numberOfSlots = getNumberOfSlots();
// Move to the next EEPROM location
currentSlot = (currentSlot + 1) %
numberOfSlots;
currentSequence++;
SavedRecord record;
record.sequence = currentSequence;record.reading = reading;
record.magic = RECORD_MAGIC;
record.checksum =
calculateChecksum(record.sequence,
record.reading);
int address = currentSlot *
sizeof(SavedRecord);
EEPROM.put(address, record);
}
void displayReading() {
uint32_t whole = reading / 100;
uint16_t decimal = reading % 100;
// Clear the second LCD row
lcd.setCursor(0, 1);
lcd.print(" ");lcd.setCursor(1, 1);
lcd.print(whole);
lcd.print(".");
if (decimal < 10) {
lcd.print("0");
}
lcd.print(decimal);
}
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("TOTAL KWh L1L2L3");
// Recover the last value stored in
EEPROMloadLastReading();
}
void loop() {
displayReading();
// Save the currently displayed reading
saveReading();
// Stop increasing when the maximum
reading is reached
if (reading >= MAX_READING) {
while (true) {
delay(1000);
}
}
delay(20000);
reading++;}

Who can help me rectified this code
When i tried to put in 4 error appears

I just wanted countdown 000000.00 to 999999.99 ( on the second line of my lcd I2C)
( l1 l2 l3 kwh) on the first line
Moving every second by 1
Must important when power go off reading have to started from when power went off

Please help

Your topic has been moved. Please do not post in "Uncategorized"; see the sticky topics in Uncategorized - Arduino Forum.

Please edit your topic, select all code and click the CODE/ button; next save your post. This will apply code tags which makes the code easier to read and easier to copy; it will also prevent that the forum software thinks that certain characters are formatting instructions.

Please let us know which board you're compiling for and post the error messages here (use code tags for that as well).


Quite obvious..
Read the How-To guides, it will help get better, faster responses.

i think the only error was

which should be

    loadLastReading();

the posted code was very poorly formated.
this code compiles (don't know if it works)

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>

LiquidCrystal_I2C lcd (0x27, 16, 2);

const uint32_t INITIAL_READING = 2870000UL;  // Displays 28700.00
const uint32_t MAX_READING     = 99999900UL; // Displays 999999.00
const uint16_t RECORD_MAGIC    = 0xA55A;

uint32_t reading;
uint32_t currentSequence = 0;
int currentSlot = -1;

// Information stored in EEPROM
struct SavedRecord {
    uint32_t sequence;
    uint32_t reading;
    uint16_t magic;
    uint16_t checksum;
};

// -----------------------------------------------------------------------------
uint16_t calculateChecksum (
    uint32_t sequence, uint32_t savedReading)
{
    uint32_t value = sequence ^ savedReading ^ 0xA55A5A5UL;
    value ^= value >> 16;
    return static_cast<uint16_t> (value);
}

bool isValidRecord (
    const SavedRecord &record)
{
    return record.magic == RECORD_MAGIC
            && record.reading >= INITIAL_READING
            && record.reading <= MAX_READING
            && record.checksum ==
                    calculateChecksum (record.sequence, record.reading);
}

int getNumberOfSlots () {
    return EEPROM.length () / sizeof(SavedRecord);
}

void loadLastReading () {
    SavedRecord record;
    bool validReadingFound = false;
    int numberOfSlots = getNumberOfSlots ();

    // Search EEPROM for the most recently saved valid reading
    for (int slot = 0; slot < numberOfSlots; slot++) {
        int address = slot * sizeof (SavedRecord);
        EEPROM.get (address, record);

        if (isValidRecord(record)) {
            bool isNewer =
            !validReadingFound ||
            static_cast<int32_t> (record.sequence -
            currentSequence) > 0;
            if (isNewer) {
                reading = record.reading;
                currentSequence = record.sequence;
                currentSlot = slot;
                validReadingFound = true;
            }
        }
    }  // Use the initial value only if EEPROM has no saved reading

    if (!validReadingFound) {
        reading = INITIAL_READING;
        currentSequence = 0;
        currentSlot = -1;
    }
}

void saveReading () {
    int numberOfSlots   = getNumberOfSlots ();
    // Move to the next EEPROM location
    currentSlot         = (currentSlot + 1) %
    numberOfSlots;
    currentSequence++;
    SavedRecord record;
    record.sequence     = currentSequence;
    record.reading      = reading;
    record.magic        = RECORD_MAGIC;
    record.checksum     = calculateChecksum (record.sequence, record.reading);
    int address         = currentSlot * sizeof (SavedRecord);
    EEPROM.put (address, record);
}

void displayReading () {
    uint32_t whole = reading / 100;
    uint16_t decimal = reading % 100;

    // Clear the second LCD row
    lcd.setCursor   (0, 1);
    lcd.print       (" ");
    lcd.setCursor   (1, 1);
    lcd.print       (whole);
    lcd.print       (".");
    if (decimal < 10) {
        lcd.print   ("0");
    }
    lcd.print (decimal);
}

void setup () {
    lcd.init ();
    lcd.backlight ();
    lcd.setCursor (0, 0);
    lcd.print ("TOTAL KWh L1L2L3");

    // Recover the last value stored in
 // EEPROMloadLastReading ();
    loadLastReading ();
}

void loop () {
    displayReading ();

    // Save the currently displayed reading
    saveReading ();

    // Stop increasing when the maximum reading is reached
    if (reading >= MAX_READING) {
        while (true) {
            delay (1000);
        }
    }
    delay (20000);
    reading++;
}

Thanks for formatting the code; I have copied it to a Wokwi project:

See https://wokwi.com/projects/471457976353763329

I changed the delay of 20 s in loop() to 2 s to speed up the simulation.

I just wanted countdown 000000.00 to 999999.99 ( on the second line of my lcd I2C)
( l1 l2 l3 kwh) on the first line
Moving every second by 1

@millot :Could you explain what you really want to see on the lcd?

Is it the value

  • of e.g. 28700.00 on line 1
  • and the currentSequence in line 2?