Microsoft TechDays 2013 Paris: une grand merci!

The greatest Microsoft event of Europe has just been closed in Paris, France.
I am soooo honored to have been mentioned in the “Geek in da House” session of Laurent Ellerbach.

Image00001

He presented two very interesting projects, both of them involving Netduino and a little hardware around.
In the first part of his session, Laurent presents his remotely controlled gardening sprinkler system. Afterward, his Netduino is used in a totally different way: as transmitter for IR commands against a Lego train. My help was just on the latter project.
Here is the link of the video (French speaking).
Have fun!

Advertisements

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.

Infrared transmitter driver for Netduino

Introduction.


There are several contexts where the infrared (IR) remote commanders are really useful: our home is plenty of appliances which are IR based. TVs, Air-conditioning, HiFi-set, games, and lot more. This technology is still alive, because is very simple to implement, and requires very little resources to be realized.
Many users are asking about how to send infrared (IR) messages using a Netduino. That’s because the pleasure of programming such a little board as Netduino is, inspires easily to create solutions where the IR communication may be involved.
At first glance seems hard making a real-time operation for a managed-code platform, and several users have solved this problem connecting an Arduino-like board to the Netduino. That is a very good solution, even pretty elegant, when well-designed. However, it sounded me like a challenge: is it possible for the Netduino sending IR messages without any external “help”?
Well, I’ve got it!

How is an IR message?

Well, there is a very good, yet detailed page, where the principle of sending data through infrared ray is explained. I guess it’s completely useless to rewrite what’s described there.
http://www.sbprojects.com/knowledge/ir/index.php
You can see that there are several protocols, almost every big manufacturer created its own protocol. Here is not important make any comparison between protocols: the aim is to implement them, because we do have some appliance using a certain protocol. So, we need that implementation.
Again, the real challenge is adding the minimum hardware to the Netduino, and make it able to reproduce almost any IR protocol.

How it works?

Once again, I chosen the SPI as primary device for generating the waveform. That because is very simple: just a shift register, and nothing else. And very fast, indeed.
If you take a look at some previous post of mine, it’s clear to see on the scope what’s the behavior of the signals outgoing from the Netduino SPI. If you perform the transfer of a single, long byte array, the SPI is able to shift the data out without almost no delay between bytes. It’s like a streaming.
This privilege gave me the idea on to shape the required waveform: create the bit-pattern on a long buffer, then let the SPI shift it all at once.
The only missing piece is obviously a good driver for the IR-led, since it requires enough current to “light” a room. Okay, we can’t see the IR light, but for the IR receiver “eye” the room is pretty dark, and even a little led can be an huge difference. Try yourself to light up a small led, when the room is completely dark.

Here follows a chart with the detailed principle of working.

Note that the reference is to the Philips RC-5 protocol, but it might be anyone else.

The physical driver circuit.

The circuit is really trivial, and it could be the same circuit pattern used many times for a normal led. By the way, an IR led actually *is* a led, but we need a lot more current flowing through.
The circuit could have been even easier, if only we avoid the ability to share the SPI with some other device. Personally, I would not like losing the ability to drive a SPI-RTC, for instance, because the IR driver. We should drive both.
Thus, there is a simple logic: an AND-gate, where one of the input is the “IR-driver enable”. When the enable is low (zero), no activity on the SPI can involve the IR stage.

The circuit is using two NAND gates (74LS00), because I haven’t at home the right chip. I would recommend the 74HC08 instead, which is a 4x AND gates, HCMOS.

Some consideration about the led current.

If you take a look at the resistor for the led is very low when compared to the typical values you are used to choose. I’ve used 22 Ohms, which is about 10 times lower than a normal led, but I should have used even a 2.2 Ohms (typical for most remote commands).

A straightful computation yields a current of about 150mA for a 22 Ohms resistor, and over 1A for a 2.2 Ohms. Such a high current is surely enough to burn the led, and it’s too high even for the Netduino supply.
You might wonder why a so high current doesn’t actually damage any part.
The answer is very simple: these values are “peaks” for a bunch of microseconds, “spikes” so short, that the average heating power is much less than the power led on the Netduino board.

If you are scared to burn your IR led, I’d suggest a small extra to the circuit. No manufacturer will ever add such a circuit, because is too expensive. However, the hobbist perspective is quite different, and I prefer to give you an opportunity to keep your parts safer.

