Intelligent NiCd/NiMH Charger/Cycler with 128x64 Graphical LCD
The accu cycler project presented here is an excellent solution for charging and discharging NiCd and NiMH accumulators
for R/C modelers and others who make use of these accumulator types. With its performance it is very close to the many of the commercial
products available on the market. The 'power' part of the design is not a common choice in similar applications, having in mind of its
size and energy dissipation, but it is very easy to understand its principles of operation even for beginners in electronics.
The 'intelligent' part of the design communicates with PC using serial port providing additional process visualization.
The process graph is saved to on-board EEPROM memory and it is possible to download the data to PC even when the charging/discharging
process has finished.
The screenshot of the Accu Cycler application:
The Accu Cycler application is available
for the download here .
The firmware for the 16F877A chip used in this design is given in the form of Basic source program that has to be compiled
with PIC Simulator IDE integrated Basic compiler to get the HEX file ready to be programmed into the microcontroller.
This design can be used without any hardware modifications with 40-pin microcontrollers from 18F family. Here is the firmware for
the 18F452 chip in the form of Basic source program that has to be compiled with PIC18 Simulator IDE integrated Basic compiler to get the HEX file
ready to be programmed into the microcontroller. This microcontroller has more available program memory, so the firmware has
several additional features. Still there is a lot of space for additional modifications.
The firmware code (18F452): Copy code
#define CLOCK_FREQUENCY = 12
Symbol t_right = PORTD.7
Symbol t_down = PORTD.6
Symbol t_up = PORTD.5
Symbol t_left = PORTD.4
Symbol ledcharge = PORTD.2
Symbol leddischarge = PORTD.3
Symbol charge = PORTC.2
Symbol discharge = PORTC.1
Symbol i2cclock = PORTC.3
Symbol i2cdata = PORTC.4
Symbol ltc_clk = PORTE.0
Symbol ltc_dout = PORTE.1
Symbol ltc_cs = PORTE.2
#define GLCD_DREG = PORTB
#define GLCD_RSREG = PORTA
#define GLCD_RSBIT = 1
#define GLCD_EREG = PORTC
#define GLCD_EBIT = 5
#define GLCD_RWREG = PORTA
#define GLCD_RWBIT = 5
#define GLCD_CS1REG = PORTD
#define GLCD_CS1BIT = 0
#define GLCD_CS2REG = PORTC
#define GLCD_CS2BIT = 0
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 k As Byte
Dim x As Byte
Dim an0 As Word
Dim vmod As Word
Dim vfinal As Word
Dim v(25) As Word
Dim vlong As Long
Dim vlast 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
Dim yy1(48) As Word
Dim yy2(48) As Word
Dim yymin As Word
Dim yymax As Word
Dim yy As Word
Dim samplesnum As Word
Dim yyymin As Word
Dim yyymax As Word
Dim yyy As Word
Dim xxx As Word
Dim xxxstep As Byte
Dim templong As Long
PORTA = 0
PORTB = 0
PORTC = 0
PORTD = 0
PORTE = 0
TRISD.2 = 0
TRISD.3 = 0
TRISC.2 = 0
TRISC.1 = 0
TRISE.0 = 0
TRISE.2 = 0
ltc_cs = 1
All_Digital
ADCON1 = 0x0f
UART_Init 19200
GLcdinit
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 Gosub prog_cycle
If program = 4 Then Gosub prog_setup
If program = 5 Then Gosub prog_setupdefaults
If program = 6 Then Gosub prog_memory
Goto newprogram
End
welcome:
GLcdclear
GLcdposition 0, 4
GLcdwrite "OshonSoft."
GLcdposition 8, 0
GLcdwrite "com"
GLcdposition 1, 4
GLcdwrite "NiCd/NiMH "
GLcdposition 9, 0
GLcdwrite "Cycler"
GLcdposition 2, 4
GLcdwrite "Initializi"
GLcdposition 10, 0
GLcdwrite "ng..."
WaitMs 3000
Return
selectprogram:
phase = 1
GLcdclear
GLcdposition 0, 4
GLcdwrite "Select pro"
GLcdposition 8, 0
GLcdwrite "gram:"
loop1:
GLcdclean 1
GLcdclean 9
GLcdposition 1, 4
If phase = 1 Then GLcdwrite "1 - Charge"
If phase = 2 Then
GLcdwrite "2 - Discha"
GLcdposition 9, 0
GLcdwrite "rge"
Endif
If phase = 3 Then GLcdwrite "3 - Cycle"
If phase = 4 Then GLcdwrite "4 - Setup"
If phase = 5 Then
GLcdwrite "5 - Setup "
GLcdposition 9, 0
GLcdwrite "defaults"
Endif
If phase = 6 Then GLcdwrite "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:
GLcdclear
GLcdposition 0, 4
GLcdwrite "Starting.."
GLcdposition 8, 0
GLcdwrite "."
WaitMs 3000
Gosub getvin
For i = 1 To 24
v(i) = vin
Next i
If vin > 19 Then yymin = vin - 19 Else yymin = 0
For i = 0 To 47
yy1(i) = 0
yy2(i) = 0
Next i
vlast = 0
vmax = 0
vmaxdelay = 0
vmaxnum = 0
finish = 0
address = 0
seconds = 251
minutes = 0
hours = 0
key = 0
Return
draw:
'horizontal graph size 96 (15-110)
'vertical graph size 38 (26-63)
Gosub drawshift
yymax = yymin + 37
yy2(47) = vfinal
Gosub drawclean
For i = 0 To 47
yy = yy1(i)
If yy < yymin Then Goto next1
If yy > yymax Then Goto next1
yy = yy - yymin
k = 15 + i
j = 63 - yy
GLcdpset k, j
next1:
Next i
For i = 0 To 47
yy = yy2(i)
If yy < yymin Then Goto next2
If yy > yymax Then Goto next2
yy = yy - yymin
k = 15 + 48 + i
j = 63 - yy
GLcdpset k, j
next2:
Next i
Return
drawshift:
For i = 0 To 46
j = i + 1
yy1(i) = yy1(j)
Next i
yy1(47) = yy2(0)
For i = 0 To 46
j = i + 1
yy2(i) = yy2(j)
Next i
Return
drawclean:
GLcdclean 3
GLcdclean 4
GLcdclean 5
GLcdclean 6
GLcdclean 7
GLcdclean 11
GLcdclean 12
GLcdclean 13
GLcdclean 14
GLcdclean 15
For i = 26 To 63
GLcdpset 0, i
GLcdpset 127, i
Next i
GLcdpset 1, 26
GLcdpset 126, 26
GLcdpset 1, 63
GLcdpset 126, 63
GLcdpset 2, 26
GLcdpset 125, 26
GLcdpset 2, 63
GLcdpset 125, 63
Return
drawall:
'horizontal graph size 120 (4-123)
'vertical graph size 38 (26-63)
samplesnum = address / 2
If samplesnum = 0 Then Goto exitdraw
xxxstep = samplesnum / 500
xxxstep = xxxstep + 1
xxxstep = xxxstep * 2
Gosub drawclean
yyymin = 4095
yyymax = 0
For cnt = 2 To address Step xxxstep
I2CRead i2cdata, i2cclock, 0xa0, cnt, sample.LB, sample.HB
If sample < yyymin Then yyymin = sample
If sample > yyymax Then yyymax = sample
Next cnt
yyymax = yyymax - yyymin
For cnt = 2 To address Step xxxstep
I2CRead i2cdata, i2cclock, 0xa0, cnt, sample.LB, sample.HB
xxx = cnt / 2
templong = xxx * 119
templong = templong / samplesnum
k = templong
k = 4 + k
yyy = sample - yyymin
templong = yyy * 37
templong = templong / yyymax
j = templong
j = 63 - j
GLcdpset k, j
Next cnt
Gosub waitkey
exitdraw:
Gosub drawclean
Return
prog_discharge:
discharge = 1
leddischarge = 1
Gosub initroutine
GLcdclear
GLcdposition 0, 4
GLcdwrite "Dischargin"
GLcdposition 8, 0
GLcdwrite "g..."
While finish = 0
If signalfiltertype = 1 Then Gosub getvfinal1
If signalfiltertype = 2 Then Gosub getvfinal2
If signalfiltertype = 3 Then Gosub getvfinal3
If signalfiltertype = 4 Then Gosub getvfinal4
If signalfiltertype = 5 Then Gosub getvfinal5
If signalfiltertype = 6 Then Gosub getvfinal6
If signalfiltertype = 7 Then Gosub getvfinal7
If vfinal <= dischargelimit Then finish = 1
Gosub settime
Gosub showvoltage
Gosub storeeeprom
Gosub serialroutine
If key = c_left Then finish = 1
If key = c_right Then Gosub drawall
key = 0
Gosub getfocus
Gosub draw
Wend
GLcdclean 0
GLcdclean 8
GLcdposition 0, 4
GLcdwrite "Completed!"
discharge = 0
leddischarge = 0
Gosub endroutine
WaitMs 3000
Return
prog_charge:
charge = 1
ledcharge = 1
Gosub initroutine
GLcdclear
GLcdposition 0, 4
GLcdwrite "Charging.."
GLcdposition 8, 0
GLcdwrite "."
While finish = 0
If signalfiltertype = 1 Then Gosub getvfinal1
If signalfiltertype = 2 Then Gosub getvfinal2
If signalfiltertype = 3 Then Gosub getvfinal3
If signalfiltertype = 4 Then Gosub getvfinal4
If signalfiltertype = 5 Then Gosub getvfinal5
If signalfiltertype = 6 Then Gosub getvfinal6
If signalfiltertype = 7 Then Gosub getvfinal7
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
If key = c_right Then Gosub drawall
key = 0
Gosub getfocus
Gosub draw
Wend
GLcdclean 0
GLcdclean 8
GLcdposition 0, 4
GLcdwrite "Completed!"
charge = 0
ledcharge = 0
Gosub endroutine
WaitMs 3000
Return
prog_cycle:
Gosub prog_discharge
WaitMs 10000
Gosub prog_charge
Return
getfocus:
yymax = yymin + 37
If vfinal < 10 Then
yymin = 0
Else
If vfinal < yymin Then yymin = vfinal - 10
Endif
If vfinal > yymax Then yymin = vfinal - 25
Return
prog_setupdefaults:
dischargelimit = 1160
signalfiltertype = 7
peakgap = 5
peakdetect = 1
mintime = 5
minvalue = 1980
maxtime = 600
Gosub saveparameters
Return
prog_setup:
phase = 1
setuploop:
GLcdclear
GLcdposition 0, 4
GLcdwrite "Setup opti"
GLcdposition 8, 0
GLcdwrite "ons:"
GLcdclean 1
GLcdclean 9
GLcdclean 2
GLcdposition 1, 4
If phase = 1 Then
GLcdwrite "1 - Discha"
GLcdposition 9, 0
GLcdwrite "rge limit"
Endif
If phase = 2 Then
GLcdwrite "2 - Filter"
GLcdposition 9, 0
GLcdwrite " type"
Endif
If phase = 3 Then
GLcdwrite "3 - Peak g"
GLcdposition 9, 0
GLcdwrite "ap"
Endif
If phase = 4 Then
GLcdwrite "4 - Peak d"
GLcdposition 9, 0
GLcdwrite "etect"
Endif
If phase = 5 Then
GLcdwrite "5 - Min ti"
GLcdposition 9, 0
GLcdwrite "me"
Endif
If phase = 6 Then
GLcdwrite "6 - Min va"
GLcdposition 9, 0
GLcdwrite "lue"
Endif
If phase = 7 Then
GLcdwrite "7 - Max ti"
GLcdposition 9, 0
GLcdwrite "me"
Endif
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
Return
setup1:
GLcdclean 2
GLcdposition 2, 4
GLcdwrite #dischargelimit
GLcdposition 10, 0
vfinal = dischargelimit
Gosub showvoltageonly
Gosub waitkey
If key = c_up Then
If dischargelimit < 4000 Then dischargelimit = dischargelimit + 20 Else dischargelimit = 10
Goto setup1
Endif
If key = c_down Then
If dischargelimit > 10 Then dischargelimit = dischargelimit - 20 Else dischargelimit = 4000
Goto setup1
Endif
Return
setup2:
GLcdclean 2
GLcdposition 2, 4
GLcdwrite #signalfiltertype
GLcdposition 10, 0
If signalfiltertype = 1 Then GLcdwrite "Raw values"
If signalfiltertype = 2 Then GLcdwrite "Average L1"
If signalfiltertype = 3 Then GLcdwrite "Average L2"
If signalfiltertype = 4 Then GLcdwrite "Average H1"
If signalfiltertype = 5 Then GLcdwrite "Average H2"
If signalfiltertype = 6 Then GLcdwrite "Average U1"
If signalfiltertype = 7 Then GLcdwrite "Average U2"
Gosub waitkey
If key = c_up Then
If signalfiltertype < 7 Then signalfiltertype = signalfiltertype + 1
Goto setup2
Endif
If key = c_down Then
If signalfiltertype > 1 Then signalfiltertype = signalfiltertype - 1
Goto setup2
Endif
Return
setup3:
GLcdclean 2
GLcdposition 2, 4
GLcdwrite #peakgap
GLcdposition 10, 0
vfinal = peakgap
Gosub showvoltageonly
Gosub waitkey
If key = c_up Then
If peakgap < 20 Then peakgap = peakgap + 1 Else peakgap = 1
Goto setup3
Endif
If key = c_down Then
If peakgap > 1 Then peakgap = peakgap - 1 Else peakgap = 20
Goto setup3
Endif
Return
setup4:
GLcdclean 2
GLcdposition 2, 4
GLcdwrite #peakdetect
GLcdposition 10, 0
If peakdetect = 0 Then GLcdwrite "Off"
If peakdetect = 1 Then GLcdwrite "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:
GLcdclean 2
GLcdposition 2, 4
GLcdwrite #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:
GLcdclean 2
GLcdposition 2, 4
GLcdwrite #minvalue
GLcdposition 10, 0
vfinal = minvalue
Gosub showvoltageonly
Gosub waitkey
If key = c_up Then
If minvalue < 4000 Then minvalue = minvalue + 20 Else minvalue = 10
Goto setup6
Endif
If key = c_down Then
If minvalue > 10 Then minvalue = minvalue - 20 Else minvalue = 4000
Goto setup6
Endif
Return
setup7:
GLcdclean 2
GLcdposition 2, 4
GLcdwrite #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 > 4000 Then dischargelimit = 4000
If signalfiltertype < 1 Then signalfiltertype = 1
If signalfiltertype > 7 Then signalfiltertype = 7
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 > 4000 Then minvalue = 4000
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 x = 1 To 10
Gosub getan0_ltc
vin = vin + an0
Gosub scankey
WaitMs 100
Gosub scankey
WaitMs 100
Gosub scankey
WaitMs 100
Gosub scankey
WaitMs 100
Gosub scankey
WaitMs 95
Next x
vmod = vin Mod 10
vin = vin / 10
If vmod >= 5 Then vin = vin + 1
Return
getan0_ltc:
ltc_cs = 0
WaitUs 5
an0 = 0
Gosub ltcclock
Gosub ltcclock
Gosub ltcclock
an0.11 = ltc_dout
Gosub ltcclock
an0.10 = ltc_dout
Gosub ltcclock
an0.9 = ltc_dout
Gosub ltcclock
an0.8 = ltc_dout
Gosub ltcclock
an0.7 = ltc_dout
Gosub ltcclock
an0.6 = ltc_dout
Gosub ltcclock
an0.5 = ltc_dout
Gosub ltcclock
an0.4 = ltc_dout
Gosub ltcclock
an0.3 = ltc_dout
Gosub ltcclock
an0.2 = ltc_dout
Gosub ltcclock
an0.1 = ltc_dout
Gosub ltcclock
an0.0 = ltc_dout
WaitUs 5
ltc_cs = 1
Return
ltcclock:
ltc_clk = 1
WaitUs 5
ltc_clk = 0
WaitUs 5
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 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
If vfinal > vlast Then
For i = 1 To 4
v(i) = vfinal
Next i
For i = 5 To 6
v(i) = vfinal + 1
Next i
Endif
vlast = vfinal
Return
getvfinal4:
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
getvfinal5:
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
If vfinal > vlast Then
For i = 1 To 8
v(i) = vfinal
Next i
For i = 9 To 12
v(i) = vfinal + 1
Next i
Endif
vlast = vfinal
Return
getvfinal6:
For i = 1 To 23
j = i + 1
v(i) = v(j)
Next i
Gosub getvin
v(24) = vin
vlong = 0
For i = 1 To 24
vlong = vlong + v(i)
Next i
vmod = vlong Mod 24
vfinal = vlong / 24
If vmod >= 12 Then vfinal = vfinal + 1
Return
getvfinal7:
For i = 1 To 23
j = i + 1
v(i) = v(j)
Next i
Gosub getvin
v(24) = vin
vlong = 0
For i = 1 To 24
vlong = vlong + v(i)
Next i
vmod = vlong Mod 24
vfinal = vlong / 24
If vmod >= 12 Then vfinal = vfinal + 1
If vfinal > vlast Then
For i = 1 To 16
v(i) = vfinal
Next i
For i = 17 To 24
v(i) = vfinal + 1
Next i
Endif
vlast = vfinal
Return
showvoltage:
GLcdclean 1
GLcdclean 9
GLcdposition 1, 4
GLcdwrite "Voltage:"
GLcdposition 9, 0
Gosub showvoltageonly
Gosub showtime
Return
showtime:
GLcdclean 2
GLcdclean 10
GLcdposition 2, 4
GLcdwrite "Time:"
GLcdposition 10, 0
hours = minutes / 60
If hours < 10 Then GLcdwrite "0"
GLcdwrite #hours, ":"
hours = minutes Mod 60
If hours < 10 Then GLcdwrite "0"
GLcdwrite #hours, ":"
If seconds < 10 Then GLcdwrite "0"
GLcdwrite #seconds
Return
showvoltageonly:
'0V=0 2.5V=4095 25000/4095=6.105
vlong = vfinal * 25000
vlong = vlong / 4095
voltage = vlong.LW
voltage1 = voltage / 10000
voltage2 = voltage Mod 10000
GLcdwrite #voltage1, "."
If voltage2 < 1000 Then GLcdwrite "0"
If voltage2 < 100 Then GLcdwrite "0"
If voltage2 < 10 Then GLcdwrite "0"
GLcdwrite #voltage2, "V"
Return
serialroutine:
UART_Write #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
GLcdclear
GLcdposition 0, 4
GLcdwrite "Memory rea"
GLcdposition 8, 0
GLcdwrite "dy..."
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
UART_Write #sample, Lf
Next cnt
exit2:
address = cnt - 2
minutes = address / 2
minutes = minutes * 5
seconds = minutes Mod 60
minutes = minutes / 60
Gosub showtime
Gosub drawall
Endif
Wend
Return
The schematics of the main board:
view
The schematics of the power board:
view
The photo of the prototype:
view