#REM Li-Ion Battery Management System Master Module. By Peter Perkins Picaxe 28X1 - PIC16F886 - 230708 - www.150mpg.co.uk - V0.66 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 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 (Lcd/Video Out) (Spare Adc In) Adc 2 -04| |25- Output 4 (Controller Cutback Out) (Spare Adc In) Adc 3 -05| P |24- Output 3 (Dashboard 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 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 (Data Bus In) (Button B In) Input 1 -12| |17- Input 6 (Interlocks In) (Temp Sensors In) Input 2 -13| |16- Input 5 (Spare Dig In) (Speed Sensor In) Input 3 -14| |15- Input 4 (Spare Dig In) ----- ************************ 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 4mhz with internal resonator (Pic limit 20mhz with external res) Average Board Supply Current at 12.00v <100ma Serial Bus data rate 2400 baud (Picaxe 08M limit at 4mhz) Maximum Cell Capacity 65ah (65,535) (Limit of 16bit Word Variable) Maximum Pack Voltage 650v (65,535) (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) Lcd Display data rate 2400 baud (Picaxe AXE033 16x2) Charger relay output 5.00v at 500ma Opto Isolated Charger/Controller Cutback outputs max 25ma RCA Video Output 1V 75ohm ******************************************************************************* #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 and 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) = Vehicle odometer distance travelled miles/km 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 ADC Value 0-255 8bit Approx 1 degree C resolution (-127 to +127C) symbol SocTimer = b24 ;b24 = SocTimer increments each second current measured until reaches 60 (1 min) 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 the Byte variables (b0) & (b1) which in turn use Word (w0) symbol DispFlag = bit0 ;bit0 = BMS Output display mode (0 = 20x2 Lcd Out) (1 = RCA Video Out) symbol PosNegFlag = bit1 ;bit1 = Positive/Negative Amps used to indicate Charge/Discharge (0=Charge+) (1=Discharge-) symbol TempFlag = bit2 ;bit2 = TempFlag used to display (+ or -) temperatures. (0 = +) (1 = -) symbol ChargeFlag = bit3 ;bit3 = ChargeFlag used to indicate charging in progress (0=Not Charging) (1=Charging) symbol IlockFlag = bit4 ;bit4 = IlockFlag used to indicate readiness to drive (0=Ready) (1=Not Ready) Interlocks symbol Unused4 = bit5 ;bit5 = symbol Unused5 = bit6 ;bit6 = symbol Unused6 = 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 Odometer readings are stored each minute symbol WhStore = 4 ;Address in EEPROM at which Wh readings are stored each minute `*** Special Compiler Variable Notes *** ` Timer = Internal timer variable and set to 1 second ticks (t1s_4) ` ptr = Scratchpad Ram Variable data pointer (Scratchpad is 128 bytes) ` @ptrinc = Scratchpad Ram pointer with automatic increment after execution. `Constants symbol Cells = 10 ;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) `Pins used for I/O and designations `*** Digital high/low Outputs *** symbol Piezo = 0 ;Piezo audible 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 Led = 3 ;Led visual warning on Output 3 symbol ControllerPWM = 4 ;Controller Cutback PWM Output on Output 4 (Opto conducts when cell V < 2.20V) symbol LcdVideo = 5 ;Dashboard Lcd/Video display on Output 5 (2400 baud Lcd or 9600 baud Video) symbol ChargerOnOff = 6 ;Charger Relay On/Off control on Output 6 (5.00v Max 500ma) symbol DriveInhibit = 7 ;Drive inhibit Opto on Output 7 `*** 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 2400baud 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 special variables, start Hardware PWM 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 Odometer reading from eeprom storage read WhStore, WORD WhMile ;Load last saved WhMile reading from eeprom storage settimer t1s_4 ;Set internal (timer) variable to 1 second ticks at 4mhz hpwm 0,0,%1100,PwmFreq,0 ;Start internal HPWM outputs 1 & 4 at 0% duty cycle DispFlag = 0 ;Set Display mode to (0) 20x2 lcd text output (1 = RCA Video Out) ;************************************************************************************************************* ;************************************************************************************************************* ;************************************************************************************************************* Main: ;Main program loop executed once a second. 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 If timer >0 then gosub SpeedCurrent ;Gosub SpeedCurrent routine to accumulate 1s charge/discharge data + speed if SocTimer >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 gosub DisplayA ;Display Normal BMS Data on Lcd/Video If ButtonA = 1 then gosub StartChg ;Gosub Start Charging Routine If ButtonB = 1 then gosub DisplayB ;Gosub Display Extended BMS Data on Lcd/Video goto main ;Goto main program loop ;************************************************************************************************************* ;************************************************************************************************************* ;************************************************************************************************************* DisplayA: ;Display Normal Parameters on Dashboard Lcd or Video Screen if TempFlag = 0 then ;Check Temp (+/-) Display flag and set character to display CountA = 43 ;Set Character (+) to be displayed Temperature > 0C else CountA = 45 ;Set Character (-) to be displayed Temperature <0C endif 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 if DispFlag = 0 then ;Select Serial output mode depending on display type selected (bit0) serout LcdVideo,N2400,(254,128,"Volts ",#PackVoltage," Temp",CountA,#PackTemp,"C ");Output to Lcd Display serout LcdVideo,N2400,(254,192,"Cap ",#Soc," Amps",CountB,#BatCurrent," ") ;Output to Lcd Display else setfreq m8 ;Setfreq to 8MHz for output to Video Chip this increases serial to 9600 baud serout LcdVideo,N4800,("Volts ",#PackVoltage," Temp",CountA,#PackTemp,"C ") ;Output to Video Display serout LcdVideo,N4800,("Cap ",#Soc," Amps",CountB,#BatCurrent," ") ;Output to Video Display setfreq m4 ;Setfreq to 4MHz for return to main program endif return ;Return to main program loop ;************************************************************************************************************** ;************************************************************************************************************** DisplayB: ;Display Extended BMS Parameters on Dashboard Lcd or Video Screen CountW = PackVoltage * BatCurrent / 100 ;Instantaneous power = PackVoltage x BatCurrent = Power in Watts ;Display shows. power in watts divided by 100 so 14000w = 14.4kw if DispFlag = 0 then ;Select Serial output mode depending on display type selected (bit0) serout LcdVideo,N2400,(254,128,"Kw ",#CountW," ");Output to Lcd Display serout LcdVideo,N2400,(254,192,"Extended Display Data");Output to Lcd Display else setfreq m8 ;Setfreq to 8MHz for output to Video Chip this increases serial to 9600 baud serout LcdVideo,N4800,("Kw ",#CountW," ") ;Output to Video Display serout LcdVideo,N4800,("Extended Display Data") ;Output to Video Display setfreq m4 ;Setfreq to 4MHz for return to main program endif Loop0: If ButtonB = 0 then Loop0 ;If Button B is not pressed goto Loop0 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 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) if DispFlag = 0 then ;Select Serial output mode depending on display type selected (bit0) serout LcdVideo,N2400,(254,1) ;Clear Lcd Display pause 30 serout LcdVideo,N2400,(254,128,"Cell ",#CountA," Volts ",#CellVoltage," ");Output to Lcd Display else setfreq m8 ;Setfreq to 8MHz for output to Video Chip this increases serial to 9600 baud serout LcdVideo,N4800,("Cell ",#CountA," Volts ",#CellVoltage," ") ;Output to Video Display setfreq m4 ;Setfreq to 4MHz for return to main program endif 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 ;************************************************************************************************************** ;************************************************************************************************************** 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 VoltageData = @ptrinc ;Load VoltageData (b2) with value from Scratchpad Ram and inc data pointer CellVoltage = VoltageData + 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 ;Loading VoltageData (b2) from Ram Word variable (w1) contains correct value 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 CellVoltage =0 ;Reset CellVoltage to 0 for next loop 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 negative = Temp <0C PackTemp = PackTemp - 128 ;Correct negative value TempFlag = 1 ;Set TempFlag to 1 to enable Display routine to display (-) character else TempFlag = 0 ;Set TempFlag to 0 to enable Display routine to display (+) character 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 ;************************************************************************************************************** SpeedCurrent: ;Accumulate 1s (Current in Amps) charge/discharge data & Vehicle Speed 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: CountW = 0 ;Reset Local Variable CountW to 0 (Zero) Count SpeedSensor,250,CountW ;Measure Vehicle speed by counting VSS pulses for 250ms (Vehicle Speed Sensor) CountW = CountW * 240 ;Multiply pulses received *240 to get number of pulses in 1 minute ;5280ft per mile / Tyre circumference 5.8ft = 910 revs per mile ;910 revs per mile * 5 pulses per rev = 4550 pulses per mile CountW = 0 ;Reset Local Variable CountW to 0 (Zero) inc SocTimer ;SocTimer = SocTimer + 1 (When reaches 60 = 1 minute elapsed) settimer t1s_4 ;Reset internal (timer) variable to 1 second ticks at 4mhz return ;Return to main program loop ;************************************************************************************************************** CalcSoc: ;Use 1 min accumulated sensor current data to calculate Soc ;Note max 1 min average charge or discharge rate is 65,000 (65A) ;This is due to the limit imposed by the 16bit integer maths if Charge > 0 then ;If no Charge in last minute jump over Charge calculations Charge = Charge / 60 ;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 / 60 ;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 current Soc reading to eeprom for storage when Master Off write DistStore, WORD Distance ;Write current Odometer reading to eeprom for storage when Master Off write WhStore, WORD WhMile ;Write current WhMile reading to eeprom for storage when Master Off SocTimer = 0 ;Reset SocTimer to 0 return ;Return to main program loop ;************************************************************************************************************** Warning: ;Warnings/Alarms routine turns on led/piezo and turns down charger etc ;Action taken depends on Warning Flags (8 different warnings max!) high Led ;Activate dash warning led If Warn1 = 1 then ;bit8 = Warning Flag (Cell over AbsMax V) high Piezo ;Activate audible Piezo alarm hpwmduty 1023 ;Set HPWM Charger/Controller to 100% to shut down Charger/Controller low ChargerOnOff ;Turn off Charger main relay endif If Warn2 = 1 then ;bit9 = Warning Flag (Cell under AbsMin V) high Piezo ;Activate audible Piezo 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 hpwmduty DutyCycle ;Set updated HPWM Charger/Controller DutyCycle to adjust output/limit endif If Warn4 = 1 then ;bit11 = Warning Flag (Cell under Min V) high Piezo ;Activate audible Piezo alarm 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) endif If Warn7 = 1 then ;bit14 = Warning Flag (Battery Pack over Max Temp) endif If Warn8 = 1 then ;bit15 = endif Warnings = 0 ;Reset Warnings Flags 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 high Piezo ;Activate audible Piezo alarm high Led ;Activate dash warning led low ChargerOnOff ;Turn off Charger main relay DutyCycle = 1023 ;Pull charger down to minimum output Set PWM to 100% hpwmduty DutyCycle ;Set updated HPWM Charger/Controller DutyCycle to adjust output/limit ChargeFlag = 0 ;Set ChargeFlag to 0 indicates Charging halted else high ChargerOnOff ;Turn on Charger main relay 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 endif pause 1000 ;Pause for 1 Second low Piezo ;Turn off audible Piezo alarm low Led ;Turn off dash warning led return ;Return to main program loop #REM ************************************************************************************************************** ************************** Odd stuff and code not used at present! ****************************************** ************************************************************************************************************** 'To display 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 ) The Honda Insight VSS is a 0-5V square wave , that has a frequency of about 100HZ at 90 MPH, and of course stops on either 5V or 0V when the car stops. The signal goes to The following places, ECM,MCM,EPS,Guage assembly, and Climate control. Not sure what the effect would be if only the ECM lost it? The VSS put out 5 pulses per wheel revolution as close as I could tell. Now the math. As nearly as I could measure, the tire has a diameter of 22 and an eighth inches. Circumference is pi * D, so the tire is 5.8 feet around. Then there must be 912 revolutions per mile. That means we get about 4560 pulses per mile. I could be off by about a half a pulse per revolution. If this is so, we're right on 4000 pulses per mile. Looks like a standard Honda design. The 4000 pulse per mile specification is a window with some latitude. #ENDREM