Capture Power Loss Data Using Adafruit FRAM Breakout Board

Posted 06 April 2018,

As an enhancement to Wall-E2, my wall-following robot I wanted a way to capture the run time at power-down so I could determine how long it has been since Wall-E2 last charged its battery, even through power cycles.

At first I tried to do this using the Arduino Mega 2560’s  onboard EEPROM, but this proved infeasible, as the time required to write to EEPROM exceeded the time available from the time power was removed to the time the Mega died.   I played around with extra capacitance on the power bus, but this still wasn’t enough to hold the power up long enough to write to EEPROM.   And, even if I finally succeeded, there was still the problem of EEPROM wear-out to deal with.

So, after some more research time with Google, I found this nice Adafruit FRAM breakout board, featuring the Fujitsu M85RC256V 32KB FRAM part

Adafruit provides a simple, but effective I2C interface library and an example sketch, and I was able to use these with a spare Arduino Uno board to verify that I could indeed write to and read from the FRAM.   However, what I really wanted to determine was whether or not the FRAM was fast enough to allow me to write data to it after power was removed from the Arduino but before the processor actually died.

I did some poking around in the Arduinio Uno schematic and determined there was a 47μF capacitor on the output of the +5V voltage regulator, and so I thought I might be able to trigger off power loss at the input to the regulator and accomplish the writes while the capacitor was still holding up the Arduino processor.   I put a 1/3:2/3 voltage divider on the +12V input line and used my trusty Tektronix 2236 scope to monitor it and the +5V regulated output.   With the scope I was able to see that the +5V output stayed up for about 5msec, and stayed above 4V for 8msec, as shown in the following scope photo.

Scope photo of Arduino Uno +5V regulated output, triggered by removal of +12V input power. Time scale 1msec/div.

The next step was to modify Adafruit’s FRAM read/write example program to implement a power-down interrupt routine to test my idea.   Here’s the code (the software is also available here)

The above code takes advantage of a modified version of Adafruit’s I2C FRAM library that facilitates writing and reading of arbitrary data types like int, long, float, etc.   The modifications were cribbed from  Nick Gammon’s wonderful ‘IC2_Anything’ library – thanks Nick!

Here’s the modified ‘Adafruit_FRAM_I2C.h’ file

With this test setup, I was able to repeatedly clear the FRAM memory and see the effect of pulling the power plug.   A typical result is shown below:

Program response when restarted with CLEAR_FRAM_PIN (pin 3) grounded

Program response after the power plug was pulled at about 8.9 sec after startup.

In the first figure above, the  CLEAR_FRAM_PIN (pin 3) was held LOW while the Arduino was restarted, resulting in zeroes being written to the first 100 FRAM locations.   In the second figure, the +12V power plug was pulled after about 9 seconds, then reconnected.   When the Arduino restarted, the power-down ISR had written program timer values from 8976 to 8990 into the first nine 4-byte segments.   This shows that the Arduino continued to operate for about 14msec after the power plug was removed.   This is very good news, as it implies that I should be able to write the current date/time value from a real-time clock (when I get it running, that is) into FRAM whenever there is a power interruption, allowing me to accurately track battery usage history.

The hardware used to perform these tests is shown in the following photos:

Experimental setup moved to new ASP solderless breadboard

Arduino Board Modification:

I ran into a problem when I started testing the power-down interrupt idea; I wanted to keep thE Arduino board connected to my PC via the USB cable, but if I did that, the Arduino would automatically switch over to USB power when I disconnected the +12V power cable. Fortunately, if you have a problem, it’s almost certain that someone else has had and solved the same problem.   In my case I found this post, that explained that T1, the automatic power crossover MOSFET switch had to be removed, as shown in the following photo.   This modification allows the USB cable to continue to supply USBVCC power to U3, the ATMEGA8U2-MU chip, which in turn allows the PC to recognize the Arduino for firmware uploads.

Loader Loading...
EAD Logo Taking too long?

Reload Reload document
| Open Open in new tab

Download

So, now that I have demonstrated the practicality of a power-down interrupt routine to capture time-of-shutdown information (at least on an Arduino Uno), the next step is to integrate this capability with the Adafruit RS3231 Precision RTC breakout board.   Stay tuned!

09 April Update:   Adafruit DS3231 RTC breakout board added:

As I mentioned in my ‘Time and Memory for Wall-E2‘ post, I planned to complement the FRAM capability with the addition of an RTC module so that I could record the time & date of any power interruptions.   As I mentioned in that post, I planned to use the Adafruit DS3231 Breakout Board for this purpose.   After receiving the module, I added it to the system by daisy-chaining the I2C SCL & SDA lines from the FRAM module, and modified the software to incorporate the RTC.   I changed the FRAM_ISR() function to acquire ‘Unixtime’ from the RTC (i.e. the number of seconds since 00:00:00 UTC on January 1, 1970) and write it to the FRAM.

I tested this by uploading this firmware to the Arduino Uno, and then pulling the power plug a few seconds after the program entered the main loop.   Here’s the printout from the run

Program run with Adafruit DS3231 RTC added. Note ‘unixtime’ printout at top, and first 5 FRAM locations at bottom

As can be seen from the above printout, the power-down ISR successfully recorded the current time (in ‘Unixtime’ format) into five successive FRAM memory locations before the Arduino died.   Note also that the recorded time was eleven seconds after the time shown at the top of the printout – about right, as the upper value is the time retrieved using the PC’s __DATE__ and ___TIME___ environment variables at the time the program was compiled and uploaded to the Arduino board.

Here are some photos of the new hardware setup:

Adafruit FRAM module on the left, DS3231 RTC module on the right

Frank

 

2 thoughts on “Capture Power Loss Data Using Adafruit FRAM Breakout Board

  1. Pingback: Another try at heading information for Wall-E2 - Paynter's Palace

  2. Pingback: Integrating Time, Memory, and Heading Capability - Paynter's Palace

Leave a Reply

Your email address will not be published. Required fields are marked *