PDA

View Full Version : Attempting to read 3x R/C servo pulses.



Peter.
- 21st July 2010, 09:43
In the few weeks since purchasing PBP I have so far learned several basics, including how to use Darrel Taylor's BarGraph.INC, etc. and have now run into this problem:



; Date: July 2010
; File name: test.pbp
; Compiler: PicBasic Pro V2.6
; Editor: MicroStudio V3.0.0.5
; Processor: 16F877A
; ----------------------------------------------------------------------------

DEFINE LCD_DREG PortB ; Use Port B for all bus lines
DEFINE LCD_DBIT 4 ; (4 = 4-bit bus; 0 = 8-bit bus)
; Connect PIC pins 37 ~ 40 (B.4 ~ B.7)
; to LCD pins 11 ~ 14 (D4 ~ D7)
DEFINE LCD_EREG PortB ; Put the Enable Register on Port B
DEFINE LCD_EBIT 3 ; Connect PIC pin 36 (B.3) to LCD pin 6 (En)
DEFINE LCD_RSREG PortB ; Put the ReSet Register on Port B
DEFINE LCD_RSBIT 2 ; Connect PIC pin 35 (B.2) to LCD pin 4 (RS)
DEFINE LCD_BITS 4 ; Set bus size (4 = 4-bit bus; 8 = 8-bit bus)
DEFINE LCD_LINES 4 ; Set number of LCD lines (1 ~ 4)
DEFINE LCD_COMMANDUS 2000 ; Set 2-millisecond command period
DEFINE LCD_DATAUS 50 ; Set data delay period

DEFINE LCD4X20 1
DEFINE OSC 20

LCDOUT $FE, 1
PAUSE 200

CMCON = 7
ADCON1 = 7

throttle VAR word
rudder VAR word
gear VAR word

LOW PortC.4 ; R/C landing gear output pin
LOW PortC.5 ; R/C rudder output pin
LOW PortC.6 ; R/C throttle output pin

; ----------------------------------------------------------------------------

start:
PULSIN PortA.3, 1 , throttle
PULSOUT PortC.6, throttle
throttle = throttle *2
LCDOUT $FE, $80, "Thtl = ", #throttle /1000, ".", #throttle DIG 2, #throttle DIG 1, "mS"

PULSIN PortA.4, 1 , rudder
PULSOUT PortC.5, rudder
rudder = rudder *2
LCDOUT $FE, $C0, "Rddr = ", #rudder /1000, ".", #rudder DIG 2, #rudder DIG 1, "mS"

PULSIN PortA.5, 1 , gear
PULSOUT PortC.4, gear
gear = gear *2
LCDOUT $FE, $94, "Gear = ", #gear /1000, ".", #gear DIG 2, #gear DIG 1, "mS"
GOTO start

END


The servos are a tad sluggish and their torque is somewhat lower than normal. If either one of the three input signals is disconnected, then the other two servos tend to move even slower or not at all. I'm thinking that perhaps I should be using Darrel's interrupt.INC, but I'm not sure how to implement it with three separate R/C inputs.
Could someone perhaps tell me if it is indeed possible to have as many as three PULSIN statements like this?

Thank you for your help.

ScaleRobotics
- 21st July 2010, 15:41
Hello Peter, looks like you are progressing very well. I think your prognosis is right on the nose. In my opinion, interrupts are the way to go. I think the servo's are not at full torque because they do not get fed their pulses at the regular intervals that they need.

Here is an example of someone using code similar to yours, but only using one input and output: http://www.picbasic.co.uk/forum/showthread.php?t=11167&p=84056#post84056

And here is Darrel's 2 servo interrupt based output example: http://www.picbasic.co.uk/forum/showthread.php?t=12319&p=81993#post81993

And here is my interrupt based input/output for up to 5 ch inputs, and 4 ch outputs. Only problem is that it does not seem to be compatible with some receivers. http://www.scalerobotics.com/stamps/84-projects/pwm/71-pwm-passthrough.html (http://www.scalerobotics.com/PWMpassthrough.html) And there is also a problem with signals that are longer than 2ms, so trims might have to be adjusted accordingly, and a scope helps.

