Version:0.9 StartHTML:0000000105 EndHTML:0000089852 StartFragment:0000001119 EndFragment:0000089836
Define CONF_WORD = 0x3f72
Define CLOCK_FREQUENCY = 12
Symbol t_right = PORTB.3
Symbol t_down = PORTB.2
Symbol t_up = PORTB.1
Symbol t_left = PORTB.0
Symbol ledcharge = PORTA.1
Symbol leddischarge = PORTA.5
Symbol charge = PORTC.2
Symbol discharge = PORTC.1
Symbol i2cclock = PORTC.3
Symbol i2cdata = PORTC.4
Define LCD_BITS = 4
Define LCD_DREG = PORTB
Define LCD_DBIT = 4
Define LCD_RSREG = PORTC
Define LCD_RSBIT = 0
Define LCD_EREG = PORTC
Define LCD_EBIT = 5
Const c_right = 1
Const c_up = 2
Const c_down = 3
Const c_left = 4
Dim vin As Word
Dim i As Byte
Dim j As Byte
Dim an0 As Word
Dim vmod As Word
Dim vfinal As Word
Dim v(13) As Word
Dim vmax As Word
Dim vmaxdelay As Byte
Dim vmaxnum As Byte
Dim finish As Bit
Dim address As Word
Dim seconds As Byte
Dim minutes As Word
Dim hours As Byte
Dim voltage As Word
Dim voltage1 As Word
Dim voltage2 As Word
Dim cnt As Word
Dim sample As Word
Dim program As Byte
Dim phase As Byte
Dim key As Byte
Dim dischargelimit As Word
Dim signalfiltertype As Byte
Dim peakgap As Byte
Dim peakdetect As Byte
Dim mintime As Byte
Dim minvalue As Word
Dim maxtime As Word
PORTA = 0
PORTB = 0
PORTC = 0
TRISA.1 = 0
TRISA.5 = 0
TRISC.2 = 0
TRISC.1 = 0
AllDigital
ADCON1 = 0x0f
Hseropen 19200
Lcdinit
WaitMs 1000
Gosub loadparameters
newprogram:
Gosub welcome
Gosub selectprogram
If program = 1 Then Gosub prog_charge
If program = 2 Then Gosub prog_discharge
If program = 3 Then Goto prog_cycle
If program = 4 Then Goto prog_setup
If program = 5 Then Gosub prog_setupdefaults
If program = 6 Then Goto prog_memory
Goto newprogram
End
welcome:
Lcdcmdout LcdClear
Lcdout "OshonSoft Cycler"
Lcdcmdout LcdLine2Home
Lcdout "Initializing..."
WaitMs 3000
Return
selectprogram:
phase = 1
Lcdcmdout LcdClear
Lcdout "Select Program:"
loop1:
Lcdcmdout LcdLine2Clear
If phase = 1 Then Lcdout "1-Charge"
If phase = 2 Then Lcdout "2-Discharge"
If phase = 3 Then Lcdout "3-Cycle"
If phase = 4 Then Lcdout "4-Setup"
If phase = 5 Then Lcdout "5-Setup defaults"
If phase = 6 Then Lcdout "6-Memory"
Gosub waitkey
If key = c_down Then
phase = phase + 1
If phase = 7 Then phase = 1
Goto loop1
Endif
If key = c_up Then
phase = phase - 1
If phase = 0 Then phase = 6
Goto loop1
Endif
If key = c_right Then program = phase
If key = c_left Then program = 0
Return
waitkey:
key = 0
If t_right = 1 Then key = c_right
If t_up = 1 Then key = c_up
If t_down = 1 Then key = c_down
If t_left = 1 Then key = c_left
If key = 0 Then Goto waitkey
Gosub debounce
Return
getkey:
key = 0
If t_right = 1 Then key = c_right
If t_up = 1 Then key = c_up
If t_down = 1 Then key = c_down
If t_left = 1 Then key = c_left
If key > 0 Then Gosub debounce
Return
debounce:
If t_right = 1 Then i = 0
If t_up = 1 Then i = 0
If t_down = 1 Then i = 0
If t_left = 1 Then i = 0
i = i + 1
WaitMs 10
If i < 10 Then Goto debounce
Return
scankey:
If t_right = 1 Then key = c_right
If t_up = 1 Then key = c_up
If t_down = 1 Then key = c_down
If t_left = 1 Then key = c_left
Return
initroutine:
Lcdcmdout LcdClear
Lcdout "Starting..."
WaitMs 3000
Gosub getvin
For i = 1 To 12
v(i) = vin
Next i
vmax = 0
vmaxdelay = 0
vmaxnum = 0
finish = 0
address = 0
seconds = 251
minutes = 0
hours = 0
key = 0
Lcdcmdout LcdClear
Return
prog_discharge:
discharge = 1
leddischarge = 1
Gosub initroutine
Lcdout "Discharging..."
Lcdcmdout LcdLine2Home
While finish = 0
If signalfiltertype = 1 Then Gosub getvfinal1
If signalfiltertype = 2 Then Gosub getvfinal2
If signalfiltertype = 3 Then Gosub getvfinal3
If vfinal <= dischargelimit Then finish = 1
Gosub settime
Gosub showvoltage
Gosub storeeeprom
Gosub serialroutine
If key = c_left Then finish = 1
key = 0
Wend
Lcdcmdout LcdLine1Clear
Lcdout "Completed!"
discharge = 0
leddischarge = 0
Gosub endroutine
WaitMs 3000
Return
prog_charge:
charge = 1
ledcharge = 1
Gosub initroutine
Lcdout "Charging..."
Lcdcmdout LcdLine2Home
While finish = 0
If signalfiltertype = 1 Then Gosub getvfinal1
If signalfiltertype = 2 Then Gosub getvfinal2
If signalfiltertype = 3 Then Gosub getvfinal3
If vfinal > vmax Then vmaxdelay = vmaxdelay + 1
If vmaxdelay = 5 Then
If vmaxnum < 5 Then vmaxnum = vmaxnum + 1
vmax = vfinal
vmaxdelay = 0
Endif
If peakdetect = 1 Then
vfinal = vfinal + peakgap
If vfinal <= vmax Then finish = 1
vfinal = vfinal - peakgap
If vmaxnum < 5 Then finish = 0
Endif
If minutes < mintime Then
finish = 0
vmax = vfinal
vmaxdelay = 0
Endif
If vfinal < minvalue Then
finish = 0
vmax = vfinal
vmaxdelay = 0
Endif
If minutes >= maxtime Then finish = 1
Gosub settime
Gosub showvoltage
Gosub storeeeprom
Gosub serialroutine
If key = c_left Then finish = 1
key = 0
Wend
Lcdcmdout LcdLine1Clear
Lcdout "Completed!"
charge = 0
ledcharge = 0
Gosub endroutine
WaitMs 3000
Return
prog_cycle:
Gosub prog_discharge
WaitMs 10000
Gosub prog_charge
Goto newprogram
Return
prog_setupdefaults:
dischargelimit = 290
signalfiltertype = 3
peakgap = 2
peakdetect = 1
mintime = 5
minvalue = 495
maxtime = 600
Gosub saveparameters
Return
prog_setup:
phase = 1
setuploop:
Lcdcmdout LcdClear
Lcdout "Setup Options:"
Lcdcmdout LcdLine2Clear
If phase = 1 Then Lcdout "1-DischargeLimit"
If phase = 2 Then Lcdout "2-FilterType"
If phase = 3 Then Lcdout "3-PeakGap"
If phase = 4 Then Lcdout "4-PeakDetect"
If phase = 5 Then Lcdout "5-MinTime"
If phase = 6 Then Lcdout "6-MinValue"
If phase = 7 Then Lcdout "7-MaxTime"
Gosub waitkey
If key = c_down Then
phase = phase + 1
If phase = 8 Then phase = 1
Goto setuploop
Endif
If key = c_up Then
phase = phase - 1
If phase = 0 Then phase = 7
Goto setuploop
Endif
If key = c_right Then
If phase = 1 Then Gosub setup1
If phase = 2 Then Gosub setup2
If phase = 3 Then Gosub setup3
If phase = 4 Then Gosub setup4
If phase = 5 Then Gosub setup5
If phase = 6 Then Gosub setup6
If phase = 7 Then Gosub setup7
Goto setuploop
Endif
If key = c_left Then Gosub saveparameters
Goto newprogram
Return
setup1:
Lcdcmdout LcdClear
Lcdout "DischargeLimit:"
Lcdcmdout LcdLine2Home
Lcdout #dischargelimit
Lcdout " "
vfinal = dischargelimit
Gosub showvoltageonly
Gosub waitkey
If key = c_up Then
If dischargelimit < 1000 Then dischargelimit = dischargelimit + 5 Else dischargelimit = 10
Goto setup1
Endif
If key = c_down Then
If dischargelimit > 10 Then dischargelimit = dischargelimit - 5 Else dischargelimit = 1000
Goto setup1
Endif
Return
setup2:
Lcdcmdout LcdClear
Lcdout "FilterType:"
Lcdcmdout LcdLine2Home
Lcdout #signalfiltertype
Lcdout " "
If signalfiltertype = 1 Then Lcdout "Raw values"
If signalfiltertype = 2 Then Lcdout "Average LO"
If signalfiltertype = 3 Then Lcdout "Average HI"
Gosub waitkey
If key = c_up Then
If signalfiltertype < 3 Then signalfiltertype = signalfiltertype + 1
Goto setup2
Endif
If key = c_down Then
If signalfiltertype > 1 Then signalfiltertype = signalfiltertype - 1
Goto setup2
Endif
Return
setup3:
Lcdcmdout LcdClear
Lcdout "PeakGap:"
Lcdcmdout LcdLine2Home
Lcdout #peakgap
Lcdout " "
vfinal = peakgap
Gosub showvoltageonly
Gosub waitkey
If key = c_up Then
If peakgap < 10 Then peakgap = peakgap + 1 Else peakgap = 1
Goto setup3
Endif
If key = c_down Then
If peakgap > 1 Then peakgap = peakgap - 1 Else peakgap = 10
Goto setup3
Endif
Return
setup4:
Lcdcmdout LcdClear
Lcdout "PeakDetect:"
Lcdcmdout LcdLine2Home
Lcdout #peakdetect
Lcdout " "
If peakdetect = 0 Then Lcdout "Off"
If peakdetect = 1 Then Lcdout "On "
Gosub waitkey
If key = c_up Then
peakdetect = 1
Goto setup4
Endif
If key = c_down Then
peakdetect = 0
Goto setup4
Endif
Return
setup5:
Lcdcmdout LcdClear
Lcdout "MinTime:"
Lcdcmdout LcdLine2Home
Lcdout #mintime, " min"
Gosub waitkey
If key = c_up Then
If mintime < 60 Then mintime = mintime + 1 Else mintime = 1
Goto setup5
Endif
If key = c_down Then
If mintime > 1 Then mintime = mintime - 1 Else mintime = 60
Goto setup5
Endif
Return
setup6:
Lcdcmdout LcdClear
Lcdout "MinValue:"
Lcdcmdout LcdLine2Home
Lcdout #minvalue
Lcdout " "
vfinal = minvalue
Gosub showvoltageonly
Gosub waitkey
If key = c_up Then
If minvalue < 1000 Then minvalue = minvalue + 5 Else minvalue = 10
Goto setup6
Endif
If key = c_down Then
If minvalue > 10 Then minvalue = minvalue - 5 Else minvalue = 1000
Goto setup6
Endif
Return
setup7:
Lcdcmdout LcdClear
Lcdout "MaxTime:"
Lcdcmdout LcdLine2Home
Lcdout #maxtime, " min"
Gosub waitkey
If key = c_up Then
If maxtime < 1000 Then maxtime = maxtime + 5 Else maxtime = 10
Goto setup7
Endif
If key = c_down Then
If maxtime > 10 Then maxtime = maxtime - 5 Else maxtime = 1000
Goto setup7
Endif
Return
loadparameters:
address = 30000
I2CRead i2cdata, i2cclock, 0xa0, address, dischargelimit.LB, dischargelimit.HB
address = 30002
I2CRead i2cdata, i2cclock, 0xa0, address, signalfiltertype
address = 30003
I2CRead i2cdata, i2cclock, 0xa0, address, peakgap
address = 30004
I2CRead i2cdata, i2cclock, 0xa0, address, peakdetect
address = 30005
I2CRead i2cdata, i2cclock, 0xa0, address, mintime
address = 30006
I2CRead i2cdata, i2cclock, 0xa0, address, minvalue.LB, minvalue.HB
address = 30008
I2CRead i2cdata, i2cclock, 0xa0, address, maxtime.LB, maxtime.HB
If dischargelimit < 10 Then dischargelimit = 10
If dischargelimit > 1000 Then dischargelimit = 1000
If signalfiltertype < 1 Then signalfiltertype = 1
If signalfiltertype > 3 Then signalfiltertype = 3
If peakgap < 1 Then peakgap = 1
If peakgap > 10 Then peakgap = 10
If peakdetect > 1 Then peakdetect = 1
If mintime < 1 Then mintime = 1
If mintime > 60 Then mintime = 60
If minvalue < 10 Then minvalue = 10
If minvalue > 1000 Then minvalue = 1000
If maxtime < 10 Then maxtime = 10
If maxtime > 1000 Then maxtime = 1000
Return
saveparameters:
address = 30000
I2CWrite i2cdata, i2cclock, 0xa0, address, dischargelimit.LB, dischargelimit.HB
WaitMs 20
address = 30002
I2CWrite i2cdata, i2cclock, 0xa0, address, signalfiltertype
WaitMs 20
address = 30003
I2CWrite i2cdata, i2cclock, 0xa0, address, peakgap
WaitMs 20
address = 30004
I2CWrite i2cdata, i2cclock, 0xa0, address, peakdetect
WaitMs 20
address = 30005
I2CWrite i2cdata, i2cclock, 0xa0, address, mintime
WaitMs 20
address = 30006
I2CWrite i2cdata, i2cclock, 0xa0, address, minvalue.LB, minvalue.HB
WaitMs 20
address = 30008
I2CWrite i2cdata, i2cclock, 0xa0, address, maxtime.LB, maxtime.HB
WaitMs 20
Return
getvin:
vin = 0
For i = 1 To 60
Adcin 0, an0
vin = vin + an0
Gosub scankey
WaitMs 83
Next i
vmod = vin Mod 60
vin = vin / 60
If vmod >= 30 Then vin = vin + 1
Return
getvfinal1:
Gosub getvin
vfinal = vin
Return
getvfinal2:
For i = 1 To 5
j = i + 1
v(i) = v(j)
Next i
Gosub getvin
v(6) = vin
vfinal = 0
For i = 1 To 6
vfinal = vfinal + v(i)
Next i
vmod = vfinal Mod 6
vfinal = vfinal / 6
If vmod >= 3 Then vfinal = vfinal + 1
Return
getvfinal3:
For i = 1 To 11
j = i + 1
v(i) = v(j)
Next i
Gosub getvin
v(12) = vin
vfinal = 0
For i = 1 To 12
vfinal = vfinal + v(i)
Next i
vmod = vfinal Mod 12
vfinal = vfinal / 12
If vmod >= 6 Then vfinal = vfinal + 1
Return
showvoltage:
'0V=0 2.5V=1023 2500/1023=2.444
voltage = (vfinal * 2) + (vfinal * 4 / 10)
voltage = voltage + (vfinal * 4 / 100) + (vfinal * 4 / 1000)
voltage1 = voltage / 1000
voltage2 = voltage Mod 1000
Lcdcmdout LcdLine2Clear
Lcdout #voltage1, "."
If voltage2 < 100 Then Lcdout "0"
If voltage2 < 10 Then Lcdout "0"
Lcdout #voltage2, "V "
hours = minutes / 60
If hours < 10 Then Lcdout "0"
Lcdout #hours, ":"
hours = minutes Mod 60
If hours < 10 Then Lcdout "0"
Lcdout #hours, ":"
If seconds < 10 Then Lcdout "0"
Lcdout #seconds
Return
showvoltageonly:
'0V=0 2.5V=1023 2500/1023=2.444
voltage = (vfinal * 2) + (vfinal * 4 / 10)
voltage = voltage + (vfinal * 4 / 100) + (vfinal * 4 / 1000)
voltage1 = voltage / 1000
voltage2 = voltage Mod 1000
Lcdout #voltage1, "."
If voltage2 < 100 Then Lcdout "0"
If voltage2 < 10 Then Lcdout "0"
Lcdout #voltage2, "V"
Return
serialroutine:
Hserout #vfinal, Lf
Return
endroutine:
address = address + 2
I2CWrite i2cdata, i2cclock, 0xa0, address, 255, 255
address = address - 2
Return
storeeeprom:
address = address + 2
I2CWrite i2cdata, i2cclock, 0xa0, address, vfinal.LB, vfinal.HB
Return
settime:
seconds = seconds + 5
If seconds >= 60 Then
seconds = 0
minutes = minutes + 1
Endif
Return
prog_memory:
finish = 0
While finish = 0
Lcdcmdout LcdClear
Lcdout "Memory Ready..."
Gosub waitkey
If key = c_left Then finish = 1
If key = c_right Then
For cnt = 2 To 20000 Step 2
I2CRead i2cdata, i2cclock, 0xa0, cnt, sample.LB, sample.HB
If sample = 65535 Then Goto exit2
Hserout #sample, Lf
Next cnt
exit2:
address = cnt - 2
Endif
Wend
Goto newprogram
Return