Go Down

Topic: Write to pgmspace? (Read 2 times) previous topic - next topic

verstapp

Jun 25, 2008, 09:45 am Last Edit: Jun 25, 2008, 09:48 am by verstapp Reason: 1
Wishing to preserve a sketch's state through a reboot, I thought of checkpointing to non-volatile memory. I first discovered EEPROM, but not wishing to wear out its 100k write cycles too quickly I looked further and found PGMSPACE. Unfortunately, the examples given assume that a bunch of variables are going to be loaded into there when the sketch is uploaded and that the space is used ever after as read-only: there is no mention of writing there. So either I find another piece of non-volatile memory that is read-writeable but without EEPROM's limit or I use EEPROM and start saving for a replacement ATmega. Any ideas?
Cheers,

PeterV in Canberra

bens

#1
Jun 25, 2008, 10:36 am Last Edit: Jun 25, 2008, 10:37 am by bens Reason: 1
First of all, you should note that program space (a.k.a. flash memory) wears out an order of magnitude faster than EEPROM.  Flash can withstand 10,000 write/erase cycles while EEPROM can withstand 100,000 write/erase cycles.  Note this endurance spec applies individually to each memory location, so this means that writing 100,000 times to the same EEPROM address will potentially wear out that address, but the remaining 511 EEPROM addresses will still function just fine.  Additionally, this endurance spec is just a safe lower bound; I've heard of people testing EEPROM by writing to the same address millions of times without any negative consequences.

If you schedule it so that you only back up your state every minute or so, you should be fine using EEPROM, especially if you can periodically change the EEPROM addresses used to store the state.  Another idea is to create your own RESET by connecting a pushbutton to one of your digital inputs and by connecting another digital input to your RESET line.  When someone pushes your custom RESET button, call a function that saves the state to EEPROM and then have your Arduino drive its own RESET low to reset itself.  Of course this idea won't help you if someone pushes the real reset button or if your power supply dies or gets disconnected.

- Ben

verstapp

#2
Jun 25, 2008, 12:17 pm Last Edit: Jun 25, 2008, 12:24 pm by verstapp Reason: 1
Your reply goes some way towards explaining *why* we're not allowed to write to pgmspace. My aim is to  log some readings on a stand-alone ardy then unplug it from the battery and plug in a usb lead to upload results to a PC. With that in mind, a pushbutton connected to a digital pin should do the trick. Poll the pin and when the button is pressed write the state to eeprom which should preserve the data through the battery->usb changeover.

Thanks for your help, bens.
Cheers,

PeterV in Canberra

Grumpy_Mike

I may be missing something but why disconnect it from the battery?
If it has to go how about a small rechargeable cell that keeps it going between battery and USB?

Finally you could use some I2C EEPROM, they are usually specked at > 1 million writes.

follower

Quote
then have your Arduino drive its own RESET low to reset itself.

I'm too lazy to double check this now but I seem to recall attaching to your own reset line is specifically "prohibited" by Atmel. Or maybe it was something else...

Presumably you'd use the Watchdog to actually achieve this result within spec.

--Phil.

follower

Quote
Your reply goes some way towards explaining *why* we're not allowed to write to pgmspace.

Just to confuse things and be pedantic, you *can* write to pgmspace but the limitations on how you can do so are so significant it's not of practical use except for specific circumstances. (Limitations include that you must access  a "page" at a time, the actual instructions that do the writing must be in the bootloader segment and probably more.) For these reasons and more, using EEPROM would probably be the way to go for you.

Quote
My aim is to  log some readings on a stand-alone ardy then unplug it from the battery and plug in a usb lead to upload results to a PC.

As mentioned above, you can have the device be battery powered and still connect via USB to the PC.

--Phil.

bens

Quote
I'm too lazy to double check this now but I seem to recall attaching to your own reset line is specifically "prohibited" by Atmel. Or maybe it was something else...

It's definitely possible to have an AVR reset itself using an I/O line (I've done it many times without ever having a problem).  If you can point me to someplace where Atmel advises against this I'd be very interested to see it.

