I have had some problems with either files being corrupted or even the complete SD card if power is lost during file IO.
So I needed some way to shut down the system gracefully and this is what I came up with and it seems to work pretty well.
My system is running from a 12V battery and only have an on/off switch. So I added a voltage regulator as the power sensor and a rather large capacitor to hold power long enough to flush data to the SD card and close the file.
This is my test code
using System;
using System.Threading;
using System.Text;
using System.IO;
using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.FEZ;
namespace MFConsoleApplication1
{
public class Program
{
static PersistentStorage sdPS;
static FileStream FileHandle;
static void Main()
{
InterruptPort Power = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.Di5, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeLow);
Power.OnInterrupt += new NativeEventHandler(Power_OnInterrupt);
sdPS = new PersistentStorage("SD");
sdPS.MountFileSystem();
string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
FileHandle = new FileStream(rootDirectory + @ "\Testfile.txt", FileMode.Create, FileAccess.Write);
byte[] data = Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\r\n");
while (true)
{
FileHandle.Write(data, 0, data.Length);
}
}
static void Power_OnInterrupt(uint data1, uint data2, DateTime time)
{
byte[] data = Encoding.UTF8.GetBytes("Lost power\r\n");
FileHandle.Write(data, 0, data.Length);
FileHandle.Flush();
FileHandle.Close();
sdPS.UnmountFileSystem();
}
}
}
And it works as you can see from the last line in the file.
ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
Lost power
You could probably use lots of different things to trigger the pin like;
[ulist]
Voltage regulator
Voltage divider
1381 voltage trigger
Zener diode
Or even a relay
[/ulist]
The reason I used a voltage regulator is that I have lots of them (eBay) and a voltage divider would also change as the battery get depleted.
great idea - love it. VREG drops to 0 as battery goes flat/disconnects, triggers an interrupt, and gracefully closes the file.
I’ve been thinking about this challenge since you posted this. There’s a couple of questions I would like to ask if I may.
Do you have any idea how long the cap will keep the system operational for, at that size? Is there an easy(ish) way to calculate runtime vs capacitor capacity? And do you have suggested sources for supercaps that aren’t going to break the bank?
My specific target here is to handle power outages; my Fez will be running on mains powered DC plugpack power, but I want it to handle power disconnects gracefully.
How are you handling the fact that now some of your main function will no longer work - the file handle is closed, writes will fail. Are you doing something like the approach I was thinking about: set a global flag appropriately in the interrupt and don’t try to do certain actions when off power? For me I have three main issues, serial I/O, network I/O, and SD card; I don’t want any of those to be attempted in the power-loss scenario, but I also want those to fire back up again should the power be reinstated without a full loss of power - that means another interrupt on the rising edge, and enabling those functions again. Have you included anything like that in your implementation?
Again, very cool concept and great use of what you have to hand
Thank you for your comment Brett.
When it comes to calculate the runtime from the capacitors it can probably be done by someone that knows electronics. I’m at a level that I can barely understand ohms law I’m more of a cut and try type of guy.
When I made my tests I had the Panda connected to a Micro SD Card Expansion shield and nothing else drawing power. When I moved it over to my Panda Tinkerer kit with a normal size SD card and a GPS hooked up I could not get it to work with the capacitor I had. I could probably get it working with a bigger cap or more of them in parallel. One idea would probably be to power all peripheral devices from something else than the FEZ itself. My other problem is that my capacitor is on the input side of the voltage regulator on the FEZ and I probably lose power there as well.
I think I will have to use something else than big ass capacitors and rater build something around a small mounted battery. The optimal solution would be to have a battery that got charged when we have power and used to gracefully take down the system on a power failure. This way one could probably operate the system for several minutes before finally taking it down if the power don’t comes back on.
Yes there’s probably more “science” behind this than I know how to do I was really hoping that you’d only done something like test how many millisecs it stayed up or something - but all of those require a log, which might require the SD card to be active which is a bit of a circular argument
I have an old Sprague 50,000uF 15v cap I found in some old stuff I was cleaning up from my dad’s workshop after he passed away, so I might see how that goes Mind you it’s 52mm dia by 108mm high, so it dwarfs the rest of my board.
I think ultimately powering the SD card from a different source might be problematic; only because that’s the main peripheral you need to keep power to to hold the file system intact. In your case I can imagine powering the GPS directly from the input source rather than the cap, and for me the Ethernet and maybe MAX232 (RS232 serial) chip; but still, having split supply is still a drama :o
We’ll see how, if at all, I progress once I get some more components in my hand…
A small UPS could also do the job very well, most of them have a serial port or usb port that notifies your system on power failures. No need to build the charging, batterycheck circuit yourself. Just write a driver for the UPS.
The reason that I tried to make this is that this device will go onboard a small boat and logging water depths on its way. It is constantly logging data so when I power the system down I might end up with a corrupt SD card after hours of logging. On my Arduino version I had a separate switch to start the logging but it was crucial to turn that switch of before cutting the power. This is an attempt to eliminate that problem and sense when the power is removed, either from turning it off or that the batteries runs out.
We also experienced the same problem of sd coruption when power off. We’re actually investigating a solution with a 150mAh NiMH battery. An IO of the EMX connected to a N-MOSFET allows to switch off the board (by cutting the GND connection) after detection of power loss. For now it works on table but I did not choose to use a dedicated charging chip to charge the battery (such as a max 712 ) and therefore charging efficiency is not so good. (The 4.8V battery is charged with constant voltage at 5.7V whereas it would be better to charge it a 6V at the beginning and then use trickle charge). Anyway, it allows to self powered the board during 2-3 mins. More than what we need… However the board comsumption is about 130-140mA and I would expect about an hour of self powering…
If my memory serves me correctly, this simply is a capacitor connected to the power input of the device and a digital IO pin connected to the power input line, so that when the power drops, the IO pin sees a transition to LOW and triggers an interrupt, at which point you stop writes and flush the SD, while the cap allows the device to continue processing for that time