Infrared receiver driver for Netduino

Introduction.

Two Lego Power-Functions infrared remote commanders

This is the completion of my old article on how to create a simple infrared transmitter with your Netduino.

To tell the truth, I had no plans on creating such a receiver, but I needed a quick and easy way to send commands wirelessly to a Netduino installed over a toy. I’m having a lot of fun with mechanical toys, such as Lego or Eitech. That’s not a news for me, because these were my favorite playgrounds during my childhood. Now, with the *duino-revolution, the creativity really has no limit.

My very first attempt.

Here is my very first attempt of creating something hybrid with Lego/Eitech and Netduino. I can do all that only during my spare time (which is few), and I needed something easy, really easy. The easier way is infrared, because I already own a couple of Lego commanders, and I know that the Lego stuffs have already been used with success by Laurent Ellerbach. He’s much creative than me in the Lego-world, but my deal is create something to simple as the children can use.
So, I chose to start with a very simple model, such a small rover, built using an Eitech kit.

The top-view of the chassis.

The bottom-view with the two motors, and the two-series of cogs for an higher torque.

It’s very simple, because it has a couple of motors: each driving a belt. The direction can be modified adjusting the motors’ speed.

The hardware.

Everything is supposed to work upon the demodulated signal outputted by any common infrared-module. Vishay’s among the greatest manufacturers, but there are many models. I used the Vishay TSOP 31238, which is pretty old (I think obsolete), but still good. However, there’s a direct replacement.

Such a modules are very easy to find, yet cheap. It’s commonly used on several appliances, such as TVs, HiFi-sets, etc.
The real infrared light running from the commander is modulated using a carrier, normally ranging from 36 to 40 kHz. This frequency is too fast for a direct detection with the Netduino, but even using a faster MCU a good analog amplifier+filtering is needed. Thus, I strongly recommend to use an integrated module.
The connection of that module to the Netduino is literally trivial: just three wires.

The Vishay module is able to work either at +3.3V, and at +5V, so don’t mind what kind of supply you’ll choose. Also there’s no any difference in the final behavior, sensivity or else. In the picture I connected it at +3.3V.
As for the rover, I used two transistors (BC337) for the motors, which are driven by the PWMs. I also provided a couple of lights (green and red leds), directly driven by two Netduino’s outputs.

How the software works.

The infrared receiver driver is very simple: just a generic base class, which has to be derived to any specific-protocol decoder. At the moment of writing, there’s only the Lego protocol decoder, though.
The basic principle is sampling the falling edges of the module’s output, using a Netduino InterruptPort as sampler. On every interrupt there’s a timestamp indicating the absolute time: for higher resolution, I considered the “ticks”. One “tick” is the smallest time-unit defined by the .Net Framework (any flavor), and it equals to 100 nanoseconds. Also, I preferred the ticks over the whole “DateTime” structure, just because it’s an Int64, and its math is very simple compared to the DateTime complexity.
So, every interrupt there’s a new “interval” value, since the previous edge/interrupt. On the very first edge there’s no any “previous” reference, thus this event is useful for detecting the message start. On the same start, a timer is started.
Since the receiver is generic, it can’t know when the message is over. So the timer plays a crucial role for claiming the message termination. This is a trick, of course, but it doesn’t look so bad!
Once the timer expires, the collection of intervals is fed to the derivation (i.e. the concrete decoder), which analyzes the intervals’ values, and converts in logical bits. For that reason, the decoder may detect errors.
When everything goes well, the decoder can pack up a “message” object containing the useful data, and the type of that message is usually strictly dependent to the specific protocol. Anyway, the message is passed as argument for an event, which can notify the host application.
So far, the usage of the class is straightful:

    public class Program
    {
        private static PWM _wheelRight = new PWM(Pins.GPIO_PIN_D5);
        private static PWM _wheelLeft = new PWM(Pins.GPIO_PIN_D6);
        private static OutputPort _red = new OutputPort(Pins.GPIO_PIN_D0, false);
        private static OutputPort _green = new OutputPort(Pins.GPIO_PIN_D1, false);


        public static void Main()
        {
            //create the infrared receiver listening to the port 8
            var irrx = new InfraredLegoReceiver(Pins.GPIO_PIN_D8);
            irrx.InfraredMessageDecoded += irrx_InfraredMessageDecoded;
            irrx.IsEnabled = true;

            //do whatever

            Thread.Sleep(Timeout.Infinite);
        }


        static void irrx_InfraredMessageDecoded(
            object sender, 
            InfraredMessageDecodedEventArgs e)
        {
            var message = (LegoMessage)e.Message;
            //Debug.Print(message.Mode + " " + message.Func);

            switch (message.Func & 0x03)
            {
                case 0:
                    _wheelLeft.SetDutyCycle(0);
                    _red.Write(false);
                    break;

                case 1:
                    _wheelLeft.SetDutyCycle(100);
                    break;

                case 2:
                    _red.Write(true);
                    break;
            }

            switch (message.Func & 0x0C)
            {
                case 0:
                    _wheelRight.SetDutyCycle(0);
                    _green.Write(false);
                    break;

                case 4:
                    _wheelRight.SetDutyCycle(100);
                    break;

                case 8:
                    _green.Write(true);
                    break;
            }
        }

    }

Please, note that the receiver itself relies on few lines: the remaining is code for the handling the incoming commands.

            //create the infrared receiver listening to the port 8
            var irrx = new InfraredLegoReceiver(Pins.GPIO_PIN_D8);
            irrx.InfraredMessageDecoded += irrx_InfraredMessageDecoded;
            irrx.IsEnabled = true;

Furthermore, all the driver is working in a event-driven fashion. That yields a total freedom for the host application, as well a very-responsive environment.

The rover preview.

Here are some more pictures about the rover, this time with much more mechanical parts, and the electronics stuffs on the top.
It’s still in an early stage, although is working fine.

The source code is available as part of the Cet Open Toolbox on Codeplex.

One thought on “Infrared receiver driver for Netduino

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s