D4G AI Racing Part 3: Computer Control of a Drone via Taranis Trainer Jack


Following on from the previous part where we hacked the FrSky PXX protocol, this article continues the drone control theme by introducing the Pulse Position Modulation (PPM) protocol. Along with Pulse Width Modulation (PWM), as used in speed controllers and servos, PPM is one of the most well implemented protocols by a range of manufacturers.

The video above shows the aim of this article: use an Arduino to control a drone via the trainer port of a Taranis radio. Although we use a FrSky Taranis here, other radio manufacturers, for example Futaba, Spektrum, Jumper and FlySky, also use PPM to talk to the modules that plug into the back of the radios, as well as their own trainer ports. In fact, if you look at the iRange setup post from one of our Drone Workshops, the iRange multiprotocol module communicates with the radio via PPM, so you could drive the module directly from an Arduino without the need for the Taranis radio. The same also applies to other types of module. This provides a simple solution for controlling a whole host of cheap micro drones via computer, for example the HubSan X4s that we use extensively.

This is the setup from the video:

Arduino, logic level shifter, Taranis trainer port and receiver

The picture above shows a more detailed view of the electronics in the video. The Arduino is running a sketch that causes the four servos to cycle through their full range of movement. This is using a PPM Encoder that we wrote to output the correct PPM pulses on pin 2 of the Arduino. The electronics on the breadboard is simply a level shifter, as the Arduino outputs PPM as 5v peak to peak and the Taranis normally uses 3.3v. I think the Taranis is probably 5v tolerant, but I'm happier doing it like this for the sake of a couple of components.

If you're interested in how to hack the protocol. What I did first was to flip the Taranis from a Trainer Master to a Trainer Slave. This causes it to transmit PPM on the trainer port so I could have a look at it with my oscilloscope to see what it looked like.

A Taranis PPM frame for 8 servo channels

The image above shows exactly what I would expect, apart from the fact that it's inverted. The sync pulses go from high to low (falling edge), while the signal is encoded in the lengths of those eight short high peaks on the square wave in the image. As I move channel 1 from min to max, the first of those peaks gets longer and shorter. Congratulations - that's really all there is to PPM!

Let's make this a bit clearer with a timing diagram:


The 0..7 channels (usually represented as 1..8 in radio control manuals), are timed from the point that the low sync pulse starts to rise until the next rising edge of the next sync pulse. These are the green timings, which show the length of all the sync pulses as 300us, with channel timing from 1000us (min) to 2000us (max). 1000us equals 1 millisecond, so that equates to between 1ms and 2ms with 1.5ms as the centre position. These timings will look very familiar to anybody who has played around with driving servos directly. In the old days of frequency modulation (FM) radios, it made it easy for the receiver electronics to convert the stream of channel data into separate PWM signals for each servo. Back then, single chip microprocessors didn't exist, so the electronics had to do it all the hard way. Look at where the timing points are taken from, though. The 2000us timing INCLUDES the length of the 300us sync pulse. That's really the only difficult part.

The full frame lasts for a maximum of 22500us, so it's sending positions updates to the radio every 22.5ms. However, as each channel can be a variable length pulse, the length of the data varies depending on the positions of all 8 channels. The clue is in the name, "pulse position", so it's the position of the pulse on the time axis that's important. This is where the frame length of 22.5ms comes in, as it included enough "padding" so that the end of one frame cannot run into the start of the next one, while maintaining a fixed update rate of one frame every 22.5ms. All these timing constants are programmed into the software, so it is easy to modify for different radio types.

Finally, if you're wondering about my level changer, this is the circuit diagram:


It's just a simple potential divider with a 3v3 zener diode to give me the correct level. The Arduino connects on the left of the diagram and the Taranis on the right.

I was getting quite a lot of noise on my channels, so I may have another look at the electronics and add a filter. However, I didn't bother to solder the wires inside the jack plug. They were only wound round the jack plug tags and twisted together, so that could be it. Also, looking at where the breadboard and wiring are in relation to the Taranis aerial, it's not exactly ideal. If you watch the second part of the video and the virtual stick positions on the Taranis display, you can see a bit of "jittering". It is rather scary to watch as the sticks wander around seemingly on their own while the Arduino controls them.

That turned out to be relatively simple, so the obvious question is what to do next. The ultimate aim is to fly a drone by computer. Before we bring in the Artificial Intelligence, I'm thinking about using a Leap Motion sensor to fly a real drone with my hand, just like I did with the one in our drone simulator here: [Fly a Drone with your Hand]. Gesture control of remotely piloted vehicles is a whole topic in itself.

The code is on GitHub here if you want to try it out for yourself: https://github.com/maptube/rogue/tree/main/arduino/sketch_RoguePPM

Having mastered control, the part 4 of D4G AI Racing involves how to detect the position of a racing gate in an FPV image.


Comments