The trick is simple: the big capacitor (1000 uF) acts as charge accumulator. The stored energy is surely enough to drive the led for some millisecond, but if you try to drive the transistor continuously (e.g. a breakpoint or a bug), the capacitor will lose all its charge, and the actual current will be limited by the additional resistor.

The Infrared library.

The library is targeted for any protocol within the range of the domestica appliances. I don’t know the IRDA protocol, nor I think should be feasible (nor convenient).
At the moment I’m writing this post, the library embeds only the Philips RC-5 (Extended mode included), for transmission. However, it’s very easy to implement many other protocols, since they are very similars.
Please, check the library progression, because I’ll add the missing modules.

Testing the circuit.

My primary goal is sending commands from Netduino to my Maerklin railroad model.

In my case the biggest effort is finding out the protocol, because Maerklin does not give any specs about its devices. However, by using my scope and a small IR-receiver module, I was able to understand that Maerkiln uses the Philips RC-5 Extended protocol.

Using the library is really simple. In the following snippet there’s an example where I wanted to mimic the original remote commander of my Maerklin railroad model.
I have used just three buttons: speed-up, speed-down and change direction. For each button, its event handler embeds a different command to be sent via infrared, according to the Maerklin code set below.

namespace Toolbox.NETMF.Hardware
{
    public class Program
    {
        /**
         * Maerklin remote commander codes:
         * light:   1.T.11000.1010000
         * btn 1:   1.T.11000.1010001
         * btn 2:   1.T.11000.1010010
         * btn 3:   1.T.11000.1010011
         * btn 4:   1.T.11000.1010100
         * btn -:   1.T.11000.0010001
         * btn +:   1.T.11000.0010000
         * dir:     1.T.11000.0001101
         **/
        private const int Address = 0x18;

        private const int SelectLight = 0x50;
        private const int SelectTrain1 = 0x51;
        private const int SelectTrain2 = 0x52;
        private const int SelectTrain3 = 0x53;
        private const int SelectTrain4 = 0x54;

        private const int SpeedDown = 0x11;
        private const int SpeedUp = 0x10;

        private const int Direction = 0x0D;


        public static void Main()
        {
            //create the infrared transmitter driver
            var irtx = new InfraredTransmitter(Pins.GPIO_PIN_D8);

            //create the codec to be used
            var codec = new InfraredCodecRC5(irtx);
            codec.ExtendedMode = true;

            //define the button for decrement speed
            var btn_dec = new InterruptPort(
                Pins.GPIO_PIN_D0,
                true,
                Port.ResistorMode.PullUp,
                Port.InterruptMode.InterruptEdgeLow
                );

            btn_dec.OnInterrupt += (a_, b_, dt_) =>
            {
                codec.Send(Address, SpeedDown);
            };

            //define the button for increment speed
            var btn_inc = new InterruptPort(
                Pins.GPIO_PIN_D1,
                true,
                Port.ResistorMode.PullUp,
                Port.InterruptMode.InterruptEdgeLow
                );

            btn_inc.OnInterrupt += (a_, b_, dt_) =>
            {
                codec.Send(Address, SpeedUp);
            };

            //define the button for the direction
            var btn_dir = new InterruptPort(
                Pins.GPIO_PIN_D2,
                true,
                Port.ResistorMode.PullUp,
                Port.InterruptMode.InterruptEdgeLow
                );

            btn_dir.OnInterrupt += (a_, b_, dt_) =>
            {
                codec.Send(Address, Direction);
            };

            Thread.Sleep(Timeout.Infinite);
        }

    }
}

Here is a small demo of the project:

Finally, it seems that this IR solution is able to solve the problem of another geek. The deal of Laurent Ellerbach was to send IR commands from the Netduino to his amazing Lego village.
Well, I’m really proud to have helped him.

Conclusion.

If your goal is having a simple yet versatile IR transmitter to add to your Netduino, then maybe this circuit is for you. However, the main reason of this project is demonstrating that even a simple real-time operation can be solved by taking advantage of certain features of your Netduino.
If you find this library useful, and you implement it somewhere, feel free to add a link to pictures, videos, or whatever else.

The library is now part of the Cet Open Toolbox, and can be downloaded together with schematics and Fritzing diagrams.