I'm looking at using an I2C EEPROM with an Arduino Mini (ATMega328) as a data logger. I need the Arduino to periodically write some bytes (approx 15) to the EEPROM. So, the code will need to keep track of the next available contiguous empty memory space, so that it knows where to write the next string of bytes (and not overwrite existing data).
I don't want to simply use a variable as a memory pointer, because if there's a black-out or a brown-out then the Arduino will lose the memory pointer. So, I had thought of storing the memory pointer in the EEPROM, and updating it after each string of bytes is written. But, what happens if the black-out or brown-out occurs when data is being written to the EEPROM? The memory pointer may become corrupt!
So, is it possible to read from the EEPROM what address the next free space is? (so no need to keep track of the location of used/free space in the EEPROM). Or, how does code typically keep track of the location of used/free memory space - in a way that doesn't get affected by black-outs or brown-outs?
The EEPROM memory pointer isn't a bad approach, although the risk you mention can happen, it's pretty remote. Also, EEPROM has a finite r/w lifetime. Why not use an SD card instead? The basic file functions (e.g., fseek()) should make it easy to update the file plus it's pretty easy to remove the card and use the data with other programs.
But, what happens if the black-out or brown-out occurs when data is being written to the EEPROM? The memory pointer may become corrupt!
Write the data first, then update the pointer. That way, the worst that will happen is that you'll loose the last data (partially) written.
So, is it possible to read from the EEPROM what address the next free space is? (so no need to keep track of the location of used/free space in the EEPROM).
If the EEPROM is unused, the values in each memory location should be -1/255 (or, you can force that to the case any time you want to reinitialize the EEPROM), so finding the first unused position is simple with a for loop. If you intend to start writing over when the EEPROM gets full, then finding the next location is more challenging. All this assumes, of course, that 255 is not a valid value for you to write to an EEPROM address.
econjack:
Why not use an SD card instead? The basic file functions (e.g., fseek()) should make it easy to update the file plus it's pretty easy to remove the card and use the data with other programs.
Hi econjack, I like the idea of using an SD card... as you mentioned it's easy to remove the card and read it in another device. However, I'm going to be powering the device with a li-ion battery, which has a working voltage range of about 3.6V to 4.2V. An SD card operates between 2.7V and 3.6V, so the fully charged li-ion battery will likely damage the SD card. I don't want to use a voltage regulator because I'm trying to make the (battery powered) circuit as efficient as possible. I've seen several EEPROMs that will work in within the voltage range of the battery...
If you can suggest a way of using an SD card within the voltage range of the battery I'd rather do that!
PaulS:
Write the data first, then update the pointer. That way, the worst that will happen is that you'll loose the last data (partially) written.
If the EEPROM is unused, the values in each memory location should be -1/255 (or, you can force that to the case any time you want to reinitialize the EEPROM), so finding the first unused position is simple with a for loop. If you intend to start writing over when the EEPROM gets full, then finding the next location is more challenging. All this assumes, of course, that 255 is not a valid value for you to write to an EEPROM address.
Hi PaulS, I was thinking along the same lines as you, about it being OK to (very rarely) lose a few bytes of data to a brown-out. However, what if it's the memory pointer in the EEPROM that becomes corrupted - then we don't know where we are!
I also like the idea of reading through every byte in the EEPROM until we find an empty one - this keeps things nice and simple. However, like you said, there's potential for valid data to be perceived as an empty space...
This memory tracking situation is new to me, but surely there are tried and tested solutions to keeping track of memory pointers!
However, what if it's the memory pointer in the EEPROM that becomes corrupted - then we don't know where we are!
How big is the EEPROM? How many bytes per record? In other words, how many records can you store in EEPROM? If less than 256, store the number of records, not the address of the next available slot. That way, the write is an atomic operation, and can not be interrupted.
That sounds good... have a number_of_records pointer (which uses a single byte) rather than a memory address pointer (which uses multiple bytes)... sadly though, the number of records will be far greater than 256...
I'm looking at writing about 15 bytes of data every 15 or 20 minutes for at least a couple of months. So that requires something like a 128kB EEPROM, which will have 5,000+ records written to it over a period of months.
Keep in mind that some diodes have smaller voltage drops (e.g., Schottky and germanium, about 0.2V) and others have larger drops (e.g., LEDs, over 1V). Check the SD card specs as they should tell you what voltages it can use.
Good point econjack, I'll measure the voltage drop across the diode to be on the safe side.
Any ideas what happens if there's a brown-out/black-out when an SD card is being written to? Would the file on the card become corrupt? Any way to protect against this?
Use a super capacitor that the Arduino charges. It can provide enough current to allow the Arduino to run for a few (dozen) milliseconds after the power goes out, so that the Arduino can close any open files.
I'm thinking that the Arduino would need to detect that the power has gone, and quickly perform some shutdown operations (close the file on the SD card, etc.) before the super capacitor runs out of juice.
What's a good way to do this? I have a protection circuit for the li-ion battery which cuts the power when the battery's voltage drops too low. I'm thinking just connect an Arduino digital input pin directly to the battery, and regularly poll that pin. If the pin's input drops, then perform some shutdown operations. Any thoughts/suggestions?
I'm thinking just connect an Arduino digital input pin directly to the battery, and regularly poll that pin. If the pin's input drops, then perform some shutdown operations. Any thoughts/suggestions?
Andy-C:
I like the idea of using an SD card... as you mentioned it's easy to remove the card and read it in another device. However, I'm going to be powering the device with a li-ion battery, which has a working voltage range of about 3.6V to 4.2V. An SD card operates between 2.7V and 3.6V, so the fully charged li-ion battery will likely damage the SD card. I don't want to use a voltage regulator because I'm trying to make the (battery powered) circuit as efficient as possible. I've seen several EEPROMs that will work in within the voltage range of the battery...
If you can suggest a way of using an SD card within the voltage range of the battery I'd rather do that!
So just use a regulator that has a low quiescent current. The MCP1700 for instance (and there are others) uses typically 1.6uA, is that low enough ?