RC Reader, interrupt driven CO-BAP for reading RC receiver

Hi,

As some of you know I’ve choosed to control my LM Phoenix with a RC controller. The main reason for why I choosed RC is probably caused by my some defect LM PS2 controller. My Phoenix are very hard to control with the PS2.

Reading the RC channels from the RC receiver is pretty easy with the pulsin command. Here is a example of the code I used:

[code]Read RC pulses
;
RCInput:

pulsin RCch01,0, pwmInput01
pwmInput01  = (pwmInput01  min RCpwmMIN) max RCpwmMAX

pulsin RCch03,0, pwmInput03
pwmInput03  = (pwmInput03  min RCpwmMIN) max RCpwmMAX	

pulsin RCch05,0, pwmInput05 'There is a 7,5mS gap between ch05 and ch06
Mode1 = False
Mode2 = False
Mode3 = False
if pwmInput05 < 980 then
	Mode1 = True
elseif ((pwmInput05 > 1510) & (pwmInput05 < 1522))
	Mode2 = True
else
	Mode3 = True
endif	
	
pulsin RCch06,0, pwmInput06	

pulsin RCch02,0, pwmInput02
pwmInput02  = (pwmInput02  min RCpwmMIN) max RCpwmMAX	

pulsin RCch04,0, pwmInput04
pwmInput04  = (pwmInput04  min RCpwmMIN) max RCpwmMAX	

return[/code]

Reading all these channels take some valuable time from the BAP code, thats probably the reason for why I can’t match Xan’s awesome speed :wink:

So I’ve been experimenting with using an extra BAP24 for reading the RC channels. This is the code I wrote for the CO-BAP:

[code];RC Reader
;
;Read 6 RC channels continiously
;When receiveing an interrupt pulse on IRQ1 (Pin8) it sends all channels out on P11 via serout (IntHandler)
;
;[CONST]
TRUE con 1
FALSE con 0

;--------------------------------------------------------------------
;[SERIAL CONNECTIONS]
Serial_OUT con P11 ;Output pin on BotBoard

;--------------------------------------------------------------------
;[RC Controller]
RCch01 con P0
RCch02 con P1
RCch03 con P2
RCch04 con P3
RCch05 con P4
RCch06 con P5

RCpwmMAX con 1850
RCpwmMIN con 1150

;--------------------------------------------------------------------
;RC variable
pwmCH01Input var word
pwmCH02Input var word
pwmCH03Input var word
pwmCH04Input var word
pwmCH05Input var word
pwmCH06Input var word

pwmCH01old var word
pwmCH02old var word
pwmCH03old var word
pwmCH04old var word
pwmCH05old var word
pwmCH06old var word

CH01_OK var bit
CH02_OK var bit
CH03_OK var bit
CH04_OK var bit
CH05_OK var bit
CH06_OK var bit

ONINTERRUPT IRQ1INT,IntHandler
PMR1.bit5 = 1 'define as IRQ input pin IRQ1, IRQ1 = pin8
ENABLE IRQ1INT

main:
;Read ch 01:
CH01_OK = FALSE
pulsin RCch01,0, pwmCH01Input
pwmCH01Input = (pwmCH01Input min RCpwmMIN) max RCpwmMAX
CH01_OK = TRUE
pwmCH01old = pwmCH01Input

;Read ch 03:
CH03_OK = FALSE	
pulsin RCch03,0, pwmCH03Input
pwmCH03Input  = (pwmCH03Input  min RCpwmMIN) max RCpwmMAX	
CH03_OK = TRUE
pwmCH03old = pwmCH03Input

;Read ch 05:
CH05_OK = FALSE
pulsin RCch05,0, pwmCH05Input
CH05_OK = TRUE
pwmCH05old = pwmCH05Input

;Read ch 06:
CH06_OK = FALSE
pulsin RCch06,0, pwmCH06Input	
CH06_OK = TRUE
pwmCH06old = pwmCH06Input

;Read ch 02:
CH02_OK = FALSE
pulsin RCch02,0, pwmCH02Input
pwmCH02Input  = (pwmCH02Input  min RCpwmMIN) max RCpwmMAX
CH02_OK = TRUE
pwmCH02old = pwmCH02Input	

