A DIY Drone Remote Controller

For a simple drone flying with the remote control, you need a remote control (:P). One way is to buy a remote control. FrSky, Radiolink is a popular drone remote for the hobbyist. There are several such remote controls. The only problem is the one shown below cost almost a 100 USD. Since I am not willing to spend 100 USD for this garbage, I decide to know how this work makes my own. However, if you feel this is too much for you, you can always go ahead and buy this RC. There are some cheaper ones from China but still, cost about 50-70 USD range.

Image result for fr sky
FrSky Drone RC. You hold it in your hands.
FrSky Telemetry Receiver. This goes on the drone.

How Drone RC works

These systems are called telemetry system. The one from FrSky lets you configure the sensitivity etc with the buttons on the RC. It also lets you display some drone data. However, let me focus for now how it works.

Transmitter (RC): The transmitter contains a bunch of buttons (an overly complicated design from FrSky I think), a push button and 4 potentiometers (the main control sticks). So a processor inside the RC reads by button presses and transmits a signal. That’s pretty much it. In my mind, I think I can replace this with a game joystick (which cost as low as 5 USD) an Arduino (5 USD). The transmitter can be the HC-12 (5 USD) I have. You might be interested in a blog I did earlier on how to get HC-12 to work.

Receiver: By design FrSky (and other hobby rc makers) keep the receiver super simple. The receiver has 8 outputs in all. 4 are used for controlling the drone movements (throttle, x,y and yaw). The other four are configurable. Usually, people set one of them to enable sports mode (aggressive motion), one for an emergency. Those 8 pins just output PWMs based on what buttons (and potentiometer position) are pressed. You might be interested in my earlier blog where I get PWM to work. In my mind I am thinking, I can replace the receiver with an Arduino and an HC-12 module.

My Own RC

I have a game joystick which I had bought a long time ago for 25 HKD (3 USD or 250 INR). It has 4 potentiometers and a few buttons. It connects to a PC with USB. The data from the joystick can be read from a PC with serial communication. A very long time ago I had attempted it successfully. The blog post is here. A more refined (and easy to use) C++ code for it is github-here. If I had to summarize it in a line, ‘Just read the /dev/joystick/’ file to get its input. I prefer this gamepad over the keyboard is because the keyboard has no potentiometer (potentiometers are a good way to get continuous valued input). I would really like a redesigned keyboard which has a way to get several continuous valued inputs in addition to the keys. Maybe I will work on it in the future.

My Cheap Gamepad

Next, I connect the HC-12 module through the USB-TTL device to my PC. Whatever I read from the RC and make it to 4 (or 5 or 6) numbers and transmit it. I just send 4 numbers (“:” separated) for now which are PWM widths in microseconds over the HC-12 for wireless communication. The HC-12 connects to my PC with serial. So writing to it is like writing a file.

The receiver which is just an HC-12 and an Arduino, receive these 4 numbers. The Arduino converts these numbers to corresponding PWMs for each of the motors. That’s it. I got a DIY RC for a drone.

To test my setup I made a small board (perf boards). You can do it on a breadboard as well. But I used perf board just for the heck of it. I connected 4 servos for testing. Above is a diagram of what I did.

Lab tEST

The entire code base is available at : https://github.com/EasyDronePlatform/joystick

Part-1: Read Serial (from PC), Interpret, Drive motors

A string is read from serial input to the Arduino. Eg. “1200:1000:2000:1600$” means M1 should be driven by 1200microsec PWM pulse and so on. This simple program already took up 23% of the memory of my Arduino Nano.

Part-2: Read Serial (from HC-12), Interpret, Drive motors

4 servos (PWM) and an hc12 (serial communication) are connected on an Arduino. This Arduino is powered by a battery. The Arduino reads incoming data from the hc12 module. The data is expected to be 4 numbers. It parsed in the Arduino and servos are driven accordingly. On a pc, another hc12 module is connected through USB-TTL device. We send data to it using cutecom on Ubuntu.

Part-3: Full System with Arduino Nano 😦

Here is how you can fetch joystick inputs in C++. Other programming environments will also have libraries for Joysticks.
Some details on the issues I encounter. See also the section “Gotchas”.

In my debugging (with oscilloscope) setup, I have an Arduino driving 4 servo motors (PWM). The Arduino is triggered by serial communication (software serial) with the HC-12 module. I noticed vibrations in the servo motors whenever the there is data on the serial with HC-12. This ideally shouldn’t be happening. I analyzed the issue with an oscilloscope.

Here are the observations:
As the data arrives on serial with HC-12 the voltage on the PWM signal pins drops to less than 3.5 volts (peak-to-peak). This causes the servos to shake. This shaking is a really serious issue. I do not dare put BLDC motors through this. And this functionality is really important to work correctly.

The PWM use hardware timers to execute the pulses precisely. However, as you try to use software serial (which also try to use the timers for its processing) it causes the timer to be unavailable to the PWMs. This causes the pulses to break.

Way around:
For now, I do not see a way around this using the Arduino Nanos. However, use of better boards like Arduino mega or the Teensy which have more hardware serial should work well with this. The key point is that look for exactly how many hardware serials and how many PWMs exists before deciding a board. The nano has only 1 hardware serial which is used by the USB.


  • There seems to be a lot of wrong information on the internet on the pin layout of Arduino nano. So the conclusion is that you need to check what bootloader you are using (old or new). Pins for old bootloader are different than new boot loader. Below is the correct pinouts for the Arduino-Nanos I bought from Taobao. There a bunch of different layouts depending on the manufacturer, so this might not be correct for your Arduino.
Source: https://bigdanzblog.wordpress.com/2015/01/30/cant-get-i2c-to-work-on-an-arduino-nano-pinout-diagrams/
  • With the vibrations I see in the servos even when I don’t command them, I don’t dare connect BLDC motors to Arduino Nano. With an oscilloscope, I figure out what happened. Look at my explanation.
  • Don’t try to run your loop() on the nano with more than 30 Hz or so. Always have a delay:
void loop() {
// your code 

  • There are buffer limits on serial communication. The default is 64 bytes (yes bytes@!). It can be expanded, but usually, don’t go more than 256 or 512. The total ram on the nano is 8096 bytes.

Part-4 : Full System (with Teensy2++)

Compared to Arduino Nano, getting things to work with Teensy was a breeze. Clear documentation, better examples, and warnings on technical issues on the official website.


In this part, we developed a DIY solution to the expensive remote control systems which are in common use amongst hobby drone flyers/drone racers, RC aircraft hobbyist etc. Our DIY solution relies on communication using the HC-12 module and a usb-game-joysticks connected to a PC.

Although a lot of RC radio link to let you transmit and receive 8 PWM, the wiring it quite clumsy if you decide to use 8 wires (4 controls and 4 aux). PPM is usually a better choice implementation wise. PPM lets you transmit several PWM together using just 1 signal wire multiplexed in time. Although from the software perspective the code gets complicated compared to PWMs you have a much lesser cluster of wires and hence prone to fewer mistakes. So if you do plan to do this, I recommend using PPM instead.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s