How to generate PPM signal with ESP32 and Arduino

The PPM protocol for encoding Remote Control channel values is now a legacy. Still, it is widely accepted by different hardware and when tinkering with Arduino, remote control, and working on own accessories for flight controllers, PPM is still a valid option.

A few years ago I presented a code that allows generating PPM stream using Arduino and AVR hardware. That solution is very hardware-specific and works only with ATMega microcontrollers.

During my work of ESP32 DiyMotionController I stumbled on a problem: if ESP32 is not compatible with AVR when timers are a concern, how to generate a PPM stream on ESP32?

PPM signal on an oscilloscope

This is why I reserved one evening, powered up my oscilloscope (Rigol DS1054Z), and created the code you can see below.

    #define PPM_FRAME_LENGTH 22500
    #define PPM_PULSE_LENGTH 300
    #define PPM_CHANNELS 8
    #define DEFAULT_CHANNEL_VALUE 1500

    #define OUTPUT_PIN 14

    uint16_t channelValue[16] = {1500};

    hw_timer_t * timer = NULL;
    portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

    enum ppmState_e {
        PPM_STATE_IDLE,
        PPM_STATE_PULSE,
        PPM_STATE_FILL,
        PPM_STATE_SYNC
    };

    int getRcChannel_wrapper(uint8_t channel)
    {
        if (channel >= 0 && channel < 16)
        {
            return channelValue[channel];
        }
        else
        {
            return DEFAULT_CHANNEL_VALUE;
        }
    }

    void IRAM_ATTR onPpmTimer() {

        static uint8_t ppmState = PPM_STATE_IDLE;
        static uint8_t ppmChannel = 0;
        static uint8_t ppmOutput = LOW;
        static int usedFrameLength = 0;
        int currentChannelValue;

        portENTER_CRITICAL(&timerMux);

        if (ppmState == PPM_STATE_IDLE) {
            ppmState = PPM_STATE_PULSE;
            ppmChannel = 0;
            usedFrameLength = 0;
        }

        if (ppmState == PPM_STATE_PULSE) {
            ppmOutput = HIGH;
            usedFrameLength += PPM_PULSE_LENGTH;
            ppmState = PPM_STATE_FILL;

            timerAlarmWrite(timer, PPM_PULSE_LENGTH, true);
        } else if (ppmState == PPM_STATE_FILL) {
            ppmOutput = LOW;
            currentChannelValue = getRcChannel_wrapper(ppmChannel);

            ppmChannel++;
            ppmState = PPM_STATE_PULSE;

            if (ppmChannel > PPM_CHANNELS) {
                ppmChannel = 0;
                timerAlarmWrite(timer, PPM_FRAME_LENGTH - usedFrameLength, true);
                usedFrameLength = 0;
            } else {
                usedFrameLength += currentChannelValue - PPM_PULSE_LENGTH;
                timerAlarmWrite(timer, currentChannelValue - PPM_PULSE_LENGTH, true);
            }
        }
        portEXIT_CRITICAL(&timerMux);
        digitalWrite(OUTPUT_PIN, ppmOutput);
    }

    void setup()
    {
        pinMode(OUTPUT_PIN, OUTPUT);
        timer = timerBegin(0, 80, true);
        timerAttachInterrupt(timer, &onPpmTimer, true);
        timerAlarmWrite(timer, 12000, true);
        timerAlarmEnable(timer);
    }

    void loop()
    {
        /*
        Here you can modify the content of channelValue array and it will be automatically
        picked up by the code and outputted as PPM stream. For example:
        */
        channelValue[0] = 1750;
        channelValue[1] = 1350;
    }

the code uses one of ESP32 Timers/Alarm to generate PPM in the background. Logic happens inside of onPpmTimer handler function. Code rescheduled the timer alarm to trigger according to RC channel values. The given example allows to encode 8 channels in a PPM stream. It's fully asynchronous from the main loop.

Jumper T18 Review

Jumper T18 radio transmitter and FrSky R9 receivers

One of the advantages of the Jumper T18 over its competition is the JP5in1 Multiprotocol Module compatibility not only with 2.4GHz FrSky and FlySky receivers but also with Long-Range FrSky 868/915MHz R9 system. At least in theory, because when I got the radio, I could not bind and use any of my R9MM or R9 Mini with the Jumper T18. However, to make it work, all that is required is to update the firmware of Jumper T18, JP5in1 Multiprotocol Module and, in some cases, in R9 receivers.

