PDA

View Full Version : RC Input to Propeller



Greg Norton
01-05-2009, 09:25 AM
I have an application where I'd like to receive 3 channels of RC input to the Propeller. My goal is to have 2 channels of directional input (from the right stick of the transmitter), and one on/off type input from one of the switches on the transmitter (normally used for landing gear on an RC plane). These are designated a channels 1,2, and 6 on the RC receiver.

The problem I'm having is with the InputServosRC object from the exchange. I can get the first two channel inputs to the propeller to work fine and show inputs from the right stick on the transmitter. However, I cannot get the 3rd input to the propeller working unless I connect it to the 3rd channel of the RC receiver.

Here's a diagram to try and clarify the situation. The following DOES work. My example program (see attached) shows expected values. I slightly modified InputServosRC to try and figure out where the problem lies.

RC Receiver Channel => Prop Input Pin
Channel 1 => Pin 8
Channel 2 => Pin 9
Channel 3 => Pin 10

The following DOES NOT work.

RC Receiver Channel => Prop Input Pin
Channel 1 => Pin 8
Channel 2 => Pin 9
Channel 6 => Pin 10

When I try the failing case, my program shows all 0 values, including the status value. I'm not even sure how this is possible. I have examined the output of the RC receiver channel 6 and it shows what I expect. The pulse width is 1.0 - 2.0 ms depending on the position of the switch. My examination of InputServosRC does not lead me to believe there is any requirement to use sequential channels from the RC receiver, but this seems to be the case so far.

Anyone have a suggestion on this?

Thanks.
Greg

hover1
01-06-2009, 10:45 AM
Greg,

What transmitter and receiver are you using? Probably does not make a difference but would be nice to know. I can try to set up same senario on my Hitec Optic 6 Xmiter and Hitec Micro 05S receiver and let you know what happens.

Jim

StefanL38
01-06-2009, 04:58 PM
Hello Greg,

the doc of the InputServosRC_v1.0.spin-files says

....
In order for a series
of pulses to be considered valid, every channel starting at 'FirstPin' and
ending at 'FirstPin' + 'Total' must receive a valid pulse, and be in sequential
order. If any channels from the radio receiver to the Propeller are
disconnected, or connected out of order, no pulse sequences will be considered
valid.....

So I think this is what's happening.

if there is a time-gap between the pulse for channel 2 and channel 6
(because inbetween the pulses for channel 3-5 are sended) the calculation of the pulse-length is out of range

To handle this you have to modify the object that every channel has it's own variables for the snapshot of cnt
for the rising edge. The falling edge is the actual value of cnt itself

The driver as it is uses the ONE variable "LastCnt" for the snapshot of the rising edge.

best regards

Stefan

Joel Rosenzweig
01-07-2009, 02:05 AM
An elegant solution, if you can afford the cogs, is to dedicate a single cog to each of the input signals. This offers a completely bullet proof, no compromises, signal aquisition system. The ability to dedicate a cog to an input signal is the reason I switched over to the Prop in the first place. I was building a device to control servos on a model helicopter, and the parallel architecture of the Prop is exactly the right tool for the job in this case.

Joel-

shanghai_fool
01-07-2009, 03:57 AM
Actually, there are 2 counters for each cog so you only need half as many. Except in cases where more than 1 pulse occurs at the same time ( usually· 8+ channel systems), you should be able to do it with 1 cog and 2 counters but you would have to sequence the input pins. Different systems output the channels in different sequences so you would need to know the order. I will be doing this for my Futaba 9C later.

Donald

Joel Rosenzweig
01-07-2009, 05:35 AM
Actually, there are 2 counters for each cog so you only need half as many.· Except in cases where more than 1 pulse occurs at the same time
That's the reason why you would need to dedicate a cog to the each input.· If you want a no compromises robust solution, then it doesn't help if you have two counters per cog, because the receiver may be of the type that outputs two signals at the same time.

There's another glitch.· In my case, I was using gyroscopes in line with the RX outputs, and the output from the gyroscopes were not perfectly periodic even if the receiver was.· Therefore, at any given instant, the signals could have one timing relationship where the signals do not overlap and another cycle at some future time the signals could overlap.

