DIY RC System.‎ > ‎

RC System Firmware v.0.1.

This page is obsolete.
A more recent version of the firmware has since bee written.
You can find the documentation page for the latest version of the firmware here:
RC System Firmware.

The firmware on the RC system is an ongoing project.
What is presented here is Version 1. This has much of the functionality of a conventional RC system and does not yet have the ability to receive data from the aircraft.
This will be added to in future firmware versions with the priority being given to 2 way data transfer.

The ground station will be referred to as the "Controller" and the aircraft mounted board which will be referred to as the "Receiver".
As this is a 2 way radio system the term "Receiver" is not 100% correct as both stations can receive a signal. It does however match conventional RC terminology though and from the users perspective the name fits.


The firmware operates on a 20ms loop to match the servos update time. This loop is controlled using the 8 bit Timer0 on the AVR (with the prescaler set to 1024) .
To make sure both the Controller and Receiver are at the same stage in the firmware loop the Controller transmits the current value of timer0 with every packet.
If the Receiver misses a packet it can continue running on it's own value in timer0.
If on the other hand it receives a packet it updates it's own timer with the value received from the Controller.

Providing the clocks on the Controller and Receiver have correctly converged the main firmware loop should be at the same position on both nodes.
Tasks are done in order starting with the most important and moving on to continually less important tasks. Each task is only completed if there are enough clock cycles left before the end of the 20ms loop.

The main program loop goes like this:
  1. The Controller sets the RF module to receive.
  2. Read the user interface device on the Controller node. (currently using a PS2 controller.)
    The Receiver assembles and transmits data packet to Controller. Retry  the transmission until a successful ACK is received or the alloted time for the PS2 read has passed.
  3. The Controller checks the RF module for received data and stores data if applicable.
    The Receiver puts it's RF module in receive mode.
  4. The Controller assembles and transmits data packet to the Receiver. Retry  the transmission until a successful ACK is received or the end of the 20ms loop has been reached.
    The Receiver waits here until a packet has been received or the end of the 20ms loop has been reached.
  5. If data packet was received the Receiver sets servo positions accordingly.
  6. If spare clock cycles are left (there should be lots) the Controller and Receiver can perform any lower priority tasks here.

RF Transmission.

RF Module.

The radio Unigen UGWJ4US modules used in this project have already been discussed in the RC System Hardware section. As they are based on the Cypress CYRF6936 chipset the firmware described here should work on any CYRF6936 based module with a little modification.

It is worth mentioning the Unigen UGWJ4US datasheet is basically just a copy of the Cypress CYRF6936 datasheet. Read this datasheet all the way through thoroughly before you start.
It is also worth noting that the Unigen datasheet does not contain all the information you need to make the module work.
The PACTL pin on the UGWJ module appears to control the TX amplifier and as such should always be disabled when receiving. This is done automatically by the default setting of the CYRF6936 PACTL register.
When transmitting it can be enabled or disabled depending on the desired power output.
The PACTLn pin on the UGWJ module appears to control the RX amplifier. As such it should always be enabled when receiving and disabled when transmitting.
After some initial confusion about the function of the UGWJ4US PACTLn pin it turns out this is controlled by the CYRF6936 XTAL_CTRL register, Bits 7,6.
Please note the PACTL pin on the UGWJ module is different to the PACTL pin and register on the Cypress CYRF6936 chip.

Little other online information is available for working with the Unigen modules so be prepaired for lots of difficult debugging and when all else fails a bit of trial and error. (Please send links to other CYRF6936 resources if you have them.)

Transmission Mode.

The CYRF6936 has several different transmission modes. In this version of the firmware the controller will issue 8DR mode data packets (discussed in the datasheet). This mode allows 250 kbps data transfer with a 16bit CRC (Cyclic Redundancy Check) making false packet detection very unlikely and allowing multiple systems to be used on the same channel.

The simplest implementation would be to use the CYRF6936s Auto Transaction Sequencer (ATS) mode so the receiver automatically replies with an ACKnolage packet in reply to a TX packet from the Controller.
This would greatly simplify RF communication but unfortunately ATS mode cannot be achieved due to the requirement of the Unigen module's PACTLn pin to be controlled in firmware.

Instead we must disable ATS and find other methods to ensure a transmission gets through.

At present i'm not sure if ATS works with the Unigen UGWJ4US or not.
It is better not to use it though as other RF modules with similar I/O pin pattern cannot use it so disabling ATS adds flexibility.