;Read ch 04:
CH04_OK = FALSE
pulsin RCch04,0, pwmCH04Input
pwmCH04Input  = (pwmCH04Input  min RCpwmMIN) max RCpwmMAX	
CH04_OK = TRUE
pwmCH04old = pwmCH04Input

goto main

IntHandler
'check if the interrupt “destroyed” the pulsin reading:
If CH01_OK & CH02_OK & CH03_OK & CH04_OK & CH05_OK & CH06_OK then
goto AllOK
elseif NOT CH01_OK 'if so, fix it:
pwmCH01Input = pwmCH01old
elseif NOT CH02_OK
pwmCH02Input = pwmCH02old
elseif NOT CH03_OK
pwmCH03Input = pwmCH03old
elseif NOT CH04_OK
pwmCH04Input = pwmCH04old
elseif NOT CH05_OK
pwmCH05Input = pwmCH05old
elseif NOT CH06_OK
pwmCH06Input = pwmCH06old
endif

AllOK:
;send pwm data to host BAP28:
serout Serial_OUT, i57600, [pwmCH01Input.lowbyte,pwmCH01Input.highbyte,|
pwmCH02Input.lowbyte,pwmCH02Input.highbyte,|
pwmCH03Input.lowbyte,pwmCH03Input.highbyte,|
pwmCH04Input.lowbyte,pwmCH04Input.highbyte,|
pwmCH05Input.lowbyte,pwmCH05Input.highbyte,|
pwmCH06Input.lowbyte,pwmCH06Input.highbyte]

resume[/code]

Since I’m no programming expert I didn’t find a way to enter/send words, therefore I used the .lowbyte and .highbyte. Does anyone know a better way to this?

If the interrupt occour when the BAP are in the middle of a pulsin command the current pwm reading will be corrupt, thats the reason for why I uses a CHXX_OK. And restore the previous (old) value.

So far this code works very well. And this is the simple code you’ll need to add into your main BAP:

[code]high IRQ_OUT ;Send the interrupt pulse to the CO-BAP
low IRQ_OUT

serin PWM_IN, i57600, [pwmInput01.lowbyte,pwmInput01.highbyte,|
pwmInput02.lowbyte,pwmInput02.highbyte,|
pwmInput03.lowbyte,pwmInput03.highbyte,|
pwmInput04.lowbyte,pwmInput04.highbyte,|
pwmInput05.lowbyte,pwmInput05.highbyte,|
pwmInput06.lowbyte,pwmInput06.highbyte][/code]

I’m thinking of making a very little simple board to hold the extra BAP24. I think the BB2 can supply this with power too? I measured that the BAP24 + RC receiver needed about 130 mAh.

Any comments are appreciated.

Looks pretty good for a “No Programming expert”! :laughing:

I believe that you are doing the right way for sending our receiving word as the manual talks about assigning each byte to a seperate variable…

Personally I prefer to not put that much processing into an interrupt such as you have in your processing of the interrupt. You might for example cause other interrupts not to be processed into you return from your interrupt handler. But you are probably fine.

If you don’t mind the delay of just one pulsin, you could also arrange your code such that the interrupt handler just sets a variable that says it happened and after each pulsing you could check this state and if it happened you do your serout back to the other processor.

Another approach may be to have your processor that is doing the pulsin to do a little more work. For example maybe have it check to see if any of the inputs have changed (more than your dead zone settings) since it last told the main processor it’s values. If something has changed, it tells the main processor. Could do this several different ways. It could set an IO pin high and waits for the other processor to ask for the data, or it could maybe serout the info and the main processor be connected to it by the HSERIN port, which would buffer the data…

I am probably going to try a different approach, to updating Xan’s code to work again with my RC Receiver ( or better yet with the DIY RC transmitter with keypad). Assuming the speed of it does not compare well with what Xan showed in his video, I will probably integrate in my Interrupt version that I did for my Rover. It basically tries to capture the timing of pulses through WKP0-5 interrupts and measures the time differences using TimerW. Some of this code is up in the thread:lynxmotion.net/viewtopic.php?t=3496. This amount of interrupt processing does cause some problems for some bit bang functions like serin/serout. One approach would be to disable these interrupts when doing the Serout. Another approach would be to use the hardware serial port to talk to the SSC32…

But again I believe your approach should work fine.

Sorry for my ramblings.

Kurt

Hi Kurt,

Thanks!

