Geeks With Blogs
Joaquin Jares Just another geek's blog

I received (by chance, mostly) a Netduino last tuesday. Netduino is an open-source hardware project based on Arduino and the .Net Micro Framework. And it’s extremely cool. I’m a C# developer and I was always interested in electronics. This is an excellent tool to start to understand that incredible world. I was about to buy an Arduino when the Netduino fell on my lap, so I was really happy about it. Netduino has various disadvantages over Arduino (for starters, it’s more expensive, not all the shields for Arduino work out of the box with Netduino yet and also I’ve read that the prototypes people create in Arduino are made into products with almost no tweaking, which is not as simple with Netduino) but Netduino has an extremely cool development environment (Visual Studio), it’s developed in .Net which I’m very experienced in and you can break and inspect variables as in any other Visual Studio project.

Out of the box you get the little board, with just one button and one led. That doesn’t give you a lot to work with other than turning the led on and off with the button and the morse code “Hello World”, which was boring after a day or so. So while my maker shed super kit gets here, I tried to make the most of it.

I’m a software guy. That makes most of the samples I’ve seen look choppy. I wanted really good abstractions that I will surely a lot once I start playing with the shields. All the hardware stuff in the code I’ve seen is too exposed. So the first thing I did was just that, creating some abstractions.

The onboard led in the Netduino is mapped to an object with the following very simple line of code (everything looks simple in Netduino):

this.led = new OutputPort(Pins.ONBOARD_LED, false);

The ONBOARD_LED is the pin in the board that the led is connected to, the false means that the led will start turned off. To turn it on, you write this:

led.Write(true);

and you write this to turn it off:

led.Write(false);

And that’s about all that you can do with a led. The pin the led is connected to is a digital pin, which means that it only has On and Off states (which, as far as I could understand, means “full voltage” and “no voltage”). The abstraction for led is then:

    public class Led
    {
        private Cpu.Pin pin;
        private OutputPort led;

        private bool state;

        public Led(Cpu.Pin pin)
        {
            this.pin = pin;
            this.state = false;
            this.led = new OutputPort(pin, state);
        }

        public bool State
        {
            get
            {
                return state;
            }
            set
            {
                state = value;
                led.Write(state);
            }
        }

        public void TurnOn()
        {
            State = true;
        }

        public void TurnOff()
        {
            State = false;
        }

        public void Invert()
        {
            State = !State; 
        }

        internal void Blink(int time)
        {
            TurnOn();
            Thread.Sleep(time);
            TurnOff();
        }
    }

Notice I also added a Blink method to turn on and off the led. This is something very common, when you only have a led!!

The button is also very simple to create. You can use either an InputPort or an InterruptPort. The InputPort lets you read the state of the button, but the InterruptPort also lets you receive an event when the button is pressed or released, which is nicer (and also saves battery, since you’re not using the processor to query the button all the time). So, to create a button with the InterruptPort, you use the following line:

this.port = new InterruptPort(Pins.ONBOARD_SW1, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);

The first parameter, as with the led, specifies the pin where the button is connected. The second and third parameters should be left as is (they have to do with the way the button is connected to the micro and to ground). The last one is really interesting.

There are five useful interrupt modes: EdgeLow, EdgeHigh, LevelLow, LevelHigh and EdgeBoth. The Level modes mean “when the button is pressed or not pressed” and they run once when the button gets to the correct state. The Edge modes mean “when the button is being pressed and released”, and IMHO are more simple to use. It’s all explained in this book. EdgeBoth means “when the button is being pressed or released”, which is what I needed to track. The event is called OnInterrupt and the header looks like this:

void

port_OnInterrupt(uint data1, uint data2, DateTime time)

Notice that this is not a normal EventArgs based .Net event. I’ll complain about that later. For now, now that data1 is the pin (in this case, Pins.ONBOARD_SW1 always), data2 is 0 when the button is pressed and 1 when it’s not and time is the time when the button was pressed. The inversion for data2 is weird, but it makes sense, I think. My abstraction for the button looks like this:

    public class Button
    {
        private InterruptPort port;
        private Cpu.Pin pin;

        public event NoParamEventHandler Pressed;
        public event NoParamEventHandler Released;

        public Button(Cpu.Pin pin)
        {
            this.pin = pin;
            this.port = new InterruptPort(pin, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
            this.port.OnInterrupt += new NativeEventHandler(port_OnInterrupt);
        }

        public bool IsPressed
        {
            get
            {
                return !port.Read(); 
            }
        }

        void port_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            if (data2 == 0)
            {
                OnPressed();
            }
            else
            {
                OnReleased();
            }
        }

        private void OnReleased()
        {
            if (Released != null)
            {
                Released();
            }
        }

        private void OnPressed()
        {
            if (Pressed != null)
            {
                Pressed();
            }
        }
    }

