Main Site Documentation

Writing to multiple files on SD card (Solved!)


#1

I can’t seem to write to more than on file on the SD card. Is that a limitation of netMF or am I missing something. I have tried disposing the FileStream, having separate methods, separate instances and nothing works. I have tried to research the issue, but I can only find examples of writing to one file. I am using a Hydra on 4.2. any suggestions? Can I generate a software reset of the program and write one file the reset and write another file if the first file exists?


#2

I am not an experienced C# programmer, actually an accountant, so I am probably doing something wrong. Here is the output error message:

The thread ‘’ (0x2) has exited with code 0 (0x0).
Using mainboard GHI Electronics FEZHydra version 1.2
Program Started
Start
The thread ‘’ (0x3) has exited with code 0 (0x0).
#### Exception System.ArgumentException - 0x00000000 (1) ####
#### Message:
#### System.IO.FileStream::.ctor [IP: 013f] ####
#### System.IO.FileStream::.ctor [IP: 0009] ####
#### TestFileStream.Program::TextWriter1 [IP: 0019] ####
#### TestFileStream.Program::timer_Tick [IP: 000a] ####
#### Microsoft.SPOT.DispatcherTimer::FireTick [IP: 0010] ####
#### Microsoft.SPOT.Dispatcher::PushFrameImpl [IP: 0054] ####
#### Microsoft.SPOT.Dispatcher::PushFrame [IP: 001a] ####
#### Microsoft.SPOT.Dispatcher::Run [IP: 0006] ####
#### Gadgeteer.Program::Run [IP: 0020] ####
A first chance exception of type ‘System.ArgumentException’ occurred in System.IO.dll
A first chance exception of type ‘System.ArgumentException’ occurred in System.IO.dll
Exception performing Timer operation

and the sample code that I tried

:

using System;
using System.Text;
using System.ComponentModel;
using System.IO;
using System.IO.Ports;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Input;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Microsoft.SPOT.Hardware;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace TestFileStream
{
    public partial class Program
    {

        string Log1FilePath = @ "SD\" + "LogFile1.txt";
        string Log2FilePath = @ "SD\" + "LogFile2.txt";
        string ResultsFilePath = @ "SD\" + "ResultsFile.txt";

        // This method is run when the mainboard is powered up or reset.  
        void ProgramStarted()
        {

            /*******************************************************************************************
            Modules added in the Program.gadgeteer designer view are used by typing
            their name followed by a period, e.g.  button.  or  camera.
           
            Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
                button.ButtonPressed +=<tab><tab>
           
            If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick +=<tab><tab>
                timer.Start();
            *******************************************************************************************/


            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");


            GT.Timer timer = new GT.Timer(4000);
            timer.Tick += new GT.Timer.TickEventHandler(timer_Tick);
            timer.Start();

        }

        void timer_Tick(GT.Timer timer)
        {

            timer.Stop();
            TextWriter1();
            TextWriter2();
            TextWriter3();

        }

        private void TextWriter1()
        {
            Debug.Print("Start");
 
            sdCard.MountSDCard();
            FileStream sdlog1stream = new FileStream(Log1FilePath, FileMode.Append, FileAccess.ReadWrite);
            StreamWriter log1writer = new StreamWriter(sdlog1stream);
            string LogData1 = "Test Log1";
            char[] buffer1 = LogData1.ToCharArray();
            log1writer.Write(buffer1, 0, buffer1.Length);
            sdlog1stream.Flush();
            sdlog1stream.Dispose();
            log1writer.Dispose();
            if (sdCard.IsCardMounted == true) { sdCard.UnmountSDCard(); }
        }

        private void TextWriter2()
        {
            sdCard.MountSDCard();
            FileStream sdlog2stream = new FileStream(Log2FilePath, FileMode.Append, FileAccess.ReadWrite);
            StreamWriter log2writer = new StreamWriter(sdlog2stream);
            string LogData2 = "Test Log2";
            char[] buffer2 = LogData2.ToCharArray();
            log2writer.Write(buffer2, 0, buffer2.Length);
            sdlog2stream.Flush();
            sdlog2stream.Dispose();
            log2writer.Dispose();
            if (sdCard.IsCardMounted == true) { sdCard.UnmountSDCard(); }
        }

        private void TextWriter3()
        {
            sdCard.MountSDCard();
            FileStream sdresultstream = new FileStream(ResultsFilePath, FileMode.Append, FileAccess.ReadWrite);
            StreamWriter resultswriter = new StreamWriter(sdresultstream);
            string ResultsData = "Test Results";
            char[] buffer3 = ResultsData.ToCharArray();
            resultswriter.Write(buffer3, 0, buffer3.Length);
            sdresultstream.Flush();
            sdresultstream.Dispose();
            resultswriter.Dispose();
            if (sdCard.IsCardMounted == true) { sdCard.UnmountSDCard(); }

            Debug.Print("End");
        }


    }
}

