I have been playing with my Netduino Plus for about two weeks now and I love it. So far, the most interesting thing about the Netduino is the use of the .Net Micro Framework (.Net MF). Being a C# developer for a decade now, I really enjoy being able to take advantage of this language in my electronic projects. In this post I will demonstrate some of the .Net MF features I used in this small project.
The project used for this demonstration is quite simple. I have a temperature sensor and a photo-resistor taking measurements every minute and logging the results in a file. There is a watch-dog LED on pin #13 and a button on pin #8 used to toggle a LED attached to pin #7. The button and the LED controls are part of the Arduino protoshield.
The code for this project is available on my GitHub account at the following location:
https://github.com/pchretien/NetduinoPlusEthSD
InterruptPort
The InterruptPort is one of the cool things in the .Net MF. You can define a callback function that will be triggered when the status of an IO changes. In this project, an interrupt has been defined on pin #8. This IO is attached to the protoshield button (S1). The interrupt callback function toggles the green led of the protoshield attached to pin #7.
// Declare the output pin #7 attached to the protoshield green LED private bool pin7Value; private readonly OutputPort pin7 = new OutputPort(Pins.GPIO_PIN_D7, false); ... // Create the interrupt port on pin #8 attached to the protoshield button (S1) private readonly InterruptPort pin8 = new InterruptPort( Pins.GPIO_PIN_D8, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow ); ... // Add a callback to the interrupt port pin8.OnInterrupt += new NativeEventHandler(this.OnInterrupt); ... // Declaration of the callback function private void OnInterrupt(uint port, uint state, DateTime time) { Debug.Print("Pin="+port+" State="+state+" Time"+time); pin8.ClearInterrupt(); pin7Value = !pin7Value; pin7.Write(pin7Value); }
The callback function receives the port number, the state and the DateTime of the event in parameters.
Internal Clock & Network
There is no real time clock with a battery on the Netduino but it is possible to set the board DateTime using code. But what time should we use if there are no RTC onboard? A simple answer is to use the net. The netduino Plus comes with an ethernet port and that is all we need to go and get time online.
The best way to do that by calling a time server using the Network Time Protocol (NTP). Don’t waste your time writing it … someone else has already done the job quite well. Micheal Schwartz is the author of the .Net Micro Framework Toolkit which includes a class that handles all that for you. You will find the code in my project.
Using this library, I load the current time at startup and set the internal clock of the Netduino. Once that’s done, you can call the DateTime.Now from anywhere in your project as long as the board is powered.
I wrote a short method to initialize the Netduino Plus networking options. All I do in this function is find the ethernet network adapter and make sure it’s using DHCP to connect on my local network.
private void InitNetwork() { // write your code here NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface networkInterface in networkInterfaces) { if (networkInterface.NetworkInterfaceType == NetworkInterfaceType.Ethernet) { if (!networkInterface.IsDhcpEnabled) { // Switch to DHCP ... networkInterface.EnableDhcp(); networkInterface.RenewDhcpLease(); Thread.Sleep(10000); } Debug.Print("IP Address: " + networkInterface.IPAddress); Debug.Print("Subnet mask " + networkInterface.SubnetMask); } } }
Timers
Timers are part of the standard .Net Framework and it’s great to know that they are supported by the .Net MF on Netduino. There are so many processes in the embedded world that need periodic actions that having access to the .Net Timers make development a lot faster and easier. I have three timers in this sample project. One is a watch-dog flashing a LED attached to pin #13, one is for temperature reading and the last is for light measurement.
// // Timers declaration // private Timer tempTimer; private Timer lightTimer; private Timer watchDogTimer; ... // // Timers callback binding // TimerCallback watchDogDelegate = new TimerCallback(this.WatchDog); watchDogTimer = new Timer(watchDogDelegate, null, 1000, 1000); TimerCallback lightCheckDelegate = new TimerCallback(this.CheckLightLevel); lightTimer = new Timer(lightCheckDelegate, null, 60000, 60000); TimerCallback tempCheckDelegate = new TimerCallback(this.CheckTemperature); tempTimer = new Timer(tempCheckDelegate, null, 60000, 60000); ... // // Timers callback function declarations // public void WatchDog(Object stateInfo) { pin13Value = !pin13Value; pin13.Write(pin13Value); } public void CheckLightLevel(Object stateInfo) { a0Value = a0.Read(); Debug.Print("Light: " + a0Value); AppendToFile(@"\SD\light.log", "Light level " + a0Value); } public void CheckTemperature(Object stateInfo) { a1Value = a1.Read(); double temperature = (a1Value*3500)/1024.0; temperature = (temperature - 500)/10.0; Debug.Print("Temp: " + temperature); AppendToFile(@"\SD\temp.log", "Temperature: " + temperature); }
Multi-threading
It’s great to have Timers but what about multi-threading support? Well, we also have it with the .Net MF on Netduino. Many will argue we don’t really need multi-threading on micro-controllers, and they may be right, but hey, it makes programming for embedded devices so much more fun with multi-threading. Threads coupled with InterruptPort could save so many lines of code … that’s a really powerful addition to the micro-controllers world.
In the sample project, I instantiate a single thread that makes the protoshield LED flash every second. This is the same LED as the one toggled by the protoshield button.
// Declare the Thread handler private Thread ledThread = null; ... // Bind the thread handler to the thread function and start it ... me.ledThread = new Thread(LedThread); me.ledThread.Start(); ... // The Thread function ... private static void LedThread() { while (true) { pin7Value = !pin7Value; pin7.Write(pin7Value); Thread.Sleep(1000); } }
File IO
The Netduino Plus comes with a micro SD card reader. It can handle up to 2Gb of SD card storage. The .Net MF offers mostly the same API to work with removable storage as the standard framework.
The SD card file system is mounted on the “\\SD\” root folder. Following are some basic utility functions to work with removable storage on the Netduino Plus.
// Check id the SD card is mounted private bool VolumeExist() { VolumeInfo[] volumes = VolumeInfo.GetVolumes(); foreach (VolumeInfo volumeInfo in volumes) { if (volumeInfo.Name.Equals("SD")) return true; } return false; } // Append to a file. // Create the file if it doesn't exist private void AppendToFile( string filename, string message) { if (!VolumeExist()) return; try { FileStream file = File.Exists(filename) ? new FileStream(filename, FileMode.Append) : new FileStream(filename, FileMode.Create); StreamWriter streamWriter = new StreamWriter(file); streamWriter.WriteLine(DateTime.Now.ToString() + ": " + message); streamWriter.Flush(); streamWriter.Close(); file.Close(); } catch(Exception) { } }
Debugging
Finally, of all the features we get with the .Net MF on Netduino, the debugger is the all categories winner. Debugging code on embedded devices has always been a hassle. This is history with the .Net MF on Netduino. You can debug your code running on the device as if it was running on your desktop.
You can step through your code line by line and print debug info to the Output console while running the code on the real world device. I’m sure I don’t have to tell you how a good debugger makes life easier.
Conclusion
I’m a big fan of the Arduino and I’m convinced this platform will remain the leader of open source micro-controllers for a while because of the huge community that supports its development.
However, combining the richness of the .Net Micro Framework and the actual work done on porting it to Mono, I think the Netduino is a very serious pretender in the world of open source micro-controllers.
Try it on your own and let me know what you think.
Philippe Chrétien
October 25, 2011
We are currently using our NetDuino Plus for our senior project at UH. We are successfully creating and storing a file on the NetDuino, however, we are having issues with transferring this file to a connected PC. Can you offer any suggestions, or places where we can useful information on how to do this? Thank you so much for any help you can provide, it’s very much appreciated.
November 1, 2011
What kind of link do you have between your Netduino and your computer? You could simply implement a simple protocol to transfer your files over a serial connection like USB or X-Bee. If you have the Netduino Plus you can simply send your files over the network. There are many samples on how to establish an HTTP connection using a Netduino.