With this, I only need an abstraction for the Netduino board itself. That abstraction looks like this:

    public class BaseBoard
    {
        public Button Button { get; private set; }
        public Led Led { get; private set; }

        public BaseBoard()
        {
            Button = new Button(Pins.ONBOARD_SW1);
            Led = new Led(Pins.ONBOARD_LED);
        }
    }

Easy, isn’t it? So what can I do with this? My test project included a state machine.

It works like this:

I start in a StandBy mode. If I press and hold the switch, I enter a “Recording” mode. This will go on until I do nothing for 5 seconds. After that, pressing the switch will replay what I have recorded. If I press and hold again, I enter recording mode and can change the recording. The code is extremely simple. In the Program, I simply have to create the board, attach events and state changes. There’s also an Infinite Sleep at the end of the Main method. If you leave that method, nothing else happens.

This is the code for it:

    public class Program
    {
        private static BaseBoard board;
        private static IState state;

        public static void Main()
        {
            board = new BaseBoard();
            board.Button.Pressed += OnPressedEvent;
            board.Button.Released += OnReleasedEvent;

            state = new StandByState(board, new ArrayList());
            state.StateChanged += state_StateChanged;

            Thread.Sleep(Timeout.Infinite);
        }

        static void state_StateChanged(IState newState)
        {
            state.StateChanged -= state_StateChanged;
            state = newState;
            state.StateChanged += state_StateChanged;
            state.Start();
        }

        static void OnPressedEvent()
        {
            state.OnPressed();
        }

        static void OnReleasedEvent()
        {
            state.OnReleased();
        }
    }

The first state, StandBy, will change modes to Recording on press-and-hold and to Playback on press. It will also blink twice to signal that recording is started. The only thing that’s interesting about the StandBy state is the usage of DateTime.Now. I don’t think that will ever show a real clock in Netduino (as there is no clock battery) but it does show the passage of time. The Timer also works as expected.

    class StandByState : IState
    {
        public event StateChangedEventArgs StateChanged;
        private BaseBoard board;
        private IList recording;
        private DateTime pressStart;
        private Timer timer;

        public StandByState(BaseBoard board, IList recording)
        {
            this.board = board;
            this.recording = recording;
        }

        public void OnPressed()
        {
            pressStart = DateTime.Now;
            this.timer = CreateTimer();
        }

        public void OnReleased()
        {
            this.timer.Dispose();
            if (StateChanged != null)
            {
                if (DateTime.Now.Subtract(pressStart) > new TimeSpan(0, 0, 2))
                {
                    StateChanged(new RecordingState(board));
                }
                else
                {
                    StateChanged(new PlaybackState(board, recording));
                }
            }
        }

        private void OnStartRecording(object state)
        {
            board.Led.Blink(100);
            Thread.Sleep(100);
            board.Led.Blink(100);
        }

        private Timer CreateTimer()
        {
            return new Timer(new TimerCallback(OnStartRecording), null, new TimeSpan(0, 0, 2).Seconds * 1000, Timeout.Infinite);
        }

        public void Start()
        {
        }
    }

The recording state is also very simple. I created a List for state changes, and add a TimeSpan to that list every time the button is pressed or released. I also have a running timer that will change the state I don’t press the button for 5 seconds.

   class RecordingState : IState
    {
        public event StateChangedEventArgs StateChanged;
        private BaseBoard board;
        private IList recording;
        Timer recordStopTimer;
        private DateTime pressTime;

        public RecordingState(BaseBoard board)
        {
            this.pressTime = DateTime.MinValue;
            this.recording = new ArrayList();
            this.board = board;
            this.recordStopTimer = CreateTimer();
        }

        private Timer CreateTimer()
        {
            return new Timer(new TimerCallback(OnStopRecording), null, new TimeSpan(0, 0, 5).Seconds * 1000, Timeout.Infinite);
        }

        private void BlinkBlink()
        {
            int time = 100;
            board.Led.Blink(time);
            Thread.Sleep(time);
            board.Led.Blink(time);
        }

        private void OnStopRecording(object state)
        {
            BlinkBlink();
            if (StateChanged != null)
            {
                StateChanged(new StandByState(board, recording));
            }
        }

        public void OnPressed()
        {
            this.recordStopTimer.Dispose();
            if (this.pressTime != DateTime.MinValue)
            {
                recording.Add(DateTime.Now.Subtract(pressTime));
            }
            board.Led.TurnOn();
            this.pressTime = DateTime.Now;
        }

        public void OnReleased()
        {
            board.Led.TurnOff();
            recording.Add(DateTime.Now.Subtract(pressTime));
            this.recordStopTimer = CreateTimer();
            this.pressTime = DateTime.Now;
        }

        public void Start()
        {
        }
    }

