Generate PPM signal with Arduino

In the beginning of this year I’ve written a short tutorial how to read PWM signals from RC radio with Arduino. While it is can be useful when building own RC equipment, it does not help much when one has to deal with PPM (CPPM) signal. Let’s be honest, PPM is much more useful than PWM: all RC channels are sent over single wire. On one side, it simplifies electrical design. On the other, it makes software part more “complicated”, since there is a need to encode multiple PWM channels into single PPM line in transmitter, and then decode PPM signal into multiple PWMs in receiver. And there are very little “ready and working out of the box” solutions in Arduino world.

In this short article I will show how to generate PPM (CPPM) signal using solution prepared few years ago by David Hasko. Originally it was posted of Google Code. But Google Code is not closed and who knows for how long it still will be available. So, let’s not let the knowledge got lost.

Code is relatively simple, and almost all work is done inside ISR(TIMER1_COMPA_vect) that is executed in the background by timer . Everything user has to do, is to put desired values to ppm array inside loop function. This code can generate both positive and negative signal. It can be easily ported to almost any project, as long as TIME1 is free to use.

Slightly more advanced example is available on GitHub.

9 thoughts on “Generate PPM signal with Arduino

  1. Hello, this is Dominik from Germany.

    I found your post and find it very interesting. A few months ago I tried the original code without success.

    Might I ask a few questions about your additional code?

    You added a switch for what purpose? Binding?

    What is the switch_step parameter used for?

    The ppm signal pin is channel_to_modify? Right?

    Did you try an frsky 8ch DIY? This is the one I got here and which is not working for unknown reason ๐Ÿ™‚

    Look here: http://www.hobbyking.com/hobbyking/store/__17205__FrSky_DHT_8ch_DIY_Telemetry_Compatible_Transmitter_Module.html

    Thanks for your patience

    Regards Dominik

    1. Button was added, coz I needed to change value of 1 channel. Every press of button was increasing channel value by switch_step.

      PPM output in on sigPin , in this case Arduino PIN 10.

      No, never tried that receiver.

  2. Hello.
    I’ve used your code with Arduino Mega. However, while checking output with oscilloscope I’ve found that it outputs incorrect pulse lengths. E.g. it outputs 1.800ms wide pulse while respective value in ppm array is 2090.

    1. My experiments with this code and Chinese clone of Arduino Pro Mini and original UNO R3 shows around 20us difference

  3. Hello everyone,
    Does anyone have a working code for reading the analog values (joysticks)?
    The map function like:

    “joystick = analogRead(joy1);
    joystick = map(joystick, 0, 1023, 0, 180); ”

    is supposed to be not soo accurate.

    Any ideas?

    Thanks Dominik

  4. Hi DZIKU,

    I just added your code without success. This problem occurs almost with every code I tried.
    As far as I know the problem is the false ppm signal. Unfortunately I can figure out the right combination of Signal length and Pulse length etc. I uploaded a video where this can be seen.

    https://youtu.be/zwoVcZT94cI

    As long as the false ppm signal is connected the servo spins like hell. At the end of the video I pulled the ppm cable and the problem stops. Also the orange light indicates that there is no valid ppm signal ๐Ÿ™

    Any suggestions?

    Greetings from Cologne

Leave a Reply

Your email address will not be published.