Reading PWM data from RC Radio
sreid55
Posts: 3
Hi all -
I'm trying to read four PWM values from an R/C radio reciever, and I've come up with the code below adapted from the BS2_functions.spin PULSIN code.· It generally works, but the data I get from it is rather jittery.· Also, rapid changes in one channel will erroneously impact the results of another channel.· I've ruled out errors in the RC hardware; servos connected to the channels are stable and clean.
Any ideas?
Thanks
Scott
I'm trying to read four PWM values from an R/C radio reciever, and I've come up with the code below adapted from the BS2_functions.spin PULSIN code.· It generally works, but the data I get from it is rather jittery.· Also, rapid changes in one channel will erroneously impact the results of another channel.· I've ruled out errors in the RC hardware; servos connected to the channels are stable and clean.
Any ideas?
Thanks
Scott
{ ******************************************** READSERVO - Read R/C PCM Input Pulses ******************************************** } CON PINROLL = 3 PINPITCH = 4 PINTHR = 5 PINYAW = 6 PINMASKROLL = %00001000 PINMASKPITCH = %00010000 PINMASKTHR = %00100000 PINMASKYAW = %01000000 VAR long stack[noparse][[/noparse]26] word roll,pitch,thr,yaw PUB start dira[noparse][[/noparse]PINROLL]~ dira[noparse][[/noparse]PINPITCH]~ dira[noparse][[/noparse]PINTHR]~ dira[noparse][[/noparse]PINYAW]~ cognew(rsmonitor,@stack) PUB readservo(channel) | i {{ readservo(channel): 1 = roll 2 = pitch 3 = throttle 4 = yaw }} if channel==1 i := roll elseif channel==2 i := pitch elseif channel==3 i := thr else i := yaw return i PRI rsmonitor '' constantly poll input channels from RC radio and update variables repeat ctra := 0 ctra := (%10100 << 26 ) | (%001 << 23) | (0 << 9) | (PINTHR) frqa := 1 waitpne(0,PINMASKTHR,0) phsa := 0 waitpeq(0,PINMASKTHR,0) waitpne(0,PINMASKTHR,0) thr := (phsa ~> 8) ' divide to get result in desired range ctra := 0 ctra := (%10100 << 26 ) | (%001 << 23) | (0 << 9) | (PINROLL) frqa := 1 waitpne(0,PINMASKROLL,0) phsa := 0 waitpeq(0,PINMASKROLL,0) waitpne(0,PINMASKROLL,0) roll := (phsa ~> 8) ctra := 0 ctra := (%10100 << 26 ) | (%001 << 23) | (0 << 9) | (PINPITCH) frqa := 1 waitpne(0,PINMASKPITCH,0) phsa := 0 waitpeq(0,PINMASKPITCH,0) waitpne(0,PINMASKPITCH,0) pitch := (phsa ~> 8) ctra := 0 ctra := (%10100 << 26 ) | (%001 << 23) | (0 << 9) | (PINYAW) frqa := 1 waitpne(0,PINMASKYAW,0) phsa := 0 waitpeq(0,PINMASKYAW,0) waitpne(0,PINMASKYAW,0) yaw := (phsa ~> 8)
Comments
This was posted some time ago... it may help.
Cheers,
Shane.
The structure of your algorithm indicates that you use negative logic;
if otherwise you have to invert the waits and use POS detection mode.
And don't set the PLL, it has no effect, but is confusing.
Your code looks much different than I would code, but that is a feature, not a bug
Edit/BTW: A pulse of 1 to 2 ms will have 160,000 counts, divided by 256 gives you an result of 320 to 640. Is that what yopu want?
@Shane: It's a different program you quote, reading the "raw" RC data, where all (eight) channels are still interleaved.
Post Edited (deSilva) : 2/16/2008 9:09:09 AM GMT
Post Edited (deSilva) : 2/16/2008 9:38:07 AM GMT
scrambled by the forum software :-(
But thank you for the hint!
And 0..3 rather than 1..4
I grew up with FORTRAN, where we started things with "One" and still try to avoid this superoptimal C-thinking.
I just WASTE the first word of RESULTS
Nevertheless there was a real bug in it (|<logPin rather than |<truePin)
Post Edited (deSilva) : 2/16/2008 9:39:27 AM GMT
Scott
I could differ with you slightly but who would care? BUT
Integration is more fun than perspiration[noparse]:)[/noparse] AND
At the top level, the Prop is all about object integration, no need to feel a slight when you use the platform the way it was intended[noparse]:)[/noparse]
Rich
is the root of successful software engineering. This is not only a belief of SWE managers
but seems to be really true
Due to the memory restrictions true module re-use was not too popular among microcontroller
developers, at most they recycled their source code, and especially the algorithmically more demanding
pieces (square root, filters, floating point as a whole,..) You see it expands.... The current development
going from 128 kB to 256 kB in micro controller program memory has its root mainly in more advanced
HLL "re-use thinking". But this is around 10 times the program memory we have available in the Prop....
So much depends on market exceptance! For years the host of MC developers AND their managers
refused to even think of using a 32 bit processor despite the obvious advantages even for smaller
projects. Reasons they gave were mostly pretext to hide their basic conservative adjustment.
Unbeatable however was always the recurrent cost argument...
ARM producing companies now have earned enough money they could start very aggressive
marketing campaigns, selling ARM7 variants around $1. This can change the mind setting..
Note however that ARM7 is a nearly out-dated concept with many weaknesses which are addressed
by a newer technology. However basically a COG is quite similar to an ARM7 chip.
· I have attached some code that I believe does exactly what you want.· It's a derivative of the code that shane posted.· It's not very elegent (it's my first foray into assembly) but should work for you.· When channels slip (due to a missed pulse edge), it resorts·the data·such that your channels do not get re-ordered. (It would be very bad if mid-flight your elevator and rudder signals were switched!!!)
·I use this to read my 3 channel reciever (propeller-motor speed, elevator, and rudder),·modulate on one·wire connected·to pin 5 of my Propeller chip with good success.
·Please let me know if you have any questions.
-JasonE
I can't say that I've ever seen that. I have a regular Futaba 7 channel receiver with 7 outputs, four are connected to four propeller pins
Scott
I'm using a fairly low-end receiver/transmitter - it's what came with my HobbyZone supercub. The signal I'm describing is the actual (raw) signal that gets modulated to the carrier frequency. Somewhere on your reciever it decodes the pulse train and breaks out the channels to different ports for you. I probed around with my usb-oscilloscope until I found a signal I could decipher. I had to do this because the supercub uses 5-wire servos instead of the standard 3-wire servos. The control signal from a 5-wire servo can not be easily interpreted, as the 5 wire servo is part of a feedback loop with the receiver.
If I want to increase the functionality of my transmitter and use some of the (currently) untapped channels, how could I go about that? Can you point me towards any good websites or reference information?
Thanks,
Jason
But you need a 8ch transmitter to be able to control all 8 channels. Transmitters with less then 8 ch. just send a blank signal on the unused channels in the ppm signal. I guess you might be able to hack more channels for some transmitters, but there is no sure method.
Edit: I just remembered that you can use the trainer port on some transmitters to insert data for the missing channels. Don't remember which ones had the possibility, but some searching should give you an answer.
Post Edited (J.A.B.) : 2/20/2008 6:44:28 PM GMT
"If I want to increase the functionality of my transmitter and use some of the (currently) untapped channels, how could I go about that?"
If you have at least two channels that are not used, you can multiplex the channel functions by setting one Channel to a "specific" locations or value, and then using the remaining channel for your data.
For example, You can create 4 Auxiliary Channels from 2 Channels if you take Ch1 and divide it so that it has 4 equal parts (250uS separation) ranging...
1000us to 1250us ... 1125us Aux1
1250us to 1500us ... 1375us Aux2
1500us to 1750us ... 1625us Aux3
1750us to 2000us ... 1875us Aux4
...and send your data on Ch2 so that it corresponds to the correct Aux position.
Note:
Sending data this way will require adjustments to the transmitter, and should be done at your own risk.
I have successfully done this with a transmitter to add a 16-key keypad (one channel for rows, another channel for columns) similar to above.
No software required on the transmitter, just weighted resistor values that created enough discrepancy on the receiver end to distinguish them.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
Thank you for your input; I think I understand what you were trying to convey to me, but let me ask a slightly different question:
Here is the pulse train my transmitter outputs: (p = hi pulse, d = low delay)
________________----___----___----___---________________----___----___----___---
(reset) p0 d0 p1 d1 p2 d2 p3 (reset) p0 d0 p1 d1 p2 d2 p3
where the data (channels 1,2, and 3) are described by length of the delays (d0, d1, d2, 1200us +/- 320us), currently all the hi-pulses are permanently fixed at 250us. I would think the easiest way to output more channels would be for me to change the length of the hi-pulses. Do you know of a way to intercept and change those pulses? I suppose that would require software and more integration work with the transmitter?
Thanks,
Jason
________________----___----___----___---________________----___----___----___---
....(reset)............. p0..d0..p1..d1..p2.d2.p3.....(reset).............p0..d0..p1..d1..p2.d2..p3
"I would think the easiest way to output more channels would be for me to change the length of the hi-pulses. Do you know of a way to intercept and change those pulses?" ... sorry not easily.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.