Netduino home hardware projects downloads community

Jump to content

The Netduino forums have been replaced by new forums at This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.

Why does my code crash after 14 hours, 8 minutes, and 47.37 seconds?

datalogging timing code crash

  • Please log in to reply
4 replies to this topic

#1 Verdris


    Advanced Member

  • Members
  • PipPipPip
  • 128 posts
  • LocationReno, NV

Posted 12 March 2013 - 08:15 PM

The first time this happened I thought it was a fluke, so I set my project to logging again. When I recovered the datafile, once again logging stopped in the same timespan (I've left the project to sit for 24+ hours in both cases). I'm going to try it again tonight just to see what happens, but I'd appreciate some insight.


Am I running out of memory? The first time I ran the project I had a lot of variable creation inside the while(true) loop portion of the code. My first instinct was that somehow the garbage collector wasn't doing its thing and so memory from a previous loop wasn't being released, or something. I'm not sure how TinyCLR does garbage collection. So, I moved a lot of variable creation to before the while(true) loop, but the same error repeated itself.


Here's the code as of right now:


    public class Program    {        public static SerialPort talkback = new SerialPort("COM2", 14400, Parity.None, 8, StopBits.One);        public static void Main()        {            RemovableMedia.Insert += new InsertEventHandler(SD_Insert);            RemovableMedia.Eject += new EjectEventHandler(SD_Eject);            int rejected = 0;            int FilterNotch = 60;            bool writeSuccessful = false;            bool d1 = false;            bool d2 = false;            bool d3 = false;            bool d4 = false;            bool d5 = false;            AD7714.Reset();            AD7714.ChannelSetup(1, d1, false, 24, false, true, FilterNotch);            AD7714.ChannelSetup(2, d2, false, 24, false, true, FilterNotch);            AD7714.ChannelSetup(3, d3, false, 24, false, true, FilterNotch);            AD7714.ChannelSetup(4, d4, false, 24, false, true, FilterNotch);            AD7714.ChannelSetup(5, d5, false, 24, false, true, FilterNotch);            int backupCounts = 0;            int backupFileCount = 0;            if (Directory.Exists(@"SD"))            {                try                {                    using (var filestream = new FileStream(@"SDdata.txt", FileMode.Append, FileAccess.Write))                    {                        StreamWriter writer = new StreamWriter(filestream);                        writer.WriteLine("Machine_Time,Duration,Ch1_Counts,Ch1_Volts,Ch2_Counts,Ch2_Volts,Ch3_Counts,Ch3_Volts,Ch4_Counts,Ch4_Volts,Ch5_Counts,Ch5_Volts,Errors");                        writer.Close();                    }                    if (File.Exists(@"SDdata.txt"))                    {                        RGB.Blue();                        LCD.Open();                        LCD.Clear();                        LCD.Print("Files Created.");                        LCD.Close();                        Thread.Sleep(500);                        RGB.Off();                    }                    else                    {                        RGB.Red();                        LCD.Open();                        LCD.Clear();                        LCD.Print("Couldn't create!");                        LCD.Close();                        Thread.Sleep(Timeout.Infinite);                    }                }                catch (Exception ex)                {                    Debug.Print("You dun goofed: " + ex.Message);                }            }            long start = 0;            long end = 0;            long duration;            int[] Channel = new int[5];            while (true)            {                start = Utility.GetMachineTime().Ticks;                for (int i = 0; i < 5; i++)                {                    Channel[i] = AD7714.ReadChannel(i, 1, false, 40);                    if (Channel[i] == 8388608)                    {                        rejected++;                    }                }                end = Utility.GetMachineTime().Ticks;                duration = (end - start) / 10000;                if (duration < 800)                {                    string timeData = Utility.GetMachineTime().ToString() + "," + duration.ToString() + " ";                    string countsData = string.Empty;                    for (int i = 0; i < 5; i++)                    {                        countsData += Channel[i].ToString() + ",";                    }                    countsData.TrimEnd(countsData[countsData.Length - 1]);                    countsData += " ";                    double[] volts = new double[5];                    string voltsData = String.Empty;                    for (int i = 0; i < 5; i++)                    {                        volts[i] = (double)Channel[i] * 3.0 / 16777215.0;                        voltsData += volts[i] + ",";                    }                    voltsData.TrimEnd(voltsData[voltsData.Length - 1]);                    voltsData += " ";                    string errorsData = rejected.ToString() + "END";                    string xmitData = timeData + countsData + voltsData + errorsData;                    string fileData = timeData.Trim() + ",";                    for (int i = 0; i < 5; i++)                    {                        fileData += Channel[i].ToString() + "," + volts[i] + ",";                    }                    fileData += rejected.ToString();                    if (File.Exists(@"SDdata.txt"))                    {                        try                        {                            using (var filestream = new FileStream(@"SDdata.txt", FileMode.Append, FileAccess.Write))                            {                                StreamWriter writer = new StreamWriter(filestream);                                writer.WriteLine(fileData);                                writer.Close();                                writeSuccessful = true;                            }                        }                        catch (Exception ex)                        {                            Debug.Print("I found an " + ex.Message);                        }                    }                    else                    {                        writeSuccessful = false;                    }                    if (writeSuccessful)                    {                        RGB.Yellow();                        Thread.Sleep(500);                        RGB.Green();                        Thread.Sleep(500);                        RGB.Off();                    }                    #region Serial Communications                    byte[] xmit = Encoding.UTF8.GetBytes(xmitData);                    talkback.Open();                    talkback.Write(xmit, 0, xmit.Length);                    talkback.Close();                    #endregion                }                else                {                    rejected++;                    AD7714.Reset();                    Thread.Sleep(1000);                }                                backupCounts++;                if (backupCounts == 14400) // 4-hour backups                {                    if (File.Exists(@"SDdata.txt"))                    {                        File.Copy(@"SDdata.txt", @"SDdata" + backupFileCount.ToString() + ".bak");                        backupFileCount++;                    }                    backupCounts = 0;                }            }        }        static void SD_Insert(object sender, MediaEventArgs args)        {            if (Directory.Exists(@"SD"))            {            }        }        static void SD_Eject(object sender, MediaEventArgs args)        {            if (!Directory.Exists(@"SD"))            {            }        }    }


AD7714 is class I wrote to control an external ADC, RGB is a class that controls an RGB LED, and LCD is a class that controls a serial LCD screen. Nothing important there. The variables created on lines 85-88 are the ones I have moved out of the loop to see it that helps.


The only thing I can think to do is run the project with the debugger attached for 14 hours and see what exceptions start getting thrown. Otherwise, I'm stumped.

#2 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 13 March 2013 - 05:06 AM

Hi Verdris, The first thing I'd try is adding some Debug.Print statements to each function in your code, printing out debug info about what functions are getting called when. Capture those in MFDeploy...and then when your code crashes you can see what function it happened in. You could also do this by writing data out to a serial port. Chris

#3 caEstrada


    Advanced Member

  • Members
  • PipPipPip
  • 84 posts

Posted 13 March 2013 - 02:18 PM

Can you try this:


//Para medir cuantos bytes quedan disponibles en runtime FreeRam  = Microsoft.SPOT.Debug.GC(true);


the use like Chris suggested Debug.Print()...



We do not know how those classes you mentioned were written.  I faced similar problems so I took the decision

that every new object should be forced out using dispose().  Perhaps there is a penalty in performance but

in my app was more important 100% availability than few milliseconds lost.

#4 caEstrada


    Advanced Member

  • Members
  • PipPipPip
  • 84 posts

Posted 13 March 2013 - 02:22 PM

Please find some extra info here:





[MethodImplAttribute]public static UInt32 GC (         bool force)
force A Boolean value that specifies whether garbage collection should be forced.
Return Value
[color=#ff0000;]The amount of free (unused) memory, in bytes.[/color]

Available in the .NET Micro Framework versions 2.0, 2.5, 3.0, 4.0, 4.1, and 4.2.

#5 Verdris


    Advanced Member

  • Members
  • PipPipPip
  • 128 posts
  • LocationReno, NV

Posted 14 March 2013 - 02:36 AM

Thanks all for the suggestions. I'm running the experiment again, this time logging Debug.GC(false) with every reading.


During tests today it appeared that with each several iterations of the loop, the value returned by Debug.GC(false) was indeed decreasing. However, I tried this with Debug.GC(true) (ostensibly forcing garbage collection) and the value STILL decreased! It started with something like 100k of free memory, and withint ten minutes was down to about 85k, and kept decreasing.


So, I tried wrapping everything I could find in using() statements. This either didn't work or didn't help. However, it seems like good practice to immediately release COM ports, so that's what I'm doing going forward.


Tonight's setup is: no COM ports whatsoever, all filestreams wrapped up in using(), and the datafile loggs Debug.GC(false) to the end of every line. I'll report back tomorrow with results. The program should crash around 945 AM, PDT.



EDIT: So, it's not that I'm running out of memory. Last night I left it running and it made it to 13:37:04.36. The last entry indicates 90024 bytes of free memory. Still, the code crashed and it stopped logging. I'm going to run the experiment again, changing Debug.GC(false) to true. At this point, though, I'm not sure it will help. If this doesn't work, I'm going to wrap the entire loop code in a try/catch statement.

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.