Main Site Documentation

Debug or SD card issue?


#1

I hate to keep asking for everyone’s help because I know that you guys have more important things to do but I am once again stuck. I am trying to write a logfile to the sd card logging the events of a time update and cannot seem to get more than 2-3 writes to a file named ‘log.txt’. I not only do I not get writes to the sd card but I also don’t get any debug messages past the initial GC messages.

If someone has time please look at my code and point out the mistakes that I have made.

Thanks,

Kevin


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

using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Net;
using Microsoft.SPOT.Hardware;

using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Net;
using GHIElectronics.NETMF.System;
using GHIElectronics.NETMF.USBHost;
using GHIElectronics.NETMF.Hardware;
using GHIElectronics.NETMF.Net.Sockets;
using GHIElectronics.NETMF.Net.NetworkInformation;
using Socket = GHIElectronics.NETMF.Net.Sockets.Socket;



public class Hydro
{
    static PersistentStorage SDCard ;
    
    static bool timeFlag = false;   // Is set to true when time is successfully update from the internet
    static DateTime UpdateRTCEvery6Hours = DateTime.Now;  //Sets the starting point for the RTC update clock


    public static void Main()
    {        
        try
        {
            byte[] mac = { 0x00, 0x9A, 0xD2, 0xC2, 0xD9, 0x2A }; // Randomly generated MAC from http://www.macvendorlookup.com
            WIZnet_W5100.Enable(SPI.SPI_module.SPI1, (Cpu.Pin)FEZ_Pin.Digital.Di10, (Cpu.Pin)FEZ_Pin.Digital.Di9, true); // WIZnet interface with FEZ Connect
            Dhcp.EnableDhcp(mac, "HydroController"); //Used to check if there were any problems with the network settings (And at work)  //
            string DNSInfo = NetworkInterface.DnsServer[0].ToString() + "." +                                         //
                                NetworkInterface.DnsServer[1].ToString() + "." +                                      //
                                NetworkInterface.DnsServer[2].ToString() + "." +                                      //
                                NetworkInterface.DnsServer[3].ToString();                                             //
            string IpInfo = NetworkInterface.IPAddress[0].ToString() + "." +                                          //
                                NetworkInterface.IPAddress[1].ToString() + "." +                                      //
                                NetworkInterface.IPAddress[2].ToString() + "." +                                      //
                                NetworkInterface.IPAddress[3].ToString();                                             //
            string SubnetInfo = NetworkInterface.SubnetMask[0].ToString() + "." +                                     //
                                NetworkInterface.SubnetMask[1].ToString() + "." +                                     //
                                NetworkInterface.SubnetMask[2].ToString() + "." +                                     //
                                NetworkInterface.SubnetMask[3].ToString();                                            //
            string MacInfo = NetworkInterface.PhysicalAddress[0].ToString() + "." +                                   //
                                NetworkInterface.PhysicalAddress[1].ToString() + "." +                                //
                                NetworkInterface.PhysicalAddress[2].ToString() + "." +                                //
                                NetworkInterface.PhysicalAddress[3].ToString();                                       //
            string GatewayInfo = NetworkInterface.GatewayAddress[0].ToString() + "." +                                //
                                NetworkInterface.GatewayAddress[1].ToString() + "." +                                 //
                                NetworkInterface.GatewayAddress[2].ToString() + "." +                                 //
                                NetworkInterface.GatewayAddress[3].ToString();                                        //
            Debug.Print("IP: " + IpInfo.ToString());                                                                  //
            Debug.Print("Subnet: " + SubnetInfo.ToString());                                                          //
            Debug.Print("Gateway: " + GatewayInfo.ToString());                                                        //
            Controls SDWriteTest = new Controls();
            SDWriteTest.UpdateSD("log.txt", IpInfo + "\r\n" + SubnetInfo);
            Thread.Sleep(100);
        }                                                                                                             //
        catch                                                                                                         //
        {                                                                                                             //
            Debug.Print("Connection failed. Verify cable is connected and network is operational.");                  //
        }

        UpdateRTCEvery6Hours = DateTime.Now;

        while (true)
        {            
            if (!timeFlag)
            {
                Controls getTime = new Controls();

                try
                {
                    timeFlag = getTime.NTPTime("time-a.nist.gov", -300);
                    Controls sd1 = new Controls();
                    sd1.UpdateSD("log.txt", "Time set via \"time-a.nist.gov\". New time is: " + DateTime.Now + @ "\r\n" + "timeFlag set to True");                    
                }
                catch
                {
                    timeFlag = getTime.NTPTime("time-b.nist.gov", -300);
                    Controls sd2 = new Controls();
                    sd2.UpdateSD("log.txt", "Time set via \"time-b.nist.gov\". New time is: " + DateTime.Now.ToString());
                }
            }
                        
                if (UpdateRTCEvery6Hours > UpdateRTCEvery6Hours.AddSeconds(10))    // Changed to seconds for testing
                {
                    Controls reOccurring = new Controls();
                    Controls sd = new Controls();
                    reOccurring.NTPTime("time-b.nist.gov", -300);
                    UpdateRTCEvery6Hours = DateTime.Now;
                    sd.UpdateSD("log.txt", "Six hour update complete. New time is: " + DateTime.Now.ToString());
                    Debug.Print("Re-occurring update complete. Time is " + DateTime.Now.ToString());
                }
            Debug.GC(true);
            Debug.EnableGCMessages(true);
            Thread.Sleep(Timeout.Infinite);
        }
    }

