R/C decoder or BlueTooth game controller?
R/C decoder or BlueTooth game controller?
Has anyone written a library to decode the pulse train from a standard R/C receiver? I want to set up some kind of simple tele-operation interface for a mostly-autonomous robot. So a simple solution would be to decode the pulse train from an R/C receiver. Ideally, picking up the signal before it is demultiplexed into servo commands. Another option would be enough Bluetooth to deal with a PS/3 game controller or Wii controller, but I'm pretty sure neither of these are Bluetooth SPP, so the simple Bluetooth add-on boards aren't going to help much.
Re: R/C decoder or BlueTooth game controller?
I know of no such library in MicroPython, but it would surely be fun to write one using the information from http://www.sbprojects.com/knowledge/ir/index.php
Re: R/C decoder or BlueTooth game controller?
I've used the Input Capture module to measure the width of a pulse from a single channel.
https://github.com/dhylands/upy-example ... ic_test.py
I've done the RC decoding thing in C on an AVR.
https://github.com/dhylands/robostix/bl ... /RCInput.c
https://github.com/dhylands/robostix/bl ... /RC-Test.c
For parsing the combined stream (where one signal contains all of the channels), I think you could easily do it using input capture just on rising edges and use that to determine the pulse widths.
https://github.com/dhylands/upy-example ... ic_test.py
I've done the RC decoding thing in C on an AVR.
https://github.com/dhylands/robostix/bl ... /RCInput.c
https://github.com/dhylands/robostix/bl ... /RC-Test.c
For parsing the combined stream (where one signal contains all of the channels), I think you could easily do it using input capture just on rising edges and use that to determine the pulse widths.
Re: R/C decoder or BlueTooth game controller?
Come to think of it, if you have room for a bluetooth board, you might as well fit a Pro Mini board there, with an IR receiver and a library like https://github.com/NicoHood/IRLremote, sending the decoded commands to your board with I2C and an interrupt pin, or something similar.
Re: R/C decoder or BlueTooth game controller?
Thanks for the reference code. There is no doubt an Arduino library, too, if I went googling for it.
So I guess since the IC timer callback runs at interrupt priority it should give reasonably accurate timings. 4 uSec accuracy would be 1 bit in an 8 bit int, if memory serves. (1mSec / 250) I was imagining that it would require a C extension, but it is probably doable as pure Python.
@dhylands I can easily try out your Python code with a live servo, so that is the next step, I think.
So I guess since the IC timer callback runs at interrupt priority it should give reasonably accurate timings. 4 uSec accuracy would be 1 bit in an 8 bit int, if memory serves. (1mSec / 250) I was imagining that it would require a C extension, but it is probably doable as pure Python.
@dhylands I can easily try out your Python code with a live servo, so that is the next step, I think.
Re: R/C decoder or BlueTooth game controller?
Yeah input capture will capture at the resolution of the timer being run. So in the examples I posted, I was running the timer at 1 MHz, so you get 1 usec resolution.
Since the RC pulses are typically 1-2msec long, the edges are far enough apart that you can deal with them in python. Even if the python is delayed by 100 usec, the timer will still have captured the timer counter back when the edge actually occurred.
I did a logic analyzer capture of the ic_test.py signals that shows the servo signal and the debug signal:
https://github.com/dhylands/upy-example ... c_test.png
Since the RC pulses are typically 1-2msec long, the edges are far enough apart that you can deal with them in python. Even if the python is delayed by 100 usec, the timer will still have captured the timer counter back when the edge actually occurred.
I did a logic analyzer capture of the ic_test.py signals that shows the servo signal and the debug signal:
https://github.com/dhylands/upy-example ... c_test.png
Re: R/C decoder or BlueTooth game controller?
So an R/C PPM decoder was actually quick and easy to get going. I'm using a Spektrum AR7700 receiver which has direct PPM out, but on many if not most R/C receivers it is easy to find the PPM signal and bring it out. I tested this code with a cheap 5 channel transmitter. (And by tested, I mean after 10 minutes of playing around randomly, it seems to work...YMMV)
The module:
A simple test:
The intent of having one more element in the channel array than there are R/C channels is so that if for some reason it misses a sync pulse or otherwise runs off the end, the last bucket can catch all the noise where it is easy to ignore.
The module:
Code: Select all
from array import array
import pyb
THROTTLE = 0
RUDDER = 1
ELEVATOR = 2
AILERON = 3
GEAR = 4
SYNC_MIN = 3000 # 3 mSec or more indicates next pulse is sync
_prev_t = 0
_next_ch = 0
def init_ppm_decode(timer_num, timer_channel_num, pin, num_rc_channels=8):
global _num_channels
global channel
global _in_comp_channel
_num_channels = num_rc_channels
channel = array('L', [0] * (_num_channels + 1))
timer = pyb.Timer(timer_num, prescaler=83, period=0x0fffffff)
_in_comp_channel = timer.channel(timer_channel_num, pin=pin,
polarity=pyb.Timer.RISING, mode=pyb.Timer.IC)
_in_comp_channel.callback(_ppm_callback)
def _ppm_callback(tim):
global channel
global _next_ch
global _prev_t
t = _in_comp_channel.capture()
delta = t - _prev_t
_prev_t = t
if delta > SYNC_MIN:
_next_ch = 0
else:
channel[_next_ch] = delta
_next_ch = _next_ch + 1 if _next_ch < _num_channels else _next_ch
if __name__ == '__main__':
pass
Code: Select all
import micropython
import pyb
import ppmdecoder as ppm
micropython.alloc_emergency_exception_buf(100)
ppm_input_pin = pyb.Pin('X1', pyb.Pin.IN)
ppm.init_ppm_decode(timer_num=2, timer_channel_num=1, pin=ppm_input_pin)
for i in range(80):
print (ppm.channel[ppm.THROTTLE], ppm.channel[ppm.RUDDER],
ppm.channel[ppm.ELEVATOR], ppm.channel[ppm.AILERON],
ppm.channel[ppm.GEAR])
pyb.delay(1000)
Re: R/C decoder or BlueTooth game controller?
Sorry for my possibly dumb question, but does this mean you can use any or most cheap R/C toy remote control receiver or are only the sophisticated hobby R/C links using that protocol?
Re: R/C decoder or BlueTooth game controller?
Well, the really super-cheap R/C units for low-end toys don't have proportional control. But if the receiver has outputs for driving a standard R/C servo, it is likely to have a PPM signal inside it even if it isn't brought out.
Way back in the 1960's when proportional, multi-channel R/C was created, they did what was simple to do with the parts available. The standard architecture is to feed the pulses coming out of the radio detector to the clock input of an 8-bit shift register. If you contrive to load a '1' into the shift register at the start (and only at the start) of every frame, and shift that '1' on every received pulse, then the 8 outputs of the shift register can directly drive the 8 servos. So if you crack open an R/C receiver and see a shift register chip, the clock pin will have the PPM signal on it. The PPM signal usually also goes to the trigger of a one-shot that generates the '1' on start-of-frame.
Now that everyone is goofy for multi-rotor drones, receivers with direct PPM output are more common. If you check out the usual sources of cheap R/C gear you can find some.
Way back in the 1960's when proportional, multi-channel R/C was created, they did what was simple to do with the parts available. The standard architecture is to feed the pulses coming out of the radio detector to the clock input of an 8-bit shift register. If you contrive to load a '1' into the shift register at the start (and only at the start) of every frame, and shift that '1' on every received pulse, then the 8 outputs of the shift register can directly drive the 8 servos. So if you crack open an R/C receiver and see a shift register chip, the clock pin will have the PPM signal on it. The PPM signal usually also goes to the trigger of a one-shot that generates the '1' on start-of-frame.
Now that everyone is goofy for multi-rotor drones, receivers with direct PPM output are more common. If you check out the usual sources of cheap R/C gear you can find some.
Re: R/C decoder or BlueTooth game controller?
I hacked a 2 channel R/C receiver to get at the PPM signal. A typical implementation is that the PPM signal is used as a clock to a shift register and you shift a 1 through the shift register. Each bit of the shift register is used for one channel of control going to an RC Servo.
The VEX receiver directly outputs a PPM signal. It looks like you can get one on eBay for about $35 US. This is a six channel system.
http://www.vexrobotics.com/75mhz.html
The VEX receiver directly outputs a PPM signal. It looks like you can get one on eBay for about $35 US. This is a six channel system.
http://www.vexrobotics.com/75mhz.html