[ Up ]
There are many references on the web for reading a single servo channel. These approaches can easily be extended to read eight channels from older FM radio systems, but it is considerably more difficult to accurately read all eight servo channels from a modern PCM receiver:
On older RC systems, the transmitter modulates a repetitive stream of pulses, and the receiver just demodulates the pulse stream. The pulses are sent for sequentially higher channel numbers, with a few hundred uSecs between pulses, and finally a several mSec pause after the last channel had been sent. I'm not a digital logic guru, but I think the receiver is fairly dumb, using a counter and a decoder to route each successive pulse to the appropriate servo pin, resetting the counter during the repetitive gap in the pulse stream.
With a radio system like this, it would be easy to decode the output from the receiver using even a single pin on the microcontroller, because you can safely assume that there will never be two channels pulsing at the same time. Just wire all receiver channels to the one pin (use diodes to prevent feeding the pulse from one channel into another receiver output, just in case the receiver has push-pull outputs). Better yet, open up the receiver and get the raw demodulated pulse stream, avoiding the need for the diodes.
Newer PCM radios digitally encode data from the transmitter, sending not only the current servo position but also fail-safe and some sort of error detection coding(ie parity/checksum/crc). Instead of being a dumb pulse demodulating widget, the receiver is actually a microcontroller. It stores failsafe info for possible future need, verifies that the incoming data is valid, and then produces output pulses for all channels. What makes it tricky is that the receiver's microcontroller may well send two pulses simultaneously. My radio is a Futaba PCM 1024 (50MHz) unit, and it sends the channel pulses two at a time. I suspect this is done so that servoes can be updated more frequently, which increases effective torque. The following graphic illustrates the timing for my radio:
I observed this pattern of channel pulses by connecting one and then more servo signals to my oscilloscope, using diodes to prevent feeding noise back into the receiver. Obviously, if I ever change brand/model of radio, I will need to repeat this exercise to see how the servo pulses are sent and if need be, adjust my PIC program code appropriately.
The abbreviated algorithm: On the servo input board, all eight channels go to a single 8-bit port, PORTB. To get good timing resolution, PORTB is scanned for a non-zero value. As soon as the port goes non-zero, a 16-bit free-running timer (TMR1) is cleared. I then scan for up to three more changes until the port returns to zero. Whenever PORTB changes, a snapshot of the port and of the timer is stored. Once PORTB goes back to zero, I know I am in at least a 300 uSec gap, and use that time to examine the snapshot data, figure out what servo channel(s) was just read, and calculate the length of the pulse(s). If the channel(s) just read are CH3/4 or CH7/8, I know I am in a 3mSec gap, and have time to write results to the shared FRAM memory ( it takes nearly 1 mSec to complete that transaction ).
Obviously, the algorithm is a little more complicated than stated above, because it needs to detect and handle missing signals, glitches, etc.
This page was lasApril 28, 2006.