It all started one bright morning when I wondered: Can the RAM memory on an AVR chip continue to store data after power is removed? If it can hold the data even just for a brief moment, then that could be very useful in a project I am working on.
To test it, I wrote a tiny little program that would check for a a special value in RAM (a “magic cookie”) upon power up and light an LED if it saw the right value…
#include <avr/io.h>
#define MAGIC_COOKIE 0xee00ff55UL // Nice cookie to exercise bits
unsigned long ram_cookie;
void init0 (void) __attribute__ ((naked)) __attribute__ ((section (".init0")));
// This code will be run immedeately on reset, before any initilization or main()
void init0(void) {
DDRD = _BV(0); // Enable output on LED on pin 19
if (ram_cookie==MAGIC_COOKIE) { // Is the cookie there?
PORTD = _BV(0); // Light the LED!
}
ram_cookie = MAGIC_COOKIE; // Load the cookie for next run
while (1); // All done
}
// We never make it to main()
int main(void)
{
}
I also built a very simple circuit with an ATTINY4313 so I could try turning the power off for various amounts of time to get a feel for how long the memory would last without power…
The idea is that you press the button for a little while to remove power from the chip. If the LED goes on when you let go, then the “cookie” was still valid in RAM and so was safely retained while the power was removed. I was careful to try and make sure that there was no place that power could leak into the circuit when the button was pressed.
After only about 10 minutes of work I was ready to start testing!
Initial results were extraordinary. It seemed like the little AVR could reliably hold data without power for a very long time. I tested progressively longer and longer times, getting up to 10 minutes without power and each time it came back to life with the cookie still intact. My finger got too tired to test any longer.
I was very excited. If you could reliability store data in RAM for more than 10 minutes without power, then this could be a great alternative to FLASH and EEPROM memory in many applications. 10 minutes is long enough to safely change a set of batteries. Don’t get me wrong – EEPROM and FLASH are great and can hold data for decades without power, but they are also thousands of times slower than RAM and they wear out if you use them too much.
So I went ahead and updated my project to use RAM and connected it all up and… it just didn’t work at all. The RAM did not reliably survive the power loss. I was confused. I had to figure why it had worked so well in testing but not at all in the real application. What was different in the project? I slowly cut away parts of the full project until I was left with nothing more that original test setup – and it still did not work. Did I use the same physical chip that I had used the first time? Was there some way I was accidentally powering that first test? Had I accidentally left the debugger connected on the test circuit?
When faced with a really frustrating situation like this sometimes the best thing to do is goto sleep, so I did.
The next morning my mind was fresh and I was sure I would be able to track down the problem. I fired everything up and… now it worked! Ahhhh!!! What was going on? I was sure it was not working the night before and I had not touched anything between then and now. Argh.
So I went ahead and built another full circuit and, of course, again it did not work at all- just like the last full circuit. Luckily this time I had kept the test circuit built just in case. I fired it up and…. it didn’t work either! Ahhhhh! Now I had two not-working circuits and I was getting really, really confused.
Knowing now that I had not changed anything about the test circuit between it working and not working, I assumed the change must be something in the environment. Higher temperatures could plausibly affect RAM data loss since it could lead to higher thermal noise in the silicon. Humidity also seemed like a reasonable candidate since that could possibly allow more leakage current through the air.
I frantically built an Ardunio-controlled rig that could automatically run continuous test passes on the circuit . It varied the power-off time for each pass while logging the results along with the ambient temperature and humidity. I used relays to completely “air gap” isolate every connection to the chip under test while power was off to be 100% sure that I was not leaking current into it anywhere.
I let that thing run for the rest of the day through thousands and thousand of test passes, but not once did the test circuit ever retain the data longer than 100ms without power – nothing like the 10+ minutes of persistence I was seeing before. I finally had to turn off the testing rig because the rapidly clicking and clacking relays were incompatible with sleep.
The next morning I got up and turned the test rig on again and immediately noticed that the delay between relay clicks was growing longer and longer – indicating successful passes. It quickly made it back up to 10 minutes of retention without a single lost byte. I let it run for a few hours more until the clicks started getting shorter indicating RAM errors. I had all the data from both runs logged, so now it was just a matter of figuring out what was different!
After a bit of number crunching it became clear that neither temp nor humidity were correlated at all with the data retention times. Not even a bit.
It took a good long hour before I finally figured out what was causing these spooky effects and now I can readily control the data retention time of my test circuit – without even touching it.
Can you figure out what mechanism was at work here?
Turns out that the circuit only/always worked in the morning. I was (un)luckily that I happened to do my first test in the morning or none of this would have ever happened. But how did the circuit know what time of day it was without any real-time clock access?
Thanks to the sun streaming through my window each morning! But how is this incredibly simple circuit light-aware without any sensors (or associated software) of any kind?
It is all thanks to the innocent looking indicator LED. When the sun hits it, it generates an extremely tiny current thanks to the photoelectric effect. But how is that powering the RAM when the LED is connected to an IO port pin?
AVR microcontrollers have clamping diodes on the input pins. My bet is that this tiny current is running through the high end diode into the internal Vcc bus on the chip and that is keeping the RAM alive. But could that tiny LED current really be enough to sustain the RAM indefinitely?
Apparently so. Keep in mind that this chip is spec’ed to use less than 0.15ua in power down mode. That is an vanishingly small amount of current. I actually backed uCurrent on KickStarter, so when it comes I’ll try to measure the current coming out of the LED and update this post with what I find.
In the meantime, I was able to easily test this theory using a flashlight. When the flashlight is shining onto the LED, the RAM persists infinitely. With the flashlight off and windows shades drawn, the RAM decays in less than 150ms.
Case closed!
