Read RC PWM signal with Arduino

Arduinos are cheap and simple development board. You can do a lot with even the simplest of them. For example build you own quadcopter and flight controller (after all MultiWii = Arduino + MPU6050). Of course, this is not as simple as one might imagine and there are few (actually a lot) obstacles that needs to be overcomed. One of them, and very basic, is how to read RC PWM signal provided by radio receiver.

Signal to decode

RC PWM signal passed from radio receiver to servos, ESC, flight controllers is encoded with a length of pulse. Pulse length of 1000us (micro seconds) is minimum stick position and pulse of 2000us length is maximum stick position. Pulses repeat every 20ms for standard 50Hz refresh rate. Like this:

RC PWM Signal

So far, nothing fancy. Unfortunately, signal like this is not so easy to read using microcontrollers. Our device has to detect moment when signal changed from LOW to HIGH, remember time in microseconds when it happened, detect moment when signal changed from HIGH to LOW and substract stored time from current time in microseconds. Separately for each RC channel. pulseIn function will not do. The answer are interrupts. You can read more about Arduino interrupts here. Bottom line is: external interrupts are simpler and better but there is limited number of them: 2 for ATMega328 based boards (Uno, Mini, Nano) and 4 for ATMega32u4 boards (Leonardo, Micro). Not enough, so pin change interrupts (they really should be called port change interrupts) have to be used instead.

Solution

Luckily, with a support of proper library, pin change interrupts are simple. My personal favorite is PinChangeInterrupt by Nico Hood. Following code uses PinChangeInterrupt library to read 3 RC PWM channels and sends decoded values to serial.

This code was written and tested on Arduino Pro Micro with ATMega32u4, but can be used without any changes on ATMega328 boards. To decode more channels just add new entries to arrays defined in lines 9-11, initialize inputs and attach interrupt functions. You also have to consult which pins can be used on different Arduino boards.

Leave a Reply

Your email address will not be published.