The current firmware transmits the same data multiple times, only updating the time stamp between each transmission. The receiving end listens until it gets a valid transmission then continues with it's program to process the data.
Any further repeated transmissions are ignored by the receiving node.

Packet Format.

The CYRF6936 only has a packet buffer of 16bytes. It is possible to send packets longer than this but the TX buffer must be loaded as a transmission occurs and the RX buffer must be emptied as a receive occurs greatly increasing the complexity of the receive code.
For this reason the maximum size of any packet will be 16 bytes. At this length no special attention need be taken to timing when a packet comes in. The microcontroller can just read the RX buffer any time after the packet arrives.
The first byte of any packet will be reserved as a Packet Type value. Only one packet is defined at this time:
Packet Type 1:
 Byte Name Description
 0   PacketType
 Only 1 packet type has been defined so far.
 1  TCNT(0) Timer value at time of TX. Used to syncronise clocks on both nodes.
 2  chan_num Channel counter. Used to synchronise the counters that track when a channel change should occur.
 4  tx_chan[0] First data byte.
 5  tx_chan[1] Second data byte.
 6  tx_chan[2] Third data byte.
 7  tx_chan[3] etc...
 8  tx_chan[4] 
 9  tx_chan[5] 
 10  tx_chan[6] 
 11  tx_chan[7] 
 12  tx_chan[8] 
 13  tx_chan[9] 
 14  tx_chan[0x0A]
 15  tx_chan[0x0B] 

Packet Type 2 will probably have the same format but allow for another 12 data values. ie. tx_chan[0x0C ] to tx_chan[0x17].

Error Checking.

One of the advantages of using a chip like the CYRF6936 is it already has 16bit CRC checks built in so any received packet without an error flag is presumed good. It is theoretically possible to get an errored packet pass the checks but this will happen for a tiny percentage of packets so can be ignored as it will have little effect on performance.

User Interface.

PS2 Controller.

For this prototype a Sony PS2 controller is being used as an input device. While it may not be to everybody's taste it does provide a nice ergonomic easy to interface way to input data at the Controller end.
Rather than go into too much detail on how to connect a PS2 controller to an AVR here is the link to how i did it on an earlier prototype:

Other UI Options.

With 6 spare analogue inputs on the AVR it would be trivial to add more conventional joystick controllers.
Many conventional RC Controllers have trainer ports. It may be possible to provide input from one of these as well. (Suggestions on the viability of this option welcome.)
I will also be adding USB input so the device can be controlled by a PC or laptop.


Controller Mixing.

Conventional RC systems control the mixing of control channels on the Controller. The servo positions then transmitted and acted on by the Receiver.
This firmware version does not yet allow for this. The controller's joystick and button positions are transmitted "at is" and the mixing is done at the Receiver end.
Future versions of the firmware will allow for mixing of channels at the Controller end as well as at the Receiver end.

Receiver Mixing.

At present all mixing is done on the Receiver. Control positions are received over the RF link and hard coded rules in the Receiver's firmware work out servo position.
Settings can be saved to EEPROM according to button presses and included in the mixing rules.
Future versions of the firmware will allow sensors attached to analogue inputs and the i2c bus to be read and included in the mixing rules.
Future versions of the firmware will allow mixing rules to be uploaded from a PC without having to modify the firmware.

With such complex mixing options possible at the receiver end full UAV operation should be possible eventually.

Thanks for the Code Guys!

This project could not have been made without numerous open source projects involved in the AVR_GNU and AVR_LIBC projects.
Of particular help were the numerous helpful PS2 hacking pages online, some of which i link to on
Also a lot of help on RC aircraft in general were the archives of
And of continuous inspiration in all things automation related:
Thanks Guys!

About the Licence.

My work, as i have already covered in the previous section, is based partly on the work of others.
Any changes i have made or code i have written are licensed under the GNU General Public License (GPL). The others work, are licensed under the GNU General Public License (GPL).

A copy of the GPL is included in License.txt.


The code is written for the AVR atMega2561 and will compile under AVR GCC.

Please note, i am not a professional programmer. This will show in the following section.
The code also has not yet been tidied up and properly commented. This will also show in the following section. I'm only posting it here because i have been asked for it.
This an OpenSource project so if any one is willing to colaborate on this code please contact me.

See the Downloads section for the latest firmware version.

<<  RC System Hardware.
Duncan Law,
22 May 2010, 06:24