AVR based PPM R/C interface


This is a re-issue of an older article I wrote a couple of years ago that was linked to a couple of times. It broke when transferring it to the new CMS so i'll spend a couple of minutes cut-and-pasting it from the archive.

This Documentation, Source Code and Schematics have been published under the GNU GPL license

The AVRRC program has been written in AVR Assembler, targeted at the ATMEGA8 microcontroller to provide a minimal-hardware cost efficient solution to interface Radio Control transmitters to Personal computers for diagnostic and application purposes.

AVRRC can emulate major interface protocols that allow it to be used with the FMS Flight simulation.

Features

optional USB interface
optional serial RS232 interface
Menu driven interactive operation
Diagnostic mode to display precise timings of PPM transmitter
Configuration of operation modes and timing parameters
Automatic recognition of positive and negative pulse PPM modulation
Generation of two interface formats understood by the popular FMS R/C flight mulator
Usage of R/C transmitter as Joystick through usage of free third party drivers
Support for an external bootloader so chip and interface can be built directly into the RC transmitter and software updates can be uploaded through USB

Hardware

I have constructed the AVRRC prototype using a general purpose controller board that I had developed some time ago. As the requirements are rather primitive, an interface can be constructed either on stripboard or any other prototype board. My PCBs are manufactured in industrial quality by German Boardmaker Drechsel 

The ATMEGA8 chip has an internal UART which is used in this application to transmit the menu and configuration items as well as the generated data streams for the FMS interface. The interface of the UART can either be to a serial port on the PC, for that a line driver chip needs to be used (as the AVR chip generates TTL level data), most likely being the MAX232.

max242-hookup.jpg

USB Interface

The more comfortable solution nevertheless is to interface the chip using a FTDI interface chip directly to a USB port which as well eliminates the need for a power supply as this can be taken from the USB bus. 

As the FTDI chips unfortunately are only available in SMD packaging, I have obtained a small PCB which already has the chip attached and which is available under the name USB2BOT from German company Segor Electronics in Berlin for 10 EUR. 

The same company of course supplies the MAX232 and AVR chips as well. Drivers can be found on the FTDI website.

ftdiboard.jpg

If you are happy soldering the SMD chip, here is the schematic required (the inductor in the schematic is a wire with a ferrite bead):

Schaltplan.jpg

The ATMEGA8

On the input side, I am using the external interrupt pin INT1 to sense the PPM pulses. The input is interfaced through a 100 Ohm Resistor and a 4.7V Zener diode in case the transmitter delivers pulses of different amplitude. For information on how to create cables which interface almost any transmitter type to TTL signals, please refer to this fine page.

The program will automatically sense whether a transmitter with positive or negative PPM logic is used and adjust itself accordingly. The function has been tested using my HITEC ECLIPSE7 transmitter which can generate both types of pulses.
avrrc.jpg

ISP connector

Please note that in this minimal configuration the chip needs to be programmed in a separate board, such as the STK500 development board or a standalone board which has a serial programing connector, at least for the first time until the Bootloader code was installed. 
If you do not at all have anything like that your only chance is to install an ISP connector in your circuit and use a software like PONYPROG and a minimal programming hardware to install the bootloader.
This how an ISP connector would look like:

avrisp.jpg

Software

The software is written straightforward and sometimes uses available memory quite generously for the sake of comfort and safety. Normally I try to generously comment as well.

The main functionality is provided by two interrupt routines and a free running counter 1, using an internal prescaler of 8. As I use an 8Mhz crystal, the counter therefore counts in microseconds. One interrupt routine is attached to the INT1 external interrupt pin and permanently changes it’s sensitivity for either raising or falling edges, depending on what is measured. If no level changes occur on INT1 (as no transmitter is attached or it was switched off), the counter will invariably overflow which in turn triggers the second interrupt. That will reset all measurements and flag that no transmitter is attached.

The only other point of interest is the definition of the protocols used to interface to FMS/PPJOY/PICJOY.

The 0xF0 protocol always sends at 9600 Baud fixed and starts with a Sync Byte which is 0xF0 plus the number of channels being transmitted. The first “channel” is always reserved to flag the status of some keys that were attached to the original PIC interface (see here) . In case of AVRRC, this byte is always Zero. The subsequent bytes map the stick position on each channel to a value between 0x00 and 0xEF. So a 7 channel transmitter would produce: 0xF8 0x00 0x80 0x80 0x80 0x80 0x80 0x80 0x80 0xF8 ….

