PDA

View Full Version : Help! Pic servo reverser


alibodin
Oct 06, 2006, 04:26 PM
I have built a pic servo reverser circuit for my twin elevators. It works appart from at some settings there is jitter. And if I sweep slowly through the range the slave servo is not smooth. The servo is fine.

I tried extra decoupling at the servo end. I tries oputting a series resistor for the input as I I have seen cicuits that do that. No difference.

Thought try a different receiver and it became stranger.

WIth mu multiplex IPD rx the circuit did not work when I used a 5 cell pack, the normal servo was fine, though the slave one did not move. Change the batery to 4 cells and iut works as with the other rx (gws) with the jitter.

Withouit a scope I am at a loss to know what is wrong.

Any one any suggestions please?

Alistair

AndyOne
Oct 06, 2006, 06:47 PM
It looks like the problem is in the code, do you have a listing.

Andy.

Comatose
Oct 07, 2006, 02:52 AM
If you're using an asynchronous technique to measure or output the pulse width (timer interrupts, for example) you need to make very certain that they can't occur simultaneously. If they do, then either the input or the output will be delayed while the other process completes. This leads to jitter.

For single-input, single-output, the easiest way is to do the processing completely in-order. That is, wait for a valid servo frame, process it, then immediately output the servo pulse. The wait for the next frame.

alibodin
Oct 07, 2006, 05:12 AM
I am doing just that wait for input pulse measure it do ouput pulse, round and round forever.

Here is the code.

; *
; Notes: *
; 1 V+
; 2 GP5 input - not used *
; 3 GP4 input - not used
; 4 GP3 input - not used
; 5 GP2 input - servo input
; 6 GP1 output - LED
; 7 GP0 output - servo output
; 8 V-
; *
; Based on http://www.rc-float-flying.rchomepage.com/RCWeb/PIC/Rev%20Assembler.htm *
;
; In this application there is a requirement to subtract a number
; from a constant (300) that gets into underflow/overflow
; under 8 bit arithmetic - that is, eight bits only produces 256 possible numbers
; To overcome this limitation, if the number is in the W register and you want "300 - W", you can use:
;
; sublw .44 Since 44 + 256 = 300.
;
; However, since we have a "low" function in the assembler, which extracts the low-order byte of a value,
; we can use it:
;
; sublw low .300
;
; This is easier to read and results in the same thing, since extracting the low byte of 300 yields 44.
;
; Function: ONE_PULSE
; Description: process one pulse
; 1) Wait for input pulse to start
; 2) Time length of input pulse
; 3) Output a pulse to the servo using current timing
; *

list p=12F629 ; list directive to define processor
#include <p12F629.inc> ; processor specific variable definitions

errorlevel -302 ; suppress message 302 from list file

__CONFIG _CP_OFF & _CPD_OFF & _BODEN_ON & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT

radix dec ; decimal

#define GP_OUTPUT 0 ; GP0 = Output to servo
#define LED 1 ; GP1 = Output to LED
#define GP_INPUT 2 ; GP2 = Input from the receiver
#define IODIR 0x4 ; GP2 ip ret op; 3c GP0,1 out rest input
#define PULSE1500 150 ; mid point
;
; EEPROM address
;

;
; Variables
;
INT_VAR UDATA_SHR 0x20
Input_Pulse RES 1 ; Input pulse width
Timer_Output RES 1 ; Output pulse width for servo
Timer RES 1 ; "Scratch" variable for timinout output pulses
;
;
; Power Up
;
RESET_VECTOR CODE 0x000 ; processor reset vector
goto main ; go to beginning of program
;
; main code starts here
;
main
call 0x3FF ; retrieve factory calibration value
bsf STATUS,RP0 ; set file register bank to 1
movwf OSCCAL ; update register with factory cal value

; Initialization bank 1
clrf INTCON ; clear all interrupts
movlw IODIR ; set up io direction
movwf TRISIO ; in the pic
movlw 0x80 ; pull up disabled
movwf OPTION_REG ; set up option reg

; Initialization bank 0
bcf STATUS,RP0 ; set file register bank to 0
clrf GPIO ; clear all outputs
clrf TMR0 ; clear timer 0 register
movlw PULSE1500 ; get neutral pulse for start
movwf Timer_Output ; into timer output

;************************************************* *********************
; main loop
;************************************************* *********************
MAIN_LOOP
call ONE_PULSE ; Wait for and time one pulse
movf Input_Pulse, W ; Get input into W
sublw low 300 ; do servo reverse
movwf Timer_Output ; Save to output timer so input = output
goto MAIN_LOOP