Oh, I was not aware of that. Lucky me that it worked ok then :unamused: . But I had a little problem at the beginning caused by a fast loop while doing the GP player in the main BAP, I had to add a 60 mS pause in the loop to inhibit the CO-BAP getting to many interrupt in a short period of time.

Good idea, but I think I stick to my code as long as it works (I want to avoid the delays…)

Another good suggestion! Actually, I’ve been thinking of using the CO-BAP to take care of all sensor readings too. I think that might be useful.

I think I read that the hserout support greater speed than 57600. But I’ve not tried it yet. Do you have any ideas of how to use hserout to send commands to the SSC32? Does hserout support 115200?

Hi again

If you do need to get other interrupts to be processed while in your interrupt, I believe you can add an ENABLE command inside of your interrupt handler.

I think this approach would probably give you the greatest speed. You could have your secondary processor simply set in IO line either high or low tht is connected to your primary to tell it that it has new data. In that way in your main loop, you could simply check the IO line to see if you have new data else go on your merry way.

I know that it has much higher speeds. Not sure if there is any default value for 115200, but you might be able to set the BRR register yourself to get it…

Now got to run
Kurt

An old thread but, dont mind if i do. lol

Kåre, im soon to pick up a FlySky 9Ch 2.4Ghz digital programmable radio (Mode 2). The PC board has been upgraded from generation 2 to 3, with a 2.4Ghz 3rd Generation 8 Channel 2.4Ghz Receiver.

Did you ever post a tutorial on how you hooked everything up and got the whole system up and running?
full code, connections etc? can it be ran with the ARC-32 (i still have to buy it) or the BAP28?

8 Channel PPM Encoder Version 2
The board plugs into the servo output ports on an R/C receiver and encodes them into a PPM pulse
store.diydrones.com/ProductDetai … de=BR-PPME
regards,

Hi Johny,

I bought the Futaba 7C 7 Channel 2.4GHz Heli RC.

You can use the ServoDecode lib to run it on an Arduino, might be able to port code:

arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230065255

I’ve been working on my Jaws, just added a digital mini servo for tilt, and changed the jaws servo to a digital mini as well. currently trying it out with the Futaba.

And I also bought the DIY Drones module, although I haven’t fired it up with the Futaba R617FS XCVR.

Alan KM6VV

Hey Alan,

What’s so special about this ServoDecode library compared to pulsin “included within the arduino library.”

–Aaron

Hi Aaron,

It uses one I/O line, and reads the PPM signal from a receiver. Beats having to use 7 or 8 I/O lines in for the R/C.

Alan KM6VV

Oh hey thats cool, except I dont think the t7c can output a single channel via PPM.

I could certainly rip apart the receiver and probe around attempt to find a signal, tapping that signal is going to be pretty difficult on that board though… connections are quite tiny!

Infact I was bugging Kurte the whole time to get assembly code for the basic micro to read the channels better and for what? I bought a Teensy2.0 and wrote code myself, I would love to buy another teensy and replace the botboard with it all! seems quite a bit better IMO.

That’s down the road though, If you want the code I wrote for the teensy let me know and I can provide it to you, however I’m about 2 weeks into C++ and Im sure you know quite a bit more then I do!
I still have your email address, I’ll just email it to you.

–Aaron

Hi Aaron,

the T7C has a “buddy” connector on the back that outputs PPM, I use it to run the Phoenix Flight SIM!

The Futaba R617FS XCVR can indeed be hacked:

fpvuk.org/forum/index.php/topic,2786.0.html

fpvuk.org/forum/index.php/topic,2786.0.html

Although I choose not to. For $24 PayPal (so it’s not real money) I got a little board already done! Source code is available!

store.diydrones.com/product_p/br-ppme.htm

Alan KM6VV

Yeah that hack is junk, you loose 2 channels :\

I however did this hack
jreise.de/PPM/R617FS.html

It does work.
! I verified this on the Oscope.

Yeah, that one looks like it would work.

I got the impression that it was the inspiration for the DIY version, maybe not.

I didn’t have time to build it!

Alan KM6VV

Its funny, there really isn’t anything to build, its just a chip no circuit or anything.

Well yeah, just wire it up!

That’s a Micro Computer for you! uP, memory, I/O and XTAL all in one package!

Alan KM6VV