Main Site Documentation

Writing .csv file to SD card


#1

Hello,
I have made a temperature logger with the aim of taking a reading every 20 seconds and adding this to a .csv file and storing it on the GHI SD Card module. I have written the code below, which when running records the temperatures as planned and displays the numbers on the output screen, but only produces a .csv file with the heading and one piece of data, rather than the heading and many lines of data I am after. I believe the issue has something to do with unmount the SD card / the flush() and close() functions but cannot find a solution! any help much appreciated

namespace sdcardtexttemplog
{
    public partial class Program
    {
        private GT.Timer _getReading = new GT.Timer(20000);
        private double _t1;
        int pictureIndex = 1;
        Stream stream;
        TextWriter writer;
        GT.StorageDevice storage;
        GT.Timer timer;
        void TheLoop()
        {
            while (true)
            {
                Thread.Sleep(10);
            }
        }
        void ProgramStarted()
        {
            Debug.Print("The Eagle Has Landed");
            sdCard.MountSDCard();
            System.Threading.Thread.Sleep(500);

            if (sdCard.IsCardMounted)
            {
                storage = sdCard.GetStorageDevice();
                display_T35.SimpleGraphics.Clear();
                display_T35.SimpleGraphics.DisplayText("SD CARD SUCCESSFULLY MOUNTED",
                Resources.GetFont(Resources.FontResources.small), GT.Color.Red, 10, 50);
            }
            else
            {
                Debug.Print("SD CARD NOT MOUNTED PROPER");
            }
            if (sdCard.IsCardMounted && storage != null)
            {
                stream = storage.Open("data_" + ".csv", FileMode.Create, FileAccess.Write);
                writer = new StreamWriter(stream);
                writer.WriteLine("Temp");

                temperatureHumidity.MeasurementComplete += new GT.Modules.Seeed.TemperatureHumidity.MeasurementCompleteEventHandler(temperatureHumidity_MeasurementComplete);
                temperatureHumidity.StartContinuousMeasurements();
                _getReading.Tick += new GT.Timer.TickEventHandler(_getReading_Tick);
                _getReading.Start();
            }
            else
            {
                temperatureHumidity.MeasurementComplete += new GT.Modules.Seeed.TemperatureHumidity.MeasurementCompleteEventHandler(temperatureHumidity_MeasurementComplete);
                temperatureHumidity.StartContinuousMeasurements();
                _getReading.Tick += new GT.Timer.TickEventHandler(_getReading_Tick);
                _getReading.Start();
                            }
        }
        void temperatureHumidity_MeasurementComplete(GT.Modules.Seeed.TemperatureHumidity sender, double temperature, double relativeHumidity)
        {
            _t1 = temperature;
        }
                void _getReading_Tick(GT.Timer timer)
        {
            display_T35.SimpleGraphics.Clear();
            Debug.Print("Temperature : " + _t1 + " degrees ");
            writer.WriteLine(_t1 + "," + pictureIndex);
            pictureIndex++;
        }
        }
        }

#2

you’re right, you need to flush your file to make sure all data gets written before you remove the SD card, and you also need to close the file handle too. If you don’t do that, the file system will have cached your data and the file will look incomplete.

Here’s a pattern that works reasonably well. Use of the USING means if there’s a file IO error the stream will always get closed correctly.

                    using (FileStream myFile = File.Open(SDCard.RootDirectory + Filename_times, FileMode.Append))
                    {
                        byte[] logMsg = UTF8Encoding.UTF8.GetBytes("temperature: " + _t1 + " degrees\r\n");
                        myFile.Write(logMsg, 0, logMsg.Length);
                        myFile.Flush();
                    }

Hope that helps


#3

Thanks very much that works perfectly