The Netduino forums have been replaced by new forums at community.wildernesslabs.co.
This site has been preserved for archival purposes only
and the ability to make new accounts or posts has been turned off.
After splitting into various threads (like one for connecting to the wifi and another for handling the data send), as well as now using the Toolbox.HTTP_Client reference, I seem to have resolved a timeout causing the Netduino/wifly module to hang
I have been able to run a test with over 700 HTTP Get requests and although there were a number of timeouts none of them caused the Netduino to hang/crash!!
Only problem I have now though is that I run out of memory... and I can't understand why, but I think that's for another thread!
Please find my code below (please ignore all the "Debug.GC(true);" lines as it's part of my efforts to figure out the memory issue) , I hope it helps someone else. Thanks to everyone for their input!!
using System;using System.Collections;using System.IO;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;using Toolbox.NETMF.Hardware;using Toolbox.NETMF.NET;namespace testToolbox21240{ public class Program { static uint intCounter = 0; static uint intTimeoutCounter = 0; static WiFlyGSX WifiModule; static string strWriteFile = "dataone"; static string strReadFile = "datatwo"; static ArrayList counterDataArray = new ArrayList(); public static void Main() { connectToWifi(); populateArray(); //httpSendData(); Thread.Sleep(Timeout.Infinite); } public static void populateArray() { Debug.Print("Populate array from: " + strReadFile); using (var filestream = new FileStream(@"SD" + strReadFile + ".txt", FileMode.Open)) { string strSendLine; StreamReader sr = new StreamReader(filestream); while ((strSendLine = sr.ReadLine()) != null) { counterDataArray.Add(strSendLine); } sr.Close(); sr.Dispose(); Debug.GC(true); } Debug.Print("send data from array"); foreach (string value in counterDataArray) { httpSendData(value); Debug.EnableGCMessages(true); } counterDataArray.Clear(); Debug.GC(true); cleanUp(); } public static void cleanUp() { if (strWriteFile == "dataone") { strWriteFile = "datatwo"; strReadFile = "dataone"; } else { strWriteFile = "dataone"; strReadFile = "datatwo"; } Debug.GC(true); Debug.Print("Free Memory: " + Debug.GC(true).ToString()); Debug.Print("Record count: " + intCounter); Debug.GC(true); populateArray(); } public static void connectToWifi() { //SimpleSocket Socket = new WiFlySocket("myURL.com", 80, WifiModule); //httpSendData(Socket); WifiModule = new WiFlyGSX(); WifiModule.EnableDHCP(); WifiModule.JoinNetwork("mySSID", 0, WiFlyGSX.AuthMode.MixedWPA1_WPA2, "myPassword"); Thread.Sleep(3500); // Showing some interesting output Debug.Print("Local IP: " + WifiModule.LocalIP); Debug.Print("MAC address: " + WifiModule.MacAddress); SNTP_Client TimeClient = new SNTP_Client(new WiFlySocket("ntp2.is.co.za", 123, WifiModule)); Thread.Sleep(500); TimeClient.Synchronize(); Thread.Sleep(500); Debug.Print("DateTime.Now: " + DateTime.Now.AddHours(2)); Thread.Sleep(3500); Debug.GC(true); } public static void httpSendData(string queryStringData) { SimpleSocket Socket = new WiFlySocket("myURL.com", 80, WifiModule); HTTP_Client WebSession = new HTTP_Client(Socket); try { HTTP_Client.HTTP_Response Response = WebSession.Get("/default.aspx?" + queryStringData); // Fetches a response header Debug.Print("value: " + queryStringData); Debug.GC(true); } catch (System.ApplicationException e) { Debug.Print("Error Code: " + e); intTimeoutCounter++; Debug.Print("intTimeoutCounter: " + intTimeoutCounter); using (var filestream = new FileStream(@"SDlog.txt", FileMode.Append)) { StreamWriter sw = new StreamWriter(filestream); sw.WriteLine("DateTime: " + DateTime.Now.AddHours(2) + "rnError Code: " + e + "rnintTimeoutCounter: " + intTimeoutCounter+ "rn"); sw.Flush(); sw.Close(); Debug.GC(true); } Thread.Sleep(1500); Debug.GC(true); httpSendData(queryStringData); } finally { Socket.Close(); //intCounter++; Debug.GC(true); } } }}
Is there a way to cycle the power to the wifly without having to physically use the switch? Is there really no other way to reset the wifly once it hangs?
Not sure if anyone else has asked this...but is the module using SPI? Are those SPI pins routed through the ICSP header? If so, be sure to sandwich a MakerShield in between your Netduino Plus 2 and shield...so that the pins are connected.
Very few shields need the ICSP headers...but for the ones that do, you'll want to sandwich in a shield which routes the pins to the right place. [As a quick fix, you can also plug jumper wires in between the ICSP's SPI pins and D11-D13.]
Not sure if anyone else has asked this...but is the module using SPI? Are those SPI pins routed through the ICSP header? If so, be sure to sandwich a MakerShield in between your Netduino Plus 2 and shield...so that the pins are connected.
It's using UART on COM1 or COM2
Currently, I have no suggestions, regretfully. I can't reproduce this on my own device.
I thought maybe it was my wifi network and have tried on a different network and it runs perfectly until the first timeout then can't connect to the socket again.
All I end up with is the little green LED (D1) blinking on the RN-XV and the PWR red LED blinking on the wifi shield.
Compliments of the season to you and I hope you all had a relaxing festive break; all the best for 2013!
First day back in the office today and I saw that there was a new release of the .NET Micro Framework Toolbox (21240). I downloaded it and created a new project to see if the newly compiled toolbox would help me get around the timeout problem I was having.
Excitedly I noticed a new reference (Toolbox.NETMF.NET.HTTP_Client) which I thought may be the answer I was looking for... and it turns out that the new reference seems to make all the difference!
The new reference seems to be able to successfully handle a caught timeout and then process the HTTP request again. I will post my code below. the only issue I now have is that after numerous timeouts I finally get the following: WARNING: TOO MANY NESTED EXCEPTIONS!!
Current date according to server: Mon, 07 Jan 2013 15:51:08 GMT
intCounter: 284
Current date according to server: Mon, 07 Jan 2013 15:51:11 GMT
intCounter: 285
WARNING: TOO MANY NESTED EXCEPTIONS!!
A first chance exception of type 'System.ApplicationException' occurred in Toolbox.NETMF.Hardware.WiFlyGSX.dll
An unhandled exception of type 'System.ApplicationException' occurred in Toolbox.NETMF.Hardware.WiFlyGSX.dll
Additional information: Connection timed out
Has anyone else come across this? I'm not sure it is going to be an issue though as in my main project there won't be an infinite loop like there is in this test project. So I don't imagine there will be that many nested exceptions...
using System;using System.Net;using System.Net.Sockets;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;using Toolbox.NETMF.Hardware;using Toolbox.NETMF.NET;namespace testToolbox21240{ public class Program { static uint intCounter = 0; static WiFlyGSX WifiModule; public static void Main() { WifiModule = new WiFlyGSX(); WifiModule.EnableDHCP(); WifiModule.JoinNetwork("mySSID", 0, WiFlyGSX.AuthMode.MixedWPA1_WPA2, "myPassword"); Thread.Sleep(2500); // Showing some interesting output Debug.Print("Local IP: " + WifiModule.LocalIP); Debug.Print("MAC address: " + WifiModule.MacAddress); SNTP_Client TimeClient = new SNTP_Client(new WiFlySocket("ntp2.is.co.za", 123, WifiModule)); TimeClient.Synchronize(); Debug.Print("DateTime.Now: " + DateTime.Now.AddHours(2)); httpSendData(); Thread.Sleep(Timeout.Infinite); } public static void httpSendData() { SimpleSocket Socket = new WiFlySocket("myServer.com", 80, WifiModule); HTTP_Client WebSession = new HTTP_Client(Socket); while (true) { try { string strDateTime = (DateTime.Now.AddHours(2).Month.ToString() + "/" + DateTime.Now.AddHours(2).Day.ToString() + "/" + DateTime.Now.AddHours(2).Year.ToString() + "%20" + DateTime.Now.AddHours(2).Hour.ToString() + ":" + DateTime.Now.AddHours(2).Minute.ToString() + ":" + DateTime.Now.AddHours(2).Second.ToString()); HTTP_Client.HTTP_Response Response = WebSession.Get("/default.aspx?deviceID=123&count=" + intCounter + "&dateTimeStamp=" + strDateTime); // Did we get the expected response? (a "200 OK") if (Response.ResponseCode != 200) throw new ApplicationException("Unexpected HTTP response code: " + Response.ResponseCode.ToString()); // Fetches a response header Debug.Print("Current date according to server: " + Response.ResponseHeader("date")); Debug.Print("intCounter: " + intCounter); } catch (System.ApplicationException e) { Debug.Print("Error Code: " + e); Thread.Sleep(2000); Debug.Print("Go back to start"); httpSendData(); } intCounter++; } } }}
Anyway, I'll keep you posted on this new "timeout" issue once I have had a chance to integrate the new reference (Toolbox.NETMF.NET.HTTP_Client) into my main project.
2. In sendHTTP_Request(), it looks like there's a loop for sending the request, but the socket is being closed within that loop. So if for any reason IsConnected is still true for a few milliseconds after the call to Close(), it will attempt to send the request again on a closed socket. I'd move that Close() outside the loop.
My advice:
Simplify your sendHTTP_Request() method so it only manages the lifetime of the Socket, using a try/finally to clean up after any exceptions. Then manage all of your exception/retry logic in a calling method, so it will be easier to see. Managing logic that is shared across two or more methods will make it confusing. Since an http request requires a socket to function, the method responsible for sending the request should create/destroy the socket. (Personally I would build the request in there as well, but that's just me)
After splitting into various threads (like one for connecting to the wifi and another for handling the data send), as well as now using the Toolbox.HTTP_Client reference, I seem to have resolved a timeout causing the Netduino/wifly module to hang
I have been able to run a test with over 700 HTTP Get requests and although there were a number of timeouts none of them caused the Netduino to hang/crash!!
Only problem I have now though is that I run out of memory... and I can't understand why, but I think that's for another thread!
Please find my code below (please ignore all the "Debug.GC(true);" lines as it's part of my efforts to figure out the memory issue) , I hope it helps someone else. Thanks to everyone for their input!!
using System;using System.Collections;using System.IO;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;using Toolbox.NETMF.Hardware;using Toolbox.NETMF.NET;namespace testToolbox21240{ public class Program { static uint intCounter = 0; static uint intTimeoutCounter = 0; static WiFlyGSX WifiModule; static string strWriteFile = "dataone"; static string strReadFile = "datatwo"; static ArrayList counterDataArray = new ArrayList(); public static void Main() { connectToWifi(); populateArray(); //httpSendData(); Thread.Sleep(Timeout.Infinite); } public static void populateArray() { Debug.Print("Populate array from: " + strReadFile); using (var filestream = new FileStream(@"SD" + strReadFile + ".txt", FileMode.Open)) { string strSendLine; StreamReader sr = new StreamReader(filestream); while ((strSendLine = sr.ReadLine()) != null) { counterDataArray.Add(strSendLine); } sr.Close(); sr.Dispose(); Debug.GC(true); } Debug.Print("send data from array"); foreach (string value in counterDataArray) { httpSendData(value); Debug.EnableGCMessages(true); } counterDataArray.Clear(); Debug.GC(true); cleanUp(); } public static void cleanUp() { if (strWriteFile == "dataone") { strWriteFile = "datatwo"; strReadFile = "dataone"; } else { strWriteFile = "dataone"; strReadFile = "datatwo"; } Debug.GC(true); Debug.Print("Free Memory: " + Debug.GC(true).ToString()); Debug.Print("Record count: " + intCounter); Debug.GC(true); populateArray(); } public static void connectToWifi() { //SimpleSocket Socket = new WiFlySocket("myURL.com", 80, WifiModule); //httpSendData(Socket); WifiModule = new WiFlyGSX(); WifiModule.EnableDHCP(); WifiModule.JoinNetwork("mySSID", 0, WiFlyGSX.AuthMode.MixedWPA1_WPA2, "myPassword"); Thread.Sleep(3500); // Showing some interesting output Debug.Print("Local IP: " + WifiModule.LocalIP); Debug.Print("MAC address: " + WifiModule.MacAddress); SNTP_Client TimeClient = new SNTP_Client(new WiFlySocket("ntp2.is.co.za", 123, WifiModule)); Thread.Sleep(500); TimeClient.Synchronize(); Thread.Sleep(500); Debug.Print("DateTime.Now: " + DateTime.Now.AddHours(2)); Thread.Sleep(3500); Debug.GC(true); } public static void httpSendData(string queryStringData) { SimpleSocket Socket = new WiFlySocket("myURL.com", 80, WifiModule); HTTP_Client WebSession = new HTTP_Client(Socket); try { HTTP_Client.HTTP_Response Response = WebSession.Get("/default.aspx?" + queryStringData); // Fetches a response header Debug.Print("value: " + queryStringData); Debug.GC(true); } catch (System.ApplicationException e) { Debug.Print("Error Code: " + e); intTimeoutCounter++; Debug.Print("intTimeoutCounter: " + intTimeoutCounter); using (var filestream = new FileStream(@"SDlog.txt", FileMode.Append)) { StreamWriter sw = new StreamWriter(filestream); sw.WriteLine("DateTime: " + DateTime.Now.AddHours(2) + "rnError Code: " + e + "rnintTimeoutCounter: " + intTimeoutCounter+ "rn"); sw.Flush(); sw.Close(); Debug.GC(true); } Thread.Sleep(1500); Debug.GC(true); httpSendData(queryStringData); } finally { Socket.Close(); //intCounter++; Debug.GC(true); } } }}