PDA

View Full Version : Help! need help 5-channel decoder 12f683


xtal
Oct 11, 2006, 06:24 PM
Here's 5 channel decoder in MIKROBASIC.........
I'm having a problem with the ESC output chan[1]
For some reason I cannot achieve 100% on....
I have a 6us neg pulse 64us apart....
I have tried a period of ff and 7f same 6us results.......
It may be a suttle pgm bug, but I can't spot it......


program D12f863Decode7
CONST GOODFRAMES AS BYTE = 25
CONST THROT AS BYTE = 1 ' THROTTLE CHANNEL IS 1
DIM RC AS INTEGER
DIM PSTAT,CRAP, CH,ACC,CC, FC AS BYTE
DIM GPULSE, TPULSE, X,Y AS INTEGER
DIM ESC AS LONGINT
DIM CHANL AS WORD[5]
'PSTAT 7=10 BAD FRAMES 6= 5= 4= 3= 2=T1CAPTURE 1= 0=
'================================================= ==================
sub procedure interrupt '
'-------------------------------------------------------------------------------
' Let TMR1 freerun AND CAPTURE INT VALUES
'-------------------------------------------------------------------------------
if INTCON.GPIF = 1 THEN ' PIN CHANGE INTERRUPT
'-------------------------------------------------------------------------------
T1CON.TMR1ON = 0 ' STOP TIMR PS=1:2
RC = TMR1H * 256 + TMR1L ' SAVE TIMER 1 VALUE
' IF GPIO.5=1 THEN
' GPIO.5=0
' ELSE
' GPIO.5=1
' END IF
tmr1L=3 ' preset 3us
tmr1H=0 ' reset timer
T1CON.TMR1ON = 1 ' START 8mhz/4=2mhz / 2 = 1mhz - 1us
'-------------------------------------------------------------------------------
CRAP = GPIO ' CLR OUTSTANDING PIN CHANGE
ClearBit(INTCON,GPIF) ' RESET INT OCCURRED
SETBIT(PSTAT,2) ' CAPTURE OCCURED
END IF '
'--------------------------------------------------------------------
' IF PIR1.ADIF = 1 THEN ' ADC INTERRUPT
' Setbit(PSTAT,0) ' SET PID_RUN
' NP = ADRESH * 256 + ADRESL '
' Clearbit(PIR1, ADIF) '
' END IF '
'-------------------------------------------------------------------------
IF Testbit(PIR1, TMR2IF) = 1 THEN ' PWM - TMR2 INTERRUPT
Clearbit(PIR1, TMR2IF) '
END IF '
'-------------------------------------------------------------------
if INTCON.T0IF =1 THEN ' TMR0 INTERRUPT
' Setbit(ADCON0,GO) ' START ADC CONVERSION
ClearBit(INTCON, T0IF) ' ClearBit as an inline function,
END IF
'------------------------------------------------------------------------ '
IF PIR1.TMR1IF = 1 THEN ' TMR1 INTERRUPT
Clearbit(PIR1, TMR1IF) '
END IF ' SIGNAL LOST
end sub '
'================================================= =======================
MAIN: OSCCON = 0X71 ' 8 MHZ INTERNAL
OSCTUNE = 0 ' SET TMR0, TMR1, TMR2
OPTION_REG = %10000001 ' !PU 1:4 = 2US RESOLUTION 8MHZ
TMR0 = 0 ' 2US RESOLUTION 1:4 PRESCALE
' 001-1:4 010-1:8 011-1:16
intcon.T0IE = 0 ' DISABLE TIMER 0 INTERRUPT
'================================================= ======================
T1CON = 0x11 ' 1:2 1us & STarted
gpio = 0 ' CLEAR IO REGISTOR
trisio = 0x08 ' OUTPUTS-GP0,1,2,4,5 INPUT-GP3
'================================================= ====================
' PWM RERIOD = [(PR2)+1*4*TOSC*TMR2 PRESCALE VALUE]
' PWM DUTY CYC =
'---------------------------------------------------------------------
pr2=0x7F 'ff ' SET PWM period
ccpr1h = 0 ' 8MHZ OSC 1:1 .5US 1:4 2US 1:16 8US
ccpr1L = 0 ' STOPPED
T2CON = 4 ' 1:1 POSTSCALE, 4-STARTED 1,0 00 01 1X
ccp1con = 0x0c ' pwm mode 1:1 1:4 1:16
'================================================= ====================
' SET ADC ' SELECT CHANNEL 0
ANSEL = 0 '0X51 ' FOSC/16[8mhz clock] & GP0[51h]
' ADCON0 = 0X81 ' RJustify, Vdd ref, AN0-000,
'================================================= ================== '
setbit(ioc,3) ' SELECT PIN CHANGE INTERRUPT PIN GP3
'================================================= ==================
' ENABLE INTS '
'setbit(pie1,adie) ' ENABLE ADC CONVERSION INTERRUPT
'setbit(pie1,tmr2ie) ' ENABLE TIMER 2 INTERRUPT
setbit(pie1,tmr1ie) ' ENABLE TIMER 1 INTERRUPT
'' setbit(intcon,T0IE) ' ENABLE TIMER 0 INTERRUPT
setbit(intcon,peie) ' ENABLE PERIPHERAL INTERRUPTS
setbit(intcon,gpie) ' ENABLE PINCHANGE INTERRUPTS
setbit(intcon,gie) ' ENABLE ALL INTERRUPTS
'================================================= ============================