The Playback state will simply walk through the list I created while recording, and invert the led state (that is, turn it on if it’s off, turn it off if it’s on).

    class PlaybackState : IState
    {
        public event StateChangedEventArgs StateChanged;
        private BaseBoard board;
        private IList recording;

        public PlaybackState(BaseBoard board, IList recording)
        {
            this.board = board;
            this.recording = recording;
        }

        private void Play(IList recording)
        {
            foreach (TimeSpan record in recording)
            {
                board.Led.Invert();
                Thread.Sleep(record.GetTotalMilliseconds());
            }
            board.Led.TurnOff();

            if (StateChanged != null)
            {
                StateChanged(new StandByState(board, recording));
            }
        }

        public void OnPressed()
        {
        }

        public void OnReleased()
        {
        }

        public void Start()
        {
            Play(this.recording);
        }
    }

I think this exercises everything you can do with a Netduino with no extra components. It will surely get way more interesting once I have the kit some servos and a breadboard. The only thing I didn’t use was multi-threading (which I will probably try, in order to cancel the playback when I press the button).

So far, I’m loving it! There are some things I found annoying on using Visual Studio with the Micro Framework. Firs, and most important, there’s no support for either Generics or Linq. I know that this is asking too much, but I’m so used to them that I missed them. Collections in Micro Framework means “Arrays”. I found that somewhat limiting. It’s also really annoying that creating a new class using the TDD refactorings will create an invalid class (one using System.Collections.Generics and System.Linq namespaces) so you still have to go to that class to make it compile. FInally, the TimeSpan doesn’t have the Total* properties. Creating extension methods is also interesting. Just take a look:

namespace BlinkingLed
{
    public static class TimeSpanExtensions
    {
        public static int GetTotalMilliseconds(this TimeSpan span)
        {
            return span.Seconds * 1000 + span.Milliseconds;
        }
    }
}

namespace System.Runtime.CompilerServices
{
    [AttributeUsageAttribute(
      AttributeTargets.Assembly
      | AttributeTargets.Class
      | AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute { }
}

Finally, the emulator is useless for Netduino, but I think that you can create your own and that’s the next thing I’m looking into. Other than that, it was really, really cool.

Posted on Saturday, October 9, 2010 7:25 PM | Back to top


Comments on this post: Playing with Netduino

# re: Playing with Netduino
Requesting Gravatar...
You should be able to use your single LED in analog mode (though that may require a resistor) which let's you play with brightness.
Left by Thomas G Mayfield on Oct 10, 2010 8:15 AM

# re: Playing with Netduino
Requesting Gravatar...
That sounds extremely cool, but the led is integrated to the board. I don't think I'll be able to put a resistor there. I'll look into it, though.
Left by Osno on Oct 10, 2010 9:01 AM

# re: Playing with Netduino
Requesting Gravatar...
UPDATE: Someone pointed out in the comments (but I don't see the comment now) that NoParamsEventHandler is not defined in the post. It should be defined like this:
public delegate void NoParamEventHandler();

Anywhere in the code (I have it on button.cs, outside the class).
Left by osno on Dec 20, 2010 4:55 AM

# re: Playing with Netduino
Requesting Gravatar...
Very interesting. But one thing. I've been programming for a while and I haven't gone into electronics yet. And this looks so appealing to me. My question is, what else can you do with Netduino. Is it just LEDs On/Off or can you attach it to something?

I know: C/C++, VB.NET/Assembly/Java/HTML and most of the Web developing languages, and am guessing it won't be a problem when i get it.

I'm really pumped up about this. :D
Thanks in advance
Left by CHX101 on Dec 22, 2010 9:19 PM

# re: Playing with Netduino
Requesting Gravatar...
You can do loooooooooots of things. Anything, I would say. You can do robots, peripherals for the pc, remote controlled stuff, clothes that do stuff... your imagination is the limit. Netduino (and Arduino) is basically tangible software.
Left by osno on Mar 11, 2011 6:56 AM

# re: Playing with Netduino
Requesting Gravatar...
I'm trying to get a grip on this code (consider me as pretty new to C#).
After "copied" the code (and added a IState interface with an event) I still end up in some compilation problems for the following line:
state.StateChanged += state_StateChanged;
"No overlodad for 'Method' matches delegate 'EventHandler'"
Is it correct to use an event within a public interface IState? and if so, how do I get pass the above compilation errors?
Left by Ryarnek on Apr 13, 2012 7:36 AM

Your comment:
 (will show your gravatar)


Copyright © Joaquin Jares | Powered by: GeeksWithBlogs.net