Eeprom corruption

I am having an issue after a reset reading back the data stored by the EDB library. I made a slight modification to the example sketch to show the error I am seeing.

Example Sketch

/*
 EDB_Simple.pde
 Extended Database Library + Internal Arduino EEPROM Demo Sketch 
 
 The Extended Database library project page is here:

 */
#include "WProgram.h"
#include <EDB.h>

// Use the Internal Arduino EEPROM as storage
#include <EEPROM.h>

// Uncomment the line appropriate for your platform
#define TABLE_SIZE 512 // Arduino 168 or greater

// The number of demo records that should be created.  This should be less 
// than (TABLE_SIZE - sizeof(EDB_Header)) / sizeof(LogEvent).  If it is higher, 
// operations will return EDB_OUT_OF_RANGE for all records outside the usable range.
#define RECORDS_TO_CREATE 10

// Arbitrary record definition for this table.  
// This should be modified to reflect your record needs.
struct LogEvent {
  char something[50];
  char something2[8];
  int id;
  int temperature;
} 
logEvent;

// The read and write handlers for using the EEPROM Library
void writer(unsigned long address, byte data)
{
  EEPROM.write(address, data);
}

byte reader(unsigned long address)
{
  return EEPROM.read(address);
}

// Create an EDB object with the appropriate write and read handlers
EDB db(&writer, &reader);

void setup()
{
  Serial.begin(9600);
  Serial.println("Extended Database Library + Arduino Internal EEPROM Demo");
  Serial.println();

  //db.create(0, TABLE_SIZE, sizeof(logEvent));
  db.open(0);
  Serial.print("Record Count: "); Serial.println(db.count());

  Serial.println("Creating Records...");
  int recno;

  Serial.print("Record Count: "); Serial.println(db.count());
  for (recno = 1; recno < RECORDS_TO_CREATE; recno++)
  {
    db.readRec(recno, EDB_REC logEvent);
    Serial.print("ID: "); Serial.println(logEvent.id);
    Serial.print("Temp: "); Serial.println(logEvent.temperature);   
    Serial.print("1: "); Serial.println(logEvent.something);
    Serial.print("2: "); Serial.println(logEvent.something2);   
  }
  db.clear();
  db.create(0, TABLE_SIZE, sizeof(logEvent));
  for (recno = 1; recno <= RECORDS_TO_CREATE; recno++)
  {
    logEvent.id = recno; 
    logEvent.temperature = recno * 2;
    strcpy(logEvent.something, "some test data that is long");
    strcpy(logEvent.something2, "test2");
    db.appendRec(EDB_REC logEvent);
  }
  Serial.print("Record Count: "); Serial.println(db.count());
  for (recno = 1; recno < RECORDS_TO_CREATE; recno++)
  {
    db.readRec(recno, EDB_REC logEvent);
    Serial.print("ID: "); Serial.println(logEvent.id);
    Serial.print("Temp: "); Serial.println(logEvent.temperature);   
    Serial.print("1: "); Serial.println(logEvent.something);
    Serial.print("2: "); Serial.println(logEvent.something2);   
  }
}

void loop()
{
}

Output after upload then pressing reset once.

Extended Database Library + Arduino Internal EEPROM Demo

Record Count: 0
Creating Records...
Record Count: 0
ID: 0
Temp: 0
1: 
2: 
ID: 0
Temp: 0
1: 
2: 
ID: 0
Temp: 0
1: 
2: 
ID: 0
Temp: 0
1: 
2: 
ID: 0
Temp: 0
1: 
2: 
ID: 0
Temp: 0
1: 
2: 
ID: 0
Temp: 0
1: 
2: 
ID: 0
Temp: 0
1: 
2: 
ID: 0
Temp: 0
1: 
2: 
Record Count: 8
ID: 1
Temp: 2
1: some test data that is long
2: test2
ID: 2
Temp: 4
1: some test data that is long
2: test2
ID: 3
Temp: 6
1: some test data that is long
2: test2
ID: 4
Temp: 8
1: some test data that is long
2: test2
ID: 5
Temp: 10
1: some test data that is long
2: test2
ID: 6
Temp: 12
1: some test data that is long
2: test2
ID: 7
Temp: 14
1: some test data that is long
2: test2
ID: 8
Temp: 16
1: some test data that is long
2: test2
ID: 8
Temp: 16
1: some test data that is long
2: test2

Reset button pressed here

Extended Database Library + Arduino Internal EEPROM Demo