The 0xFF protocol always sends at 19200 Baud fixed and starts with a Sync Byte which is constant 0xFF plus as many bytes that map the transmitters channels between 0x00 and 0xFE. Example: 0xFF 0x80 0x80 0x80 0x80 0xFF 0x80 would be a 4 channel transmitter with sticks in center position.

All functions of the interface can be controlled from the main menu, which automatically appears after applying power to the application. It initially expects communication at 19200 Baud 8 bits, no parity, one stop bit. Please use a terminal emulation that can understand VT100 control codes.

<D> enters the Diagnostic menu which is described further down
<C> enters the Configuration menu which is described further down
<B> Initiates a boot sequence by executing a direct jump to address 0E00. I have been happy to use Herbert Dingfelders Bootloader (described here),
which allows me to easily upload new versions of the operating software without using the ISP.

<X> and <Y> generate data streams understood by the FMS R/C simulation software and by the PPJOY and PICJOY applications which can be used to map the RC transmitter to a virtual joystick.
mainmenu.jpg

Diagnostic Menu

scope.jpg
A (positive logic) PPM signal, if seen on an oscilloscope looks like this.

As you can see, there is a rather large phase in the signal where it is kept at LOW level. This is called the “Sync Pulse” and indicates that a sequence of pulses indicating the status of the transmitter levers is about to follow. The Sync pulse would be of different length in different transmitters and is about 12 Milliseconds in the HITEC transmitter. It is followed by a rather short positive pulse which is always of constant length, here it is 0.4 Milliseconds long. This little spike is called the Interpulse Gap (IPG). After that, the signal is pulled LOW again and remains there for a time which is dependent on the position of the joystick on the transmitter. In my case, Channel 1 is the rudder and, if fully deflected to the left, yields a pulse length of 0.7mS, if fully deflected to the right of 1.4mS. Then comes another positive IPG and Channel 2 and so forth until all channels have been transmitted and the next Sync pulse can start.
When connecting the transmitter to the AVRRC module, the output of the same can be seen like this:
diag.jpg
As you can see, Channel 1 is in middle position, 3 (throttle in my case) is all the way back and so forth. You can as well see that my transmitter is currently sending negative logic pulses and has seven channels. Depending on the polarity of the IPG pulses, the pulse train seen on the above oscillogram would be called a POSITIVE logic PPM pulse as its IPG spikes are pointing upward. Were the oscillogram turned upside down, actually, mirrored vertically, it would be regarded using NEGATIVE logic as its IPG pulses point downward.
config.jpg

Configuration menu

The configuration page is used to set up the working parameters of the application.

<A> Can be used to configure the interface to automatically start to produce the required interface protocol stream if no activity can be registered on the main menu within 20 seconds after startup. Either 9K6 or 19K protocol streams can be aborted by sending the ESC character through the serial line to the interface.

<C> Enters a calibration page in which the application measures maximum and minimum pulselengths for the connected transmitter by requesting the user to shift the sticks to the minimum and maximum positions.

<B> is used to set the baudrate at which the regular serial communications (the menu) takes place. This can be either 19200 or 9600 Baud and should be selected to be at the same baudrate than the most commonly used protocol stream to allow interrupting the same without extensive switching of the baudrates in the terminal program..

All other options in the Configuration menu should be self explanatory.

Potential for further development

As initially mentioned, due to the low cost of components (3 EUR) and Interface (10 EUR), the entire interface could be built into the RC transmitter. Now, instead of connecting the input to the trainer signal only, it should be possible to actually break the PPM stream of the digital transmitter logic to the HF stage and insert the AVRRC circuit. As the current code only occupies less than 40% of the ATMEGA8’s memory, additional functions could be easily integrated that can be configured via an attached PC like:

• Positive/Negative logic conversion
• Mixers
• Exponential servo travel
• Remapping of channels
• Inserting of more (like in a nautic module) channels
• Changing channel direction
• Battery monitoring
• Timer
• Multiple Setups (the chip has a large EEPROM)

Using such features, any outdated FM radio could be easily converted to a modern computer radio at minimal cost! 
In case you have more ideas and want to develop the code any further, kindly let me know of your modifications so I can incorporate them into the published code.