SD card logging

My code.
Thanks

namespace FEZ_Domino_SD_test_godFather89_
{
    public class Program
    {
        static Thread thread;
        static bool running;
        static string url = "http://api.thingspeak.com/update";
        static string key = "<YourThingSpeakChannelKey>";
        static AnalogIn thermometer;
        static AnalogIn lightSensor;
        static int temp;
        static int light;
       
        bool cardLoaded = true;
        static int idx;

        private static string path;
        bool FileOpen = false;

        public bool DebugMirror = true;
        private static PersistentStorage pStore;
        private static VolumeInfo pStoreI;
        
        public static void Main()
        {
            bool ledState = false;

            OutputPort led = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, ledState);
            pStore = new PersistentStorage("SD");
            pStore.MountFileSystem();
            pStoreI = VolumeInfo.GetVolumes()[0];
            string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
            //path = rootDirectory + @ "\log " + ".csv";
            path = rootDirectory + @ "\log" + ".txt";
            // Initialize the eblocks
            thermometer = new AnalogIn((AnalogIn.Pin)FEZ_Pin.AnalogIn.An2);
            thermometer.SetLinearScale(-22, 56);
            lightSensor = new AnalogIn((AnalogIn.Pin)FEZ_Pin.AnalogIn.An3);
            lightSensor.SetLinearScale(0, 100);

            FileStream fHandle = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
            int offset = 0;
            const int size = 4096; //4KB buffer
            byte[] buffer = new byte[size];

            Timer t = new Timer((o) =>
            {
                int v1 = 10;
                int v2 = 20;

                buffer[offset++] = (byte)((v1 >> (0 * 8)) & 0xFF);
                buffer[offset++] = (byte)((v1 >> (1 * 8)) & 0xFF);
                buffer[offset++] = (byte)((v1 >> (2 * 8)) & 0xFF);
                buffer[offset++] = (byte)((v1 >> (3 * 8)) & 0xFF);

                buffer[offset++] = (byte)((v2 >> (0 * 8)) & 0xFF);
                buffer[offset++] = (byte)((v2 >> (1 * 8)) & 0xFF);
                buffer[offset++] = (byte)((v2 >> (2 * 8)) & 0xFF);
                buffer[offset++] = (byte)((v2 >> (3 * 8)) & 0xFF);

                if (offset == size)
                {
                    fHandle.Write(buffer, 0, size);
                    offset = 0;
                }
            }, null, 0, 10);
            Thread.Sleep(Timeout.Infinite);
        }

    }
}

Try something like this:


Timer t = new Timer((o) =>
            {
                int v1 = 10;
                int v2 = 20;
 
                buffer[offset++] = (byte)((v1 >> (0 * 8)) & 0xFF);
                buffer[offset++] = (byte)((v1 >> (1 * 8)) & 0xFF);
                buffer[offset++] = (byte)((v1 >> (2 * 8)) & 0xFF);
                buffer[offset++] = (byte)((v1 >> (3 * 8)) & 0xFF);
 
                buffer[offset++] = (byte)((v2 >> (0 * 8)) & 0xFF);
                buffer[offset++] = (byte)((v2 >> (1 * 8)) & 0xFF);
                buffer[offset++] = (byte)((v2 >> (2 * 8)) & 0xFF);
                buffer[offset++] = (byte)((v2 >> (3 * 8)) & 0xFF);
 
                if (offset == size)
                {
                    fHandle.Write(buffer, 0, size);
                    offset = 0;
                }
            }, null, 0, 10);
            Thread.Sleep(Timeout.Infinite);
            t.Dispose();

I think that the Timer gets collected by GC because the reference it’s not used anymore in the rest of the program. By putting t.Dispose (even if it’s never called), I inform it that the object is still used and can not be collected.

use

t.Dispose(); 

the same
but when I modify code to below, it work.
Why? What is the difference?

  if (offset == size)
                {
                     FileStream fHandle = new FileStream(path, FileMode.Append, FileAccess.Write);
                    fHandle.Write(buffer, 0, size);
                    offset = 0;
                    fHandle.Close();
                }

Maybe the GC collects the object referenced by fHandle. Try to put fHandle.Close() after Thread.Sleep(…).

The same.

I have no idea. It would be useful to have a debug interface to send some debug data while running in Release.

I had a similar problem and I solved it by creating a jagged array and filling it with lots of data and then writing the arrays to the sd card.

I did this from a suggestion of someone on this board and it worked great. I could sample at 2 kHz and around 300 lines of data as follows (arbitrary example):

11/2/2011 354 354 444 .093498989

@ godFather89

How can I set the timer sampling for maybe 3 minute then leave the timer?

@ rgm Could you please post your code?

Thanks.

Something like this:


Thread.Sleep(3 * 60 * 1000); //3 min sleep
t.Change(Timeout.Infinite, Timeout.Infinite); //stop the timer
if (offset != 0) //write any remaining data to the file
    fHandle.Write(buffer, 0, offset);
t.Dispose();
fHandle.Close();