    public class Controls
    {        
        public bool NTPTime(string TimeServer, int GmtOffset = 0)
        {
            Socket s = null;
            try
            {
                EndPoint rep = new IPEndPoint(Dns.GetHostEntry(TimeServer).AddressList[0], 123);
                s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                byte[] ntpData = new byte[48];
                Array.Clear(ntpData, 0, 48);
                ntpData[0] = 0x1B; // Set protocol version
                s.SendTo(ntpData, rep); // Send Request   
                if (s.Poll(30 * 1000 * 1000, SelectMode.SelectRead)) // Waiting an answer for 30s, if nothing: timeout
                {
                    s.ReceiveFrom(ntpData, ref rep); // Receive Time
                    byte offsetTransmitTime = 40;
                    ulong intpart = 0;
                    ulong fractpart = 0;
                    for (int i = 0; i <= 3; i++) intpart = (intpart << 8) | ntpData[offsetTransmitTime + i];
                    for (int i = 4; i <= 7; i++) fractpart = (fractpart << 8) | ntpData[offsetTransmitTime + i];
                    ulong milliseconds = (intpart * 1000 + (fractpart * 1000) / 0x100000000L);
                    s.Close();
                    TimeSpan timeSpan = TimeSpan.FromTicks((long)milliseconds * TimeSpan.TicksPerMillisecond);
                    DateTime dateTime = new DateTime(1900, 1, 1);
                    dateTime += timeSpan;
                    Utility.SetLocalTime(dateTime.AddMinutes(GmtOffset));
                    RealTimeClock.SetTime(DateTime.Now);
                    return true;
                }
                s.Close();
            }
            catch
            {
                try { s.Close(); }
                catch { }
            }
            return false;
        }
        public bool UpdateSD(string fileName, string dataToFile)
        {
            SDCard = new PersistentStorage("SD");
            SDCard.MountFileSystem();

            if (VolumeInfo.GetVolumes()[0].IsFormatted)
                try
                {                    
                    string root = VolumeInfo.GetVolumes()[0].RootDirectory;
                    string fileToWrite = root + @ "\" + fileName;
                    FileStream dataWriter = new FileStream(fileToWrite, FileMode.OpenOrCreate, FileAccess.Write);
                    dataWriter.Seek(0, SeekOrigin.End);
                    byte[] data = Encoding.UTF8.GetBytes(DateTime.Now.ToString() + ":     "  + dataToFile);
                    dataWriter.Write(data, 0, data.Length);
                    dataWriter.Close();
                    Debug.Print("Write to SD complete");
                }
                catch
                {
                    Debug.Print("Write to SD failed");
                    return false;
                }
            Thread.Sleep(10);
            SDCard.UnmountFileSystem();
            SDCard.Dispose();
                                   
            return true;
        }        
    }
}


#2

You shouldn’t mount the FS everytime your are writting a line to the file.
Try to mount it once at the beginning of your code ;
Then use your UpdateSD() only to open file and write into it.

Also here is some good code for detecting SD cards and auto mounting it: http://wiki.tinyclr.com/index.php?title=SD_Cards (see “Auto-Mounting SD Cards”)

Good luck :wink: !


#3

We have a functioning sd logger in the code section. Why reinvent the wheel, just adopt it for your needs:

http://code.tinyclr.com/project/169/sd-card-program-logging/