#3

The link
https://www.ghielectronics.com/docs/51/accessing-folders-and-files

does not work as listed for the Hydra (open source doesn’t have some of the commands). However using it as the basis for the second time, paying close attention to the line sequence, I now have it working.

Thank you.

The revised working code is as follows:


using System;
using System.Text;
using System.ComponentModel;
using System.IO;
using System.IO.Ports;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Input;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Microsoft.SPOT.Hardware;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace TestFileStream
{
    public partial class Program
    {

        string Log1FilePath = @ "SD\" + "LogFile1.txt";
        string Log2FilePath = @ "SD\" + "LogFile2.txt";
        string ResultsFilePath = @ "SD\" + "ResultsFile.txt";

        // This method is run when the mainboard is powered up or reset.  
        void ProgramStarted()
        {

            /*******************************************************************************************
            Modules added in the Program.gadgeteer designer view are used by typing
            their name followed by a period, e.g.  button.  or  camera.
           
            Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
                button.ButtonPressed +=<tab><tab>
           
            If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick +=<tab><tab>
                timer.Start();
            *******************************************************************************************/


            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");


            GT.Timer timer = new GT.Timer(4000);
            timer.Tick += new GT.Timer.TickEventHandler(timer_Tick);
            timer.Start();

        }

        void timer_Tick(GT.Timer timer)
        {

            timer.Stop();
            TextWriter1();
            TextWriter2();
            TextWriter3();

        }

        private void TextWriter1()
        {
            Debug.Print("Start");

            if (sdCard.IsCardMounted == false) { sdCard.MountSDCard(); }
            FileStream sdcardstream = new FileStream(@ "SD\" + "LogFile1.txt", FileMode.Append);
            byte[] buffer = Encoding.UTF8.GetBytes("1,2,1,1,4,1,1" + "\r\n");
            sdcardstream.Write(buffer, 0, buffer.Length);
            sdcardstream.Close();
            if (sdCard.IsCardMounted == true) { sdCard.UnmountSDCard(); }
        }

        private void TextWriter2()
        {
            if (sdCard.IsCardMounted == false) { sdCard.MountSDCard(); }
            FileStream sdcardstream = new FileStream(@ "SD\" + "LogFile2.txt", FileMode.Append);
            byte[] buffer = Encoding.UTF8.GetBytes("Test Log2" + "\r\n");
            sdcardstream.Write(buffer, 0, buffer.Length);
            sdcardstream.Close();
            if (sdCard.IsCardMounted == true) { sdCard.UnmountSDCard(); }
        }

        private void TextWriter3()
        {
            if (sdCard.IsCardMounted == false) { sdCard.MountSDCard(); }
            FileStream sdcardstream = new FileStream(@ "SD\" + "ResultsFile.txt", FileMode.Append);
            byte[] buffer = Encoding.UTF8.GetBytes("Test Results" + "\r\n");
            sdcardstream.Write(buffer, 0, buffer.Length);
            sdcardstream.Close();
            if (sdCard.IsCardMounted == true) { sdCard.UnmountSDCard(); }

            Debug.Print("End");
        }
    }
}