Jumper T18 Multiprotocol Radio

Continue reading “Jumper T18 radio transmitter and FrSky R9 receivers” »

EmuFlight

EmuFlight Kalman Filter Tuning

The most distinctive feature of the EmuFlight flight controller software is it’s gyro Kalman filter. Yes, the same filter that some people name the dynamic PT1, doubt that it works or calls it magic. I will not discuss if the EmuFlight Kalman works and how it works (it works tho, I have enough time in the air to confirm that). Instead, I will show you how to tune the filter to get your racer’s best performance or a freestyle machine.

EmuFlight Quadcopter Drone

Continue reading “EmuFlight Kalman Filter Tuning” »

inav rover tutorial

How to setup INAV on a rover

INAV 2.5 finally allowed to use INAV and INAV compatible flight controllers to be used on rovers and boats. Finally, INAV supports not only flying vehicles. Bear in mind, that the rover and boat support is not full, and some functionalities might not be working like expected.

What works:

  • Reversible ESC and motors
  • Steering
  • Waypoints
  • Return to home on a straight line without any obstacle avoidance
  • Failsafe

Continue reading “How to setup INAV on a rover” »

Long-Range FPV tips

Long-Range FPV Tips

Long-range FPV is one of the hardest aspects of the modern R/C hobby. Not only will you be sending your foam airplane of drone miles and miles above the line of sight range, if anything goes wrong, but you will probably never recover your UAV. Dead servo, burned motor, broken linkage, or just depleted battery equals crash. Finding your model miles away is extremely hard even if you know the GPS coordinates and last known position. Before making a first long-range flight, do everything you can to ensure your airplane or a drone will come back safely.

Ritewing Mini Drak

Long-Range FPV Airplane Mini Drak

Here are tips about how to do that. But bear in mind, that I will skip the most obvious tips like:

Continue reading “Long-Range FPV Tips” »

what is pid controller

What is a PID controller and how it works?

The whole FPV hobby, and especially multirotor drones, work only thanks to control theory and PID controllers. They are the only thing that separates chaos and immediate flip-over from a stable flight. A regular multirotor has at least 3 PID controllers. If you enable any mode with self-leveling, the number goes to 6. Any GPS assisted mode increases the number to at least 12.

Of course, the PID controllers we think when we think about when we say about multirotors, are Rate PID controllers. They keep our drones stable by keeping angular velocity at desired levels. And usually, they are the ones that have to be tuned to achieve a nice, smooth and stable flight.

Continue reading “What is a PID controller and how it works?” »

Drone and RC airplane motors – everything you wanted to know but you were afraid to ask!

Today, let's have a nice talk about brushless electic motors we use in the RC hobby. Both on airplanes, as well as on drones. In this video we will discuss:

  • motor size
  • motor KV and rotation speed
  • KV versus KT as motor constants
  • stator and rotor
  • number of coils and poles
  • winding
  • phases
  • airflow and cooling
  • does a motor care about rotation direction
  • how to change the rotation direction of a motor
  • shaft and hub
  • mounting holes spacing
  • how not to fry your motor right away

Your first 7-inch FPV drone

I love 7-inch FPV drones and during the last year, they were my most used FPV gear. For freestyle, cinematic, cruising and long-range. I currently own 3 7-inch FPV drones and 4th one in the assembly process. I think of myself as a 7-inch expert. I’ve wasted enough money and equipment to know what works and what does not work well with 7-inch propellers.

TBS Source One 7-inch FPV drone

If you are thinking about building your own 7-inch FPV drone, here are some tips that might save you a lot of time and a lot of money on wrongly chosen equipment. Continue reading “Your first 7-inch FPV drone” »

7 tips and tricks for smooth HD video on 7-inch quads

7 inch quads are great, but they are tricky. It’s much harder to make them fly smoothly than 5-inchers. It’s just more demanding in term of stiffness, propellers, vibrations, jello and so on. After almost one year of fighting with all those issues, here is my list of 7 tips and tricks how to get a smooth HD video footage on 7-inch quads. Bear in mind that almost all of those tricks apply for 5 and 6 inchers too. They are maybe not that important for great results there.