Peter.
- 21st July 2010, 21:57
[QUOTE=scalerobotics;91705]
And here is my interrupt based input/output for up to 5 ch inputs, and 4 ch outputs... http://www.scalerobotics.com/PWMpassthrough.html (http://www.scalerobotics.com/PWMpassthrough.html)
QUOTE]

Scalerobotics,
First off, thanks for coming back with your help. Funnily enough, just last night I stumbled upon your pages while searching the forum. Although I'm not too familiar with all the wonders of PBP just yet, I feel I can somehow associate with what you done regarding the inputs being fed via separate diodes. I see you use a lot of assembler, which is maybe a tad too advanced for me to fully understand at this juncture; I'm not sure how I would transpose your code to the 16F877A.
Darrel's link shows that he's placed his two servo outputs on the CCP pins. You're probably already aware that the '877 does indeed have two CCP ports, but this is where I get more confused because I'm basically wanting to monitor three separate servo pulses from a bog-standard Futaba FASST 7-ch Rx.
From what I've so far managed to glean from the 3 links that you'd sent, I see that the on-board timers are pressed into service - I don't see one single PULSIN statement anywhere. My code does indeed display the correct numbers on the LCD, but at the expense of the servos being a tad sluggish when trying to measure more than two pulses.
I am prepeared to get my hands dirty and learn, but would you happen to know where I might get some very basic info. first?

Again, many thanks for coming back.

ScaleRobotics
- 21st July 2010, 23:25
Hello Peter,

The best way to get started, is probably to make a few interrupt routines with Darrel's Instant Interrupts. He has made them pretty easy. Here is his page for DT_INTS-14 which will be compatible with your 16f877. The newest version is 1.0, to which there is a download at the bottom left of this page: http://www.darreltaylor.com/DT_INTS-14/intro2.html Then check out the blinky examples and such, and have some fun setting up different interrupts.

Here is a very nice example of hardware capture CCP1 interrupts by Bruce: http://www.picbasic.co.uk/forum/showthread.php?t=12562&p=83605#post83605

Only "problem" is that he does not use DT_INTS, and I think for most people, DT_INTS should be used.

Here is an example I had for detecting pulse width using DT_INTS: http://www.picbasic.co.uk/forum/showthread.php?t=12039&p=82990#post82990 but mine uses an 18F in this example. Since it is only detecting pulse width of one channel, it is a bit easier read than my pwmpassthrough.

I must admit that my PWMpassthrough example is a bit exhausting to look at. Here is basically what it does: It looks for 6 transitions, starting with a rise. This is the first part of the first pulse. The timer value is grabbed at that moment, and put in CCPR1H and CCPR1L (high and low 8 bit registers for the 16 bit timer). It is next interrupted at what I call "falltime" when the pulse goes low. This falltime is set in CCPR1H and CCPR1L. To get the width, you must subract falltime from risetime. It collects all of these, and does the subtraction to find the pulse width.

Then values are read to ouput to the servos, and software pwm pulses these out. And all this is done before the next round of inputs need to be measured.

For your application, you would only need to read the pulse width for channels 1 and 3. You could determine the width of radio ch2 by subtracting rise ch3 from fall ch1. If that makes any sense. See the diagram below.



; The input signal should look something like this:-
;
; |<------------------ 1 frame (~20mS) -------------->|
; |<1~2mS>
; ______ ______ ______ ______
; _______| |______| |______| |________________| |____
; gap ch1 ch2 ch3 ch4 ch5 sync gap ch1 etc


The funny part is, that I did not know I could use some PBP statements in an interrupt routine of type "ASM". So what could have been cleaner to read (and write) was done in assembly.

ScaleRobotics
- 22nd July 2010, 04:38
This chapter on CCP modules is very informative, and shows a lot about how capture and pwm work.
http://www.mikroe.com/eng/chapters/view/6/chapter-5-ccp-modules/

http://www.picbasic.co.uk/forum/attachment.php?attachmentid=4626&d=1279769909