; -- Wait for input pulse to start --
ONE_PULSE
btfss GPIO, GP_INPUT ; If GP3 is "set," pulse has started
goto ONE_PULSE ; If not, continue to wait

; -- Time length of input pulse --
clrf Input_Pulse ; Start at zero
IN_LOOP
incf Input_Pulse, f ; (1) Increment each time around the loop
nop ; (2) No-ops to pad loop to be exactly 10 microsecond
nop ; (3)
nop ; (4)
nop ; (5)
nop ; (6)
nop ; (7)
btfsc GPIO, GP_INPUT ; (8) If GP3 is "clear," pulse has ended
goto IN_LOOP ; (9 & 10) Otherwise, continue with loop

; -- Output a pulse to the servo --
IGNORE_IP
movf Timer_Output, W ; Get current timing for servo pulse
movwf Timer ; Save to "scratch" timer variable
bsf GPIO, GP_OUTPUT ; Start our pulse on GP2
OUTLOOP
nop ; (1) No-ops to pad loop to be exactly 10 microsecond
nop ; (2)
nop ; (3)
nop ; (4)
nop ; (5)
nop ; (6)
nop ; (7)
decfsz Timer, f ; (8) Decrement the timer
goto OUTLOOP ; (9 & 10) Loop if timer hasn't reached zero yet
bcf GPIO, GP_OUTPUT ; End our pulse on GP1

; That's it -- we're done!
return

; initialize eeprom locations

EE CODE 0x2100
DE 0x00, 0x01, 0x02, 0x03




END ; directive 'end of program'

What puzzles me is why 5 cells on mpx and it does not work yet 5 on agws rx and it does work. Well work with the jitter,

Alistair

JMP_blackfoot
Oct 07, 2006, 06:14 AM
The attached assembly language file works well for me in a PIC 12C508A, it should be easily adapted for 12F629.
The idea is that a counter starts downcounting as the the input goes high. When the input goes low, the program sets the output to one, the counter keeps down counting until 3 ms have elapsed and resets the output to zero. The output pulse time is thus (3 ms - input pulse). Hope it helps. Keep it simple ;>)

mike50
Oct 07, 2006, 04:59 PM
You are using only 100 steps between 1ms and 2ms. With a PIC with a 4MHz clock (1uS instruction time) you can easily achieve twice this resolution ( 5 uS per iteration of the timing loops). I don't know if that would help with the jitter though.

Also, it seems odd that you delay your output pulses by 20 ms. You are reading an input pulse and then putting out the reversal of the previous input pulse. Why not put out the reversal of the most recent input pulse?

I notice that you are not initializing the CMCON register to disable the comparator. I don't know if that will have some affect, but it should be done.

Here is the circuit and source for my PIC servo reverser that has 5 uS resolution, and works very smoothly.

http://www.rcgroups.com/forums/showthread.php?t=575173

Mike

hilgert
Oct 07, 2006, 11:27 PM
On the 12F683 you can run it a 8Mhz on the internal clock, so you can get even finer resolution. Not sure about the part you are using (too lazy to check), but I have run the 12F683 at 8Mhz just fine for another project.

mike50
Oct 08, 2006, 12:09 AM
The part I used is the 10F206 which only runs at 4 MHz.

Mike

hilgert
Oct 08, 2006, 12:18 AM
The part I used is the 10F206 which only runs at 4 MHz.

Mike
Just suggesting an alternate part if it was an option available to you, since it runs at 8Mhz.

alibodin
Oct 08, 2006, 10:04 AM
My biggest challnege is the circuit does not work with my mpx rx which I will be using. Even with 4 cells, so I have decided to ditch it and reverse the servo in the tailplane,

Thanks for all the tips and suggestions. JMP I like your solution of the 3ms timer and might look at that.

Alistair

JMP_blackfoot
Oct 08, 2006, 11:36 AM
I wrote that in 1999, I think. It is the simplest I could think of. It could be rewritten to a resolution ofµs, or perhaps 3 µs, even for the 4MHz clock. I'll see what I come up with.

