I have built a couple of home-automation devices using the Netduino Plus 2 and, until fairly recently, was pretty happy with them. Certainly the process of development using the .Net MicroFramework is really excellent – it is nothing short of miraculous to be able to debug embedded code in a desktop environment.
BUT neither of the devices was totally reliable and investigation showed that the web-server element of the applications was to blame. They would stay working for weeks at a time but then fail and fail completely – no longer visible on the network – and no longer fulfilling their functions as controllers.
The web-server code I was using came from this blog post by Jasper Schuurmans and to test it to destruction I used Selenium as described in a previous post.
Web Server Woes
Having identified the web-server as the culprit I assumed it would be easy to fix the code or to swap out a different web-server in total. I worked hard on Jasper’s code to instrument it and identified that the code (almost) always failed at the same place – line 29 in the code below.
private void StartServer() { using (var server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { server.Bind(new IPEndPoint(IPAddress.Any, this.Port)); server.Listen(1); while (!cancel) { using (Socket connection = server.Accept()) { if (connection.Poll(-1, SelectMode.SelectRead)) { // Create buffer and receive raw bytes. byte[] bytes = new byte[connection.Available]; int count = connection.Receive(bytes); // Convert to string, will include HTTP headers. string rawData = new string(Encoding.UTF8.GetChars(bytes)); WebCommand command = InterpretRequest(rawData); if (command != null) { WebCommandEventArgs args = new WebCommandEventArgs(command); if (CommandReceived != null) { CommandReceived(this, args); byte[] returnBytes = Encoding.UTF8.GetBytes(args.ReturnString); connection.Send(returnBytes, 0, returnBytes.Length, SocketFlags.None); } } } } } } }
It seemed logical that I could just catch whatever error was occurring and deal with it BUT, and this is a big BUT, the exception was (almost) never caught and the main program loop was (almost) always halted too. I read up on various sites to see if I could find reference to the problem – and found at least one possible looking post – but nothing that specifically matched my problems.
So what to do?
I started to think of the things that might make my application differ from others and cause increased stress on the .Net MicroFramework that might cause it to break. My home-page was loaded from resources (to avoid having to have an SD card) and was loaded in a single chunk of around 8Kb. I decided to split this up and send in chunks with a delay between – but again without success – eventually the application crashed without a catchable exception.
Alternative Web Servers
I then decided to locate and try out other web-servers for the .Net MicroFramework and identified the following:
I tried out each in my program to my horror in each case I saw the same result in each case. The application failed without a catchable exception.
I figured it might be something else to do with my app so I then tried NRestWeb without any modification – as it comes with a demo program provided. And again – after a few thousand page loads the server crashes with a uncatchable exception.
So maybe I’ll junk the Netduinos and move to MBED?
I’ve already done the work to move one application to MBED. I actually did that partly to try out MBED development with a more real-world example – but now I’m seeing the benefit of that work.
It’s going to be more work to move the door-lock but maybe Netduino just isn’t ready for prime-time?