- Ben

MysteriousAges

Quote
Quote
then have your Arduino drive its own RESET low to reset itself.

I'm too lazy to double check this now but I seem to recall attaching to your own reset line is specifically "prohibited" by Atmel. Or maybe it was something else...

Maybe it was having something on the reset line when using the AVR Dragon or a similar debugger? For those, Atmel says the debugger needs full control of the line, and having a capacitor or something else on it will bugger with things.

westfw

If you're paranoid about "burning out" the internal eeprom, you can alway connect a cheap external eeprom chip; if you wear it out, you just replace it.  (although... a new ATmega168 is not so much more expensive than an external eeprom chip.  "Under $5" means your "real" costs may be dominated by postage, etc, rather than the cost of the chip itself.)

verstapp

Farnell says ATmega168 PUs for AUD9.42 ea, kess for 25+. I don't think I'll worry about wearing it out...
Cheers,

PeterV in Canberra

trialex

#10
Jun 26, 2008, 05:58 am Last Edit: Jun 26, 2008, 05:58 am by trialex Reason: 1
Quote
Farnell says ATmega168 PUs for AUD9.42 ea, kess for 25+. I don't think I'll worry about wearing it out...


Dude don't be buying from Farnell in Australia unless you are in a real hurry and can't wait for Futurlec to deliver. The have '168s for AU$4.20 each. Delivery is AU$4 for orders under AU$50.

http://www.futurlec.com.au/test13.jsp?category=Integrated%20Circuits%20-%20Atmel&category_title=Atmel%20Microcontrollers&main_menu=IC&sub_menu=ICATMEL

melka

+1 for the external EEPROM, if you can stand the 3ms write time
http://melka.one.free.fr/blog/
http://www.flickr.com/photos/melkaone/

bens

The external EEPROM sounds fairly unnecessary given what verstapp seems to want to do (all he needs is some signal to tell him when to back up the state to EEPROM, which means he won't be burning anything out).  Additionally, he might not even need to backup the state since he doesn't have to turn off the Arduino to plug it into USB.  Lastly, the internal EEPROM has a write time of 3.4 ms, too.  Lastly lastly, if he does burn out the internal EEPROM, he can buy external EEPROM at that point and use it instead (the AVR will still function with burned out EEPROM addresses).

- Ben

spiffed

An honest question, has anyone seen an over used eeprom location in an ATMega? I've seen over-used flash, but never eeprom.
I figure it's time to find out. I've just grabbed a fresh new ATMega168 (I can't find the manufacture date for this lot, but it's recent) and loaded the following sketch into it. With a 0.1s delays, it should destroy this address in about 2.7 hours by Atmel's standards. For reference, VCC=~4.8V.

In all honesty, this doesn't stress the retention characteristics of the memory, only asking for 100uS of retention and with the power on, but any other test would take forever!

Quote
#include <EEPROM.h>

unsigned char x = 1;
unsigned long c=0;

void setup(){
  Serial.begin(9600);
  EEPROM.write(55,x);
  delay(100);
}

void loop(){
 unsigned char y=EEPROM.read(55);
 if(x==y){
   Serial.print("OK for ");
   Serial.print((unsigned)x,HEX);
   Serial.print(", tick# ");
   Serial.println(c);
 }else{
   Serial.print("Failure at tick# ");
   Serial.println(c);
   Serial.print("Expected: ");
   Serial.print((unsigned)x,HEX);
   Serial.print(" - Read: ");
   Serial.println((unsigned)y,HEX);
   while(1);
 }
 x+=3;
 c++;
 EEPROM.write(55,x);
 delay(100);
}
iDuino - MaxSerial - [url=http://spi

bens

That looks like a good test.  I might have just had the stored value alternate between 0x55 (01010101) and 0xAA (10101010), but incrementing the value by 3 each time sounds reasonably robust.  I also might have chosen to do this test on EEPROM address 511 so that it would be easier to remember which address is bad later.

- Ben

Go Up