Mr.RC-CAM
Oct 08, 2006, 12:53 PM
What puzzles me is why 5 cells on mpx and it does not work yet 5 on agws rx and it does work.I think this may solve your 5-cell problem:
[1] Move the servo input from GP2 to another Pin (GP2 is an ST characterized pin, which you don't want in this app).
[2] The series protection resistor on the input pin should be 1K ohms. Do not omit this resistor.
[3] Add a 1K resistor to the servo output too.
[4] Be sure that the PIC's voltage does not exceed 5.5VDC. For good osc timing, aim for 4VDC to 5VDC.

With the code you posted, jitter will be excessive. So, the servo will twitch a bit.

AndyOne
Oct 08, 2006, 01:34 PM
Using Oshonsoft Basic all you need is...

DIM length AS BYTE
TRISB.0 = 1
TRISB.1 = 0
loop:
SERVOIN PORTB.0, length
IF length < 100 THEN length = 100
IF length > 200 THEN length = 200
length = length - 100
length = 100 - length
length = length + 100
SERVOOUT PORTB.1, length
GOTO loop

Simple.

Andy.

alibodin
Oct 08, 2006, 02:33 PM
I think this may solve your 5-cell problem:
[1] Move the servo input from GP2 to another Pin (GP2 is an ST characterized pin, which you don't want in this app).
[2] The series protection resistor on the input pin should be 1K ohms. Do not omit this resistor.
[3] Add a 1K resistor to the servo output too.
[4] Be sure that the PIC's voltage does not exceed 5.5VDC. For good osc timing, aim for 4VDC to 5VDC.

With the code you posted, jitter will be excessive. So, the servo will twitch a bit.

Interesting, thanks RC Cam, slow progress.

Moved the input to GP1 using 270R as I was using on GP2 and it now works with the mpx at 5 cell and 4 cell. What is an ST chaeactersied ip? Need to get a 1k for the ip and op. Also seems like I need to regulate the voltage to the pic to be less than 5.5V.

The jitter is still there and if I tighten the loop to 5us it should improve.

Alistair

Chippie
Oct 08, 2006, 03:09 PM
Interesting, thanks RC Cam, slow progress.



What is an ST chaeactersied ip? Alistair


Its a Schmitt Trigger type input....

alibodin
Oct 08, 2006, 04:58 PM
I suspected as much :)

Thought of what I think is an even better way to get better accuracy. User timer 1.

Here is my logic

Set timer to 3ms well actually 65535-3000 (as clocked at 4MHz ie 1us count)
wait for servo input to be low
wait for servo input to go high
start timer
wait for servo input to go low
set servo output to be high
wait timer 1 to overflow (it counts up 3ms) poll the bit in the PIR1
set servo output low

I reckon this gets the pulse width to within a few us which has to be good :)

Alistair

JMP_blackfoot
Oct 09, 2006, 09:36 AM
Yes, that ought to give you 3µs accuracy with the 1µs clock. My early one at 5µs loop time did not give any noticeable jitter with regular servos.

Acetronics
Oct 09, 2006, 09:49 AM
Hi, JMP

In the datasheets ... I saw some PICS with an external Timer Gating pin ... may be 14 pins models.

he,he ... also the 12F683 with TMR1 ( yeah, great !!! ) external gating !!!

Alain

JMP_blackfoot
Oct 09, 2006, 10:25 AM
Then the code boils down to only 18 instructions (see attached text file)

alibodin
Oct 09, 2006, 03:57 PM
JMO

That software works a treat combined with RC Cam tip to not use ST input. Now just need a small regulator for when using 5 cell so pic voltage is 4.5v or 5v,

Thanks

Alistair

xtal
Oct 09, 2006, 04:21 PM
If alibodin wasn,t fro England I would think he worked for NASA.....ie
a 2$ smart inverter and 50 man hours to get it working.....

alibodin
Oct 09, 2006, 05:12 PM
:)

Hey the fun of these things is the challenge of making them work, it may tae a few hours but one gets their in the end,

AListair

DuskWolf
Oct 10, 2006, 06:14 AM
Besides for a lazy man like me going for the shop to buy one is too much. So I prefer to sit and make one...
The code works great, I had in mind building one and the Idea I had was exactly the 3ms timer...thanx for providing it. :)

anestho
Oct 10, 2006, 07:56 PM
It may just be an exercise for you with PIC programming, but what you describe is a simple inverter which can be done with 1 transistor, comparator/op-amp/ or inverter chip. It will cost way less, be much lighter, and give 1:1 resolution. All it will do is invert the positive input to zero and vice versa.

AndyOne
Oct 10, 2006, 08:06 PM
It may just be an exercise for you with PIC programming, but what you describe is a simple inverter which can be done with 1 transistor, comparator/op-amp/ or inverter chip. It will cost way less, be much lighter, and give 1:1 resolution. All it will do is invert the positive input to zero and vice versa.

What is in discussion here is a pulse length inverter not a simple polarity inverter.

Andy.