Database library question

In reference to the database library. I cannot get a modified example to read data back out of eeprom.

I have broken the example sketch into 2 sketches, one which should write and one to read, read loaded after write.

write:

#include "WProgram.h"
#include <EEPROM.h>
#include <DB.h>
#include <string.h>

DB db;


struct MyRec {
  int temperature;
} myrec;

void setup()
{
  Serial.begin(9600);
  db.create(1,sizeof(myrec));
  Serial.println("DONE");

  Serial.print("Creating records...");
 
  myrec.temperature = 6;
  db.append(DB_REC myrec);
  Serial.println("DONE");
}

void loop()
{
}

read:

#include "WProgram.h"
#include <EEPROM.h>
#include <DB.h>
#include <string.h>

DB db;

struct MyRec {
  int temperature;
} myrec;

void setup()
{
  Serial.begin(9600);
  Serial.println("Reading records from EEPROM...");
  Serial.println();
  db.open(1);
  db.read(1, DB_REC myrec);
  Serial.print("Temperature: "); Serial.println(myrec.temperature);
}

void loop()
{
}

The data read back should be 6, but it is zero. Can anyone explain why?

Can anyone explain why?

Pretty simple, really.

struct MyRec {
  int temperature;
} myrec;

This defines a type. It does not create an instance of that type.

  myrec.temperature = 6;

This tries to set the temperature member of the instance myrec to 6. Since there is no myrec instance, I,m surprised this even compiles.

But, even if it does,

  db.append(DB_REC myrec);

creates a new instance of a type DB_REC and passes that new instance to the append method. This hardly seems like what you wanted to do.

When you load a sketch the EEPROM is erased. It is used to save data across resets and power cycles, not for saving data between sketches.

You can use a Serial EEPROM or SD card for long-term storage to be used by multiple sketches.

When you load a sketch the EEPROM is erased.

Not unless that sketch explicitly erases it. One can store data in EEPROM, make changes to the sketch, and upload again. Saved data is still there.

When you load a sketch the EEPROM is erased. It is used to save data across resets and power cycles, not for saving data between sketches.

As Paul stated that is not what happens. The arduino bootloader and AVRDUDE do have the capability to read, write or erase the EEPROM memory, however the arduino IDE does not do that as part of a upload operation.

Lefty

PaulS:

When you load a sketch the EEPROM is erased.

Not unless that sketch explicitly erases it. One can store data in EEPROM, make changes to the sketch, and upload again. Saved data is still there.

It doesn't get initialized on upload??? I thought when it said "Locations that have never been written to have the value of 255." it meant "written by this sketch". Silly me.

I guess it's not necessary. One could tag the EEPROM with a hash of the build date/time. If the tag wasn't already set the sketch is new and should initialize the EEPROM with reasonable defaults.

Where is the part that actually writes the EEPROM in the original code?

from:

"store values ... into the EEPROM using theEEPROM.write() function. These values will stay in the EEPROM when the board is turned off and may be retrieved later by another sketch."

  // write the value to the appropriate byte of the EEPROM.
  // these values will remain there when the board is
  // turned off.
  EEPROM.write(addr, val);

Ok well then I presume there must be something wrong with the example sketch. My sketches were nothing more then a stripped down version of example sketch.

http://www.arduino.cc/playground/Code/DatabaseLibrary

Well, I see some EEPROM references within DB.h, guess it is being done there:

int EEPROM_dbWrite(int ee, const byte* p);
int EEPROM_dbRead(int ee, byte* p);

These libraries & classesand whatnot are convenient, pain in the butt debugging when you have do a bunch of digging in multiple locations to see what they really do.

I think a more valuable option is to ditch eeprom database and move to sd card, which is what I will be doing.

However it would be good to revise the example sketch, if it is indeed wrong.

The bug is in DB::create(). It fails to initialize DB::DB_tbl_ptr.

If you follow DB.create(1, recsize); with DB.open(1); (like is done in the example) that will work around the problem.

To fix the problem so the DB.open() is not necessary after DB.create():

void DB::create(int head_ptr, byte recsize)
{
  DB_head_ptr = head_ptr;
  DB_tbl_ptr  = head_ptr + DB_HEAD_SIZE;  //////  INSERT THIS LINE IN DB.CPP
  DB_head.n_recs   = 0;
  DB_head.rec_size = recsize;
  writeHead();
}