PROGMEM confusion - storing an int in flash

I want to do something that I thought was very simple, but I cannot get my head around it.

I want my program to store a value in flash memory that is then read in the next time the power resets in setup(). Essentially this number is a counter, and I want it to continue counting from where it left of.

I have looked at all the PROGMEM and the Flash library but I don't understand how I pull in a variable that hasn't been declared - if that makes sense.

James

I don't think you can dynamically store a variable in flash rom, thats only when you upload a new sketch, and you can have constants stored there like tables etc.

There is another memory suitable for what you want though, you should look into EEPROM library: http://arduino.cc/en/Reference/EEPROM

Note that EEPROM has only about 10000 read/writes so using a counter in EEPROM can be killing. So putting the variable in EEPROM to read when started and store only when one stops (or once every 1000 increments) gives the EEPROM a much longer live.

Furthermore one oculd use external EEPROM e.g. http://www.arduino.cc/playground/Code/I2CEEPROM so the internal EEPROM is spared.


number is 100.000 iso 10.000 see below (and datasheet ) :-[ thanx AWOL :)

You could also spread the counter out across multiple EEPROM addresses, so that it's not destroying it as fast...

Note that EEPROM has only about 10000 read/writes

100000 erase/write cycles - the number of read cycles is effectively infinite.

(for future reference, it’s on the front page of the datasheet)

Thanks all, that clears it up.

I just need to work out how to get a long int split in to separate bytes then.

This is for a rally computer, so I will make it only write when the car stops for x number of seconds.

Do external EEPROMs have similar number of erase/write cycles?

Do external EEPROMs have similar number of erase/write cycles?

Maybe 10x more.

I just need to work out how to get a long int split in to separate bytes then

Cast the address of the "long" to a "byte" pointer, then just write out the four bytes.

Quote: Do external EEPROMs have similar number of erase/write cycles? Maybe 10x more.

Main reason to mention them was that they are easier to replace especially when placed in a socket...

Thanks all.

A pointer - now I am getting a little confused.

I tried this and it seems to output ok

void setup() {
Serial.begin(9600);

test = 123456789;
outputAsBytes((byte *)test);
}

void loop() {
}

void outputAsBytes(byte* data) {
  for (int i=0; i < 4; i++) {
    Serial.println(data[i], DEC);
  }
}

I get:

87
127
170
16

Which I think makes sense.

Now… how to put them back together?

Don't you mean outputAsBytes((byte *)&test); ?

how to put them back together?

Pretty much as you took them apart, assuming you took them apart correctly.

Ahhhh now it really works!

void outputAsBytes(byte* data) {
  for (int i=0; i <= sizeof(data)+1; i++) {
    Serial.println(data[i], HEX);
  }
}

123456789 = 75BCD15

and the output is:

15
CD
5B
7

So I am trying this:

long collectBytes(byte a, byte b, byte c, byte d) {
  byte* buf;
  buf[0] = a;
  buf[1] = b;
  buf[2] = c;
  buf[3] = d;
  return (long) buf;
}

test2 = collectBytes(0x15, 0xCD, 0x5B, 0x07);

But it's giving me 0 as the output.

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

  byte* buf;
  buf[0] = a;
  buf[1] = b;
  buf[2] = c;
  buf[3] = d;

A pointer needs to point to something. What does buf point to?

But it's giving me 0 as the output

And "buf" points to what, exactly?[edit]Ooo! 16 seconds. He's good.[/edit]

Ok the pointer stuff confuses me… :slight_smile:

However… the EEPROM write anything is perfect - exactly what I need!

Thanks all!

Pointers are easy to use. A pointer needs to point to memory that has been dynamically allocated by malloc or new or to statically allocated. Until it points to something, it can not be dereferenced.

it can not be dereferenced.

I think we’ve shown it can.
However, it should not.

I think we've shown it can.

On any system that can throw exceptions, one would be thrown if a program tried to dereference a NULL pointer.

But, I understand your comment and will attempt to be more concise in the future.