#picaxe 08m2
SetFreq M16
' Code snippets from Rampz, Goeytex & Jack Burns
'.----------------------------.
#REM
REQUIREMENTS
============
1. If the button is pressed for say 20ms then I want the output to
stay on for 400ms.
(DONE)
2. If the button is pressed and held on, then I want the output to
stay on till button released plus 400ms.
(DONE)
3a. If the output is switched on continuously for more than say
30 seconds, then treat it as a stalled motor, so stop the output
to protect the motor until the microswitch resets and re-triggers.
(DONE)
3b. Also flash C0 a couple of times and write 1 to memory for
later recall.
(NOT IMPLEMENTED)
4a Disable C4 if voltage is seen to be below 10.4v for a set time
of (say) 10secs to protect motor and battery.
(DONE)
5. When voltage returns to a higher level say 11.5v wait 1 hour
for battery to charge enough to power the motor again.
(DONE)
6. Each time C4 is disabled due to low voltage write 1 to memory
for later recall.
(NOT IMPLEMENTED)
#ENDREM
'#no_data
#terminal 19200
'.----------------------------.
'| Constants |
''----------------------------'
symbol BTN = PinC.3 '// Tilt Switch
symbol btn1 = PinC.1 ' memory recall button
Symbol LED = C.4 ' mosfet output
Symbol LED2 = C.0 ' Originally used C.0 but changed to C.1 as SERTXD messages are now used
symbol released = 0 'added
Symbol Pressed = 1
Symbol LowBattLevel = 104 ' Low voltage threshold x 10 (104 = 10.4v)
Symbol AvgCount = 10 ' Number of ADC readings to be averaged when calculating battery voltage
Symbol MaxRunTime = 6 ' Time in seconds. (Set low for testing, 30 required)
Symbol MinRunTime = 501 '// 501 = 400 ms approx. Adjust this value to change delay time after button released
Symbol LowBattDuration = 10 'set at 10 seconds
Symbol ChargeReadInterval = 4000 ' 4000 = 1 sec @ 16Mhz Take a reading every second
'// TEMPORARILY SET ChargeReadCount TO 20 WHILE BENCH TESTING (This will make testing quicker).
'// ChargeReadCount NEEDS TO BE 3600
Symbol ChargeReadCount = 20 ' 3600 ' Normally 3600 readings while battery charges
'// 3600 Readings at 1 sec = 1 hour (Combination of ChargeReadInterval & ChargeReadCount)
symbol highbattvolt = 115 'battery on again voltage 115 = 11.5v
'.----------------------------.
'| Variables Used |
''----------------------------'
symbol ReserveB1 = b1 ' Used in "MeasureBatteryVoltage" routine
symbol ReserveB2 = b2 ' Used in "MeasureBatteryVoltage" routine
symbol ReserveB3 = b3 ' Used in "MeasureBatteryVoltage" routine
symbol Counter = W2 ' Used in several places
symbol ADCvalue = W3 ' Used in "MeasureBatteryVoltage" routine
symbol ADCavg = W4 ' Used in "MeasureBatteryVoltage" routine
symbol Volts = W5 ' Used in several places
symbol VmonCount = W6 ' Used in battery monitoring loop
symbol LowBattCount = W7 ' Used for testing batt low for 10 seconds
symbol stallfaultcount = W8 ' counter for how many times stalled
symbol FlashCount = W9 ' Put this line at start of main code.
symbol LVDfaultcount = W10 ' counter for how many times low voltage disconnect happened
sertxd("coding by Rampz, Goeytex and Jack Burns",13,10)
MAIN:
if btn1= pressed then 'new mine
gosub memoryrecall 'new mine
end if 'new mine
IF BTN = Pressed then
High LED
StartCounter:
Time = 0
Counter = MinRunTime ' approx 400 ms
Do : Loop while BTN = Pressed and Time < MaxRunTime
if Time >= MaxRunTime then gosub MotorStalled
'// If here then switch released
'// Time Out after 400 ms (however, no delay if motor was previously stalled)
'// If another Press detected then reset timer
Do While Counter > 1
Counter = Counter - 1
If BTN = Pressed then 'start over
Goto StartCounter
END IF
Loop
LOW LED
END IF
' Now measure battery voltage approx once a second
inc VmonCount
if VmonCount>1000 then ' 1000 = approx 1 sec. Measure battery voltage approx once a second
VmonCount = 0
gosub MeasureBatteryVoltage
sertxd("Main Loop - Battery level: ")
gosub ShowVoltage
sertxd(" (LowBattCount: ",#LowBattCount,")",13,10) 'was cf,lf
if Volts <= LowBattLevel then ' Set at 10.4 Volts in "Constants" section
inc LowBattCount
if LowBattCount > LowBattDuration then ' approx 10 seconds
gosub LowBatteryVoltage
end if
else
LowBattCount = 0 ' reset count if battery doesn't stay low for specified duration
end if
end if
GOTO MAIN:
MotorStalled:
sertxd("Motor Stalled",13,10)
stallfaultcount = stallfaultcount + 1 ' added
write 16, word w8
SERTXD("motor stalled count = ",#stallfaultcount ,cr,lf) 'added
low LED '// Turn motor drive off
high LED2 '// Turn fault light on
do : loop while BTN = pressed '// Wait for switch to be released
'// If here then switch has been released
low LED2 '// Turn fault light off
sertxd("Microswitch has now reset",13,10) 'was cr,lf
Counter = 0 ' Set to zero so that it falls through 400 ms delay after return to main code
return
MeasureBatteryVoltage:
'// Measure average voltage over 10 readings.
ADCavg = 0 'Initialise to 0
for b1 = 1 to AvgCount 'adjust above for readings to average
ReadADC10 C.2,ADCvalue
ADCavg = ADCavg + ADCvalue
next b1
ADCavg = ADCavg / AvgCount
' Convert ADC Value to Voltage
Volts = ADCavg **64064 ' Convert 1023 to 1000 steps (**64064) for 5.00v reference
volts = volts *65 ' correction needed to make 102
volts = volts /64 ' read 104
Volts = Volts *16 ' Multiply by Vin (Fullscale 16v)(R1 22K)(R2 10K)
Volts = Volts /100 ' Reduce to 3 digits
'// Volts here will be 10 times actual voltage, eg 104 = 10.4v , 115 = 11.5v
return
ShowVoltage:
BinTOASCII Volts, b3,b2,b1 : IF b3 = "0" THEN : b3 = " " : ENDIF' leading zero blanking
Sertxd (b3,b2,".",b1," Volts") ' 0.1 resolution
return
LowBatteryVoltage:
LVDfaultcount = LVDfaultcount + 1 ‘ <<< Add this line
write 20,word w10
sertxd("LVDfaultcount: ",#LVDfaultcount,13,10) ‘ <<< Add this line
do
gosub MeasureBatteryVoltage
sertxd("Low Battery (")
gosub ShowVoltage
sertxd(") - Waiting for Voltage to reach 11.5V",13,10) 'was cf,ld
pause 4000 ' wait 1 second between readings
loop until Volts >= highbattvolt 'see symbols above was (115)
'// Battery voltage has now reached upper level
sertxd("Battery has reached 11.5v ")
gosub ShowVoltage
sertxd(" - Now charging for 1 hour",13,10) 'was cr.lf
'// Now wait an hour while battery continues to charge
'// Total charge time = Combination of ChargeReadInterval & ChargeReadCount
Counter = ChargeReadCount
do
gosub MeasureBatteryVoltage
sertxd("Battery level: ")
gosub ShowVoltage
sertxd(" - Charge time remaing: ",#Counter," Seconds",13,10) 'was cr,lf
pause ChargeReadInterval ' Time between voltage readings while charging
dec Counter
loop while Counter > 0
LowBattCount = 0 ' Reset time count for low battery voltage
return
Memoryrecall:
read 16,word w8 ' added for eprom storage
FlashCount = stallfaultcount 'Initialise loop counter to number of required flashes
Do Until FlashCount = 0
high 0
pause 5000
low 0
pause 5000
Dec FlashCount
loop
pause 10000
read 20,word w10 ' added for eeprom storage
flashcount = LVDfaultcount
Do Until FlashCount = 0
high 0
pause 5000
low 0
pause 5000
Dec FlashCount
loop
stallfaultcount = 0 'clears counters in ram but not eeprom
write 16, 0
LVDfaultcount = 0 'clears counters in ram but not eeprom
write 20, 0
return
'info
'Symbol MaxRunTime = 6 ' Time in seconds. (Set low for testing, 30 required)
'// TEMPORARILY SET ChargeReadCount TO 20 WHILE BENCH TESTING (This will make testing quicker).
'// ChargeReadCount NEEDS TO BE 3600 (currently 20 seconds)
'Symbol ChargeReadCount = 20 ' Normally 3600 readings while battery charges