#REM Li-Ion Battery Management System Master Module. By Peter Perkins Picaxe 28X1 - PIC16F886 - 270708 - www.150mpg.co.uk - V0.77 Video Beta **************************** General Information ****************************** The BMS modules carry no warranty or guarantee, and are used at the owners own risk. No liability will be entertained in any shape or form whatsoever. The modules and software have been produced for the benefit of the EV and electronic community. The software, hardware and source files, inc pcb layouts are made available free via the internet. Users may modify or adapt the system as they see fit. If you are not fully competent to work on potentially lethal battery systems and voltages, then do not experiment with/use this system. ************************** Master Picaxe 28X1 Pinout ************************** Top _____ (Pic Reset) Reset -01| ^ |28- Output 7 (Drive Inhibit Out) (Current Sensor In) Adc 0 -02| |27- Output 6 (Charger Relay Out) (Spare Adc In) Adc 1 -03| |26- Output 5 (Video Display Out) (Spare Adc In) Adc 2 -04| |25- Output 4 (Controller Cutback Out) (Spare Adc In) Adc 3 -05| P |24- Output 3 (WatchDog Led Out) (Program In) Rxd -06| 2 |23- Output 2 (Interrupt Out) (Program Out) Txd -07| 8 |22- Output 1 (Charger Cutback Out) (- Supply) -Ve -08| X |21- Output 0 (Audible Alarm Out) (Resonator In) Osc 1 -09| 1 |20- +Ve (+ Supply) (Resonator In) Osc 2 -10| |19- -Ve (- Supply) (Button A In) Input 0 -11| |18- Input 7 (Slave Data Bus In) (Button B In) Input 1 -12| |17- Input 6 (Interlocks In) (Temp Sensors In) Input 2 -13| |16- Output X (Dash Led 1 Out) (Speed Sensor In) Input 3 -14| |15- Output X (Dash Led 2 Out) ----- ************************ Master Module Specification ************************** Board Supply Voltage 8.00-20.00V DC or as limited by 5.00V 78L05 regulator CPU Supply Voltage 5.00V CPU Speed 8mhz with internal resonator (Pic limit 20mhz with external res) Average Board Supply Current at 12.00v <100ma Serial Bus data rate 4800 baud (Picaxe 08M limit at 8mhz) Maximum Cell Capacity 65ah (65535) (Limit of 16bit Word Variable) Maximum Pack Voltage 650v (65535) (Limit of 16bit Word Variable) Maximum Charge/Discharge rate 100A (Allegro Current Sensor limit) Maximum 128 Slave Modules per Master Module (Pic Scratchpad Ram limit) Battery Pack Temp Sensor Range (0 to 127C) Composite Video Display data rate 9600 baud (SV2000 Serial to Video Chip) Composite RCA Video Monitor Output 1V 75ohm PAL/NTSC Charger relay output 5.00v at 500ma Opto Isolated Charger/Controller Cutback outputs max 25ma ******************************************************************************* #ENDREM `Variables Constants and I/O definitions `Variables 16bit (Word) symbol CellVoltage = w1 ;w1 (b2,b3) = Cell Voltage 0-1023 10bit (0-5v) symbol PackVoltage = w2 ;w2 (b4,b5) = Calculated pack voltage (Voltage of individual Cells added together) symbol Soc = w3 ;w3 (b6,b7) = Calculated pack capacity (Soc State of Charge) resolution 10ma symbol BatCurrent = w4 ;w4 (b8,b9) = Current Sensor ADC value 0-1023 10bit Approx 200ma resolution symbol DutyCycle = w5 ;w5 (b10,b11) = Charger & Controller HPWM Duty Cycle 0 - 100% (0-1023) (+/- 10 = 1%) symbol Charge = w6 ;w6 (b12,b13) = Accumulated Charge current for last minute symbol Discharge = w7 ;w7 (b14,b15) = Accumulated Discharge current for last minute symbol Speed = w8 ;w8 (b16,b17) = Vehicle calculated speed in mph/kph symbol Distance = w9 ;w9 (b18,b19) = Distance (feet) travelled accumulator (5280ft = 1 mile) symbol WhMile = w10 ;w10(b20,b21) = Watt Hours per mile (Power Consumed) symbol CountW = w11 ;w11(b22,b23) = General 0-65535 16bit Word Counter/Local Variable `Variables 8bit (Byte) symbol CountA = b27 ;b27 = General 0-255 8bit Byte Counter or General/Local Variable symbol CountB = b26 ;b26 = General 0-255 8bit Byte Counter or General/Local Variable symbol PackTemp = b25 ;b25 = Pack Temperature 1C resolution (0 to 127C) symbol SocCounter = b24 ;b24 = SocCounter increments each time current measured to calc av 1 min current symbol VoltageData = b2 ;b2 = Voltage data byte (8bit value) (Received from Slave via serial link) symbol Warnings = b1 ;b1 = Warnings Flags byte (To clear all warning flags set b1=0) `General Flags x8 1bit (b0) ;Note the 16 Bit flags use Byte variables (b0) & (b1) which in turn use Word (w0) symbol WatchFlag = bit0 ;bit0 = Watchdog Flag pulses dash led every other time through Main loop symbol PosNegFlag = bit1 ;bit1 = Pos/Neg Amps used to indicate Charge/Discharge (0=Charge+) (1=Discharge-) symbol ChargeFlag = bit2 ;bit2 = ChargeFlag indicates charging in progress (0=Not Charging) (1=Charging) symbol IlockFlag = bit3 ;bit3 = IlockFlag indicates readiness to drive (0=Ready) (1=Not Ready) Interlocks symbol Unused4 = bit4 ;bit4 = symbol Unused5 = bit5 ;bit5 = symbol Unused6 = bit6 ;bit6 = symbol Unused7 = bit7 ;bit7 = `Note to clear all eight warning flags below in one go set (Warnings or b1 to Zero) `Warning Flags x 8 1bit (b1) symbol Warn1 = bit8 ;bit8 = Warning Flag (Cell over AbsMax V) symbol Warn2 = bit9 ;bit9 = Warning Flag (Cell under AbsMin V) symbol Warn3 = bit10 ;bit10 = Warning Flag (Cell over Max V) symbol Warn4 = bit11 ;bit11 = Warning Flag (Cell under Min V) symbol Warn5 = bit12 ;bit12 = Warning Flag (Cell data serial transfer timeout error) symbol Warn6 = bit13 ;bit13 = Warning Flag (Battery Pack over AbsMax Temp) symbol Warn7 = bit14 ;bit14 = Warning Flag (Battery Pack over Max Temp) symbol Warn8 = bit15 ;bit15 = `***** EEPROM Data Storage 0-255 bytes used for SOC, Odometer, Wh and other as yet undefined ideas! **** `Data Store Constants symbol SocStore = 0 ;Address in EEPROM at which SOC readings are stored each minute symbol DistStore = 2 ;Address in EEPROM at which Distance readings are stored symbol OdoStore = 4 ;Address in EEPROM at which Odometer readings are stored symbol WhStore = 6 ;Address in EEPROM at which WhMile readings are stored each minute `*** Special Compiler Variable Notes *** `Timer = Internal timer variable and set to 1 second ticks (t1s_8) `ptr = Scratchpad Ram Variable data pointer (Scratchpad is 128 bytes) `@ptrinc = Scratchpad Ram pointer with automatic increment after execution. `Constants symbol Cells = 50 ;Number of cells in the battery pack (50) (Max is 128 cells) symbol MaxPackVoltage = 19000 ;Maximum pack voltage = 190v (19,000 as 16 bit value) Res 10mv (Max 650v) symbol MinPackVoltage = 10000 ;Minimum pack voltage = 100v (10,000 as 16 bit value) Res 10mv symbol AbsMaxCellVoltage = 385 ;Absolute Maximum permitted cell voltage = (3.85V) (Alarm & Shutdown point) symbol MaxCellVoltage = 370 ;Normal Maximum permitted cell voltage = (3.70V) (Charger/Regen cutback point) symbol MinCellVoltage = 220 ;Normal Minimum permitted cell voltage = (2.20V) (Controller/Assist cutback point) symbol AbsMinCellVoltage = 200 ;Absolute Minimum permitted cell voltage = (2.00V) (Alarm & Shutdown point) symbol AbsMaxPackTemp = 55 ;Absolute Maximum permitted pack temperature = (55C) (Alarm & Shutdown point) symbol MaxPackTemp = 45 ;Maximum permitted pack temperature = (45C) (Warning & Cutback point) symbol CellCapacity = 40000 ;Nominal cell capacity = 40ah (40,000 as 16 bit value) Res 1ma (Max 65A) symbol Delay = 5 ;Interrupt and data delay in milliseconds (5ms) symbol DiscardLow = 175 ;Cell correction value 175 or 1.75V added to CellVoltage to recreate correct V symbol DiscardHigh = 430 ;Cell correction value 430 or 4.30V (Not currently used in Master Software) symbol TimeOut = 100 ;Serial Data Receive Timeout value 100ms symbol PwmFreq = 199 ;Frequency for HPWM outputs (199 = 5khz) (99 = 10khz) (49 = 20khz) symbol PulsePerMile = 455 ;Pulses from speed sensor per mile (4550) / 10 to fit into integer maths symbol MaxMainsChg = 15 ;Maximum permitted mains charging current in amps (15A) `Pins used for I/O and designations `*** Digital high/low Outputs *** symbol Alarm = 0 ;Audible Alarm warning on Output 0 symbol ChargerPWM = 1 ;Charger Cutback PWM output on Output 1 (Opto conducts when cell V > 3.70V) symbol SlaveInitiate = 2 ;Slave Data initiate interrupt Opto on Output 2 symbol WatchDogLed = 3 ;Watchdog flashing Green Led on Output 3 symbol ControllerPWM = 4 ;Controller Cutback PWM Output on Output 4 (Opto conducts when cell V < 2.20V) symbol Video = 5 ;Dashboard Video display on Output 5 (9600 baud Video) (4800 x 2) at 8mhz symbol ChargerOnOff = 6 ;Charger Relay On/Off control on Output 6 (5.00v Max 500ma) symbol DriveInhibit = 7 ;Drive inhibit Opto on Output 7 symbol Led1 = X ;Dashboard Led 1 on Output X) symbol Led2 = X ;Dashboard Led 2 on Output X) `*** Digital high/low Inputs *** symbol ButtonA = pin0 ;Dashboard A button on Input 0 symbol ButtonB = pin1 ;Dashboard B button on Input 1 symbol TempSensor = 2 ;I2C DS18B20 Battery Pack Temp Sensors on Input 2 (-55 to +125C) symbol SpeedSensor = 3 ;Speed Sensor 5.00V pulse counter input on Input 3 symbol Interlocks = pin6 ;Interlocks and additional safety switch inputs on Input 6 symbol SlaveData = 7 ;Slave Data Bus 4800baud on Input 7 `*** Analogue ADC Inputs *** symbol CurrentSensor = 0 ;Battery Current Sensor 0-5V ADC on Input 0 (+100 to -100A) 2.5v = 0 Amps ;************************************************************************************************************* Start: ;Initialise Program. Start Timer, Load Variables, Start Hardware PWM setfreq m8 ;Setfreq CPU Freq to 8mhz read SocStore, WORD Soc ;Load last saved Soc reading from eeprom storage if Soc = 0 then ;Test if stored SOC is 0, if it is then reset SOC to CellCapacity Soc = CellCapacity ;Set Initial SOC (State of charge) to CellCapacity (40ah = 40,000) endif read DistStore, WORD Distance ;Load last saved Distance (Feet) reading from eeprom storage read WhStore, WORD WhMile ;Load last saved WhMile reading from eeprom storage settimer t1s_8 ;Set internal (timer) variable to 1 second ticks at 8mhz hpwm 0,0,%1100,PwmFreq,0 ;Start internal HPWM outputs 1 & 4 at 0% duty cycle ;************************************************************************************************************* ;************************************************************************************************************* MainLoop: ;Main program loop If WatchFlag = 0 then ;If WatchFlag = 0 then turn on Led high WatchDogLed ;Turn on Green Led WatchFlag = 1 ;Set WatchFlag to 1 else ;If WatchFlag = 1 then turn off led low WatchDogLed ;Turn off Green Led WatchFlag = 0 ;Set WatchFlag to 0 end if gosub CheckCells ;Gosub CheckCells routine to interogate cells and collect cell V data gosub CheckTemp ;Gosub Checktemp routine to evaluate battery pack temperature gosub CheckInterlocks ;Gosub CheckInterlocks routine to evaluate readiness to drive gosub CheckCurrent ;Gosub CheckCurrent routine to accumulate charge/discharge data gosub CheckSpeed ;Gosub CheckSpeed routine to calculate/speed distance if timer >59 then gosub CalcSoc ;if SocTimer > 59 (1 Minute has elapsed so Calculate Soc) if Warnings > 0 then gosub Warning ;Gosub Warning Flags Routine if set and act on Warnings as reqd If ButtonA = 1 then gosub StartChg ;Gosub Start Charging Routine gosub Display ;Gosub Display BMS Data on Lcd/Video routine goto mainloop ;Goto main program loop ;************************************************************************************************************* ;************************************************************************************************************* CheckCells: ;Check Cells subroutine, receive data to calculate pack voltage ptr = 0 ;Reset Scratchpad pointer to 0 (Start of 128 byte Scratchpad Ram) high SlaveInitiate ;Send interrupt signal to Slave cell 1 opto pause Delay ;Hold interrupt signal high until Slave has time to respond low SlaveInitiate ;Turn off Slave Interrupt signal for CountB = 1 to Cells ;Start for/next loop to store cell data in 128 byte Scratchpad Ram serin [TimeOut,DataError],SlaveData,N2400,@ptrinc ;Receive Data on opto bus into Scratchpad Ram and inc pointer next CountB ;Increment for/next loop and move to next Cell PackVoltage = 0 ;Reset PackVoltage Total to zero = 0V ptr = 0 ;Reset Scratchpad pointer to 0 (Start of 128 byte Scratchpad Ram) for CountB = 1 to Cells ;Start for/next loop to calculate Pack voltage and check cell data/voltage CellVoltage = 0 ;Clear CellVoltage Variable VoltageData = @ptrinc ;Load VoltageData (b2) with value from Scratchpad Ram and inc data pointer CellVoltage = CellVoltage + DiscardLow ;CellVoltage (w1) = CellVoltage (w1) (1-255 0.01-2.55V) + (175 1.75V) ;Note (w1) is a 16 bit word variable made up of (b2) & (b3) byte variables if CellVoltage > AbsMaxCellVoltage then ;If cell V > AbsMaxCellVoltage then set Warning Flag Warn1 = 1 ;Set Warn1 Flag to 1 (Indicates Cell over AbsMax Voltage condition) endif if CellVoltage < AbsMinCellVoltage then ;If cell V < AbsMinCellVoltage then set Warning Flag Warn2 = 1 ;Set Warn2 Flag to 1 (Indicates Cell under AbsMin Voltage condition) endif if CellVoltage > MaxCellVoltage then ;If cell V > MaxCellVoltage then set Warning Flag Warn3 = 1 ;Set Warn3 Flag to 1 (Indicates Cell over Max Voltage condition) endif if CellVoltage < MinCellVoltage then ;If cell V < MinCellVoltage then set Warning Flag Warn4 = 1 ;Set Warn4 Flag to 1 (Indicates Cell under Min Voltage condition) endif PackVoltage = PackVoltage + CellVoltage ;Add Cell voltage to accumulated Pack voltage next CountB ;Increment for/next loop and move to next cell return ;Return to main program loop DataError: ;Serial Slave Data Receive TimeOut error routine. ;If no Data received within (TimeOut = 100ms) then execution jumps here Warn5 = 1 ;Set Warn5 Flag to 1 (Indicates Cell Data Timeout Error) return ;Return to main program loop ;************************************************************************************************************** CheckTemp: ;Check Battery Pack temperature routine readtemp TempSensor, PackTemp ;Read Battery Pack temperature into variable (PackTemp) (+127C to -127C) if PackTemp > 127 then ;Test for Value >127 = Temp <0C PackTemp = 0 ;Set Temp to 0C if less than 0C endif if PackTemp > AbsMaxPackTemp then ;If PackTemp > AbsMaxPackTemp set Warning Flag Warn6 = 1 ;Set Warn6 Flag to 1 (Indicates Pack over AbsMax Temp condition) endif if PackTemp > MaxPackTemp then ;If PackTemp > MaxPackTemp set Warning Flag Warn7 = 1 ;Set Warn7 Flag to 1 (Indicates Pack over Max Temp condition) endif return ;Return to main program loop ;************************************************************************************************************** CheckInterlocks: ;Check Interlocks Routine for readiness to drive If Interlocks = 1 then ;If Interlocks pin = 1 (High) then set IlockFlag IlockFlag = 1 ;Set IlockFlag to 1 (Indicates Interlock Set condition = Not ready to drive) High DriveInhibit ;Set Drive Inhibit output high to disable controller (Prevent Driving) else IlockFlag = 0 ;Set IlockFlag to 0 (Indicates Interlock Clear condition = Ready to drive) Low DriveInhibit ;Set Drive Inhibit output low to enable controller (Allow Driving) endif return ;Return to main program loop ;************************************************************************************************************** CheckCurrent: ;Accumulate (Current in Amps) charge/discharge data CountW = 0 ;Set Local Variable CountW to 0 (Zero) for CountB = 1 to 10 ;10x ADC Current Sensor Oversampling loop counter readadc10 CurrentSensor, BatCurrent ;Read present charge/discharge current (0-1023 10bit)(-100A to +100A 0-5V) CountW = CountW + BatCurrent ;Add latest ADC reading to running total CountW (Local Variable) next CountB ;Repeat loop until 10 ADC readings obtained BatCurrent = CountW / 10 ;Calculate average ADC reading for last 10 readings if BatCurrent >512 then ;If BatCurrent is >512 means system is Charging BatCurrent = BatCurrent - 512 ;Subtract sensor offset to get a positive number (0-512 = 0-100A+) BatCurrent = BatCurrent * 100 / 512 ;Convert sensor charge rate to charge rate in Amps Charge = Charge + BatCurrent ;Add Latest sensor Current reading to running 1 minute Charge total PosNegFlag = 0 ;Set display indicator flag to (0 = +) Display Ascii Character (43 Decimal) goto ExitCurrent endif if BatCurrent <512 then ;If BatCurrent is <512 means system is Discharging BatCurrent = 512 - BatCurrent ;Subtract sensor offset to get a positive number (0-512 = 0-100A-) BatCurrent = BatCurrent * 100 / 512 ;Convert sensor charge rate to charge rate in Amps Discharge = Discharge + BatCurrent ;Add Latest sensor Current reading to running 1 minute Discharge total PosNegFlag = 1 ;Set display indicator flag to (1 = -) Display Ascii Character (45 Decimal) goto ExitCurrent endif ExitCurrent: inc SocCounter ;SocCounter = SocCounter + 1 return ;Return to main program loop ;************************************************************************************************************** CheckSpeed: CountW = 0 ;Set Local Variable CountW to 0 (Zero) Count SpeedSensor,250,CountW ;Measure speed by counting VSS pulses for 250ms (Vehicle Speed Sensor) Speed = CountW * 1440 / PulsePerMile ;Calculate Speed in mph CountW = CountW * 2112 / PulsePerMile ;Calculate Feet travelled in last second Distance = Distance + CountW ;Add distance travelled in last second to running total If Distance >= 5280 then ;5280ft per mile / Tyre circumference 5.8ft = 910 revs per mile read OdoStore, WORD CountW ;Load last saved Odometer (Mile) reading from eeprom storage inc CountW ;Increment Odometer by 1 mile write OdoStore, WORD CountW ;Write current Odometer reading to eeprom for storage when Master Off Distance = Distance - 5280 ;Subtract (5280ft 1mile) from Distance and start accumulating again endif return ;Return to main program loop ;************************************************************************************************************** CalcSoc: ;Use 1 min accumulated sensor current data to calculate Soc if Charge > 0 then ;If no Charge in last minute jump over Charge calculations Charge = Charge / SocCounter ;Calculate average sensor charge rate for last minute `REM Charge = Charge * 100 / 6 ;This line may be needed with values that exceed 65,000 integer maths Charge = Charge * 1000 / 60 ;Calculate Amount of power/current added in last minute Soc = Soc + Charge ;Add amount of power generated in last minute to (Soc) PackCapacity Charge = 0 ;Reset Charge Counter to 0 endif if Discharge > 0 then ;If no Discharge in last minute jump over Discharge calculations Discharge = Discharge / SocCounter ;Calculate average sensor discharge rate for last minute `REM Discharge = Discharge * 100 / 6 ;This line may be needed with values that exceed 65,000 integer maths Discharge = Discharge * 1000 / 60 ;Calculate Amount of power/current used in last minute Soc = Soc - Discharge ;Subtract amount of power used in last minute from (Soc) PackCapacity Discharge = 0 ;Reset Discharge Counter to 0 endif write SocStore, WORD Soc ;Write Soc reading to eeprom for storage when Master Off write DistStore, WORD Distance ;Write Distance reading to eeprom for storage when Master Off write WhStore, WORD WhMile ;Write WhMile reading to eeprom for storage when Master Off SocCounter = 0 ;Reset SocCounter to 0 settimer t1s_8 ;Reset internal (timer) variable to 1 second ticks at 8mhz return ;Return to main program loop ;************************************************************************************************************** Warning: ;Warnings/Alarms turns on led/audible alarms and turns down charger etc ;Action taken depends on Warning Flags (8 different warnings max!) If Warn1 = 1 then ;bit8 = Warning Flag (Cell over AbsMax V) high DriveInhibit ;Set drive inhibit opto output high high Alarm ;Activate audible alarm low ChargerOnOff ;Turn off Charger main relay else low DriveInhibit ;Set drive inhibit opto output low low Alarm ;Deactivate audible alarm endif If Warn2 = 1 then ;bit9 = Warning Flag (Cell under AbsMin V) high DriveInhibit ;Set drive inhibit opto output high high Alarm ;Activate audible alarm else low DriveInhibit ;Set drive inhibit opto output low low Alarm ;Deactivate audible alarm endif If Warn3 = 1 then ;bit10 = Warning Flag (Cell over Max V) if DutyCycle <= 1013 then ;Check to see if DutyCyle <= 1013 and can be Incremented (Max 1023) DutyCycle = DutyCycle + 10 ;Increment DutyCycle by 10 to increase opto conduction by 1% endif endif If Warn4 = 1 then ;bit11 = Warning Flag (Cell under Min V) endif If Warn5 = 1 then ;bit12 = Warning Flag (Cell data serial transfer timeout error) endif If Warn6 = 1 then ;bit13 = Warning Flag (Battery Pack over Abs Max Temp) high DriveInhibit ;Set drive inhibit opto output high high Alarm ;Activate audible alarm low ChargerOnOff ;Turn off Charger main relay else low DriveInhibit ;Set drive inhibit opto output low low Alarm ;Deactivate audible alarm endif If Warn7 = 1 then ;bit14 = Warning Flag (Battery Pack over Max Temp) endif If Warn8 = 1 then ;bit15 = Unused Warning Flag endif hpwmduty DutyCycle ;Set updated HPWM Charger/Controller DutyCycle to adjust output/limit return ;Return to main program loop ;************************************************************************************************************** ;************************************************************************************************************** Display: ;General and Extended Cell BMS Data Display Routines If ButtonB = 1 then DisplayB ;Goto Display Extended Cell BMS Data DisplayA: ;Display General Parameters on Dashboard Lcd or Video Screen if PosNegFlag = 0 then ;Check Amps (+/-) Display flag and set character to display CountB = 43 ;Set Character (+) to be displayed if charging else CountB = 45 ;Set Character (-) to be displayed if discharging endif CountW = PackVoltage * BatCurrent / 100 ;Instantaneous Power (W) = PackVoltage x BatCurrent = Power in Watts serout Video,N4800,("Volts ",#PackVoltage," Temp",#PackTemp,"C ") ;Output to Video Display serout Video,N4800,("Cap ",#Soc," Amps",CountB,#BatCurrent," ") ;Output to Video Display serout Video,N4800,("Kw ",#CountW," Wh ",#WhMile," ") ;Output to Video Display serout Video,N4800,("Mph ",#Speed," Odo ",#Distance," ") ;Output to Video Display serout Video,N4800,("Alarms") ;Output to Video Display Warnings = 0 ;Reset Warnings Flags return ;Return to main program loop ;************************************************************************************************************** DisplayB: ;Display Extended Cell BMS Data ptr = 0 ;Reset Scratchpad pointer to 0 (Start of 128 byte Scratchpad Ram) for CountA = 1 to Cells ;Start for/next loop to read cell data from 128 byte Scratchpad Ram CellVoltage = 0 ;Clear CellVoltage Variable VoltageData = @ptrinc ;Load VoltageData (b2) with value from Scratchpad Ram and inc data pointer CellVoltage = CellVoltage + DiscardLow ;CellVoltage (w1) = CellVoltage (w1) (1-255 0.01-2.55V) + (175 1.75V) serout Video,N4800,("Cell ",#CountA," Volts ",#CellVoltage," ") ;Output to Video Display Loop1: If ButtonB = 0 then Loop1 ;If Button B is not pressed goto Loop1 next CountA ;Increment for/next loop and move to next cell return ;Return to main program loop ;************************************************************************************************************** ;************************************************************************************************************** StartChg: ;Start Charging Cycle Routine If Warnings>0 then ;If Warnings >0 means an error flag is set & charge start is aborted return ;Return to main loop, charging aborted due to error flag set endif DutyCycle = 0 ;Allow charger to start at maximum output Set PWM to 0% hpwmduty DutyCycle ;Set updated HPWM Charger/Controller DutyCycle to adjust output/limit ChargeFlag = 1 ;Set ChargeFlag to 1 indicates Charging in progress high ChargerOnOff ;Turn on Charger main relay return ;Return to main program loop #REM ************************************************************************************************************** ************************** Odd stuff and code not used at present! ****************************************** ************************************************************************************************************** 'To display an Integer Word Varaiable to two decimal places on Picaxe Lcd Axe033 w0 = value / 1000 w1 = value // 1000 SerTxd( #w0, "." ) If w1 < 100 Then : SerTxd("0") : End If If w1 < 10 Then : SerTxd("0") : End If SerTxd( #w1, CR, LF ) else if DutyCycle >= 10 then ;Check to see if DutyCyle >= 10 and can be decremented (Min 0) DutyCycle = DutyCycle - 10 ;Decrement DutyCycle by 10 to decrease opto conduction by 1% #ENDREM