Hi, Alex
I spent some more time on your code ...
should work as I verified the timing and flow with MPSIM ...
Code:
'****************************************************************************
' (c)2009 Alexandros Zahariadis (E.A.TH.) Greece *
' Electric Glider electronic switch to be used in F3J-GR competitions.
' The device will cut-off motor if 200m ALT reached or 30seconds passed
' whichever comes first!
' There is also a status led option which idicates if you have reached 200m
' or not (may be because of luck of power!)
' steady led -> 200m ALT reached , blinking led -> 30 secs passed.
' NOTE: after a lot of experiments and because of code execution speed
' I use direct ADC raw sample values without converting them to meters first!
' :: thanks to Acetronics (Alain) and picbasic forum for codding ideas ::
'****************************************************************************
'@ DEVICE FCMEN_OFF
'@ DEVICE IESO_OFF
'@ DEVICE BOD_ON
'@ DEVICE CPD_OFF
'@ DEVICE PROTECT_OFF
'@ DEVICE MCLR_OFF
'@ DEVICE PWRT_OFF
'@ DEVICE WDT_OFF
'@ DEVICE INTRC_OSC
@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _BOD_ON
INCLUDE "modedefs.bas"
DEFINE OSC 4
DEFINE PULSIN_MAX 2500
;DEFINE DEBUG_REG GPIO
;DEFINE DEBUG_BIT 2
;DEFINE DEBUG_BAUD 9600
;DEFINE DEBUG_MODE 1
OSCCON = $60 ' $60:4 Mhz $70:8 Mhz int.
CMCON0 = 7 'TURN COMPARATORS OFF
TRISIO = %00001010 'Set GPIO1 and GPIO3 0 INPUTS, others to OUTPUT
ANSEL = %00000100 'Set AN2 , Fosc/32
ADCON0 = %00000000 'AN2 select & Right Justify for 10-bit
;---------------------------------------------------------------------------
'
THROTTLE VAR GPIO.0 'Outputs to throttle servo
RADIO VAR GPIO.1 'Input from receiver
LED VAR GPIO.2 'status indicator
ADC_DATA VAR GPIO.3 ' adc serial data
ADC_SCLK VAR GPIO.5 ' adc serial clock
ADC_CS VAR GPIO.4 ' adc chip select
;---------------------------------------------------------------------------
advalue VAR word ' value read from adc
groundALT VAR word
difalt VAR word
P VAR WORD ' This stores the PULSIN value
x VAR byte ' general var
y VAR byte ' general var
Dummy VAR word
SEC_COUNT VAR BYTE ' seconds counter
O_FLOWS VAR BYTE ' holds the number of timer1 overflows
BRAKE_PULSE VAR word ' servo pulse to STOP (brake on) THR servo
CLEAR
'BRAKE_PULSE = 100
'-= vars for averaging routine =-
AvgCount CON 6 ' = Number of samples to average
FAspread CON 1000 ' = Fast Average threshold +/-
Value VAR WORD
'-= end of vars for averaging routine =-
'******************************************************************************
' TIMER1 Cycle MUST be longer than a R/C frame duration to be sure not to miss any ticks.
' 50 ms is a good value for timing precision.
' PL = 15543 @ 4Mhz ( reload = 7 cycle )
'******************************************************************************
T1LO CON $49 'timer1 preload values
T1HI CON $C3 '$C349 -> -15543
LOW throttle
INTCON = 0 ' disable interrupts
T1CON = %00010000 ' 1:2 prescale (1uS per tick), timer1 off (max 1:8!)
' 11 = 1:8 ,10 = 1:4, 01 = 1:2, 00 = 1:1 Prescale Value
TMR1H = T1HI ' 65,536-15536 = 50.000
TMR1L = T1LO ' 50.000 ticks * 1uS =50.000usec.=100msec
' 1 second= 100*10
' every 10 timer1 overflows = 1 second 1uS=
'---------------------------------------------------------------------------
pause 3'000
for x=1 to 4
high led
pause 2'00
low led
pause 1'00
next x
'******************************************************************************
CAL_BP: ' CALIBRATING Brake_Pulse ( P )
' Controller must see Brake Pulse to Unlock ...
'******************************************************************************
Pause 50
LOW led
Brake_Pulse = 0
For x = 1 TO 16
PULSIN radio,1,P
IF ( P < 80 ) OR ( P > 220 ) Then
Led = 1
GoTo CAL_BP
EndIF
IF Brake_Pulse = $00 Then prems
IF ( P < (Brake_Pulse -1)) OR ( P > (Brake_Pulse +1)) THEN
Led = 1
GoTo CAL_BP
ENDIF
prems: Brake_Pulse = P
Next x
LOW Throttle
'*****************************************************************************
precheck: 'leave some seconds to do a motor test
'then motor brake is ON for some seconds
for y=1 to 3
for x=1 to 255
PULSIN RADIO,1,P
IF ( P < 80 ) OR ( P > 220 ) Then
Led = 1
GoTo Precheck
EndIF
Led = 0
LOW Throttle
PULSOUT THROTTLE, p
next x
next y
'******************************************************************************
' GroundAlt measure : Motor is Locked, But Brake_Pulse lenght must be sent ...
'******************************************************************************
for x=1 to 160 '160 x 22ms =
LOW Throttle
PULSOUT THROTTLE, brake_pulse
pause 19
next x
low THROTTLE
GOSUB GetAdc 'Get ground ALT
groundalt = value
'******************************************************************************
armcheck: '20.9 ms ' Now, we can launch the beast ...
PULSIN RADIO,1,P
IF ( P < 80 ) OR ( P > 220 ) Then
Led = 1 ' Show Problem !!!
LOW Throttle
PULSOUT THROTTLE, brake_pulse ' Not to lock Controller
GoTo Armcheck
ENDIF
Led = 0
low throttle
PULSOUT THROTTLE, p
GOSUB GetAdc 'Get ALT
if difalt < 2 OR difalt > 10000 then Armcheck 'Arm if>=5mALT (in adc samples) reached!!
'******************************************************************************
'******************************************************************************
start: ' We are flying , now ... preset timer1
SEC_COUNT=28 ' load for 30 to 0 seconds countdown
O_FLOWS=0 ' clear overflow count
PIR1.0=0 ' clear timer1 overflow flag
T1CON.0=1 ' start timer1
low throttle ' to be sure ...
'******************************************************************************
main:
gosub GetADC
PULSIN RADIO,1,P
pauseUS 10
pULSOUT THROTTLE, p
' Note: Timer1 overflows every 0.050 seconds
IF PIR1.0 THEN ' if timer1 overflow then
O_FLOWS = O_FLOWS + 1 ' inc oveflow counter
IF O_FLOWS = 20 THEN ' if 1 second elapsed
SEC_COUNT = SEC_COUNT - 1 ' decrement seconds count
O_FLOWS=0 ' reset overflow counter
ENDIF
PIR1.0=0 ' clear timer1 overflow flag
T1CON.0 = 0 ' stop timer1
TMR1H = T1HI ' Reload values
TMR1L = T1LO
T1CON.0=1 ' re-start timer1
ENDIF
if difalt>=89 and difalt<10000 then KILL_MOTOR_ALT 'Check if 100mALT
'(in adc samples) reached!!
if sec_count < 1 then KILL_MOTOR_TMR
goto main
' SUBROUTINES
'******************************************************************************
'******************************************************************************
GetADC: 'Read MAX187 12bit ADC value - Take 9.25 ms
low ADC_CS
PAUSEUS 10
Average:' -=-=-=-=-=-= Average 16 X Analog values -=-=-=-=-=-=-=-=-=-=
For x = 0 to 15 ' 16 Samples MAXI !!!
shiftin ADC_DATA,ADC_SCLK,msbpost,[advalue\12] '337 µs
value = value + advalue
PAUSEUS 200
NEXT x
Value = Value / 16
difalt = groundalt - value
high ADC_CS
RETURN
END
'******************************************************************************
KILL_MOTOR_ALT:
low throttle
high led
LOOP1:
PULSOUT throttle, brake_pulse ' Kill motor - adjust this value. 4Mhz ->> 10uSec
pause 19
goto LOOP1
END
'******************************************************************************
KILL_MOTOR_TMR:
x = 0
T1CON.0 = 0 ' Stop the Timer
LOOP2:
low throttle
PULSOUT throttle, brake_pulse ' Kill motor - adjust this value. 4Mhz ->> 10uSec
IF X = 0 THEN led = led ^ 1
x = ( x+1 ) // 18 ' Counter for led Blinking @ 1.5 Hz
pause 19
goto LOOP2
END
'******************************************************************************
'******************************************************************************
Fond some " strange " things and corrected them ...
Alain
Bookmarks