Different systems output the channels in different sequences so you would need to know the order.
If you already know exactly what the input will look like, then you can optimize for that.· If you're trying to make a product that works with everything available,·then you have to design it to be more robust.· In my case, I was making a product that was meant to interface to everyone's receiver, not just the one I had on my shelf.

I don't know if Greg needs anything this robust or not.· I decided to mention it to help others who might pursue building a device that needs a bullet proof front end such as this.· It all depends on what you're doing.· Some people might choose to simply filter the glitches out with software.· I'd prefer to eliminate the glitch at the source.

Joel-


·

shanghai_fool
01-07-2009, 05:40 AM
One cog (2 counters) can operate at the same time. They are completely independant.

Greg Norton
01-07-2009, 06:21 AM
Thanks to all who responded.

I found out through experimentation what StefanL38 pointed out from the comments (should have read them more closelyhttp://forums.parallax.com/images/smilies/nono.gif ).· Looking at waveforms on the outputs of the receiver showed that the sequential channels share a falling/rising edge.· That is, the falling edge of the channel 1 pulse is the same as the rising of the channel 2 pulse.· The code was designed for this and was only looking for falling edges of pulses after the initial rising edge from channel 1.· I modified the code to look for a rising edge on each of the additional channels and then do the measurement based on that.· This could be causing me to miss the rising edge of channel 2, but then channel 2·will be·measured·on the next set of pulses from the receiver.· I'll have to check this out when I get home.· My application is a fairly slow moving robot so I can afford the degraded refresh rate that results.

Greg

JasonDorie
01-07-2009, 06:50 AM
Greg - it's possible to sample 8 channels with arbitrary order (even simultaneous) and get decent precision.· J.A.B. posted code to do it quite a while ago here:

http://forums.parallax.com/showthread.php?p=690465

His comments imply that it gets 1uS resolution, but it's actually 1/4 that (he's assuming 1 instruction per clock, but it's every 4 clocks), so you get about 250 steps over the 1ms range for all 8 inputs.

That said, if you modify the code to handle only 4 inputs, you can double the precision, and run two cogs to sample 4 pins each.· My quad-rotor is using this code modified to handle 6 inputs (gets me a little more precision) and it's great.
·

shanghai_fool
01-19-2009, 06:01 PM
I have finally gotten around to do some testing with my Futaba T9CHP 9 channel PCM system. I have done a demo in spin to test the accuracy and viability of using a single cog with the 2 counters. It works and gives 12.5 ns accuracy but I am just using the integer microseconds at this time. It does work in spin but really need to be done in assembly as there are only about 200us between pulse pairs. Also, using the wait peq, there is the possibily of system hang but that can be dealt with in the main routine later. Lots more to do but its a beginning. The terminal screen shot is attached.


{
* PCM Receiver Test
* The receiver outputs (up to 10) are connected to P0..P9 through ~4.7k resistors.
* Donald Nash 1/19/2009
*
*
}
CON

_clkmode = xtal1 + pll16x ' System clock → 80 MHz
_xinfreq = 5_000_000
OBJ

text : "PC_Interface"
VAR
long tmr1, tmr2
long prr, mode
long chan
PUB Main
text.start(31,30)
text.out(0) ' clear screen
'WAITPEQ (State, Mask, Port ) for my own reference
waitpeq(0,1,0) 'wait for all pulses off
waitcnt(cnt + clkfreq) 'delay for display
text.str(string("Receiver test .. Waiting for input",13))
waitpeq(1,1,0) 'wait for chan 1 on
tmr1 := cnt 'start counter
waitpeq(0,1,0) 'wait for chan 1 off
tmr2 := cnt
text.str(string("Received chan. 1 "))
text.dec((tmr2 - tmr1)/80) ' time in us
text.str(string(" us",13))
waitpeq(1,1,0) 'wait for chan 1 on
prr := cnt - tmr1
text.str(string("Receiver period = "))
text.dec(prr/80)
text.str(string(" us",13))
text.str(string("Mode is "))
waitpeq(0,1,0) 'wait for all pulses off
waitpeq(1,1,0) 'wait for chan 1 on
mode := ina & $3FF 'test number of simultaneous pulses
if mode >1
text.str(string("PCM",13))
text.bin(mode,10) 'show binary mask
text.out(" ")
text.dec(mode) 'show decimal mask
text.out(13)
waitpeq(0,$3FF,0) 'wait for all off
waitpne(0,$3FF,0) 'wait for next set
chan := ina & $3FF 'save it
text.bin(chan,10) 'show binary mask
text.out(" ")
text.dec(chan) 'show decimal mask
text.out(13)
waitpeq(0,$3FF,0) 'wait for all off
waitpne(0,$3FF,0) 'wait for next set
chan := ina & $3FF 'save it
text.bin(chan,10) 'show binary mask
text.out(" ")
text.dec(chan) 'show decimal mask
text.out(13)
waitpeq(0,$3FF,0) 'wait for all off
waitpne(0,$3FF,0) 'wait for next set
chan := ina & $3FF 'save it
text.bin(chan,10) 'show binary mask
text.out(" ")
text.dec(chan) 'show decimal mask
text.out(13)
waitpeq(0,$3FF,0) 'wait for all off
waitpne(0,$3FF,0) 'wait for next set
chan := ina & $3FF 'save it
text.bin(chan,10) 'show binary mask
text.out(" ")
text.dec(chan) 'show decimal mask
text.out(13)
frqa := frqb := 1
ctra[30..26] := %01000 ' Set ctra to POS mode
ctrb[30..26] := %01000 ' Set ctrb to POS mode
' This is main routine for PCM
' there is only about 300us from end of first pair to
' start of next pair. Need to stash phsa &phsb to channel
' values and then change counter input pins and zero counters
repeat
'chan 1&2
ctra[5..0] := 0 ' Set ctra's APIN
ctrb[5..0] := 1 ' Set ctra's APIN
'waitpeq(%0000000011,%0000000011,0)
waitpeq(%0000000000,%0000000011,0)
phsa := phsb := 0 ' zero counters
waitpeq(%0000000011,%0000000011,0) ' wait for pulse
waitpeq(%0000000000,%0000000011,0) ' wait for pulse end
setpos(0,9)
text.dec(phsa /80 )
setpos(0,10)
text.dec(phsb /80 )

'chan 7$8
ctra[5..0] := 6 ' Set ctra's APIN
ctrb[5..0] := 7 ' Set ctra's APIN
'waitpeq(%0011000000,%0011000000,0)
waitpeq(%0000000000,%0011000000,0)
phsa := phsb := 0 ' zero counters
waitpeq(%0011000000,%0011000000,0)
waitpeq(%0000000000,%0011000000,0)
setpos(10,11)
text.dec(phsa /80 )
setpos(10,12)
text.dec(phsb /80 )

'chan 3&4
ctra[5..0] := 2 ' Set ctra's APIN
ctrb[5..0] := 3 ' Set ctra's APIN
'waitpeq(%0000001100,%0000001100,0)
waitpeq(%0000000000,%0000001100,0)
phsa := phsb := 0 ' zero counters
waitpeq(%0000001100,%0000001100,0)
waitpeq(%0000000000,%0000001100,0)
setpos(0,11)
text.dec(phsa /80 )
setpos(0,12)
text.dec(phsb /80 )

'chan 9
ctra[5..0] := 8 ' Set ctra's APIN
'waitpeq(%0100000000,%0100000000,0)
waitpeq(%0000000000,%0100000000,0)
phsa := phsb := 0 ' zero counters
waitpeq(%0100000000,%0100000000,0)
waitpeq(%0000000000,%0100000000,0)
setpos(20,9)
text.dec(phsa /80 )

'chan 5&6
ctra[5..0] := 4 ' Set ctra's APIN
ctrb[5..0] := 5 ' Set ctra's APIN
'waitpeq(%0000110000,%0000110000,0)
waitpeq(%0000000000,%0000110000,0)
phsa := phsb := 0 ' zero counters
waitpeq(%0000110000,%0000110000,0)
waitpeq(%0000000000,%0000110000,0)
setpos(10,9)
text.dec(phsa /80 )
setpos(10,10)
text.dec(phsb /80 )

' code for PPM receivers
else
text.str(string("PPM",13))
repeat 'stub

PRI setpos(px, py)
text.out(10)
text.out(px)
text.out(11)
text.out(py)


Donald