Domino: Problems writing to SD card

Hello,

I’m having some problems writing data to an SD card. I used some of SD and realtime clock sample code from revision 1.06 of the Beginners Guide as the basis of a simple data logger to test a thermocouple circuit that I’ve been working on. The code is shown below:

using System;
using System.Threading;
using System.Text;
using System.IO;

using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using GHIElectronics.NETMF.IO;
using Microsoft.SPOT.Hardware;

using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Hardware;

namespace FEZ_Domino_Application1
{
    public class Program
    {
        public static void Main()
        {
            // Assume that the SD card is inserted and create a new storage device
            PersistentStorage sdPS = new PersistentStorage("SD");
            // Mount the file system
            sdPS.MountFileSystem();
            // Read the root directory from the card and get the file handle
            string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
            FileStream FileHandle = new FileStream(rootDirectory + "\\data.txt", FileMode.Append);
            byte[] data;
            // Set up an analog input channel
            AnalogIn thermocouple = new AnalogIn((AnalogIn.Pin)FEZ_Pin.AnalogIn.An5);
            // Set the scale so that the A-to-D reading will be in tenths of a degree
            thermocouple.SetLinearScale(-500, 500);
            int reading = 0;
            double tempC = 0.0D;
            double tempF = 0.0D;
            // Set the real time clock
            if (RealTimeClock.IsTimeValid == false)
            {
                Debug.Print("Setting real time clock ...");
                RealTimeClock.SetTime(new DateTime(2010, 12, 7, 12, 26, 30));
            } 
            Utility.SetLocalTime(RealTimeClock.GetTime());

            while (true)
            {
                // Read the thermocouple
                reading = thermocouple.Read();
                // Convert to a floating point value in degrees C
                tempC = ((double)reading) / 10.0D;
                // Calculate temperature in degrees F
                tempF = ((tempC / 100.0D) * 180.0D) + 32.0D;
                data = Encoding.UTF8.GetBytes(DateTime.Now.ToString() + " " + tempC.ToString("F1") + " C, " + tempF.ToString("F1") + " F\r\n");
                try
                {
                    FileHandle.Write(data, 0, data.Length);
                }
                catch { }
                FileHandle.Flush();
                Debug.Print(DateTime.Now.ToString() + " " + tempC.ToString("F1") + " C, " + tempF.ToString("F1") + " F");
                Thread.Sleep(1000);
            }
        }

    }
}

What is happening is that after running for a while (about 35 minutes at one sample every 5 seconds, about 5 minutes if I try to log a sample every second) the code croaks with the following exception …

12/07/2010 14:18:44 0.2 C, 32.4 F
#### Exception System.IO.IOException - CLR_E_FILE_IO (1) ####
#### Message:
#### Microsoft.SPOT.IO.NativeFileStream::Write [IP: 0000] ####
#### System.IO.FileStream::Write [IP: 002a] ####
#### FEZ_Domino_Application1.Program::Main [IP: 0116] ####
A first chance exception of type ‘System.IO.IOException’ occurred in Microsoft.SPOT.IO.dll
12/07/2010 14:18:46 0.0 C, 32.0 F

The date, time and temperature info is the output of my code … the thermocouple was in an ice/water bath.

Any help or pointers would be greatly appreciated.

Thanks,
Al

Just to be sure. You do have enough free space on the card, right?

Can try something a little simpler that you can generate in few seconds? If yes, it is easier for us to try here.
Try something like:

data = Encoding.GetBytes(“11/12/…”);
while(true)
{
file.Write(data);
file.Flush();
}
any problems?

Yes, it’s a 2 GB card and the only thing on it is the 72 KBs worth of data from the logger code.

Mike,

I’ll do that and get back to you in a little bit.

Mike,

I removed all of the code except the SD-related stuff -

using System;
using System.Threading;
using System.Text;
using System.IO;

using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using GHIElectronics.NETMF.IO;
using Microsoft.SPOT.Hardware;

using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Hardware;

namespace FEZ_Domino_Application1
{
    public class Program
    {
        public static void Main()
        {
            // Assume that the SD card is inserted and create a new storage device
            PersistentStorage sdPS = new PersistentStorage("SD");
            // Mount the file system
            sdPS.MountFileSystem();
            // Read the root directory from the card and get the file handle
            string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
            FileStream FileHandle = new FileStream(rootDirectory + "\\data.txt", FileMode.Append);
            byte[] data;
            while (true)
            {
                data = Encoding.UTF8.GetBytes("12/7/10 15:16:00 0.0 C, 32.0 F\r\n");
                try
                {
                    FileHandle.Write(data, 0, data.Length);
                }
                catch { }
                FileHandle.Flush();
                Debug.Print("OK");
                Thread.Sleep(1000);
            }
        }

    }

It runs for several minutes before producing the same sort of exception -

#### Exception System.IO.IOException - CLR_E_FILE_IO (1) ####
#### Message: 
#### Microsoft.SPOT.IO.NativeFileStream::Write [IP: 0000] ####
#### System.IO.FileStream::Write [IP: 002a] ####
#### FEZ_Domino_Application1.Program::Main [IP: 0039] ####

A first chance exception of type ‘System.IO.IOException’ occurred in Microsoft.SPOT.IO.dll

Since the SD file was opened in append mode, should it have been positioned to the end of file before starting to write to it?

It should do it automatically. But even if not it shouldn’t throw the exception after writing ~14K worth of data.

“Since the SD file was opened in append mode, should it have been positioned to the end of file before starting to write to it?”

I don’t think so. I wondered about that too, so I tested it. I started out with a blank card and ran the code for about about 30 seconds. It created the file and wrote a bunch of readings to it. I stopped the code and looked at the file on a PC, then I put the card back in the Domino and let write some more data to the file. Everything looked OK. The only time I have the problem is if I let the code run for more than a few minutes.

“It should do it automatically. But even if not it shouldn’t throw the exception after writing ~14K worth of data.”

Yes, I agree … It appears that the problem occurs after a fixed amount of data has been written to the file.

n3kfl:

I could run your program (the short one) fine! without changing anything!!

How do you format your microSD card??

Here is the result:

[quote]12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
12/7/10 15:16:00 0.0 C, 32.0 F
[/quote]

Before testing, please format your SD card on the PC.
Use FAT32 and some known number for allocation unit size (cluster size) not the default.
We will try to do the same test here.

Please tell me the allocation unit size and if you have the same problem.

Sam,

Did you run it for 5-10 minutes as he did?

Architect,
Yes, more than five minutes with no problems!

Mike,

I hadn’t reformatted the card … it’s new.

I reformatted it FAT32 using 4KB allocation units. The exception occurred after about 3 minutes when 257 lines of data had been written to the file.

I tried a few more allocation unit sizes. With 8K or 16K bytes, the exception occurred in about 6.5 minutes.

Have you tried different card?

“Have you tried different card?”

Not yet. I’ll pick up another one tomorrow and see if that solves the problem.

Are you sure you are not stopping your program unsafely? I mean you are in a while(true), if you remove the SD card while it is writing, then the next time you plug it in, you will have exceptions at some point because the file system is corrupted.
Format the SD card and run the program, do you have problems the very first time?

“Format the SD card and run the program, do you have problems the very first time?”

Mike,

Yes, the problem occurs the first time I use the card right after re-formatting it.

This morning I stopped and got a new 2 GB micro SD card. I switched brands and bought a PNY this time instead of SanDisk. It looks like that solved the problem … the code has been running for over 50 minutes without a problem. I’ll modify my code so that I can close the file properly before removing the card.

Thanks to everyone for all the help …

Al