'################################################# ##############################

BADPULSE:
MAIN1:
while pstat.2 = 0 wend ' wait t1 int

pstat.2 = 0 ''''TIMR1 INT STOPS TIMER
TPULSE = rc ' SAVE TIMER 1 VALUE
if tpulse < 2400 then GOTO MAIN1 END IF
'-------------------------------------------------------------------------------
FOR CH = 0 TO 4
WHILE PSTAT.2 = 0 WEND
PSTAT.2 = 0
GPULSE = RC
IF ((GPULSE > 450) OR (GPULSE < 250)) THEN GOTO BADPULSE END IF
WHILE PSTAT.2 = 0 WEND
PSTAT.2 = 0
TPULSE = RC + GPULSE
IF TPULSE < 1000 THEN TPULSE = 1000 END IF
IF TPULSE > 2000 THEN TPULSE = 2000 END IF

' IF ((TPULSE < 1000) AND (TPULSE > 700)) THEN
' TPULSE = 1000
' ELSE
' GOTO BADPULSE
' END IF
' IF ((TPULSE > 2000) AND (TPULSE < 2300)) THEN
' TPULSE = 2000
' ELSE
' GOTO BADPULSE
' END IF
' IF ((TPULSE < 1000) OR (TPULSE > 2000)) THEN GOTO BADPULSE END IF
if ch = 0 then
chanl[0] = tpulse - 1000
else
CHANL[CH] = (TPULSE-1000)/8 ' SAVE ADJUSTED PULSE 0=1 1=2 2=3 3=4 4=5
end if

NEXT CH
'-------------------------------------------------------------------------------
''''PLAY SERVOS NOW

ESC = CHANL[0] ' CHANNEL 1
'ESC = ESC*255/1000
ESC = ESC*128/1000
IF ESC < 5 THEN ESC = 0 END IF
IF ESC > 124 THEN ESC = 128 END IF
'CCPR1H = 0
CCPR1L = ESC
'-------------------------------------------
Y = CHANL[1]+105 ' CHANNEL 2
GPIO.1 = 1
FOR X = 1 TO Y NEXT X
GPIO.1 = 0
'-------------------------------------------
Y = CHANL[2]+105 ' CHANNEL 3
GPIO.0 = 1
FOR X = 1 TO Y NEXT X
GPIO.0 = 0
'-------------------------------------------
Y = CHANL[3]+105 ' CHANNEL 4
GPIO.4 = 1
FOR X = 1 TO Y NEXT X
GPIO.4 = 0
'-------------------------------------------
Y = CHANL[4]+105 ' CHANNEL 5
GPIO.5 = 1
FOR X = 1 TO Y NEXT X
GPIO.5 = 0
'-------------------------------------------
GOTO MAIN1
'################################################# ##############################
' WAIT FOR NEXT SYNC
'================================================= ==============================
END.

Acetronics
Oct 12, 2006, 08:14 AM
Hi, Crystal

Where do you take your serial sequence from ???

Alain

xtal
Oct 12, 2006, 07:01 PM
Alain..
I stay in main1 until I detect a sync period...
then the next 5 channels, I capture/verify the 300us pulse, then capture the channel pulse, then verify 1000-2000 us and set max/min/ or leave as is and store in array...

Next I play the array,,, 1st slot = throttle = ESC value that should control the duty cycle of pwm

next play the remaining 4 channels set/loop/clear as needed
then go back to wait for sync

I have hard jammed 255 into esc, but still get a 6us -pulse,,, it never turns full on
jamming 0 does shut it off

Bruce Abbott
Oct 13, 2006, 03:50 PM
The PWM duty cycle register is 10 bit, but you are only changing the upper 8 bits (in CCPR1L). Try setting the lower 2 bits (in CCP1CON<5:4>), ie:-

ccp1con = 0x2c ' pwm mode

This should get rid of the spike, but then you won't be able to get zero duty cycle. The quick and dirty solution is to just clear bits 5 and 4 of CCP1CON when you want zero duty cycle, and set them otherwise.

xtal
Oct 13, 2006, 07:27 PM
setting ccp1con5,4 just induces a 0.2 us glitch....I did discover that if
I jam 255 into directly ccpr1L instead of setting ESC = 255 It looks ok
Will have to take a very close look at the esc computation.....

Bruce Abbott
Oct 14, 2006, 10:13 PM
I see now that you are using a maximum duty cycle value of 128 with a period of 0x7f, so you don't need to set the lower 2 bits (however, you do need to when using a period of 0xff).

Your code is working fine, so I suspect the input, ie. your radio is not generating a full 1~2mS pulse range. You just need to adjust your throttle range to suit.

Acetronics
Oct 15, 2006, 04:43 AM
Hi, Xtal Hi,Bruce

These days, I had to scope the coder signal of an Old 6014 Graupner ( NE5044 ) ... big surprise !!!

The leading pulse ( negative here ) is very far from the std " 300µS " or so. Only few micro seconds !!! only the 7 following have the nominal value.

That was the purpose of my question ...:Where does the signal come ?

Alain

xtal
Oct 15, 2006, 07:10 AM
Bruce is right on....If I changed min/max to 1100-1900 then I can achieve 100%
with very small .2us glitch, which I thought was the LSB's
but and when set to 11 gives a glitch on low end.....
I can live with it, but don't understand why I get it.

But of course another issue.... the input on scope indicates 1000us to 1980....
Now where am I loosing my high end....

There's always something.....