Main Site Documentation

PPM signal decoding from RC receiver


#1

Have anybody used FEZ as an additional brain for RC models, eg. for stabilising plane or make an intelligent RC car ?

I see a lot of components are already available here (GPS, servos, accelerometers), but still haven’t found the simple way of decoding RC receiver PPM signal using .NET MF.

As I’m pretty sure somebody have already tried this, I’d like to ask for advice or code sample…


#2

I would love to help but I do not know what is PPM


#3

In short this is a standard of signal transmitted from RC radio to receiver, carrying the info about all sticks positions. Inside receiver we can find a place where this is in clean frame form, which can be read into Microcontroller using single pin, then processed using all additional hardware, sensors etc. and transferred to servos. Nice PPM drawing is here:


but code refers to arduino.
I am pretty sure that with FEZ it shall also be very easy, but as I am newbie in both areas it is not obvious for me what can be easily ported…


#4

It is in fact easy but there is a catch…

You can do it the easy way by polling a pin. This is how the Arduino code you showed does it.
This is a very bad way since you will kill the processor on polling instead of doing other useful stuff.

The right way would be by using interrupt pins. This way you can do decoding with minimal processor interaction so the system is free for whatever you like.

I would start by doing it the easy way first.

Since you didn’t know how to do this I will assume you are very beginner and you really should read the book and do other things before you try to decode a signal :slight_smile:

Here is the Arduino code converted to C#

        const int channumber = 4;
        long[] value = new long[channumber];

        while(true)
        {
            while(pulseIn() < 5000){} //Wait for the beginning of the frame
            for(int x=0; x<=channumber-1; x++)//Loop to store all the channel position
            {
                value[x]=pulseIn();
            }
            for(int x=0; x<=channumber-1; x++)//Loop to print and clear all the channel readings
            {
                Debug.Print("Channel " + x +" = "+ value[x]); //Print the value
                value[x]=0; //Clear the value afeter is printed
            }
            
        }

I am not sure exactly how pulse in work but you should be able to figure that out
This is just to get you started

static InputPort _ppm = new InputPort((Cpu.Pin)FEZ_Pin.Interrupt.Di3, false, Port.ResistorMode.Disabled);
    static long pulseIn()
    {
        // this all wrong but should get you started
        long ticks;
        //ticks are 100ns
        while (_ppm.Read() == true) ;
        ticks = DateTime.Now.Ticks;
        while (_ppm.Read() == false) ;
        ticks = DateTime.Now.Ticks - ticks;

        return (ticks / 10);//100ns to 1 us conversion
    }


#5

This is nice because I am thinking about getting a hobby grade RC car pretty soon and one of the things I want to do with it is connect the RX to the FEZ.

In your code, it looks like you are decoding the multipart signal sent from the TX, although with my project I’ll need to get the PPM from the RX, which should be much easier since the signal has already been parsed.

I’ll post my code when/if I do the project.


#6

Ok, I’ll try it and right - maybe I shall read a bit more and understand the process on Arduino first, but I want to go fast and I feel your help will speed up my learning curve significantly :slight_smile:
Also very curious about your suggestions about interrupt based solution, which definitely makes much more sense here, leaving processor time to other tasks. This is also much more educational, being ideal sample of interrupt driven programming on NETMF…

Chris - you’re right, but… with parsed signal you need not one but 4 input lines (ok, in car 2 will be fine, but if you start adding stuff…) and same numbers of interrupts what may, paradoxically, be more complicated than reading the sequence from just one frame… Anyway, I’ll be also greatful to see your code and will try to test both approaches.