Record Count: 8
Creating Records...
Record Count: 8
ID: 0
Temp: 25972
1: 
2: 
ID: 0
Temp: 25972
1: st2
2: 
ID: 0
Temp: 25972
1: st2
2: 
ID: 0
Temp: 25972
1: st2
2: 
ID: 0
Temp: 25972
1: st2
2: 
ID: 0
Temp: 25972
1: st2
2: 
ID: 0
Temp: 25972
1: st2
2: 
ID: 0
Temp: 25972
1: st2
2: 
ID: 0
Temp: 25972
1: st2
2: 
Record Count: 8
ID: 1
Temp: 2
1: some test data that is long
2: test2
ID: 2
Temp: 4
1: some test data that is long
2: test2
ID: 3
Temp: 6
1: some test data that is long
2: test2
ID: 4
Temp: 8
1: some test data that is long
2: test2
ID: 5
Temp: 10
1: some test data that is long
2: test2
ID: 6
Temp: 12
1: some test data that is long
2: test2
ID: 7
Temp: 14
1: some test data that is long
2: test2
ID: 8
Temp: 16
1: some test data that is long
2: test2
ID: 8
Temp: 16
1: some test data that is long
2: test2
  for (recno = 1; recno < RECORDS_TO_CREATE; recno++)
  for (recno = 1; recno <= RECORDS_TO_CREATE; recno++)
  for (recno = 1; recno < RECORDS_TO_CREATE; recno++)

The first record is numbered 0, not 1. The valid record numbers are 0 to RECORDS_TO_CREATE - 1, not 1 to RECORDS_TO_CREATE.

The size of the LogEvent structure is 50 + 8 + 2 + 2 or more. That is 62 bytes per record, or more. The structure may be padded to for word alignment purposes.

You want 10 records, 62+ bytes each, to fit in a 512 byte table.

Do you think they will really fit?

The first record is 1, this is from the example and i haven't changed the looping logic. in the code it does:

// reads a record from a given recno
EDB_Status EDB::readRec(unsigned long recno, EDB_Rec rec)
{
  if (recno < 1 || recno > EDB_head.n_recs) return EDB_OUT_OF_RANGE;
  edbRead(EDB_table_ptr + ((recno - 1) * EDB_head.rec_size), rec, EDB_head.rec_size);
  return EDB_OK;
}

It always does a -1 on the head so you can have a 1 based index.

I am on an at328 with 1k of eeprom space available so there should be plenty of room. I am able to write and read the data properly if i use the EXROM library. I suspect it is a problem with how the EDB library is loading the struct. Below is the EXROM code that i have in my main sketch that is working properly between resets.:

void WriteCharactersToEeprom(int charidx=0) {
  int pos = 0;
  byte len=0;
  byte maxnum = MAX_CHARACTERS;
  if (charidx != 0)
    maxnum = charidx + 1;
  for (int i=charidx;i<maxnum;i++)
  {
    len = 50;
    EXROM.write(pos, characters[i].username, len);
    pos += len;
    len = 8;
    EXROM.write(pos, characters[i].charname, len);
    pos += len;
    len = sizeof(byte);
    EXROM.write(pos, &characters[i].race, len);
    pos += len;
    len = sizeof(byte);
    EXROM.write(pos, &characters[i].room, len);
    pos += len;
    len = sizeof(unsigned int);
    EXROM.write(pos, &characters[i].experience, len);
    pos += len;
  }
}

I'm just not sure why the EDB isn't working properly between resets.

After shrinking the number of records and table size, I tried running the test on a Teensy++. The board stops responding.

I'm going to go out on a limb and say there's a bug in the EDB library. Eye-balling the source code, I didn't see any problems. My suggestion is to contact the EDB author.

Thanks for the help, I just wanted to make sure I wasn't missing something obvious.

I just wanted to make sure I wasn't missing something obvious

Hopefully, we both didn't miss the obvious. :wink:

This is an old thread by now, but I just wanted to add that I couldn't get this library to work either (after a reset). Instead, I switched back to the more simple library DB and that one works fine.

I'm having problems with the EDB library using an AT24C1024 memory, first I create a db with some data, I read the data back to verify it was written correctly, and it was.

After i reset the arduino, the data from the two first registers of the database are corrupt, just the two first.

I would like to know if someone is having the same problem. I need some advice.

thanks

i'm appending a capture of five strings i saved to the database,
when I save them and read them back from the database they are like this:

T12345 F200 G200 H200 S1
T12345 F200 G200 H200 S1
T12345 F200 G200 H200 S1
T12345 F200 G200 H200 S1
T12345 F200 G200 H200 S1

after a reset the same strings read this:

T17 F0 G0 H8 S0
T2 F200 G200 H200 S1
T12345 F200 G200 H200 S1
T12345 F200 G200 H200 S1
T12345 F200 G200 H200 S1