mirror of
https://github.com/doppelhub/Honda_Insight_LiBCM.git
synced 2026-06-10 23:47:28 -04:00
Merge pull request #77 from doppelhub/JTS_inWork
JTS_IN_WORK to Prerelease: -VpackSpoof Calibration -Improved Balancing
This commit is contained in:
@@ -7,8 +7,8 @@
|
||||
#define config_h
|
||||
#include "src/libcm.h"
|
||||
|
||||
#define FW_VERSION "0.9.5f"
|
||||
#define BUILD_DATE "2025JUN02"
|
||||
#define FW_VERSION "0.9.5n"
|
||||
#define BUILD_DATE "2025JUL07"
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -25,15 +25,15 @@
|
||||
|
||||
//choose your battery type:
|
||||
//#define BATTERY_TYPE_5AhG3 //if you're not sure, you probably have this battery
|
||||
//#define BATTERY_TYPE_47AhFoMoCo
|
||||
//#define BATTERY_TYPE_47Ah //aka FoMoCo //aka Samsung SDI modules
|
||||
|
||||
//choose how many cells are in series:
|
||||
//#define STACK_IS_48S //All 5AhG3 Kits & FoMoCo Kits with QTY4 modules
|
||||
//#define STACK_IS_60S //FoMoCo Kits with QTY5 modules
|
||||
//#define STACK_IS_48S //All 5AhG3 Kits & 47Ah Kits with QTY4 modules
|
||||
//#define STACK_IS_60S //47Ah Kits with QTY5 modules
|
||||
|
||||
//choose which grid charger is installed
|
||||
//#define GRIDCHARGER_IS_NOT_1500W //All 5AhG3 Kits & 'standard' 47Ah FoMoCo Kits
|
||||
//#define GRIDCHARGER_IS_1500W //'faster' 47Ah FoMoCo Kits only
|
||||
//#define GRIDCHARGER_IS_NOT_1500W //All 5AhG3 Kits & 'standard' 47Ah Kits
|
||||
//#define GRIDCHARGER_IS_1500W //47Ah Kits with 'fast' 6.5A charger
|
||||
|
||||
//choose ONE of the following
|
||||
//must match actual "current hack" hardware configuration:
|
||||
@@ -95,14 +95,11 @@
|
||||
|
||||
#define CELL_VMAX_REGEN 43000 //43000 = 4.3000 volts
|
||||
#define CELL_VMIN_ASSIST 31900
|
||||
#define CELL_VMAX_GRIDCHARGER 39600 //3.9 volts is 75% SoC //other values: See SoC.cpp //MUST be less than 'CELL_VREST_85_PERCENT_SoC'
|
||||
#define CELL_VMAX_GRIDCHARGER 39600 //MUST be less than 'CELL_VREST_085_PERCENT_SoC'
|
||||
#define CELL_VMIN_GRIDCHARGER 30000 //grid charger will not charge severely empty cells
|
||||
#define CELL_VMIN_KEYOFF CELL_VREST_10_PERCENT_SoC //when car is off, LiBCM turns off below this voltage
|
||||
#define CELL_VMIN_KEYOFF CELL_VREST_010_PERCENT_SoC //when car is off, LiBCM turns off below this voltage
|
||||
#define CELL_BALANCE_MIN_SoC 65 //when car is off, cell balancing is disabled when battery is less than this percent charged
|
||||
#define CELL_BALANCE_TO_WITHIN_COUNTS_LOOSE 32 //'32' = 3.2 mV //CANNOT exceed 255 counts (25.5 mV)
|
||||
#define CELL_BALANCE_TO_WITHIN_COUNTS_TIGHT 22 //'22' = 2.2 mV //LTC6804 measurement uncertainty is 2.2 mV //MUST be less than CELL_BALANCE_TO_WITHIN_COUNTS_LOOSE
|
||||
#define CELL_BALANCE_MAX_TEMP_C 40
|
||||
//#define ONLY_BALANCE_CELLS_WHEN_GRID_CHARGER_PLUGGED_IN //uncomment to disable keyOFF cell balancing (unless the grid charger is plugged in)
|
||||
|
||||
//temp setpoints
|
||||
#define COOL_BATTERY_ABOVE_TEMP_C_KEYOFF 36 //cabin air cooling
|
||||
|
||||
@@ -113,7 +113,7 @@ void validateAndStoreNextCVR(uint8_t chipAddress, char cellVoltageRegister)
|
||||
uint8_t cellX=0; //1st cell in returnedData (LTC cell 1, 4, 7, or 10)
|
||||
uint8_t cellY=0; //2nd cell in returnedData (LTC cell 2, 5, 8, or 11)
|
||||
uint8_t cellZ=0; //3rd cell in returnedData (LTC cell 3, 6, 9, or 12)
|
||||
switch (cellVoltageRegister) //LUT to prevent QTY3 multiplies & QTY12 adds per call
|
||||
switch (cellVoltageRegister) //LUT prevents QTY3 multiplies & QTY12 adds per call
|
||||
{
|
||||
case 'A': cellX=0; cellY=1; cellZ=2 ; break; //LTC cells 1/ 2/ 3 (LTC 1-indexed, array 0-indexed)
|
||||
case 'B': cellX=3; cellY=4; cellZ=5 ; break; //LTC cells 4/ 5/ 6
|
||||
@@ -130,15 +130,10 @@ void validateAndStoreNextCVR(uint8_t chipAddress, char cellVoltageRegister)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//results stored in LTC68042results.c
|
||||
void processAllCellVoltages(void)
|
||||
//For hardware reasons, cell 19's measured voltage is corrected here
|
||||
uint16_t calculateVoltageCell19(uint16_t cell19Voltage_measured, uint16_t hiCellVoltage, uint16_t loCellVoltage)
|
||||
{
|
||||
uint32_t packVoltage_RAW = 0; //Multiply by 0.0001 for volts
|
||||
uint16_t loCellVoltage = 65535;
|
||||
uint16_t hiCellVoltage = 0;
|
||||
|
||||
#ifdef BATTERY_TYPE_5AhG3
|
||||
//On LiBCM, QTY3 LTC6804 ICs measure QTY2 18S EHW5 modules:
|
||||
//On LiBCM, QTY3 LTC6804 ICs measure QTY2 18S EHW5 modules:
|
||||
// -LTC6804 'A' measures the first QTY12 cells in the 1st 18S module (stack cells 01:12). No problems here.
|
||||
// -LTC6804 'C' measures the last QTY12 cells in the 2nd 18S module (stack cells 25:36). No problems here.
|
||||
// -LTC6804 'B' measures the remaining QTY6 cells in both modules (stack cells 13:18 in module 'A', as well as stack cells 19:24 in module 'C').
|
||||
@@ -157,79 +152,88 @@ void processAllCellVoltages(void)
|
||||
//The ideal solution would be to use the LTC6813 - which measures QTY18 cells - on both 18S EHW5 modules.
|
||||
//However, that IC is backordered for years, hence the above hardware decision and this workaround.
|
||||
//It's not ideal, but it's what we've got. STFP!
|
||||
|
||||
const uint8_t VOLTAGECORRECTION_mV_PER_AMP = 1; //1 mV/A error measured on 4 AWG cable between modules
|
||||
const uint8_t LTC6804_COUNTS_PER_mV = 10; //LSB is 100 uV
|
||||
const uint8_t LTC6804_COUNT_ADJUSTMENT_PER_AMP = (VOLTAGECORRECTION_mV_PER_AMP * LTC6804_COUNTS_PER_mV);
|
||||
|
||||
//cell 19 is the seventh cell on the second IC
|
||||
#define CELL19_CHIP_NUMBER 1 //array is zero-indexed // '1' is the 2nd IC
|
||||
#define CELL19_CELL_NUMBER 6 //array is zero-indexed // '6' is seventh cell (i.e. stack cell 19)
|
||||
uint16_t midpointVoltage = ((hiCellVoltage - loCellVoltage) >> 1) + loCellVoltage;
|
||||
uint16_t cell19absDelta_measured = 0;
|
||||
uint16_t cell19absDelta_adjusted = 0;
|
||||
uint16_t cell19Voltage_adjusted = cell19Voltage_measured + adc_getLatestBatteryCurrent_amps() * LTC6804_COUNT_ADJUSTMENT_PER_AMP;
|
||||
|
||||
#define VOLTAGECORRECTION_mV_PER_AMP 1 //1 mV/A error measured on RevC hardware //only corrects cell 19 for this specific issue
|
||||
#define LTC6804_COUNTS_PER_mV 10 //LSB is 100 uV
|
||||
#define LTC6804_COUNT_ADJUSTMENT_PER_AMP (VOLTAGECORRECTION_mV_PER_AMP * LTC6804_COUNTS_PER_mV) //preprocessor handles this multiply
|
||||
//find measured voltage magnitude from midpoint
|
||||
if (cell19Voltage_measured > midpointVoltage) { cell19absDelta_measured = cell19Voltage_measured - midpointVoltage; }
|
||||
else { cell19absDelta_measured = midpointVoltage - cell19Voltage_measured; }
|
||||
|
||||
uint16_t cell19Voltage_measured = cellVoltages_counts[CELL19_CHIP_NUMBER][CELL19_CELL_NUMBER]; //store cell 19 voltage for later
|
||||
uint16_t cell19Voltage_adjusted = cell19Voltage_measured + adc_getLatestBatteryCurrent_amps() * LTC6804_COUNT_ADJUSTMENT_PER_AMP;
|
||||
//find adjusted voltage magnitude from midpoint
|
||||
if (cell19Voltage_adjusted > midpointVoltage) { cell19absDelta_adjusted = cell19Voltage_adjusted - midpointVoltage; }
|
||||
else { cell19absDelta_adjusted = midpointVoltage - cell19Voltage_adjusted; }
|
||||
|
||||
//temporarily replace cell 19's voltage with cell 18's, to prevent cell 19's (possibly incorrect) voltage from being either the highest or lowest voltage
|
||||
cellVoltages_counts[CELL19_CHIP_NUMBER][CELL19_CELL_NUMBER] = cellVoltages_counts[CELL19_CHIP_NUMBER][CELL19_CELL_NUMBER - 1];
|
||||
//we'll restore cell 19's voltage after we determine pack hi/lo (in the for loops below)
|
||||
uint16_t cell19Voltage_closest = 0;
|
||||
|
||||
if (cell19absDelta_measured > cell19absDelta_adjusted) { cell19Voltage_closest = cell19Voltage_adjusted; } //adjusted value is closer to midpoint
|
||||
else { cell19Voltage_closest = cell19Voltage_measured; } //measured value is closer to midpoint
|
||||
|
||||
return cell19Voltage_closest;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//results stored in LTC68042results.c
|
||||
void processAllCellVoltages(void)
|
||||
{
|
||||
#ifdef BATTERY_TYPE_5AhG3
|
||||
//store actual cell 19 voltage measurement for later recall
|
||||
uint16_t cell19Voltage_measured = cellVoltages_counts[CELL19_CHIP_NUMBER][CELL19_CELL_NUMBER];
|
||||
|
||||
//temporarily replace cell 19's voltage with another cell
|
||||
uint16_t cell19Voltage_spoofed = cellVoltages_counts[CELL19_CHIP_NUMBER][CELL19_CELL_NUMBER - 1];
|
||||
cellVoltages_counts[CELL19_CHIP_NUMBER][CELL19_CELL_NUMBER] = cell19Voltage_spoofed;
|
||||
//see calculateVoltageCell19() for explanation
|
||||
#endif
|
||||
|
||||
uint32_t packVoltage_RAW = 0; //Multiply by 0.0001 for volts
|
||||
uint16_t loCellVoltage = 65535;
|
||||
uint16_t hiCellVoltage = 0;
|
||||
uint8_t loCellNumber = 0;
|
||||
uint8_t hiCellNumber = 0;
|
||||
|
||||
//loop through every cell in pack
|
||||
for (int chip = 0 ; chip < TOTAL_IC; chip++) //actual LTC serial address: 'chip' + FIRST_IC_ADDR )
|
||||
{
|
||||
for (int cell=0; cell < CELLS_PER_IC; cell++) //actual LTC cell number: 'cell' + 1 (zero-indexed)
|
||||
{
|
||||
for (int cell=0; cell < CELLS_PER_IC; cell++) //physical LTC cell number (1 to 48): 'cell' + 1 (array is zero-indexed)
|
||||
{
|
||||
uint16_t cellVoltageUnderTest = cellVoltages_counts[chip][cell];
|
||||
|
||||
//accumulate Vpack
|
||||
packVoltage_RAW += cellVoltageUnderTest;
|
||||
uint16_t Vcell = cellVoltages_counts[chip][cell];
|
||||
|
||||
LTC68042result_specificCellVoltage_set(chip, cell, Vcell);
|
||||
|
||||
packVoltage_RAW += Vcell;
|
||||
|
||||
//find hi/lo cells
|
||||
if (cellVoltageUnderTest < loCellVoltage) { loCellVoltage = cellVoltageUnderTest; }
|
||||
if (cellVoltageUnderTest > hiCellVoltage) { hiCellVoltage = cellVoltageUnderTest; }
|
||||
|
||||
//check for new maxEver/minEver cells (if any)
|
||||
//If BATTERY_TYPE_5AhG3 is defined, cell 19 voltage cannot become maxEver or minEver right now, but we'll check again down below
|
||||
if (cellVoltageUnderTest > LTC68042result_maxEverCellVoltage_get()) {LTC68042result_maxEverCellVoltage_set(cellVoltageUnderTest); }
|
||||
if (cellVoltageUnderTest < LTC68042result_minEverCellVoltage_get()) {LTC68042result_minEverCellVoltage_set(cellVoltageUnderTest); }
|
||||
|
||||
LTC68042result_specificCellVoltage_set(chip, cell, cellVoltageUnderTest);
|
||||
if (Vcell < loCellVoltage) { loCellVoltage = Vcell; loCellNumber = chip*CELLS_PER_IC+cell+1; }
|
||||
if (Vcell > hiCellVoltage) { hiCellVoltage = Vcell; hiCellNumber = chip*CELLS_PER_IC+cell+1; }
|
||||
}
|
||||
}
|
||||
|
||||
LTC68042result_packVoltage_set( (uint8_t)(packVoltage_RAW * 0.0001) );
|
||||
|
||||
#ifdef BATTERY_TYPE_5AhG3
|
||||
uint16_t cell19Voltage_final = calculateVoltageCell19(cell19Voltage_measured, hiCellVoltage, loCellVoltage);
|
||||
|
||||
LTC68042result_specificCellVoltage_set(CELL19_CHIP_NUMBER, CELL19_CELL_NUMBER, cell19Voltage_final);
|
||||
if (cell19Voltage_final > hiCellVoltage) { hiCellVoltage = cell19Voltage_final; hiCellNumber = 19; }
|
||||
if (cell19Voltage_final < loCellVoltage) { loCellVoltage = cell19Voltage_final; loCellNumber = 19; }
|
||||
|
||||
packVoltage_RAW = packVoltage_RAW - cell19Voltage_spoofed + cell19Voltage_measured;
|
||||
#endif
|
||||
|
||||
LTC68042result_loCellVoltage_set(loCellVoltage);
|
||||
LTC68042result_hiCellVoltage_set(hiCellVoltage);
|
||||
LTC68042result_loCellNum_set(loCellNumber);
|
||||
LTC68042result_hiCellNum_set(hiCellNumber);
|
||||
LTC68042result_deltaCellVoltage_set(hiCellVoltage - loCellVoltage);
|
||||
LTC68042result_packVoltage_set( (uint8_t)(packVoltage_RAW * 0.0001) );
|
||||
|
||||
#ifdef BATTERY_TYPE_5AhG3
|
||||
//Now we need to determine which cell 19 voltage is correct (the actual measured value, or the current-adjusted one)
|
||||
//We do this by determining which voltage has the smallest magnitude from the max/min cell voltages (determined above).
|
||||
|
||||
uint16_t midpointVoltage = ((hiCellVoltage - loCellVoltage) >> 1) + loCellVoltage;
|
||||
uint16_t cell19deltaMagnitude_measured = 0;
|
||||
uint16_t cell19deltaMagnitude_adjusted = 0;
|
||||
|
||||
//find measured voltage magnitude from midpoint
|
||||
if (cell19Voltage_measured > midpointVoltage) { cell19deltaMagnitude_measured = cell19Voltage_measured - midpointVoltage; }
|
||||
else { cell19deltaMagnitude_measured = midpointVoltage - cell19Voltage_measured; }
|
||||
|
||||
//find adjusted voltage magnitude from midpoint
|
||||
if (cell19Voltage_adjusted > midpointVoltage) { cell19deltaMagnitude_adjusted = cell19Voltage_adjusted - midpointVoltage; }
|
||||
else { cell19deltaMagnitude_adjusted = midpointVoltage - cell19Voltage_adjusted; }
|
||||
|
||||
uint16_t cell19Voltage_final = 0;
|
||||
|
||||
if (cell19deltaMagnitude_measured > cell19deltaMagnitude_adjusted) { cell19Voltage_final = cell19Voltage_adjusted; } //adjusted value is closer to midpoint
|
||||
else { cell19Voltage_final = cell19Voltage_measured; } //measured value is closer to midpoint
|
||||
|
||||
//store whichever cell 19 voltage is closest to the other cells
|
||||
LTC68042result_specificCellVoltage_set(CELL19_CHIP_NUMBER, CELL19_CELL_NUMBER, cell19Voltage_final);
|
||||
|
||||
//finally, we need to check if cell 19 is either the highest or lowest voltage
|
||||
if (cell19Voltage_final > hiCellVoltage) { LTC68042result_hiCellVoltage_set(cell19Voltage_final); }
|
||||
if (cell19Voltage_final < loCellVoltage) { LTC68042result_loCellVoltage_set(cell19Voltage_final); }
|
||||
#endif
|
||||
if (hiCellVoltage > LTC68042result_maxEverCellVoltage_get()) {LTC68042result_maxEverCellVoltage_set(hiCellVoltage); }
|
||||
if (loCellVoltage < LTC68042result_minEverCellVoltage_get()) {LTC68042result_minEverCellVoltage_set(loCellVoltage); }
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -300,6 +304,9 @@ bool LTC68042cell_nextVoltages(void)
|
||||
while (1) {;} //hang here until watchdog resets.
|
||||
}
|
||||
|
||||
if (cellVoltageDataStatus == CELL_DATA_PROCESSED) { LTC68042result_wasDataProcessedThisLoop_set(YES); }
|
||||
else { LTC68042result_wasDataProcessedThisLoop_set(NO); }
|
||||
|
||||
return cellVoltageDataStatus;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
|
||||
#define LTC6804_MAX_CONVERSION_TIME_ms 5 //4.43 ms in '2kHz' sampling mode
|
||||
|
||||
//cell 19 is the seventh cell on the second IC
|
||||
#define CELL19_CHIP_NUMBER 1 //array is zero-indexed // '1' is the 2nd IC
|
||||
#define CELL19_CELL_NUMBER 6 //array is zero-indexed // '6' is seventh cell (i.e. stack cell 19)
|
||||
|
||||
bool LTC68042cell_nextVoltages(void);
|
||||
void LTC68042cell_acquireAllCellVoltages(void);
|
||||
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
//Copyright 2021-2024(c) John Sullivan
|
||||
//github.com/doppelhub/Honda_Insight_LiBCM
|
||||
|
||||
//The latest results gathered from LTC6804 are stored here.
|
||||
//latest LTC6804 results are stored here
|
||||
|
||||
#include "libcm.h"
|
||||
|
||||
bool wasProcessed = NO;
|
||||
bool LTC68042result_wasDataProcessedThisLoop_get(void ) { return wasProcessed; }
|
||||
void LTC68042result_wasDataProcessedThisLoop_set(bool newStatus) { wasProcessed = newStatus; }
|
||||
|
||||
uint8_t isoSPI_errorCount = 0;
|
||||
uint8_t LTC68042result_errorCount_get (void ) { return isoSPI_errorCount; }
|
||||
void LTC68042result_errorCount_set (uint8_t newErrorCount) { isoSPI_errorCount = newErrorCount; }
|
||||
@@ -12,7 +16,15 @@ void LTC68042result_errorCount_increment (void ) { isoSPI_err
|
||||
|
||||
uint8_t packVoltage_actual = 170;
|
||||
void LTC68042result_packVoltage_set (uint8_t voltage) { packVoltage_actual = voltage; }
|
||||
uint8_t LTC68042result_packVoltage_get (void ) { return packVoltage_actual; }
|
||||
uint8_t LTC68042result_packVoltage_get (void ) { return packVoltage_actual; }
|
||||
|
||||
uint8_t loCellNumber = 0;
|
||||
void LTC68042result_loCellNum_set(uint8_t cellNumber) { loCellNumber = cellNumber; }
|
||||
uint8_t LTC68042result_loCellNum_get(void) { return loCellNumber; }
|
||||
|
||||
uint8_t hiCellNumber = 0;
|
||||
void LTC68042result_hiCellNum_set(uint8_t cellNumber) { hiCellNumber = cellNumber; }
|
||||
uint8_t LTC68042result_hiCellNum_get(void) { return hiCellNumber; }
|
||||
|
||||
uint16_t minEverCellVoltage_counts = 65535; //since last key event
|
||||
void LTC68042result_minEverCellVoltage_set(uint16_t newMin_counts) { minEverCellVoltage_counts = newMin_counts; }
|
||||
@@ -30,6 +42,10 @@ uint16_t hiCellVoltage_counts = 34567;
|
||||
void LTC68042result_hiCellVoltage_set(uint16_t newHi_counts) { hiCellVoltage_counts = newHi_counts; }
|
||||
uint16_t LTC68042result_hiCellVoltage_get(void ) { return hiCellVoltage_counts; }
|
||||
|
||||
uint16_t deltaCellVoltage_counts = 0;
|
||||
void LTC68042result_deltaCellVoltage_set(uint16_t newDelta_counts) { deltaCellVoltage_counts = newDelta_counts; }
|
||||
uint16_t LTC68042result_deltaCellVoltage_get(void ) { return deltaCellVoltage_counts; }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//All cell voltages in this array are guaranteed to be acquired at the same time
|
||||
|
||||
@@ -4,12 +4,21 @@
|
||||
#ifndef LTC68042result_h
|
||||
#define LTC68042result_h
|
||||
|
||||
uint8_t LTC68042result_errorCount_get (void );
|
||||
void LTC68042result_errorCount_set (uint8_t newErrorCount);
|
||||
void LTC68042result_errorCount_increment (void );
|
||||
bool LTC68042result_wasDataProcessedThisLoop_get(void );
|
||||
void LTC68042result_wasDataProcessedThisLoop_set(bool newStatus);
|
||||
|
||||
void LTC68042result_packVoltage_set (uint8_t voltage);
|
||||
uint8_t LTC68042result_packVoltage_get (void );
|
||||
uint8_t LTC68042result_errorCount_get (void );
|
||||
void LTC68042result_errorCount_set (uint8_t newErrorCount);
|
||||
void LTC68042result_errorCount_increment(void );
|
||||
|
||||
void LTC68042result_packVoltage_set(uint8_t voltage);
|
||||
uint8_t LTC68042result_packVoltage_get(void );
|
||||
|
||||
void LTC68042result_loCellNum_set(uint8_t cellNumber);
|
||||
uint8_t LTC68042result_loCellNum_get(void); //first cell is '1'
|
||||
|
||||
void LTC68042result_hiCellNum_set(uint8_t cellNumber);
|
||||
uint8_t LTC68042result_hiCellNum_get(void); //first cell is '1'
|
||||
|
||||
void LTC68042result_minEverCellVoltage_set(uint16_t newMin_counts);
|
||||
uint16_t LTC68042result_minEverCellVoltage_get(void );
|
||||
@@ -23,9 +32,9 @@
|
||||
void LTC68042result_hiCellVoltage_set(uint16_t newHi_counts);
|
||||
uint16_t LTC68042result_hiCellVoltage_get(void );
|
||||
|
||||
void LTC68042result_deltaCellVoltage_set(uint16_t newDelta_counts);
|
||||
uint16_t LTC68042result_deltaCellVoltage_get(void );
|
||||
|
||||
void LTC68042result_specificCellVoltage_set(uint8_t icNumber, uint8_t cellNumber, uint16_t cellVoltage);
|
||||
uint16_t LTC68042result_specificCellVoltage_get (uint8_t icNumber, uint8_t cellNumber);
|
||||
|
||||
uint16_t LTC68042result_specificCellVoltage_get(uint8_t icNumber, uint8_t cellNumber);
|
||||
#endif
|
||||
|
||||
// void printCellVoltage_all(); //JTS2doLater: Add back
|
||||
|
||||
@@ -97,7 +97,7 @@ void LiDisplay_begin(void)
|
||||
{
|
||||
#ifdef LIDISPLAY_CONNECTED
|
||||
|
||||
#ifdef BATTERY_TYPE_47AhFoMoCo
|
||||
#ifdef BATTERY_TYPE_47Ah
|
||||
#undef LIDISPLAY_GRIDCHARGE_PAGE_ID
|
||||
#define LIDISPLAY_GRIDCHARGE_PAGE_ID 5
|
||||
#endif
|
||||
@@ -300,7 +300,7 @@ LiDisplay_updateNextCellValue() {
|
||||
static uint8_t cellToUpdate = 0;
|
||||
static uint8_t ic_index = 0;
|
||||
static uint8_t ic_cell_num = 0;
|
||||
static uint16_t cell_avg_voltage = 0;
|
||||
static uint16_t cell_avg_voltage = 0; //TODO_NATALYA - JTS: this doesn't need to be static
|
||||
static String cell_color_number = "2016";
|
||||
static int cell_voltage_diff_from_avg = 0;
|
||||
static int temp_cell_voltage = 0;
|
||||
@@ -318,10 +318,11 @@ LiDisplay_updateNextCellValue() {
|
||||
else if (cellToUpdate <= 59) { ic_index = 4; ic_cell_num = (cellToUpdate - 48); }
|
||||
|
||||
// 09 Feb 2023 -- cell_avg_voltage is a crude approximation of the centre of the voltage range. Ideally this would be replaced with the median cell voltage.
|
||||
LiDisplayAverageCellVoltage = ((LTC68042result_hiCellVoltage_get() - LTC68042result_loCellVoltage_get()) * 0.5);
|
||||
LiDisplayAverageCellVoltage = ((LTC68042result_hiCellVoltage_get() - LTC68042result_loCellVoltage_get()) * 0.5); //TODO_NATALYA - JTS: replace this line with next line
|
||||
//LiDisplayAverageCellVoltage = (LTC68042result_deltaCellVoltage_get() >> 1 ) + LTC68042result_loCellVoltage_get();
|
||||
|
||||
cell_avg_voltage = (LiDisplayAverageCellVoltage + LTC68042result_loCellVoltage_get());
|
||||
LiDisplayAverageCellVoltage = (cell_avg_voltage); // TODO_NATALYA - get rid of cell_avg_voltage
|
||||
cell_avg_voltage = (LiDisplayAverageCellVoltage + LTC68042result_loCellVoltage_get()); //TODO_NATALYA - JTS: remove entire line and entire variable
|
||||
LiDisplayAverageCellVoltage = (cell_avg_voltage); // TODO_NATALYA - get rid of cell_avg_voltage //TODO_NATALYA - JTS: remove entire line
|
||||
temp_cell_voltage = LTC68042result_specificCellVoltage_get(ic_index, ic_cell_num);
|
||||
|
||||
cell_voltage_diff_from_avg = cell_avg_voltage - temp_cell_voltage;
|
||||
@@ -856,7 +857,7 @@ void LiDisplay_updateElement() {
|
||||
LiDisplay_calculateFanSpeedStr();
|
||||
if (!gc_sixty_s_fomoco_e_block_enabled && (MAX_CELL_INDEX == 59))
|
||||
{
|
||||
LiDisplay_updateNumericVal(LIDISPLAY_GRIDCHARGE_PAGE_ID, "t16", 3, "65516"); // E block label will be missing on a 60S FoMoCo pack display if we don't run this once.
|
||||
LiDisplay_updateNumericVal(LIDISPLAY_GRIDCHARGE_PAGE_ID, "t16", 3, "65516"); // E block label will be missing on a 60S 47Ah pack display if we don't run this once.
|
||||
gc_sixty_s_fomoco_e_block_enabled = true;
|
||||
}
|
||||
else if (LiDisplayFanSpeed_onScreen != currentFanSpeed)
|
||||
|
||||
@@ -104,224 +104,224 @@ void SoC_updateUsingLatestOpenCircuitVoltage(void)
|
||||
uint16_t restingCellVoltage = LTC68042result_loCellVoltage_get(); //JTS2doLater: need an algorithm to look at hi cell, too.
|
||||
uint8_t estimatedSoC = 0;
|
||||
|
||||
if (restingCellVoltage >= 42000) { estimatedSoC = 100; }
|
||||
else if (restingCellVoltage >= 41820) { estimatedSoC = 99; }
|
||||
else if (restingCellVoltage >= 41640) { estimatedSoC = 98; }
|
||||
else if (restingCellVoltage >= 41460) { estimatedSoC = 97; }
|
||||
else if (restingCellVoltage >= 41280) { estimatedSoC = 96; }
|
||||
else if (restingCellVoltage >= 41100) { estimatedSoC = 95; }
|
||||
else if (restingCellVoltage >= 40980) { estimatedSoC = 94; }
|
||||
else if (restingCellVoltage >= 40860) { estimatedSoC = 93; }
|
||||
else if (restingCellVoltage >= 40740) { estimatedSoC = 92; }
|
||||
else if (restingCellVoltage >= 40620) { estimatedSoC = 91; }
|
||||
else if (restingCellVoltage >= 40500) { estimatedSoC = 90; }
|
||||
else if (restingCellVoltage >= 40400) { estimatedSoC = 89; }
|
||||
else if (restingCellVoltage >= 40300) { estimatedSoC = 88; }
|
||||
else if (restingCellVoltage >= 40200) { estimatedSoC = 87; }
|
||||
else if (restingCellVoltage >= 40100) { estimatedSoC = 86; }
|
||||
else if (restingCellVoltage >= CELL_VREST_85_PERCENT_SoC) { estimatedSoC = 85; } //max cell voltage for long lifetime
|
||||
else if (restingCellVoltage >= 39880) { estimatedSoC = 84; }
|
||||
else if (restingCellVoltage >= 39760) { estimatedSoC = 83; }
|
||||
else if (restingCellVoltage >= 39640) { estimatedSoC = 82; }
|
||||
else if (restingCellVoltage >= 39520) { estimatedSoC = 81; }
|
||||
else if (restingCellVoltage >= 39400) { estimatedSoC = 80; }
|
||||
else if (restingCellVoltage >= 39260) { estimatedSoC = 79; }
|
||||
else if (restingCellVoltage >= 39120) { estimatedSoC = 78; }
|
||||
else if (restingCellVoltage >= 38980) { estimatedSoC = 77; }
|
||||
else if (restingCellVoltage >= 38840) { estimatedSoC = 76; }
|
||||
else if (restingCellVoltage >= 38700) { estimatedSoC = 75; }
|
||||
else if (restingCellVoltage >= 38620) { estimatedSoC = 74; }
|
||||
else if (restingCellVoltage >= 38540) { estimatedSoC = 73; }
|
||||
else if (restingCellVoltage >= 38460) { estimatedSoC = 72; }
|
||||
else if (restingCellVoltage >= 38380) { estimatedSoC = 71; }
|
||||
else if (restingCellVoltage >= 38300) { estimatedSoC = 70; }
|
||||
else if (restingCellVoltage >= 38230) { estimatedSoC = 69; }
|
||||
else if (restingCellVoltage >= 38160) { estimatedSoC = 68; }
|
||||
else if (restingCellVoltage >= 38090) { estimatedSoC = 67; }
|
||||
else if (restingCellVoltage >= 38020) { estimatedSoC = 66; }
|
||||
else if (restingCellVoltage >= 37950) { estimatedSoC = 65; }
|
||||
else if (restingCellVoltage >= 37890) { estimatedSoC = 64; }
|
||||
else if (restingCellVoltage >= 37830) { estimatedSoC = 63; }
|
||||
else if (restingCellVoltage >= 37770) { estimatedSoC = 62; }
|
||||
else if (restingCellVoltage >= 37710) { estimatedSoC = 61; }
|
||||
else if (restingCellVoltage >= 37650) { estimatedSoC = 60; }
|
||||
else if (restingCellVoltage >= 37580) { estimatedSoC = 59; }
|
||||
else if (restingCellVoltage >= 37510) { estimatedSoC = 58; }
|
||||
else if (restingCellVoltage >= 37440) { estimatedSoC = 57; }
|
||||
else if (restingCellVoltage >= 37370) { estimatedSoC = 56; }
|
||||
else if (restingCellVoltage >= 37300) { estimatedSoC = 55; }
|
||||
else if (restingCellVoltage >= 37250) { estimatedSoC = 54; }
|
||||
else if (restingCellVoltage >= 37200) { estimatedSoC = 53; }
|
||||
else if (restingCellVoltage >= 37150) { estimatedSoC = 52; }
|
||||
else if (restingCellVoltage >= 37100) { estimatedSoC = 51; }
|
||||
else if (restingCellVoltage >= 37050) { estimatedSoC = 50; }
|
||||
else if (restingCellVoltage >= 37000) { estimatedSoC = 49; }
|
||||
else if (restingCellVoltage >= 36950) { estimatedSoC = 48; }
|
||||
else if (restingCellVoltage >= 36900) { estimatedSoC = 47; }
|
||||
else if (restingCellVoltage >= 36850) { estimatedSoC = 46; }
|
||||
else if (restingCellVoltage >= 36800) { estimatedSoC = 45; }
|
||||
else if (restingCellVoltage >= 36750) { estimatedSoC = 44; }
|
||||
else if (restingCellVoltage >= 36700) { estimatedSoC = 43; }
|
||||
else if (restingCellVoltage >= 36650) { estimatedSoC = 42; }
|
||||
else if (restingCellVoltage >= 36600) { estimatedSoC = 41; }
|
||||
else if (restingCellVoltage >= 36550) { estimatedSoC = 40; }
|
||||
else if (restingCellVoltage >= 36480) { estimatedSoC = 39; }
|
||||
else if (restingCellVoltage >= 36410) { estimatedSoC = 38; }
|
||||
else if (restingCellVoltage >= 36340) { estimatedSoC = 37; }
|
||||
else if (restingCellVoltage >= 36270) { estimatedSoC = 36; }
|
||||
else if (restingCellVoltage >= 36200) { estimatedSoC = 35; }
|
||||
else if (restingCellVoltage >= 36140) { estimatedSoC = 34; }
|
||||
else if (restingCellVoltage >= 36080) { estimatedSoC = 33; }
|
||||
else if (restingCellVoltage >= 36020) { estimatedSoC = 32; }
|
||||
else if (restingCellVoltage >= 35960) { estimatedSoC = 31; }
|
||||
else if (restingCellVoltage >= 35900) { estimatedSoC = 30; }
|
||||
else if (restingCellVoltage >= 35800) { estimatedSoC = 29; }
|
||||
else if (restingCellVoltage >= 35700) { estimatedSoC = 28; }
|
||||
else if (restingCellVoltage >= 35600) { estimatedSoC = 27; }
|
||||
else if (restingCellVoltage >= 35500) { estimatedSoC = 26; }
|
||||
else if (restingCellVoltage >= 35400) { estimatedSoC = 25; }
|
||||
else if (restingCellVoltage >= 35360) { estimatedSoC = 24; }
|
||||
else if (restingCellVoltage >= 35320) { estimatedSoC = 23; }
|
||||
else if (restingCellVoltage >= 35280) { estimatedSoC = 22; }
|
||||
else if (restingCellVoltage >= 35240) { estimatedSoC = 21; }
|
||||
else if (restingCellVoltage >= 35200) { estimatedSoC = 20; }
|
||||
else if (restingCellVoltage >= 35160) { estimatedSoC = 19; }
|
||||
else if (restingCellVoltage >= 35120) { estimatedSoC = 18; }
|
||||
else if (restingCellVoltage >= 35080) { estimatedSoC = 17; }
|
||||
else if (restingCellVoltage >= 35040) { estimatedSoC = 16; }
|
||||
else if (restingCellVoltage >= 35000) { estimatedSoC = 15; }
|
||||
else if (restingCellVoltage >= 34900) { estimatedSoC = 14; }
|
||||
else if (restingCellVoltage >= 34800) { estimatedSoC = 13; }
|
||||
else if (restingCellVoltage >= 34700) { estimatedSoC = 12; }
|
||||
else if (restingCellVoltage >= 34540) { estimatedSoC = 11; }
|
||||
else if (restingCellVoltage >= CELL_VREST_10_PERCENT_SoC) { estimatedSoC = 10; } //min cell voltage for long lifetime
|
||||
else if (restingCellVoltage >= 33900) { estimatedSoC = 9; }
|
||||
else if (restingCellVoltage >= 33600) { estimatedSoC = 8; }
|
||||
else if (restingCellVoltage >= 33200) { estimatedSoC = 7; }
|
||||
else if (restingCellVoltage >= 32800) { estimatedSoC = 6; }
|
||||
else if (restingCellVoltage >= 32200) { estimatedSoC = 5; }
|
||||
else if (restingCellVoltage >= 31700) { estimatedSoC = 4; }
|
||||
else if (restingCellVoltage >= 31000) { estimatedSoC = 3; }
|
||||
else if (restingCellVoltage >= 30500) { estimatedSoC = 2; }
|
||||
else if (restingCellVoltage >= 29500) { estimatedSoC = 1; }
|
||||
else { estimatedSoC = 0; }
|
||||
if (restingCellVoltage >= CELL_VREST_100_PERCENT_SoC) { estimatedSoC = 100; }
|
||||
else if (restingCellVoltage >= 41820) { estimatedSoC = 99; }
|
||||
else if (restingCellVoltage >= 41640) { estimatedSoC = 98; }
|
||||
else if (restingCellVoltage >= 41460) { estimatedSoC = 97; }
|
||||
else if (restingCellVoltage >= 41280) { estimatedSoC = 96; }
|
||||
else if (restingCellVoltage >= 41100) { estimatedSoC = 95; }
|
||||
else if (restingCellVoltage >= 40980) { estimatedSoC = 94; }
|
||||
else if (restingCellVoltage >= 40860) { estimatedSoC = 93; }
|
||||
else if (restingCellVoltage >= 40740) { estimatedSoC = 92; }
|
||||
else if (restingCellVoltage >= 40620) { estimatedSoC = 91; }
|
||||
else if (restingCellVoltage >= 40500) { estimatedSoC = 90; }
|
||||
else if (restingCellVoltage >= 40400) { estimatedSoC = 89; }
|
||||
else if (restingCellVoltage >= 40300) { estimatedSoC = 88; }
|
||||
else if (restingCellVoltage >= 40200) { estimatedSoC = 87; }
|
||||
else if (restingCellVoltage >= 40100) { estimatedSoC = 86; }
|
||||
else if (restingCellVoltage >= CELL_VREST_085_PERCENT_SoC) { estimatedSoC = 85; } //Vmax for long lifetime
|
||||
else if (restingCellVoltage >= 39880) { estimatedSoC = 84; }
|
||||
else if (restingCellVoltage >= 39760) { estimatedSoC = 83; }
|
||||
else if (restingCellVoltage >= 39640) { estimatedSoC = 82; }
|
||||
else if (restingCellVoltage >= 39520) { estimatedSoC = 81; }
|
||||
else if (restingCellVoltage >= 39400) { estimatedSoC = 80; }
|
||||
else if (restingCellVoltage >= 39260) { estimatedSoC = 79; }
|
||||
else if (restingCellVoltage >= 39120) { estimatedSoC = 78; }
|
||||
else if (restingCellVoltage >= 38980) { estimatedSoC = 77; }
|
||||
else if (restingCellVoltage >= 38840) { estimatedSoC = 76; }
|
||||
else if (restingCellVoltage >= 38700) { estimatedSoC = 75; }
|
||||
else if (restingCellVoltage >= 38620) { estimatedSoC = 74; }
|
||||
else if (restingCellVoltage >= 38540) { estimatedSoC = 73; }
|
||||
else if (restingCellVoltage >= 38460) { estimatedSoC = 72; }
|
||||
else if (restingCellVoltage >= 38380) { estimatedSoC = 71; }
|
||||
else if (restingCellVoltage >= 38300) { estimatedSoC = 70; }
|
||||
else if (restingCellVoltage >= 38230) { estimatedSoC = 69; }
|
||||
else if (restingCellVoltage >= 38160) { estimatedSoC = 68; }
|
||||
else if (restingCellVoltage >= 38090) { estimatedSoC = 67; }
|
||||
else if (restingCellVoltage >= 38020) { estimatedSoC = 66; }
|
||||
else if (restingCellVoltage >= 37950) { estimatedSoC = 65; }
|
||||
else if (restingCellVoltage >= 37890) { estimatedSoC = 64; }
|
||||
else if (restingCellVoltage >= 37830) { estimatedSoC = 63; }
|
||||
else if (restingCellVoltage >= 37770) { estimatedSoC = 62; }
|
||||
else if (restingCellVoltage >= 37710) { estimatedSoC = 61; }
|
||||
else if (restingCellVoltage >= 37650) { estimatedSoC = 60; }
|
||||
else if (restingCellVoltage >= 37580) { estimatedSoC = 59; }
|
||||
else if (restingCellVoltage >= 37510) { estimatedSoC = 58; }
|
||||
else if (restingCellVoltage >= 37440) { estimatedSoC = 57; }
|
||||
else if (restingCellVoltage >= 37370) { estimatedSoC = 56; }
|
||||
else if (restingCellVoltage >= 37300) { estimatedSoC = 55; }
|
||||
else if (restingCellVoltage >= 37250) { estimatedSoC = 54; }
|
||||
else if (restingCellVoltage >= 37200) { estimatedSoC = 53; }
|
||||
else if (restingCellVoltage >= 37150) { estimatedSoC = 52; }
|
||||
else if (restingCellVoltage >= 37100) { estimatedSoC = 51; }
|
||||
else if (restingCellVoltage >= 37050) { estimatedSoC = 50; }
|
||||
else if (restingCellVoltage >= 37000) { estimatedSoC = 49; }
|
||||
else if (restingCellVoltage >= 36950) { estimatedSoC = 48; }
|
||||
else if (restingCellVoltage >= 36900) { estimatedSoC = 47; }
|
||||
else if (restingCellVoltage >= 36850) { estimatedSoC = 46; }
|
||||
else if (restingCellVoltage >= 36800) { estimatedSoC = 45; }
|
||||
else if (restingCellVoltage >= 36750) { estimatedSoC = 44; }
|
||||
else if (restingCellVoltage >= 36700) { estimatedSoC = 43; }
|
||||
else if (restingCellVoltage >= 36650) { estimatedSoC = 42; }
|
||||
else if (restingCellVoltage >= 36600) { estimatedSoC = 41; }
|
||||
else if (restingCellVoltage >= 36550) { estimatedSoC = 40; }
|
||||
else if (restingCellVoltage >= 36480) { estimatedSoC = 39; }
|
||||
else if (restingCellVoltage >= 36410) { estimatedSoC = 38; }
|
||||
else if (restingCellVoltage >= 36340) { estimatedSoC = 37; }
|
||||
else if (restingCellVoltage >= 36270) { estimatedSoC = 36; }
|
||||
else if (restingCellVoltage >= 36200) { estimatedSoC = 35; }
|
||||
else if (restingCellVoltage >= 36140) { estimatedSoC = 34; }
|
||||
else if (restingCellVoltage >= 36080) { estimatedSoC = 33; }
|
||||
else if (restingCellVoltage >= 36020) { estimatedSoC = 32; }
|
||||
else if (restingCellVoltage >= 35960) { estimatedSoC = 31; }
|
||||
else if (restingCellVoltage >= 35900) { estimatedSoC = 30; }
|
||||
else if (restingCellVoltage >= 35800) { estimatedSoC = 29; }
|
||||
else if (restingCellVoltage >= 35700) { estimatedSoC = 28; }
|
||||
else if (restingCellVoltage >= 35600) { estimatedSoC = 27; }
|
||||
else if (restingCellVoltage >= 35500) { estimatedSoC = 26; }
|
||||
else if (restingCellVoltage >= 35400) { estimatedSoC = 25; }
|
||||
else if (restingCellVoltage >= 35360) { estimatedSoC = 24; }
|
||||
else if (restingCellVoltage >= 35320) { estimatedSoC = 23; }
|
||||
else if (restingCellVoltage >= 35280) { estimatedSoC = 22; }
|
||||
else if (restingCellVoltage >= 35240) { estimatedSoC = 21; }
|
||||
else if (restingCellVoltage >= 35200) { estimatedSoC = 20; }
|
||||
else if (restingCellVoltage >= 35160) { estimatedSoC = 19; }
|
||||
else if (restingCellVoltage >= 35120) { estimatedSoC = 18; }
|
||||
else if (restingCellVoltage >= 35080) { estimatedSoC = 17; }
|
||||
else if (restingCellVoltage >= 35040) { estimatedSoC = 16; }
|
||||
else if (restingCellVoltage >= 35000) { estimatedSoC = 15; }
|
||||
else if (restingCellVoltage >= 34900) { estimatedSoC = 14; }
|
||||
else if (restingCellVoltage >= 34800) { estimatedSoC = 13; }
|
||||
else if (restingCellVoltage >= 34700) { estimatedSoC = 12; }
|
||||
else if (restingCellVoltage >= 34540) { estimatedSoC = 11; }
|
||||
else if (restingCellVoltage >= CELL_VREST_010_PERCENT_SoC) { estimatedSoC = 10; } //Vmin for long lifetime
|
||||
else if (restingCellVoltage >= 33900) { estimatedSoC = 9; }
|
||||
else if (restingCellVoltage >= 33600) { estimatedSoC = 8; }
|
||||
else if (restingCellVoltage >= 33200) { estimatedSoC = 7; }
|
||||
else if (restingCellVoltage >= 32800) { estimatedSoC = 6; }
|
||||
else if (restingCellVoltage >= 32200) { estimatedSoC = 5; }
|
||||
else if (restingCellVoltage >= 31700) { estimatedSoC = 4; }
|
||||
else if (restingCellVoltage >= 31000) { estimatedSoC = 3; }
|
||||
else if (restingCellVoltage >= 30500) { estimatedSoC = 2; }
|
||||
else if (restingCellVoltage >= 29500) { estimatedSoC = 1; }
|
||||
else { estimatedSoC = 0; }
|
||||
|
||||
return estimatedSoC;
|
||||
}
|
||||
|
||||
#elif defined BATTERY_TYPE_47AhFoMoCo
|
||||
#elif defined BATTERY_TYPE_47Ah
|
||||
|
||||
uint8_t SoC_estimateFromRestingCellVoltage_percent(void)
|
||||
{
|
||||
uint16_t restingCellVoltage = LTC68042result_loCellVoltage_get();
|
||||
uint8_t estimatedSoC = 0;
|
||||
{
|
||||
uint16_t restingCellVoltage = LTC68042result_loCellVoltage_get();
|
||||
uint8_t estimatedSoC = 0;
|
||||
|
||||
//~/Honda_Insight_LiBCM/Electronics/Lithium Batteries/47 Ah FoMoCo Modules/Resting SoC Discharge Curve
|
||||
if (restingCellVoltage >= 42000) { estimatedSoC = 100; }
|
||||
else if (restingCellVoltage >= 41800) { estimatedSoC = 99; }
|
||||
else if (restingCellVoltage >= 41600) { estimatedSoC = 98; }
|
||||
else if (restingCellVoltage >= 41400) { estimatedSoC = 97; }
|
||||
else if (restingCellVoltage >= 41200) { estimatedSoC = 96; }
|
||||
else if (restingCellVoltage >= 41000) { estimatedSoC = 95; }
|
||||
else if (restingCellVoltage >= 40880) { estimatedSoC = 94; }
|
||||
else if (restingCellVoltage >= 40760) { estimatedSoC = 93; }
|
||||
else if (restingCellVoltage >= 40640) { estimatedSoC = 92; }
|
||||
else if (restingCellVoltage >= 40520) { estimatedSoC = 91; }
|
||||
else if (restingCellVoltage >= 40400) { estimatedSoC = 90; }
|
||||
else if (restingCellVoltage >= 40260) { estimatedSoC = 89; }
|
||||
else if (restingCellVoltage >= 40120) { estimatedSoC = 88; }
|
||||
else if (restingCellVoltage >= 39980) { estimatedSoC = 87; }
|
||||
else if (restingCellVoltage >= 39840) { estimatedSoC = 86; }
|
||||
else if (restingCellVoltage >= CELL_VREST_85_PERCENT_SoC) { estimatedSoC = 85; } //max cell voltage for long lifetime
|
||||
else if (restingCellVoltage >= 39600) { estimatedSoC = 84; }
|
||||
else if (restingCellVoltage >= 39500) { estimatedSoC = 83; }
|
||||
else if (restingCellVoltage >= 39400) { estimatedSoC = 82; }
|
||||
else if (restingCellVoltage >= 39300) { estimatedSoC = 81; }
|
||||
else if (restingCellVoltage >= 39200) { estimatedSoC = 80; }
|
||||
else if (restingCellVoltage >= 39100) { estimatedSoC = 79; }
|
||||
else if (restingCellVoltage >= 39000) { estimatedSoC = 78; }
|
||||
else if (restingCellVoltage >= 38900) { estimatedSoC = 77; }
|
||||
else if (restingCellVoltage >= 38800) { estimatedSoC = 76; }
|
||||
else if (restingCellVoltage >= 38700) { estimatedSoC = 75; }
|
||||
else if (restingCellVoltage >= 38600) { estimatedSoC = 74; }
|
||||
else if (restingCellVoltage >= 38500) { estimatedSoC = 73; }
|
||||
else if (restingCellVoltage >= 38400) { estimatedSoC = 72; }
|
||||
else if (restingCellVoltage >= 38300) { estimatedSoC = 71; }
|
||||
else if (restingCellVoltage >= 38200) { estimatedSoC = 70; }
|
||||
else if (restingCellVoltage >= 38100) { estimatedSoC = 69; }
|
||||
else if (restingCellVoltage >= 38000) { estimatedSoC = 68; }
|
||||
else if (restingCellVoltage >= 37900) { estimatedSoC = 67; }
|
||||
else if (restingCellVoltage >= 37800) { estimatedSoC = 66; }
|
||||
else if (restingCellVoltage >= 37700) { estimatedSoC = 65; }
|
||||
else if (restingCellVoltage >= 37580) { estimatedSoC = 64; }
|
||||
else if (restingCellVoltage >= 37460) { estimatedSoC = 63; }
|
||||
else if (restingCellVoltage >= 37340) { estimatedSoC = 62; }
|
||||
else if (restingCellVoltage >= 37220) { estimatedSoC = 61; }
|
||||
else if (restingCellVoltage >= 37100) { estimatedSoC = 60; }
|
||||
else if (restingCellVoltage >= 37020) { estimatedSoC = 59; }
|
||||
else if (restingCellVoltage >= 36940) { estimatedSoC = 58; }
|
||||
else if (restingCellVoltage >= 36860) { estimatedSoC = 57; }
|
||||
else if (restingCellVoltage >= 36780) { estimatedSoC = 56; }
|
||||
else if (restingCellVoltage >= 36770) { estimatedSoC = 55; }
|
||||
else if (restingCellVoltage >= 36640) { estimatedSoC = 54; }
|
||||
else if (restingCellVoltage >= 36580) { estimatedSoC = 53; }
|
||||
else if (restingCellVoltage >= 36520) { estimatedSoC = 52; }
|
||||
else if (restingCellVoltage >= 36460) { estimatedSoC = 51; }
|
||||
else if (restingCellVoltage >= 36400) { estimatedSoC = 50; }
|
||||
else if (restingCellVoltage >= 36360) { estimatedSoC = 49; }
|
||||
else if (restingCellVoltage >= 36320) { estimatedSoC = 48; }
|
||||
else if (restingCellVoltage >= 36280) { estimatedSoC = 47; }
|
||||
else if (restingCellVoltage >= 36240) { estimatedSoC = 46; }
|
||||
else if (restingCellVoltage >= 36200) { estimatedSoC = 45; }
|
||||
else if (restingCellVoltage >= 36160) { estimatedSoC = 44; }
|
||||
else if (restingCellVoltage >= 36120) { estimatedSoC = 43; }
|
||||
else if (restingCellVoltage >= 36080) { estimatedSoC = 42; }
|
||||
else if (restingCellVoltage >= 36040) { estimatedSoC = 41; }
|
||||
else if (restingCellVoltage >= 36000) { estimatedSoC = 40; }
|
||||
else if (restingCellVoltage >= 35960) { estimatedSoC = 39; }
|
||||
else if (restingCellVoltage >= 35920) { estimatedSoC = 38; }
|
||||
else if (restingCellVoltage >= 35880) { estimatedSoC = 37; }
|
||||
else if (restingCellVoltage >= 35840) { estimatedSoC = 36; }
|
||||
else if (restingCellVoltage >= 35800) { estimatedSoC = 35; }
|
||||
else if (restingCellVoltage >= 35760) { estimatedSoC = 34; }
|
||||
else if (restingCellVoltage >= 35720) { estimatedSoC = 33; }
|
||||
else if (restingCellVoltage >= 35680) { estimatedSoC = 32; }
|
||||
else if (restingCellVoltage >= 35640) { estimatedSoC = 31; }
|
||||
else if (restingCellVoltage >= 35600) { estimatedSoC = 30; }
|
||||
else if (restingCellVoltage >= 35540) { estimatedSoC = 29; }
|
||||
else if (restingCellVoltage >= 35480) { estimatedSoC = 28; }
|
||||
else if (restingCellVoltage >= 35420) { estimatedSoC = 27; }
|
||||
else if (restingCellVoltage >= 35360) { estimatedSoC = 26; }
|
||||
else if (restingCellVoltage >= 35300) { estimatedSoC = 25; }
|
||||
else if (restingCellVoltage >= 35240) { estimatedSoC = 24; }
|
||||
else if (restingCellVoltage >= 35180) { estimatedSoC = 23; }
|
||||
else if (restingCellVoltage >= 35120) { estimatedSoC = 22; }
|
||||
else if (restingCellVoltage >= 35060) { estimatedSoC = 21; }
|
||||
else if (restingCellVoltage >= 35000) { estimatedSoC = 20; }
|
||||
else if (restingCellVoltage >= 34880) { estimatedSoC = 19; }
|
||||
else if (restingCellVoltage >= 34760) { estimatedSoC = 18; }
|
||||
else if (restingCellVoltage >= 34640) { estimatedSoC = 17; }
|
||||
else if (restingCellVoltage >= 34520) { estimatedSoC = 16; }
|
||||
else if (restingCellVoltage >= 34400) { estimatedSoC = 15; }
|
||||
else if (restingCellVoltage >= 34320) { estimatedSoC = 14; }
|
||||
else if (restingCellVoltage >= 34240) { estimatedSoC = 13; }
|
||||
else if (restingCellVoltage >= 34160) { estimatedSoC = 12; }
|
||||
else if (restingCellVoltage >= 34080) { estimatedSoC = 11; }
|
||||
else if (restingCellVoltage >= CELL_VREST_10_PERCENT_SoC) { estimatedSoC = 10; } //min cell voltage for long lifetime
|
||||
else if (restingCellVoltage >= 33900) { estimatedSoC = 9; }
|
||||
else if (restingCellVoltage >= 33800) { estimatedSoC = 8; }
|
||||
else if (restingCellVoltage >= 33700) { estimatedSoC = 7; }
|
||||
else if (restingCellVoltage >= 33600) { estimatedSoC = 6; }
|
||||
else if (restingCellVoltage >= 33200) { estimatedSoC = 5; }
|
||||
else if (restingCellVoltage >= 32600) { estimatedSoC = 4; }
|
||||
else if (restingCellVoltage >= 32000) { estimatedSoC = 3; }
|
||||
else if (restingCellVoltage >= 31000) { estimatedSoC = 2; }
|
||||
else if (restingCellVoltage >= 30000) { estimatedSoC = 1; }
|
||||
else { estimatedSoC = 0; }
|
||||
//~/Honda_Insight_LiBCM/Electronics/Lithium Batteries/47 Ah FoMoCo Modules/Resting SoC Discharge Curve
|
||||
if (restingCellVoltage >= CELL_VREST_100_PERCENT_SoC) { estimatedSoC = 100; }
|
||||
else if (restingCellVoltage >= 41800) { estimatedSoC = 99; }
|
||||
else if (restingCellVoltage >= 41600) { estimatedSoC = 98; }
|
||||
else if (restingCellVoltage >= 41400) { estimatedSoC = 97; }
|
||||
else if (restingCellVoltage >= 41200) { estimatedSoC = 96; }
|
||||
else if (restingCellVoltage >= 41000) { estimatedSoC = 95; }
|
||||
else if (restingCellVoltage >= 40880) { estimatedSoC = 94; }
|
||||
else if (restingCellVoltage >= 40760) { estimatedSoC = 93; }
|
||||
else if (restingCellVoltage >= 40640) { estimatedSoC = 92; }
|
||||
else if (restingCellVoltage >= 40520) { estimatedSoC = 91; }
|
||||
else if (restingCellVoltage >= 40400) { estimatedSoC = 90; }
|
||||
else if (restingCellVoltage >= 40260) { estimatedSoC = 89; }
|
||||
else if (restingCellVoltage >= 40120) { estimatedSoC = 88; }
|
||||
else if (restingCellVoltage >= 39980) { estimatedSoC = 87; }
|
||||
else if (restingCellVoltage >= 39840) { estimatedSoC = 86; }
|
||||
else if (restingCellVoltage >= CELL_VREST_085_PERCENT_SoC) { estimatedSoC = 85; } //Vmax for long lifetime
|
||||
else if (restingCellVoltage >= 39600) { estimatedSoC = 84; }
|
||||
else if (restingCellVoltage >= 39500) { estimatedSoC = 83; }
|
||||
else if (restingCellVoltage >= 39400) { estimatedSoC = 82; }
|
||||
else if (restingCellVoltage >= 39300) { estimatedSoC = 81; }
|
||||
else if (restingCellVoltage >= 39200) { estimatedSoC = 80; }
|
||||
else if (restingCellVoltage >= 39100) { estimatedSoC = 79; }
|
||||
else if (restingCellVoltage >= 39000) { estimatedSoC = 78; }
|
||||
else if (restingCellVoltage >= 38900) { estimatedSoC = 77; }
|
||||
else if (restingCellVoltage >= 38800) { estimatedSoC = 76; }
|
||||
else if (restingCellVoltage >= 38700) { estimatedSoC = 75; }
|
||||
else if (restingCellVoltage >= 38600) { estimatedSoC = 74; }
|
||||
else if (restingCellVoltage >= 38500) { estimatedSoC = 73; }
|
||||
else if (restingCellVoltage >= 38400) { estimatedSoC = 72; }
|
||||
else if (restingCellVoltage >= 38300) { estimatedSoC = 71; }
|
||||
else if (restingCellVoltage >= 38200) { estimatedSoC = 70; }
|
||||
else if (restingCellVoltage >= 38100) { estimatedSoC = 69; }
|
||||
else if (restingCellVoltage >= 38000) { estimatedSoC = 68; }
|
||||
else if (restingCellVoltage >= 37900) { estimatedSoC = 67; }
|
||||
else if (restingCellVoltage >= 37800) { estimatedSoC = 66; }
|
||||
else if (restingCellVoltage >= 37700) { estimatedSoC = 65; }
|
||||
else if (restingCellVoltage >= 37580) { estimatedSoC = 64; }
|
||||
else if (restingCellVoltage >= 37460) { estimatedSoC = 63; }
|
||||
else if (restingCellVoltage >= 37340) { estimatedSoC = 62; }
|
||||
else if (restingCellVoltage >= 37220) { estimatedSoC = 61; }
|
||||
else if (restingCellVoltage >= 37100) { estimatedSoC = 60; }
|
||||
else if (restingCellVoltage >= 37020) { estimatedSoC = 59; }
|
||||
else if (restingCellVoltage >= 36940) { estimatedSoC = 58; }
|
||||
else if (restingCellVoltage >= 36860) { estimatedSoC = 57; }
|
||||
else if (restingCellVoltage >= 36780) { estimatedSoC = 56; }
|
||||
else if (restingCellVoltage >= 36770) { estimatedSoC = 55; }
|
||||
else if (restingCellVoltage >= 36640) { estimatedSoC = 54; }
|
||||
else if (restingCellVoltage >= 36580) { estimatedSoC = 53; }
|
||||
else if (restingCellVoltage >= 36520) { estimatedSoC = 52; }
|
||||
else if (restingCellVoltage >= 36460) { estimatedSoC = 51; }
|
||||
else if (restingCellVoltage >= 36400) { estimatedSoC = 50; }
|
||||
else if (restingCellVoltage >= 36360) { estimatedSoC = 49; }
|
||||
else if (restingCellVoltage >= 36320) { estimatedSoC = 48; }
|
||||
else if (restingCellVoltage >= 36280) { estimatedSoC = 47; }
|
||||
else if (restingCellVoltage >= 36240) { estimatedSoC = 46; }
|
||||
else if (restingCellVoltage >= 36200) { estimatedSoC = 45; }
|
||||
else if (restingCellVoltage >= 36160) { estimatedSoC = 44; }
|
||||
else if (restingCellVoltage >= 36120) { estimatedSoC = 43; }
|
||||
else if (restingCellVoltage >= 36080) { estimatedSoC = 42; }
|
||||
else if (restingCellVoltage >= 36040) { estimatedSoC = 41; }
|
||||
else if (restingCellVoltage >= 36000) { estimatedSoC = 40; }
|
||||
else if (restingCellVoltage >= 35960) { estimatedSoC = 39; }
|
||||
else if (restingCellVoltage >= 35920) { estimatedSoC = 38; }
|
||||
else if (restingCellVoltage >= 35880) { estimatedSoC = 37; }
|
||||
else if (restingCellVoltage >= 35840) { estimatedSoC = 36; }
|
||||
else if (restingCellVoltage >= 35800) { estimatedSoC = 35; }
|
||||
else if (restingCellVoltage >= 35760) { estimatedSoC = 34; }
|
||||
else if (restingCellVoltage >= 35720) { estimatedSoC = 33; }
|
||||
else if (restingCellVoltage >= 35680) { estimatedSoC = 32; }
|
||||
else if (restingCellVoltage >= 35640) { estimatedSoC = 31; }
|
||||
else if (restingCellVoltage >= 35600) { estimatedSoC = 30; }
|
||||
else if (restingCellVoltage >= 35540) { estimatedSoC = 29; }
|
||||
else if (restingCellVoltage >= 35480) { estimatedSoC = 28; }
|
||||
else if (restingCellVoltage >= 35420) { estimatedSoC = 27; }
|
||||
else if (restingCellVoltage >= 35360) { estimatedSoC = 26; }
|
||||
else if (restingCellVoltage >= 35300) { estimatedSoC = 25; }
|
||||
else if (restingCellVoltage >= 35240) { estimatedSoC = 24; }
|
||||
else if (restingCellVoltage >= 35180) { estimatedSoC = 23; }
|
||||
else if (restingCellVoltage >= 35120) { estimatedSoC = 22; }
|
||||
else if (restingCellVoltage >= 35060) { estimatedSoC = 21; }
|
||||
else if (restingCellVoltage >= 35000) { estimatedSoC = 20; }
|
||||
else if (restingCellVoltage >= 34880) { estimatedSoC = 19; }
|
||||
else if (restingCellVoltage >= 34760) { estimatedSoC = 18; }
|
||||
else if (restingCellVoltage >= 34640) { estimatedSoC = 17; }
|
||||
else if (restingCellVoltage >= 34520) { estimatedSoC = 16; }
|
||||
else if (restingCellVoltage >= 34400) { estimatedSoC = 15; }
|
||||
else if (restingCellVoltage >= 34320) { estimatedSoC = 14; }
|
||||
else if (restingCellVoltage >= 34240) { estimatedSoC = 13; }
|
||||
else if (restingCellVoltage >= 34160) { estimatedSoC = 12; }
|
||||
else if (restingCellVoltage >= 34080) { estimatedSoC = 11; }
|
||||
else if (restingCellVoltage >= CELL_VREST_010_PERCENT_SoC) { estimatedSoC = 10; } //Vmin for long lifetime
|
||||
else if (restingCellVoltage >= 33900) { estimatedSoC = 9; }
|
||||
else if (restingCellVoltage >= 33800) { estimatedSoC = 8; }
|
||||
else if (restingCellVoltage >= 33700) { estimatedSoC = 7; }
|
||||
else if (restingCellVoltage >= 33600) { estimatedSoC = 6; }
|
||||
else if (restingCellVoltage >= 33200) { estimatedSoC = 5; }
|
||||
else if (restingCellVoltage >= 32600) { estimatedSoC = 4; }
|
||||
else if (restingCellVoltage >= 32000) { estimatedSoC = 3; }
|
||||
else if (restingCellVoltage >= 31000) { estimatedSoC = 2; }
|
||||
else if (restingCellVoltage >= 30000) { estimatedSoC = 1; }
|
||||
else { estimatedSoC = 0; }
|
||||
|
||||
return estimatedSoC;
|
||||
}
|
||||
#endif
|
||||
return estimatedSoC;
|
||||
}
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
void SoC_setBatteryStateNow_percent(uint8_t newSoC);
|
||||
uint8_t SoC_getBatteryStateNow_percent(void);
|
||||
uint16_t SoC_getBatteryStateNow_deciPercent(void); //JTS2doNow: Use this in Battsci, etc.
|
||||
uint16_t SoC_getBatteryStateNow_deciPercent(void); //JTS2doLater: Use this in Battsci, etc.
|
||||
|
||||
uint8_t SoC_estimateFromRestingCellVoltage_percent(void);
|
||||
|
||||
@@ -19,13 +19,18 @@
|
||||
|
||||
void SoC_handler(void);
|
||||
|
||||
#define VCELL_CRITICALLY_OVERCHARGED 43000 //'43000' = 4.3 V
|
||||
#define VCELL_CRITICALLY_DISCHARGED 28000 //'28000' = 2.8 V
|
||||
|
||||
#ifdef BATTERY_TYPE_5AhG3
|
||||
#define CELL_VREST_85_PERCENT_SoC 40000 //for maximum life, resting cell voltage should remain below 85% SoC
|
||||
#define CELL_VREST_10_PERCENT_SoC 34200 //for maximum life, resting cell voltage should remain above 10% SoC
|
||||
#define CELL_VREST_100_PERCENT_SoC 42000
|
||||
#define CELL_VREST_085_PERCENT_SoC 40000 //for maximum life, resting cell voltage should remain below 85% SoC
|
||||
#define CELL_VREST_010_PERCENT_SoC 34200 //for maximum life, resting cell voltage should remain above 10% SoC
|
||||
#define STACK_mAh_NOM 5000 //5 Ah nominal //nominal pack size (0:100% SoC)
|
||||
#elif defined BATTERY_TYPE_47AhFoMoCo
|
||||
#define CELL_VREST_85_PERCENT_SoC 39700
|
||||
#define CELL_VREST_10_PERCENT_SoC 34000
|
||||
#elif defined BATTERY_TYPE_47Ah
|
||||
#define CELL_VREST_100_PERCENT_SoC 42000
|
||||
#define CELL_VREST_085_PERCENT_SoC 39700
|
||||
#define CELL_VREST_010_PERCENT_SoC 34000
|
||||
#define STACK_mAh_NOM 47000
|
||||
#else
|
||||
#error (Battery type not specified in config.h)
|
||||
|
||||
@@ -53,6 +53,9 @@ void printDebug(void)
|
||||
|
||||
Serial.print(F("\n -Has LiBCM limited regen since last cleared?: "));
|
||||
(eeprom_hasLibcmDisabledRegen_get() == EEPROM_LIBCM_DISABLED_REGEN) ? Serial.print(F("YES")) : Serial.print(F("NO"));
|
||||
|
||||
Serial.print(F("\n -Maximum resting cell delta (min is '1000' = 100.0 mV): "));
|
||||
Serial.print(eeprom_maxCellVoltageDelta_get(), DEC);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -115,7 +118,6 @@ void USB_userInterface_runTestCode(uint8_t testToRun)
|
||||
else if (testToRun == 'T') { temperature_measureAndPrintAll(); }
|
||||
else if (testToRun == 'R') { LTC6804gpio_areAllVoltageReferencesPassing(); }
|
||||
else if (testToRun == 'W') { batteryHistory_printAll(); }
|
||||
else if (testToRun == 'E') { eeprom_resetAll_userConfirm(); }
|
||||
else if (testToRun == 'C')
|
||||
{
|
||||
LTC68042cell_acquireAllCellVoltages();
|
||||
@@ -150,41 +152,38 @@ void(* rebootLiBCM) (void) = 0;//declare reset function at address 0
|
||||
void printHelp(void)
|
||||
{
|
||||
Serial.print(F("\n\nLiBCM commands:"
|
||||
"\n -'$BOOT': restart LiBCM"
|
||||
"\n -'$OFF': turn LiBCM off (for testing purposes)"
|
||||
"\n -'$BOOT' : restart LiBCM"
|
||||
"\n -'$OFF' : turn LiBCM off (for testing purposes)"
|
||||
"\n -'$TESTR': run LTC6804 VREF test"
|
||||
"\n -'$TESTW': battery temp & SoC history"
|
||||
"\n -'$TESTH': blink heater LED"
|
||||
"\n -'$TESTC': print cell voltages"
|
||||
"\n -'$TESTT': print temperatures"
|
||||
"\n -'$TESTE': EEPROM factory reset"
|
||||
"\n -'$TEST1'/2/3/4: run temporary debug test code. See 'USB_userInterface_runTestCode()')"
|
||||
"\n -'$DEBUG': info stored in EEPROM. 'DEBUG=CLR' to restore defaults"
|
||||
"\n -'$KEYms': delay after keyON before LiBCM starts. 'KEYms=___' to set (0 to 254 ms)"
|
||||
"\n -'$SoC': battery charge in percent. 'SoC=___' to set (0 to 100%)"
|
||||
"\n -'$DISP=PWR'/SCI/CELL/TEMP/DBG/OFF: data to stream (power/BAT&METSCI/Vcell/temperature/none)"
|
||||
"\n -'$RATE=___': USB updates per second (1 to 255 Hz)"
|
||||
"\n -'$LOOP: LiBCM loop period. '$LOOP=___' to set (1 to 255 ms)"
|
||||
"\n -'$SCIms': period between BATTSCI frames. '$SCIms=___' to set (0 to 255 ms)"
|
||||
"\n -'$TRIP': print energy consumption and distance records ('TRIP=CLR' to zero all)"
|
||||
"\n -'$EPROM': dump EEPROM. '$EPROM=RST' to factory reset"
|
||||
"\n -'$TEST_': 1/2/3/4: run temporary debug test code. See 'USB_userInterface_runTestCode()')"
|
||||
"\n -'$DEBUG': info stored in EEPROM. '$DEBUG=CLR' to restore defaults"
|
||||
"\n -'$KEYms': delay after keyON before LiBCM starts. 'KEYms=_' to set (0 to 254 ms)"
|
||||
"\n -'$SoC' : battery charge in percent. '$SoC=_' to set (0 to 100%)"
|
||||
"\n -'$DISP=_: PWR/SCI/CELL/TEMP/DBG/OFF: data to stream"
|
||||
"\n -'$RATE=_: USB updates per second (1 to 255 Hz)"
|
||||
"\n -'$LOOP : LiBCM loop period. '$LOOP=_' to set (1 to 255 ms)"
|
||||
"\n -'$SCIms': period between BATTSCI frames. '$SCIms=_' to set (0 to 255 ms)"
|
||||
"\n -'$TRIP' : print energy consumption and distance records ('TRIP=CLR' to zero all)"
|
||||
"\n -'$SPOOF': print voltage spoofing calibration commands and instructions"
|
||||
"\n"
|
||||
"\nDebug characters:"
|
||||
"\n -'@': isoSPI error occurred"
|
||||
"\n -'*': loop period exceeded"
|
||||
"\n"
|
||||
"\nTip: Hit up arrow to recall previous commands"
|
||||
"\n"
|
||||
/*
|
||||
"\nFuture LiBCM commands (not presently supported"
|
||||
"\n -'$DEFAULT' restore all EEPROM values to default"
|
||||
"\n -'$FAN' display fan status. '$FAN=OFF'/LOW/HI to set."
|
||||
"\n -'$IHACK' display current hack setting. '$IHACK=00'/20/40/60 to set."
|
||||
"\n -'$VHACK' display voltage hack setting. '$VHACK=OEM'/ASSISTONLY_VAR/ASSISTONLY_BIN/ALWAYS."
|
||||
"\n -'$ASSIST_OFF' disable assist until LiBCM resets."
|
||||
"\n -'$ASSIST_ON' enable assist until LiBCM resets."
|
||||
"\n -'$REGEN_OFF' disable regen until LiBCM resets."
|
||||
"\n -'$REGEN_ON' enable regen until LiBCM resets."
|
||||
"\n -'BATTmAh' display battery capacity in mAh. 'BATTmAh=____' to set."
|
||||
"\n -'SoC_MAX' display max allowed SoC. 'SoC_MAX=__' to set."
|
||||
"\n -'SoC_MIN' display min allowed SoC. 'SoC_MIN=__' to set."
|
||||
"\n -'$AST=ON/OFF'"
|
||||
"\n -'$RGN=ON/OFF'"
|
||||
*/
|
||||
));
|
||||
//When adding new commands, make sure to add cases to the following functions:
|
||||
@@ -195,6 +194,32 @@ void printHelp(void)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void printVspoofInstructions(void)
|
||||
{
|
||||
Serial.print(F("\n\nVoltage Spoofing Commands:"
|
||||
"\n -'$BVO=_ : +/-/0: adjust OBDIIC&C parameter 0x0A"
|
||||
"\n -'$MDV=_ : +/-/0: adjust OBDIIC&C parameter 0x05"
|
||||
"\n -'$SPF=_ : +/-/0: adjust max allowed spoofed pack voltage"
|
||||
"\n"
|
||||
"\nCalibration instructions:"
|
||||
"\n 0: KeyON, engine off, IMA light must remain off throughout test"
|
||||
"\n 1: Configure OBDIIC&C to display BVO parameter 0x0A"
|
||||
"\n 2: Configure OBDIIC&C to display MDV parameter 0x05"
|
||||
"\n 4: Adjust BVO (on OBDIIC&C) until equal to SPF (on LiBCM LCD)"
|
||||
"\n Example: BVO is 169 volts & SPF is 175 volts. Type '$BVO=+' repeatedly until BVO=SPF"
|
||||
"\n Note: If '$BVO=+' doesn't increase BVO, type '$SPF=-' to reduce SPF"
|
||||
"\n 5: Adjust MDV until equal to SPF"
|
||||
"\n Example: MDV is 171 volts & SPF is 168 volts. Type '$MDV=-' repeatedly until MDV=SPF"
|
||||
"\n 6: Verify SPF & BVO & MDV are within 5 volts (ideally 0 volts)"
|
||||
));
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void printText_invalidEntry (void) { Serial.print(F("\nInvalid Entry")); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//LiBCM's atoi() implementation for uint8_t
|
||||
uint8_t get_uint8_FromInput(uint8_t digit1, uint8_t digit2, uint8_t digit3)
|
||||
{
|
||||
@@ -222,13 +247,13 @@ uint8_t get_uint8_FromInput(uint8_t digit1, uint8_t digit2, uint8_t digit3)
|
||||
//determine which command to run
|
||||
void USB_userInterface_executeUserInput(void)
|
||||
{
|
||||
if (line[0] == '$') //valid commands start with '$'
|
||||
if (line[0]=='$') //valid commands start with '$'
|
||||
{
|
||||
//$HELP
|
||||
if ((line[1] == 'H') && (line[2] == 'E') && (line[3] == 'L') && (line[4] == 'P')) { printHelp(); }
|
||||
if ((line[1]=='H') && (line[2]=='E') && (line[3]=='L') && (line[4]=='P')) { printHelp(); }
|
||||
|
||||
//$BOOT
|
||||
else if ((line[1] == 'B') && (line[2] == 'O') && (line[3] == 'O') && (line[4] == 'T'))
|
||||
else if ((line[1]=='B') && (line[2]=='O') && (line[3]=='O') && (line[4]=='T'))
|
||||
{
|
||||
Serial.print(F("\nRebooting LiBCM"));
|
||||
delay(50); //give serial buffer time to send
|
||||
@@ -236,7 +261,7 @@ void USB_userInterface_executeUserInput(void)
|
||||
}
|
||||
|
||||
//$OFF
|
||||
else if ((line[1] == 'O') && (line[2] == 'F') && (line[3] == 'F'))
|
||||
else if ((line[1]=='O') && (line[2]=='F') && (line[3]=='F'))
|
||||
{
|
||||
Serial.print(F("\nUnplug USB cable before the counter gets to zero:"));
|
||||
Serial.print(F("\nLiBCM turning off in "));
|
||||
@@ -258,125 +283,173 @@ void USB_userInterface_executeUserInput(void)
|
||||
}
|
||||
|
||||
//$TEST
|
||||
else if ((line[1] == 'T') && (line[2] == 'E') && (line[3] == 'S') && (line[4] == 'T')) { USB_userInterface_runTestCode(line[5]); }
|
||||
else if ((line[1]=='T') && (line[2]=='E') && (line[3]=='S') && (line[4]=='T')) { USB_userInterface_runTestCode(line[5]); }
|
||||
|
||||
//$DEBUG
|
||||
else if ((line[1] == 'D') && (line[2] == 'E') && (line[3] == 'B') && (line[4] == 'U') && (line[5] == 'G'))
|
||||
else if ((line[1]=='D') && (line[2]=='E') && (line[3]=='B') && (line[4]=='U') && (line[5]=='G'))
|
||||
{
|
||||
if ((line[6] == '=') && (line[7] == 'C') && (line[8] == 'L') && (line[9] == 'R'))
|
||||
if ((line[6]=='=') && (line[7]=='C') && (line[8]=='L') && (line[9]=='R'))
|
||||
{
|
||||
Serial.print(F("\nRestoring default DEBUG values"));
|
||||
eeprom_resetDebugValues();
|
||||
}
|
||||
else if (line[6] == STRING_TERMINATION_CHARACTER) { printDebug(); }
|
||||
else if (line[6]==STRING_TERMINATION_CHARACTER) { printDebug(); }
|
||||
else { printText_invalidEntry(); }
|
||||
}
|
||||
/*
|
||||
//$LIDISP //TOTO_Natalya: Move to '$TEST' //JTS2doLater: Delete if no longer used
|
||||
else if ((line[1] == 'L') && (line[2] == 'I') && (line[3] == 'D') && (line[4] == 'I') && (line[5] == 'S') && (line[6] == 'P'))
|
||||
{
|
||||
LiDisplay_setDebugMode(line[7]);
|
||||
} */
|
||||
|
||||
//KEYms
|
||||
else if ((line[1] == 'K') && (line[2] == 'E') && (line[3] == 'Y') && (line[4] == 'M') && (line[5] == 'S'))
|
||||
//$KEYms
|
||||
else if ((line[1]=='K') && (line[2]=='E') && (line[3]=='Y') && (line[4]=='M') && (line[5]=='S'))
|
||||
{
|
||||
if (line[6] == '=')
|
||||
if (line[6]=='=')
|
||||
{
|
||||
uint8_t newKeyOnDelay_ms = get_uint8_FromInput(line[7],line[8],line[9]);
|
||||
Serial.print(F("\nnewKeyOnDelay_ms is "));
|
||||
Serial.print(newKeyOnDelay_ms, DEC);
|
||||
eeprom_delayKeyON_ms_set(newKeyOnDelay_ms);
|
||||
}
|
||||
else if (line[6] == STRING_TERMINATION_CHARACTER)
|
||||
else if (line[6]==STRING_TERMINATION_CHARACTER)
|
||||
{
|
||||
Serial.print(F("\n Additional delay before LiBCM responds to keyON event (ms): "));
|
||||
Serial.print( eeprom_delayKeyON_ms_get(), DEC);
|
||||
}
|
||||
else { printText_invalidEntry(); }
|
||||
}
|
||||
|
||||
//SoC
|
||||
else if ((line[1] == 'S') && (line[2] == 'O') && (line[3] == 'C'))
|
||||
//$SoC
|
||||
else if ((line[1]=='S') && (line[2]=='O') && (line[3]=='C'))
|
||||
{
|
||||
if (line[4] == '=')
|
||||
if (line[4]=='=')
|
||||
{
|
||||
uint8_t newSoC_percent = get_uint8_FromInput(line[5],line[6],line[7]);
|
||||
Serial.print(F("\nnewSoC is "));
|
||||
Serial.print(newSoC_percent, DEC);
|
||||
SoC_setBatteryStateNow_percent(newSoC_percent);
|
||||
}
|
||||
else if (line[4] == STRING_TERMINATION_CHARACTER)
|
||||
else if (line[4]==STRING_TERMINATION_CHARACTER)
|
||||
{
|
||||
Serial.print(F("\nBattery SoC is (%): "));
|
||||
Serial.print(SoC_getBatteryStateNow_percent(),DEC);
|
||||
}
|
||||
else { printText_invalidEntry(); }
|
||||
}
|
||||
|
||||
//DISP
|
||||
//$DISP
|
||||
//JTS2doLater: Make this function work while grid charging, too
|
||||
else if ((line[1] == 'D') && (line[2] == 'I') && (line[3] == 'S') && (line[4] == 'P') && (line[5] == '='))
|
||||
else if ((line[1]=='D') && (line[2]=='I') && (line[3]=='S') && (line[4]=='P') && (line[5]=='='))
|
||||
{
|
||||
if ((line[6] == 'P') && (line[7] == 'W') && (line[8] == 'R')) { debugUSB_dataTypeToStream_set(DEBUGUSB_STREAM_POWER); }
|
||||
else if ((line[6] == 'S') && (line[7] == 'C') && (line[8] == 'I')) { debugUSB_dataTypeToStream_set(DEBUGUSB_STREAM_BATTMETSCI); }
|
||||
else if ((line[6] == 'C') && (line[7] == 'E') && (line[8] == 'L')) { debugUSB_dataTypeToStream_set(DEBUGUSB_STREAM_CELL); }
|
||||
else if ((line[6] == 'O') && (line[7] == 'F') && (line[8] == 'F')) { debugUSB_dataTypeToStream_set(DEBUGUSB_STREAM_NONE); }
|
||||
else if ((line[6] == 'T') && (line[7] == 'E') && (line[8] == 'M')) { debugUSB_dataTypeToStream_set(DEBUGUSB_STREAM_TEMP); }
|
||||
else if ((line[6] == 'D') && (line[7] == 'B') && (line[8] == 'G')) { debugUSB_dataTypeToStream_set(DEBUGUSB_STREAM_DEBUG); }
|
||||
if ((line[6]=='P') && (line[7]=='W') && (line[8]=='R')) { debugUSB_dataTypeToStream_set(DEBUGUSB_STREAM_POWER); }
|
||||
else if ((line[6]=='S') && (line[7]=='C') && (line[8]=='I')) { debugUSB_dataTypeToStream_set(DEBUGUSB_STREAM_BATTMETSCI); }
|
||||
else if ((line[6]=='C') && (line[7]=='E') && (line[8]=='L')) { debugUSB_dataTypeToStream_set(DEBUGUSB_STREAM_CELL); }
|
||||
else if ((line[6]=='O') && (line[7]=='F') && (line[8]=='F')) { debugUSB_dataTypeToStream_set(DEBUGUSB_STREAM_NONE); }
|
||||
else if ((line[6]=='T') && (line[7]=='E') && (line[8]=='M')) { debugUSB_dataTypeToStream_set(DEBUGUSB_STREAM_TEMP); }
|
||||
else if ((line[6]=='D') && (line[7]=='B') && (line[8]=='G')) { debugUSB_dataTypeToStream_set(DEBUGUSB_STREAM_DEBUG); }
|
||||
else { printText_invalidEntry(); }
|
||||
}
|
||||
|
||||
//RATE
|
||||
else if ((line[1] == 'R') && (line[2] == 'A') && (line[3] == 'T') && (line[4] == 'E') && (line[5] == '='))
|
||||
//$RATE
|
||||
else if ((line[1]=='R') && (line[2]=='A') && (line[3]=='T') && (line[4]=='E') && (line[5]=='='))
|
||||
{
|
||||
uint8_t newUpdatesPerSecond = get_uint8_FromInput(line[6],line[7],line[8]);
|
||||
debugUSB_dataUpdatePeriod_ms_set( time_hertz_to_milliseconds(newUpdatesPerSecond) );
|
||||
}
|
||||
|
||||
//LOOP
|
||||
else if ((line[1] == 'L') && (line[2] == 'O') && (line[3] == 'O') && (line[4] == 'P'))
|
||||
//$LOOP
|
||||
else if ((line[1]=='L') && (line[2]=='O') && (line[3]=='O') && (line[4]=='P'))
|
||||
{
|
||||
if (line[5] == '=')
|
||||
if (line[5]=='=')
|
||||
{
|
||||
uint8_t newLooprate_ms = get_uint8_FromInput(line[6],line[7],line[8]);
|
||||
time_loopPeriod_ms_set(newLooprate_ms);
|
||||
}
|
||||
else if (line[5] == STRING_TERMINATION_CHARACTER)
|
||||
else if (line[5]==STRING_TERMINATION_CHARACTER)
|
||||
{
|
||||
Serial.print(F("\nLoop period is (ms): "));
|
||||
Serial.print(time_loopPeriod_ms_get(),DEC);
|
||||
}
|
||||
else { printText_invalidEntry(); }
|
||||
}
|
||||
|
||||
//SCIms
|
||||
else if ((line[1] == 'S') && (line[2] == 'C') && (line[3] == 'I') && (line[4] == 'M') && (line[5] == 'S'))
|
||||
//$SCIms
|
||||
else if ((line[1]=='S') && (line[2]=='C') && (line[3]=='I') && (line[4]=='M') && (line[5]=='S'))
|
||||
{
|
||||
if (line[6] == '=')
|
||||
if (line[6]=='=')
|
||||
{
|
||||
uint8_t newPeriod_ms = get_uint8_FromInput(line[7],line[8],line[9]);
|
||||
BATTSCI_framePeriod_ms_set(newPeriod_ms);
|
||||
}
|
||||
else if (line[6] == STRING_TERMINATION_CHARACTER)
|
||||
else if (line[6]==STRING_TERMINATION_CHARACTER)
|
||||
{
|
||||
Serial.print(F("\nBATTSCI period is (ms): "));
|
||||
Serial.print(BATTSCI_framePeriod_ms_get(),DEC);
|
||||
}
|
||||
else { printText_invalidEntry(); }
|
||||
}
|
||||
|
||||
//TRIP
|
||||
else if ((line[1] == 'T') && (line[2] == 'R') && (line[3] == 'I') && (line[4] == 'P'))
|
||||
//$TRIP
|
||||
else if ((line[1]=='T') && (line[2]=='R') && (line[3]=='I') && (line[4]=='P'))
|
||||
{
|
||||
if ((line[5] == '=') && (line[6] == 'C') && (line[7] == 'L') && (line[8] == 'R'))
|
||||
if ((line[5]=='=') && (line[6]=='C') && (line[7]=='L') && (line[8]=='R'))
|
||||
{
|
||||
eeprom_wattHourHistory_reset();
|
||||
}
|
||||
else if (line[5] == STRING_TERMINATION_CHARACTER)
|
||||
{
|
||||
eeprom_wattHourHistory_printTripHistory();
|
||||
}
|
||||
else if (line[5]==STRING_TERMINATION_CHARACTER) { eeprom_wattHourHistory_printTripHistory(); }
|
||||
else { printText_invalidEntry(); }
|
||||
}
|
||||
|
||||
//$DEFAULT
|
||||
else { Serial.print(F("\nInvalid Entry")); }
|
||||
//$EPROM
|
||||
else if ((line[1]=='E') && (line[2]=='P') && (line[3]=='R') && (line[4]=='O') && (line[5]=='M'))
|
||||
{
|
||||
if ((line[6]=='=') && (line[7]=='R') && (line[8]=='S') && (line[9]=='T')) { eeprom_resetAll_userConfirm(); }
|
||||
else if (line[6]==STRING_TERMINATION_CHARACTER) { eeprom_printAll(); }
|
||||
else { printText_invalidEntry(); }
|
||||
}
|
||||
|
||||
//$BVO
|
||||
else if ((line[1]=='B') && (line[2]=='V') && (line[3]=='O'))
|
||||
{
|
||||
//BVO affects MCMe output
|
||||
Serial.print(' ');
|
||||
if ( (line[4]=='=') &&
|
||||
((line[5]=='+') || (line[5]=='-') || (line[5]=='0')) &&
|
||||
(line[6]==STRING_TERMINATION_CHARACTER) ) { vPackSpoof_offsetBVO_adjust(line[5]); }
|
||||
else if (line[4]==STRING_TERMINATION_CHARACTER) { Serial.print(vPackSpoof_offsetBVO_get()); }
|
||||
else { printText_invalidEntry(); }
|
||||
}
|
||||
|
||||
//$MDV
|
||||
else if ((line[1]=='M') && (line[2]=='D') && (line[3]=='V'))
|
||||
{
|
||||
//MDV affects VPIN output
|
||||
Serial.print(' ');
|
||||
if ( (line[4]=='=') &&
|
||||
((line[5]=='+') || (line[5]=='-') || (line[5]=='0')) &&
|
||||
(line[6]==STRING_TERMINATION_CHARACTER) ) { vPackSpoof_offsetMDV_adjust(line[5]); }
|
||||
else if (line[4]==STRING_TERMINATION_CHARACTER) { Serial.print(vPackSpoof_offsetMDV_get()); }
|
||||
else { printText_invalidEntry(); }
|
||||
}
|
||||
|
||||
//$SPF
|
||||
else if ((line[1]=='S') && (line[2]=='P') && (line[3]=='F'))
|
||||
{
|
||||
//MDV affects VPIN output
|
||||
Serial.print(' ');
|
||||
if ( (line[4]=='=') &&
|
||||
((line[5]=='+') || (line[5]=='-') || (line[5]=='0')) &&
|
||||
(line[6]==STRING_TERMINATION_CHARACTER) ) { vPackSpoof_offsetSPF_adjust(line[5]); }
|
||||
else if (line[4]==STRING_TERMINATION_CHARACTER) { Serial.print(vPackSpoof_offsetSPF_get()); }
|
||||
else { printText_invalidEntry(); }
|
||||
}
|
||||
|
||||
//$SPOOF
|
||||
else if ((line[1]=='S') && (line[2]=='P') && (line[3]=='O') && (line[4]=='O') && (line[5]=='F'))
|
||||
{
|
||||
printVspoofInstructions();
|
||||
}
|
||||
|
||||
//DEFAULT
|
||||
else { printText_invalidEntry(); }
|
||||
}
|
||||
else { Serial.print(F("\nInvalid Entry")); }
|
||||
else { printText_invalidEntry(); }
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -192,7 +192,7 @@ uint8_t BATTSCI_calculateRegenAssistFlags(void)
|
||||
if ((BATTSCI_isPackFull() == YES) || //pack is full
|
||||
((temperature_battery_getLatest() < TEMP_FREEZING_DEGC + 2) && (BATTSCI_isPackEmpty() == NO)) ) //pack too cold to charge; DCDC still powered
|
||||
//JTS2doLater: Allow minimal regen when pack below freezing (e.g. using LiControl to limit max regen)
|
||||
//JTS2doNow: Disable assist and regen if pack too hot
|
||||
//JTS2doLater: Disable assist and regen if pack too hot
|
||||
#endif
|
||||
{
|
||||
flags |= BATTSCI_DISABLE_REGEN_FLAG; //when this flag is set, MCM draws zero power from IMA motor
|
||||
@@ -219,7 +219,7 @@ uint8_t BATTSCI_calculateRegenAssistFlags(void)
|
||||
// 0x32 = 50d = 0b0011 0010: pack empty
|
||||
// 0x52 = 82d = 0b0101 0010: pack full (usually... see "Day1-1" for case where pack is empty)
|
||||
|
||||
//JTS2doNow: Allow regen at lower temperatures (see calculations in LiBCM Support Thread post#3637)
|
||||
//JTS2doLater: Allow regen at lower temperatures (see calculations in LiBCM Support Thread post#3637)
|
||||
//kindly request regen and/or no regen from MCM
|
||||
uint8_t BATTSCI_calculateChargeRequestByte(void)
|
||||
{
|
||||
|
||||
@@ -39,12 +39,10 @@ bool cellBalance_areCellsBalancing(void) { return cellsAreBalancing; }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//JTS2doLater: Always allow discharge balancing when a cell is overcharged (for safety)
|
||||
//JTS2doLater: Write keyOff test that measures each cell voltage twice: once with discharge resistor off, and again with resistor on.
|
||||
// Then verify voltage drop, which means the discharge resistor is turning off and on. If there isn't enough resolution,
|
||||
// another method would be to wait a few hours for pack voltages to settle, then log all cell voltages an hour apart.
|
||||
//JTS2doLater: Add per-cell SoC, to allow balancing at any SoC (see icn.net:post#1502833,comment#579)
|
||||
//balance cells (if needed)
|
||||
void configureDischargeResistors(void)
|
||||
{
|
||||
static uint8_t balanceHysteresis = CELL_BALANCE_TO_WITHIN_COUNTS_TIGHT;
|
||||
@@ -53,7 +51,7 @@ void configureDischargeResistors(void)
|
||||
|
||||
cellsAreBalancing = NO;
|
||||
|
||||
if (LTC68042result_hiCellVoltage_get() > CELL_VREST_85_PERCENT_SoC) { cellDischargeVoltageThreshold = CELL_VREST_85_PERCENT_SoC; }
|
||||
if (LTC68042result_hiCellVoltage_get() > CELL_VREST_085_PERCENT_SoC) { cellDischargeVoltageThreshold = CELL_VREST_085_PERCENT_SoC; }
|
||||
else { cellDischargeVoltageThreshold = LTC68042result_loCellVoltage_get() + balanceHysteresis; }
|
||||
|
||||
//determine which cells to balance
|
||||
@@ -94,42 +92,81 @@ void disableDischargeResistors(void)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//JTS2doNext: Add "balance really unbalanced pack" code outlined in ic.net post #3876
|
||||
uint8_t isBalancingAllowed(void)
|
||||
//balancing criteria for a healthy pack
|
||||
uint8_t isBalancingPossible(void)
|
||||
{
|
||||
//order is important
|
||||
//external checks
|
||||
if (key_getSampledState() == KEYSTATE_ON ) { return NO__KEY_IS_ON; }
|
||||
#ifdef ONLY_BALANCE_CELLS_WHEN_GRID_CHARGER_PLUGGED_IN
|
||||
if (gpio_isGridChargerPluggedInNow() == NO ) { return NO__CHARGER_UNPLUGGED; }
|
||||
#else
|
||||
if ((gpio_isGridChargerPluggedInNow() == NO ) &&
|
||||
(SoC_getBatteryStateNow_percent() < CELL_BALANCE_MIN_SoC) ) { return NO__SoC_TOO_LOW; }
|
||||
#endif
|
||||
//cell voltage checks
|
||||
if (LTC68042result_hiCellVoltage_get() > CELL_VMAX_REGEN ) { return NO__ATLEASTONECELL_TOO_HIGH; }
|
||||
if (LTC68042result_loCellVoltage_get() < CELL_VMIN_GRIDCHARGER ) { return NO__ATLEASTONECELL_TOO_LOW; }
|
||||
//thermal checks
|
||||
if (temperature_battery_getLatest() > CELL_BALANCE_MAX_TEMP_C) { return NO__BATTERY_IS_HOT; }
|
||||
|
||||
//time checks
|
||||
if (time_isItTimeToPerformKeyOffTasks() == NO ) { return DELAY_DO_NOTHING; }
|
||||
|
||||
return YES__BALANCING_ALLOWED;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//JTS2doLater: balance majorly imbalanced cells even when grid charger is unplugged
|
||||
void cellBalance_handler(void)
|
||||
//balancing criteria for a majorly unbalanced pack
|
||||
uint8_t isBalancingMandatory(void)
|
||||
{
|
||||
static uint8_t isBalancingAllowed_previous = NO__UNINITIALIZED;
|
||||
uint8_t isBalancingAllowed_now = isBalancingAllowed();
|
||||
uint16_t cellDeltaV = LTC68042result_deltaCellVoltage_get();
|
||||
|
||||
if (isBalancingAllowed_now == YES__BALANCING_ALLOWED)
|
||||
{
|
||||
if (time_isItTimeToPerformKeyOffTasks() == YES) { configureDischargeResistors(); }
|
||||
}
|
||||
else if (isBalancingAllowed_previous == YES__BALANCING_ALLOWED) { disableDischargeResistors(); }
|
||||
if (cellDeltaV < CELL_MAJOR_IMBALANCE_DELTA) { return NO__BALANCING_NOT_REQUESTED; }
|
||||
|
||||
isBalancingAllowed_previous = isBalancingAllowed_now;
|
||||
//if we get here, pack is majorly unbalanced
|
||||
//keyState doesn't matter
|
||||
//grid charger state doesn't matter
|
||||
//pack temperature doesn't matter
|
||||
if (LTC68042result_loCellVoltage_get() < CELL_VMIN_GRIDCHARGER ) { return NO__ATLEASTONECELL_TOO_LOW; }
|
||||
if (adc_getLatestSpoofedCurrent_deciAmps() > CELL_IMAX_MAJOR_IMBALANCE_DECIAMPS) { return NO__PACK_CURRENT_TOO_HIGH; }
|
||||
if (adc_getLatestSpoofedCurrent_deciAmps() < -CELL_IMAX_MAJOR_IMBALANCE_DECIAMPS) { return NO__PACK_CURRENT_TOO_HIGH; }
|
||||
|
||||
if (cellDeltaV > eeprom_maxCellVoltageDelta_get()) { eeprom_maxCellVoltageDelta_set(cellDeltaV); }
|
||||
|
||||
return YES__BALANCING_ALLOWED;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint8_t isEntirePackOvercharged(void)
|
||||
{
|
||||
if ((LTC68042result_hiCellVoltage_get() > CELL_VREST_100_PERCENT_SoC ) &&
|
||||
(LTC68042result_loCellVoltage_get() > CELL_VMAX_GRIDCHARGER ) ) { return YES__BALANCING_ALLOWED; }
|
||||
|
||||
return NO__BALANCING_NOT_REQUESTED;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint8_t getBalanceRequest(void)
|
||||
{
|
||||
if (isBalancingMandatory() == YES__BALANCING_ALLOWED) { return YES__BALANCING_ALLOWED; }
|
||||
if (isEntirePackOvercharged() == YES__BALANCING_ALLOWED) { return YES__BALANCING_ALLOWED; }
|
||||
|
||||
return isBalancingPossible();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void cellBalance_handler(void)
|
||||
{
|
||||
if (LTC68042result_wasDataProcessedThisLoop_get() == NO) { return; } //wait for new Vcell data
|
||||
|
||||
static uint8_t isBalancingAllowed_previous = NO__UNINITIALIZED;
|
||||
uint8_t isBalancingAllowed_now = getBalanceRequest();
|
||||
|
||||
if (isBalancingAllowed_now == DELAY_DO_NOTHING ) { return; }
|
||||
else if (isBalancingAllowed_now == YES__BALANCING_ALLOWED) { configureDischargeResistors(); }
|
||||
else if (isBalancingAllowed_previous == YES__BALANCING_ALLOWED) { disableDischargeResistors(); }
|
||||
|
||||
isBalancingAllowed_previous = isBalancingAllowed_now; //not updated if 'DELAY_DO_NOTHING'
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -7,7 +7,14 @@
|
||||
#define BALANCING_DISABLED 0
|
||||
#define BALANCING_ALLOWED 1
|
||||
|
||||
#define YES__BALANCING_ALLOWED YES__CHARGING_ALLOWED //balancing code reusing grid charging constants
|
||||
#define CELL_MAJOR_IMBALANCE_DELTA 1000 // '1000' = 100 mV
|
||||
#define CELL_IMAX_MAJOR_IMBALANCE_DECIAMPS 90 // '90' = 9.0 A
|
||||
#define CELL_BALANCE_TO_WITHIN_COUNTS_LOOSE 32 // '32' = 3.2 mV //CANNOT exceed 255 counts (25.5 mV)
|
||||
#define CELL_BALANCE_TO_WITHIN_COUNTS_TIGHT 22 // '22' = 2.2 mV //ADC uncertainty: 2.2 mV //MUST be less than CELL_BALANCE_TO_WITHIN_COUNTS_LOOSE
|
||||
|
||||
//balancing constants reuse grid charging constants
|
||||
#define YES__BALANCING_ALLOWED YES__CHARGING_ALLOWED
|
||||
#define NO__BALANCING_NOT_REQUESTED NO__CHARGING_NOT_REQUESTED
|
||||
|
||||
bool cellBalance_areCellsBalancing(void);
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
#define PIN_BATTCURRENT A0
|
||||
#define PIN_USER_SW A1
|
||||
#define PIN_VPIN_IN A2
|
||||
#define PIN_TEMP_YEL A3 // 5AhG3: Exhaust, FoMoCo Top middle battery module
|
||||
#define PIN_TEMP_GRN A4 // 5AhG3: Intake, FoMoCo Top rear battery module
|
||||
#define PIN_TEMP_YEL A3 // 5AhG3: Exhaust //47Ah: Top middle battery
|
||||
#define PIN_TEMP_GRN A4 // 5AhG3: Intake //47Ah: Top rear battery
|
||||
#define PIN_TEMP_WHT A5
|
||||
#define PIN_TEMP_BLU A6
|
||||
#define PIN_FANOEM_LOW A7
|
||||
@@ -48,7 +48,7 @@
|
||||
#define PIN_BATTSCI_DE 41
|
||||
#define PIN_COVER_SWITCH 42
|
||||
#define PIN_GPIO0_CS_MIMA 43
|
||||
#define PIN_GPIO3 44 //with daughterboard: 1500W charger current (if installed) //without daughterboard: heater (if installed)
|
||||
#define PIN_GPIO3 44 //with daughterboard: 1500W charger current //without DB: heater (if installed)
|
||||
#define PIN_BUZZER_PWM 45
|
||||
#define PIN_LED3 46
|
||||
#define PIN_SPI_EXT_CS 47
|
||||
|
||||
@@ -193,7 +193,7 @@ void debugUSB_printData_temperatures(void)
|
||||
Serial.print(F(", T_in:"));
|
||||
Serial.print(String(temperature_intake_getLatest()));
|
||||
Serial.print(F(", T_out:"));
|
||||
#ifndef BATTERY_TYPE_47AhFoMoCo
|
||||
#ifndef BATTERY_TYPE_47Ah
|
||||
Serial.print(String(temperature_exhaust_getLatest()));
|
||||
#else
|
||||
Serial.print(F("none"));
|
||||
@@ -201,7 +201,7 @@ void debugUSB_printData_temperatures(void)
|
||||
Serial.print(F(", T_charger:"));
|
||||
Serial.print(String(temperature_gridCharger_getLatest()));
|
||||
Serial.print(F(", T_bay:"));
|
||||
#ifndef BATTERY_TYPE_47AhFoMoCo
|
||||
#ifndef BATTERY_TYPE_47Ah
|
||||
Serial.print(String(temperature_ambient_getLatest()));
|
||||
#else
|
||||
Serial.print(F("none"));
|
||||
@@ -277,8 +277,8 @@ void debugUSB_printConfigParameters(void)
|
||||
|
||||
#ifdef BATTERY_TYPE_5AhG3
|
||||
Serial.print(F("/5AhG3"));
|
||||
#elif defined BATTERY_TYPE_47AhFoMoCo
|
||||
Serial.print(F("/FoMoCo"));
|
||||
#elif defined BATTERY_TYPE_47Ah
|
||||
Serial.print(F("/47Ah"));
|
||||
#endif
|
||||
|
||||
#ifdef STACK_IS_48S
|
||||
|
||||
@@ -25,6 +25,10 @@ const uint16_t EEPROM_ADDRESS_BATTSCI_ASSIST = 0x010; //EEPROM range is 0x0
|
||||
const uint16_t EEPROM_ADDRESS_KEYON_DELAY = 0x011; //EEPROM range is 0x011 ( 1B)
|
||||
const uint16_t EEPROM_ADDRESS_NEXT_Wh_RECORD = 0x012; //EEPROM range is 0x012 ( 1B)
|
||||
const uint16_t EEPROM_ADDRESS_COMPILE_TIME = 0x013; //EEPROM range is 0x013:0x01B ( 9B)
|
||||
const uint16_t EEPROM_ADDRESS_MAX_VCELL_DELTA = 0x01C; //EEPROM range is 0x01C:0x01D ( 2B)
|
||||
const uint16_t EEPROM_ADDRESS_BVO_OFFSET = 0x01E; //EEPROM range is 0x01E ( 1B)
|
||||
const uint16_t EEPROM_ADDRESS_MDV_OFFSET = 0x01F; //EEPROM range is 0x01F ( 1B)
|
||||
const uint16_t EEPROM_ADDRESS_SPF_OFFSET = 0x020; //EEPROM range is 0x020 ( 1B)
|
||||
//this EEPROM space still available
|
||||
//The following addresses start from end of EEPROM space and work backwards to beginning
|
||||
const uint16_t EEPROM_ADDRESS_BATT_HISTORY = EEPROM_LAST_USABLE_ADDRESS - NUM_BYTES_BATTERY_HISTORY; //0xA57:0xF9F (1536B)
|
||||
@@ -145,9 +149,6 @@ uint16_t hoursSincePreviousKeyOff(void)
|
||||
|
||||
remainder_ms = delta_ms;
|
||||
|
||||
Serial.print(F("\nRemainder_ms: "));
|
||||
Serial.print(remainder_ms);
|
||||
|
||||
return delta_hours;
|
||||
}
|
||||
|
||||
@@ -189,41 +190,86 @@ void eeprom_keyOffCheckForExpiredFirmware(void)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint8_t eeprom_hasLibcmDisabledAssist_get(void) { return EEPROM.read(EEPROM_ADDRESS_BATTSCI_ASSIST); }
|
||||
uint8_t eeprom_hasLibcmDisabledAssist_get(void) { return EEPROM.read (EEPROM_ADDRESS_BATTSCI_ASSIST); }
|
||||
void eeprom_hasLibcmDisabledAssist_set(uint8_t wasAssistLimited) { EEPROM.update(EEPROM_ADDRESS_BATTSCI_ASSIST, wasAssistLimited); }
|
||||
|
||||
uint8_t eeprom_hasLibcmDisabledRegen_get(void) { return EEPROM.read(EEPROM_ADDRESS_BATTSCI_REGEN); }
|
||||
void eeprom_hasLibcmDisabledRegen_set(uint8_t wasRegenLimited) { EEPROM.update(EEPROM_ADDRESS_BATTSCI_REGEN, wasRegenLimited); }
|
||||
uint8_t eeprom_hasLibcmDisabledRegen_get(void) { return EEPROM.read (EEPROM_ADDRESS_BATTSCI_REGEN); }
|
||||
void eeprom_hasLibcmDisabledRegen_set(uint8_t wasRegenLimited) { EEPROM.update(EEPROM_ADDRESS_BATTSCI_REGEN, wasRegenLimited); }
|
||||
|
||||
uint16_t eeprom_maxCellVoltageDelta_get(void) { return readFromEEPROM_uint16(EEPROM_ADDRESS_MAX_VCELL_DELTA); }
|
||||
void eeprom_maxCellVoltageDelta_set(uint16_t newMax) { writeToEEPROM_uint16(EEPROM_ADDRESS_MAX_VCELL_DELTA, newMax); }
|
||||
|
||||
uint8_t eeprom_delayKeyON_ms_get(void) { return EEPROM.read (EEPROM_ADDRESS_KEYON_DELAY); }
|
||||
void eeprom_delayKeyON_ms_set(uint8_t delay_ms) { EEPROM.update(EEPROM_ADDRESS_KEYON_DELAY, delay_ms); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint8_t eeprom_delayKeyON_ms_get(void) { return EEPROM.read(EEPROM_ADDRESS_KEYON_DELAY); }
|
||||
void eeprom_delayKeyON_ms_set(uint8_t delay_ms) { EEPROM.update(EEPROM_ADDRESS_KEYON_DELAY, delay_ms); }
|
||||
int8_t eeprom_getVspoofOffset_BVO(void) { return EEPROM.read (EEPROM_ADDRESS_BVO_OFFSET); }
|
||||
int8_t eeprom_getVspoofOffset_MDV(void) { return EEPROM.read (EEPROM_ADDRESS_MDV_OFFSET); }
|
||||
int8_t eeprom_getVspoofOffset_SPF(void) { return EEPROM.read (EEPROM_ADDRESS_SPF_OFFSET); }
|
||||
|
||||
void eeprom_setVspoofOffset_BVO(int8_t newOffset_counts) { EEPROM.update(EEPROM_ADDRESS_BVO_OFFSET, newOffset_counts); }
|
||||
void eeprom_setVspoofOffset_MDV(int8_t newOffset_counts) { EEPROM.update(EEPROM_ADDRESS_MDV_OFFSET, newOffset_counts); }
|
||||
void eeprom_setVspoofOffset_SPF(int8_t newOffset_counts) { EEPROM.update(EEPROM_ADDRESS_SPF_OFFSET, newOffset_counts); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void printMessage_RestoringEEPROM(void) { Serial.print(F("\nRestoring EEPROM value: ")); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eeprom_verifyDataValid(void)
|
||||
{
|
||||
//verify all runtime-configurable data stored in EEPROM is valid. If not, load default value(s)
|
||||
if ( !( (eeprom_hasLibcmDisabledRegen_get() == EEPROM_LIBCM_DISABLED_REGEN) || (eeprom_hasLibcmDisabledRegen_get() == EEPROM_REGEN_NEVER_LIMITED) ) )
|
||||
if ( !((eeprom_hasLibcmDisabledRegen_get() == EEPROM_LIBCM_DISABLED_REGEN) ||
|
||||
(eeprom_hasLibcmDisabledRegen_get() == EEPROM_REGEN_NEVER_LIMITED ) ) )
|
||||
{
|
||||
//invalid data in EEPROM
|
||||
Serial.print(F("\nRestoring EEPROM value: EEPROM_LIBCM_DISABLED_REGEN"));
|
||||
printMessage_RestoringEEPROM(); Serial.print(F("LIBCM_DISABLED_REGEN"));
|
||||
eeprom_hasLibcmDisabledRegen_set(EEPROM_REGEN_NEVER_LIMITED);
|
||||
}
|
||||
|
||||
if ( !( (eeprom_hasLibcmDisabledAssist_get() == EEPROM_LIBCM_DISABLED_ASSIST) || (eeprom_hasLibcmDisabledAssist_get() == EEPROM_ASSIST_NEVER_LIMITED) ) )
|
||||
if ( !((eeprom_hasLibcmDisabledAssist_get() == EEPROM_LIBCM_DISABLED_ASSIST) ||
|
||||
(eeprom_hasLibcmDisabledAssist_get() == EEPROM_ASSIST_NEVER_LIMITED ) ) )
|
||||
{
|
||||
//invalid data in EEPROM
|
||||
Serial.print(F("\nRestoring EEPROM value: EEPROM_LIBCM_DISABLED_ASSIST"));
|
||||
printMessage_RestoringEEPROM(); Serial.print(F("LIBCM_DISABLED_ASSIST"));
|
||||
eeprom_hasLibcmDisabledAssist_set(EEPROM_ASSIST_NEVER_LIMITED);
|
||||
}
|
||||
|
||||
if (eeprom_delayKeyON_ms_get() == EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE)
|
||||
if (eeprom_delayKeyON_ms_get() == EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE_8b)
|
||||
{
|
||||
Serial.print(F("\nRestoring EEPROM value: EEPROM_ADDRESS_KEYON_DELAY"));
|
||||
printMessage_RestoringEEPROM(); Serial.print(F("KEYON_DELAY"));
|
||||
eeprom_delayKeyON_ms_set(0);
|
||||
}
|
||||
|
||||
if (eeprom_maxCellVoltageDelta_get() == EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE_16b)
|
||||
{
|
||||
printMessage_RestoringEEPROM(); Serial.print(F("IMBALANCE_DELTA"));
|
||||
eeprom_maxCellVoltageDelta_set(CELL_MAJOR_IMBALANCE_DELTA);
|
||||
}
|
||||
|
||||
if (EEPROM.read(EEPROM_ADDRESS_BATT_HISTORY_UNINIT) == EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE_8b)
|
||||
{
|
||||
eeprom_batteryHistory_reset();
|
||||
EEPROM.update(EEPROM_ADDRESS_BATT_HISTORY_UNINIT, EEPROM_ADDRESS_FORMATTED_VALUE);
|
||||
}
|
||||
|
||||
if (EEPROM.read(EEPROM_ADDRESS_Wh_RECORDS_UNINIT) == EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE_8b)
|
||||
{
|
||||
eeprom_wattHourHistory_reset();
|
||||
EEPROM.update(EEPROM_ADDRESS_Wh_RECORDS_UNINIT, EEPROM_ADDRESS_FORMATTED_VALUE);
|
||||
EEPROM.update(EEPROM_ADDRESS_NEXT_Wh_RECORD, EEPROM_ADDRESS_FORMATTED_VALUE);
|
||||
}
|
||||
|
||||
if ((EEPROM.read(EEPROM_ADDRESS_BVO_OFFSET) == EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE_8b) &&
|
||||
(EEPROM.read(EEPROM_ADDRESS_MDV_OFFSET) == EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE_8b) &&
|
||||
(EEPROM.read(EEPROM_ADDRESS_SPF_OFFSET) == EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE_8b) )
|
||||
{
|
||||
//JTS2doLater: fix int8_t issue where EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE_8b = 0xFF = -1
|
||||
printMessage_RestoringEEPROM(); Serial.print(F("VPACKSPOOF_OFFSETS"));
|
||||
EEPROM.update(EEPROM_ADDRESS_BVO_OFFSET, EEPROM_ADDRESS_FORMATTED_VALUE);
|
||||
EEPROM.update(EEPROM_ADDRESS_MDV_OFFSET, EEPROM_ADDRESS_FORMATTED_VALUE);
|
||||
EEPROM.update(EEPROM_ADDRESS_SPF_OFFSET, EEPROM_ADDRESS_FORMATTED_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -232,6 +278,7 @@ void eeprom_resetDebugValues(void)
|
||||
{
|
||||
eeprom_hasLibcmDisabledRegen_set(EEPROM_REGEN_NEVER_LIMITED);
|
||||
eeprom_hasLibcmDisabledAssist_set(EEPROM_ASSIST_NEVER_LIMITED);
|
||||
eeprom_maxCellVoltageDelta_set(CELL_MAJOR_IMBALANCE_DELTA);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -266,20 +313,18 @@ void eeprom_batteryHistory_incrementValue(uint8_t indexTemperature, uint8_t inde
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eeprom_eraseRange(uint16_t minAddress, uint16_t maxAddress, uint8_t valueToWrite)
|
||||
{
|
||||
Serial.print('\n');
|
||||
|
||||
{
|
||||
for (uint16_t address = minAddress; address <= maxAddress; address++)
|
||||
{
|
||||
EEPROM.update(address, valueToWrite);
|
||||
|
||||
Serial.print('.');
|
||||
|
||||
if ((address & 0b01111111) == 0) //if divisible by 128
|
||||
{
|
||||
wdt_reset();
|
||||
Serial.print('\n');
|
||||
}
|
||||
|
||||
EEPROM.update(address, valueToWrite);
|
||||
|
||||
Serial.print('.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,7 +433,7 @@ void eeprom_resetAll(void)
|
||||
|
||||
Serial.print(F("\nEEPROM factory reset"));
|
||||
|
||||
eeprom_eraseRange(minAddress, maxAddress, EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE);
|
||||
eeprom_eraseRange(minAddress, maxAddress, EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE_8b);
|
||||
|
||||
Serial.print(F("\nDone. Rebooting."));
|
||||
|
||||
@@ -412,23 +457,36 @@ void eeprom_resetAll_userConfirm(void)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eeprom_begin(void)
|
||||
void eeprom_printAll(void)
|
||||
{
|
||||
eeprom_verifyDataValid();
|
||||
Serial.print(F("\n\nDumping EEPROM"));
|
||||
|
||||
if (EEPROM.read(EEPROM_ADDRESS_BATT_HISTORY_UNINIT) == EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE)
|
||||
for(uint16_t address = 0; address <= EEPROM_LAST_USABLE_ADDRESS; address++)
|
||||
{
|
||||
eeprom_batteryHistory_reset();
|
||||
EEPROM.update(EEPROM_ADDRESS_BATT_HISTORY_UNINIT, EEPROM_ADDRESS_FORMATTED_VALUE);
|
||||
}
|
||||
if ((address & 0b00001111) == 0) //if divisible by 16
|
||||
{
|
||||
wdt_reset();
|
||||
Serial.print('\n');
|
||||
Serial.print(F("0x"));
|
||||
if (address <= 0xF ) { Serial.print('0'); }
|
||||
if (address <= 0xFF) { Serial.print('0'); }
|
||||
Serial.print(address, HEX);
|
||||
Serial.print(F(": "));
|
||||
}
|
||||
|
||||
if (EEPROM.read(EEPROM_ADDRESS_Wh_RECORDS_UNINIT) == EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE)
|
||||
{
|
||||
eeprom_wattHourHistory_reset();
|
||||
EEPROM.update(EEPROM_ADDRESS_Wh_RECORDS_UNINIT, EEPROM_ADDRESS_FORMATTED_VALUE);
|
||||
EEPROM.update(EEPROM_ADDRESS_NEXT_Wh_RECORD, EEPROM_ADDRESS_FORMATTED_VALUE);
|
||||
}
|
||||
uint8_t data = EEPROM.read(address);
|
||||
|
||||
if (data <= 0xF) { Serial.print('0'); }
|
||||
Serial.print(data, HEX);
|
||||
Serial.print(',');
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eeprom_begin(void)
|
||||
{
|
||||
eeprom_verifyDataValid();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
#define EEPROM_LIBCM_DISABLED_ASSIST 0xCC
|
||||
#define EEPROM_ASSIST_NEVER_LIMITED 0x33
|
||||
|
||||
#define EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE 0xFF
|
||||
#define EEPROM_ADDRESS_FORMATTED_VALUE 0x00
|
||||
#define EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE_16b 0xFFFF
|
||||
#define EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE_8b 0xFF
|
||||
#define EEPROM_ADDRESS_FORMATTED_VALUE 0x00
|
||||
|
||||
#define BYTES_IN_DATE 12 //JTS2doLater: Is date 11 bytes or 12?
|
||||
#define BYTES_IN_TIME 9 //JTS2doLater: Is time 9 bytes or 8?
|
||||
#define BYTES_IN_DATE 12
|
||||
#define BYTES_IN_TIME 9
|
||||
|
||||
#define REQUIRED_FIRMWARE_UPDATE_PERIOD_DAYS 120
|
||||
#define REQUIRED_FIRMWARE_UPDATE_PERIOD_HOURS (REQUIRED_FIRMWARE_UPDATE_PERIOD_DAYS * 24)
|
||||
@@ -39,9 +40,20 @@
|
||||
uint8_t eeprom_hasLibcmDisabledRegen_get(void);
|
||||
void eeprom_hasLibcmDisabledRegen_set(uint8_t);
|
||||
|
||||
uint16_t eeprom_maxCellVoltageDelta_get(void);
|
||||
void eeprom_maxCellVoltageDelta_set(uint16_t);
|
||||
|
||||
uint8_t eeprom_delayKeyON_ms_get(void);
|
||||
void eeprom_delayKeyON_ms_set(uint8_t);
|
||||
|
||||
int8_t eeprom_getVspoofOffset_BVO(void);
|
||||
int8_t eeprom_getVspoofOffset_MDV(void);
|
||||
int8_t eeprom_getVspoofOffset_SPF(void);
|
||||
|
||||
void eeprom_setVspoofOffset_BVO(int8_t);
|
||||
void eeprom_setVspoofOffset_MDV(int8_t);
|
||||
void eeprom_setVspoofOffset_SPF(int8_t);
|
||||
|
||||
void eeprom_resetDebugValues(void);
|
||||
|
||||
void eeprom_verifyDataValid(void);
|
||||
@@ -63,4 +75,6 @@
|
||||
|
||||
void writeToEEPROM_uint16(uint16_t startAddress, uint16_t value);
|
||||
|
||||
void eeprom_printAll(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -246,8 +246,8 @@ void fan_handler(void)
|
||||
|
||||
#ifdef BATTERY_TYPE_5AhG3
|
||||
gpio_setFanSpeed_OEM(fanSpeed_now);
|
||||
#elif defined BATTERY_TYPE_47AhFoMoCo
|
||||
//OEM battery fan is removed in FoMoCo systems. The battery fan circuitry is repurposed to allow LiBCM to control the PDU fan
|
||||
#elif defined BATTERY_TYPE_47Ah
|
||||
//OEM battery fan is removed in 47Ah Kits. The battery fan circuitry is repurposed to allow LiBCM to control the PDU fan
|
||||
//Note that the MCM retains its OEM behavior (i.e. it can still control the PDU fan, too).
|
||||
//JTS2doLater: Add new fan handler specifically for OEM fan... the direct gpio functions used below will only work properly if no other subsystem calls them
|
||||
//JTS2doLater: Enable high speed if more than 500 kJ have flowed through the IGBT stage over the previous 60 seconds.
|
||||
|
||||
@@ -90,7 +90,7 @@ void gpio_setFanSpeed_OEM(char speed)
|
||||
//case FAN_MED: digitalWrite(PIN_FANOEM_LOW, HIGH); digitalWrite(PIN_FANOEM_HI, LOW); break; //same as FAN_LOW... OEM fan only supports OFF/LOW/HIGH
|
||||
#ifdef BATTERY_TYPE_5AhG3
|
||||
case FAN_HIGH: digitalWrite(PIN_FANOEM_LOW, LOW); digitalWrite(PIN_FANOEM_HI, HIGH); break; //OEM fan schematic requires one relay for high speed
|
||||
#elif defined BATTERY_TYPE_47AhFoMoCo
|
||||
#elif defined BATTERY_TYPE_47Ah
|
||||
case FAN_HIGH: digitalWrite(PIN_FANOEM_LOW, HIGH); digitalWrite(PIN_FANOEM_HI, HIGH); break; //PDU fan schematic requires both relays for high speed
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -24,12 +24,12 @@ void runFansIfNeeded(void)
|
||||
else if (fan_getSpeed_now() == FAN_OFF ) { hysteresis_C = FAN_SPEED_HYSTERESIS_OFF_degC; }
|
||||
|
||||
if ( (temperature_intake_getLatest() < (GRID_CHARGING_FANS_OFF_BELOW_TEMP_C - hysteresis_C)) &&
|
||||
#ifndef BATTERY_TYPE_47AhFoMoCo
|
||||
#ifndef BATTERY_TYPE_47Ah
|
||||
(temperature_ambient_getLatest() < (GRID_CHARGING_FANS_OFF_BELOW_TEMP_C - hysteresis_C)) &&
|
||||
#endif
|
||||
(temperature_battery_getLatest() < (GRID_CHARGING_FANS_OFF_BELOW_TEMP_C - hysteresis_C)) ) { fan_requestSpeed(FAN_REQUESTOR_GRIDCHARGER, FAN_OFF); }
|
||||
else if ( (temperature_intake_getLatest() < (GRID_CHARGING_FANS_LOW_BELOW_TEMP_C - hysteresis_C)) &&
|
||||
#ifndef BATTERY_TYPE_47AhFoMoCo
|
||||
#ifndef BATTERY_TYPE_47Ah
|
||||
(temperature_ambient_getLatest() < (GRID_CHARGING_FANS_LOW_BELOW_TEMP_C - hysteresis_C)) &&
|
||||
#endif
|
||||
(temperature_battery_getLatest() < (GRID_CHARGING_FANS_LOW_BELOW_TEMP_C - hysteresis_C)) ) { fan_requestSpeed(FAN_REQUESTOR_GRIDCHARGER, FAN_LOW); }
|
||||
@@ -54,7 +54,7 @@ uint8_t gridCharger_isAllowedNow(void)
|
||||
if (gpio_isGridChargerPluggedInNow() == NO ) { return NO__CHARGER_UNPLUGGED; }
|
||||
if (key_getSampledState() == KEYSTATE_ON ) { return NO__KEY_IS_ON; }
|
||||
//cell voltage checks
|
||||
if (LTC68042result_hiCellVoltage_get() > CELL_VREST_85_PERCENT_SoC ) { return NO__ATLEASTONECELL_TOO_HIGH; }
|
||||
if (LTC68042result_hiCellVoltage_get() > CELL_VREST_085_PERCENT_SoC ) { return NO__ATLEASTONECELL_TOO_HIGH; }
|
||||
if (LTC68042result_loCellVoltage_get() < CELL_VMIN_GRIDCHARGER ) { return NO__ATLEASTONECELL_TOO_LOW; }
|
||||
if (LTC68042result_hiCellVoltage_get() > CELL_VMAX_GRIDCHARGER ) { return NO__ATLEASTONECELL_FULL; }
|
||||
if (LTC68042result_hiCellVoltage_get() > determineMaxAllowedCellVoltage() ) { return NO__CELL_VOLTAGE_HYSTERESIS; }
|
||||
@@ -65,7 +65,7 @@ uint8_t gridCharger_isAllowedNow(void)
|
||||
if (temperature_battery_getLatest() > DISABLE_GRIDCHARGING_ABOVE_BATTERY_TEMP_C) { return NO__BATTERY_IS_HOT; }
|
||||
if (temperature_intake_getLatest() > DISABLE_GRIDCHARGING_ABOVE_INTAKE_TEMP_C ) { return NO__AIRINTAKE_IS_HOT; }
|
||||
if (temperature_intake_getLatest() == TEMPERATURE_SENSOR_FAULT_LO ) { return NO__TEMP_UNPLUGGED_INTAKE; }
|
||||
#ifndef BATTERY_TYPE_47AhFoMoCo
|
||||
#ifndef BATTERY_TYPE_47Ah
|
||||
if (temperature_exhaust_getLatest() > DISABLE_GRIDCHARGING_ABOVE_EXHAUST_TEMP_C) { return NO__TEMP_EXHAUST_IS_HOT; }
|
||||
#endif
|
||||
//time checks
|
||||
@@ -117,6 +117,7 @@ void processChargerDisableReason(uint8_t canWeCharge)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//JTS2doLater: add current feedback to 1500 charger, so LiBCM can cycle charger if no output current detected
|
||||
//JTS2doLater: add timer/current logic to detect if grid charger isn't working
|
||||
void chargerControlSignals_handler(void)
|
||||
{
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
|
||||
#define VCELL_HYSTERESIS 150 // '150' = 15 mV //prevents rapid grid charger on/off toggling when first cell is full
|
||||
|
||||
#define YES__CHARGING_ALLOWED 0b01111111 //if charging allowed, first three bits are '011'
|
||||
#define NO__UNINITIALIZED 0b10000000 //if charging disabled, first three bits are '100' //safety feature in case a single bit flips
|
||||
#define YES__CHARGING_ALLOWED 0b01111111 //first three bits are '011' for 'YES__'
|
||||
#define DELAY_DO_NOTHING 0b00111110 //first three bits are '001' for 'DELAY'
|
||||
#define NO__UNINITIALIZED 0b10000000 //first three bits are '100' for 'NO__' //safety feature in case a single bit flips
|
||||
#define NO__CHARGER_IS_HOT 0b10000001
|
||||
#define NO__BATTERY_IS_COLD 0b10000010
|
||||
#define NO__BATTERY_IS_HOT 0b10000011
|
||||
@@ -15,7 +16,7 @@
|
||||
#define NO__TEMP_UNPLUGGED_GRID 0b10000101
|
||||
#define NO__TEMP_UNPLUGGED_INTAKE 0b10000110
|
||||
#define NO__TEMP_EXHAUST_IS_HOT 0b10000111
|
||||
#define NO__ATLEASTONECELL_TOO_HIGH 0b10001000 //JTS2doLater: Allow charging if highest cell below 4.3000 when charger plugged in
|
||||
#define NO__ATLEASTONECELL_TOO_HIGH 0b10001000
|
||||
#define NO__ATLEASTONECELL_FULL 0b10001001
|
||||
#define NO__ATLEASTONECELL_TOO_LOW 0b10001010
|
||||
#define NO__JUST_PLUGGED_IN 0b10001011
|
||||
@@ -25,10 +26,13 @@
|
||||
#define NO__CELL_VOLTAGE_HYSTERESIS 0b10001111
|
||||
#define NO__CHARGER_UNPLUGGED 0b10010000
|
||||
#define NO__SoC_TOO_LOW 0b10010001
|
||||
#define NO__PACK_CURRENT_TOO_HIGH 0b10010010
|
||||
//place other NO__ conditions here
|
||||
#define NO__CHARGING_NOT_REQUESTED 0b10011111
|
||||
|
||||
#define DISABLE_GRIDCHARGING_ABOVE_CHARGER_TEMP_C 60
|
||||
#define DISABLE_GRIDCHARGING_BELOW_BATTERY_TEMP_C -25
|
||||
#define DISABLE_GRIDCHARGING_ABOVE_BATTERY_TEMP_C 40
|
||||
#define DISABLE_GRIDCHARGING_ABOVE_BATTERY_TEMP_C 43
|
||||
#define DISABLE_GRIDCHARGING_ABOVE_INTAKE_TEMP_C 45
|
||||
#define DISABLE_GRIDCHARGING_ABOVE_EXHAUST_TEMP_C 50
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ void key_handleKeyEvent_off(void)
|
||||
METSCI_disable();
|
||||
LTC68042cell_acquireAllCellVoltages();
|
||||
SoC_updateUsingLatestOpenCircuitVoltage(); //JTS2doLater: Add ten minute delay before VoC->SoC LUT
|
||||
adc_calibrateBatteryCurrentSensorOffset(DEBUG_TEXT_ENABLED);
|
||||
adc_calibrateBatteryCurrentSensorOffset(DEBUG_TEXT_ENABLED); //JTS2doNext: move to keyON
|
||||
gpio_turnPowerSensors_off();
|
||||
LTC68042configure_handleKeyStateChange();
|
||||
vPackSpoof_handleKeyOFF();
|
||||
@@ -127,7 +127,7 @@ void keyOn_coldBootTasks(void)
|
||||
vPackSpoof_setVoltage();
|
||||
SoC_setBatteryStateNow_percent(SoC_estimateFromRestingCellVoltage_percent());
|
||||
BATTSCI_enable(); //must occur after we have valid Vcell data
|
||||
adc_calibrateBatteryCurrentSensorOffset(DEBUG_TEXT_DISABLED); //current sensor settles almost immediately
|
||||
adc_calibrateBatteryCurrentSensorOffset(DEBUG_TEXT_DISABLED); //current sensor settles almost immediately //JTS2doLater: Can we detect true keyON from USB reset?
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -98,7 +98,7 @@ bool lcd_flashBacklight(void)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//JTS2doNow: Build string in RAM, then send all at once to display (much faster).
|
||||
//JTS2doLater: Build string in RAM, then send all at once to display (much faster).
|
||||
|
||||
//alternates between:
|
||||
//time since last keyON, and; //"tuuuuu" in seconds
|
||||
@@ -398,7 +398,7 @@ bool lcd_printCellVoltage_delta(void)
|
||||
|
||||
static uint16_t deltaVoltage_onScreen = 0;
|
||||
|
||||
uint16_t deltaVoltage_LTC6804 = LTC68042result_hiCellVoltage_get() - LTC68042result_loCellVoltage_get();
|
||||
uint16_t deltaVoltage_LTC6804 = LTC68042result_deltaCellVoltage_get();
|
||||
|
||||
if (deltaVoltage_onScreen != deltaVoltage_LTC6804)
|
||||
{
|
||||
|
||||
@@ -11,19 +11,19 @@
|
||||
int8_t tempBattery = ROOM_TEMP_DEGC;
|
||||
int8_t tempIntake = ROOM_TEMP_DEGC;
|
||||
int8_t tempCharger = ROOM_TEMP_DEGC;
|
||||
#ifndef BATTERY_TYPE_47AhFoMoCo // No explicit exhaust nor ambient temp sensors in FoMoCo case
|
||||
int8_t tempExhaust = ROOM_TEMP_DEGC;
|
||||
int8_t tempAmbient = ROOM_TEMP_DEGC;
|
||||
#ifndef BATTERY_TYPE_47Ah //47Ah Kits don't have exhaust or ambient sensors
|
||||
int8_t tempExhaust = ROOM_TEMP_DEGC;
|
||||
int8_t tempAmbient = ROOM_TEMP_DEGC;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int8_t temperature_battery_getLatest(void) { return tempBattery; }
|
||||
int8_t temperature_intake_getLatest(void) { return tempIntake; } //GRN (5AhG3 case) or WHT (FoMoCo case) OEM temp sensor
|
||||
int8_t temperature_gridCharger_getLatest(void){ return tempCharger; } //BLU OEM temp sensor
|
||||
#ifndef BATTERY_TYPE_47AhFoMoCo // No explicit exhaust nor ambient temp sensors in FoMoCo case
|
||||
int8_t temperature_exhaust_getLatest(void) { return tempExhaust; } //YEL OEM temp sensor
|
||||
int8_t temperature_ambient_getLatest(void) { return tempAmbient; } //WHT OEM temp sensor
|
||||
int8_t temperature_battery_getLatest(void) { return tempBattery; }
|
||||
int8_t temperature_intake_getLatest(void) { return tempIntake; } //OEM temp sensor: 5AhG3=GRN 47Ah=WHT
|
||||
int8_t temperature_gridCharger_getLatest(void) { return tempCharger; } //BLU OEM temp sensor
|
||||
#ifndef BATTERY_TYPE_47Ah //47Ah Kits don't have exhaust or ambient sensors
|
||||
int8_t temperature_exhaust_getLatest(void) { return tempExhaust; } //YEL OEM temp sensor
|
||||
int8_t temperature_ambient_getLatest(void) { return tempAmbient; } //WHT OEM temp sensor
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -36,7 +36,7 @@ void temperature_measureOEM(void)
|
||||
tempExhaust = temperature_measureOneSensor_degC(PIN_TEMP_YEL);
|
||||
tempCharger = temperature_measureOneSensor_degC(PIN_TEMP_BLU);
|
||||
tempAmbient = temperature_measureOneSensor_degC(PIN_TEMP_WHT);
|
||||
#elif defined BATTERY_TYPE_47AhFoMoCo
|
||||
#elif defined BATTERY_TYPE_47Ah
|
||||
tempIntake = temperature_measureOneSensor_degC(PIN_TEMP_WHT);
|
||||
tempCharger = temperature_measureOneSensor_degC(PIN_TEMP_BLU);
|
||||
#endif
|
||||
@@ -54,10 +54,10 @@ void temperature_measureBattery(void)
|
||||
batteryTemps[1] = temperature_measureOneSensor_degC(PIN_TEMP_BAY1);
|
||||
batteryTemps[2] = temperature_measureOneSensor_degC(PIN_TEMP_BAY2);
|
||||
batteryTemps[3] = temperature_measureOneSensor_degC(PIN_TEMP_BAY3);
|
||||
#ifdef BATTERY_TYPE_47AhFoMoCo
|
||||
batteryTemps[4] = temperature_measureOneSensor_degC(PIN_TEMP_GRN); //Top rear battery module
|
||||
batteryTemps[5] = temperature_measureOneSensor_degC(PIN_TEMP_YEL); //Top middle battery module
|
||||
#endif
|
||||
#ifdef BATTERY_TYPE_47Ah
|
||||
batteryTemps[4] = temperature_measureOneSensor_degC(PIN_TEMP_GRN); //Top rear battery module
|
||||
batteryTemps[5] = temperature_measureOneSensor_degC(PIN_TEMP_YEL); //Top middle battery module
|
||||
#endif
|
||||
|
||||
|
||||
//stores hottest and coldest temp sensor value
|
||||
@@ -69,29 +69,21 @@ void temperature_measureBattery(void)
|
||||
if ((batteryTemps[ii] == TEMPERATURE_SENSOR_FAULT_HI) ||
|
||||
(batteryTemps[ii] == TEMPERATURE_SENSOR_FAULT_LO) )
|
||||
{
|
||||
#ifdef BATTERY_TYPE_5AhG3
|
||||
Serial.print(F("\nCheck Batt Temp Sensor! Bay: "));
|
||||
Serial.print(String(ii,DEC));
|
||||
#elif defined BATTERY_TYPE_47AhFoMoCo
|
||||
Serial.print(F("\nCheck Batt Temp Sensor!"));
|
||||
switch (ii) {
|
||||
case 1:
|
||||
Serial.print(F(" Middle tray rail, driver side")); //BAY1
|
||||
break;
|
||||
case 2:
|
||||
Serial.print(F(" Bottom tray, middle")); //BAY2
|
||||
break;
|
||||
case 3:
|
||||
Serial.print(F(" Middle tray rail, passenger side")); //BAY3
|
||||
break;
|
||||
case 4:
|
||||
Serial.print(F(" Top rear battery module"));
|
||||
break;
|
||||
case 5:
|
||||
Serial.print(F(" Top middle battery module"));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
Serial.print(F("\nCheck Batt Temp Sensor: "));
|
||||
|
||||
#ifdef BATTERY_TYPE_5AhG3
|
||||
Serial.print(F("Bay "));
|
||||
Serial.print(String(ii,DEC));
|
||||
#elif defined BATTERY_TYPE_47Ah
|
||||
switch (ii)
|
||||
{
|
||||
case 1: Serial.print(F(" Middle tray, driver" )); break; //5AhG3 BAY1
|
||||
case 2: Serial.print(F(" Bottom tray, center" )); break; //5AhG3 BAY2
|
||||
case 3: Serial.print(F(" Middle tray, passenger")); break; //5AhG3 BAY3
|
||||
case 4: Serial.print(F(" Top rear battery" )); break;
|
||||
case 5: Serial.print(F(" Top middle battery" )); break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -126,19 +118,18 @@ void temperature_printAll_latest(void)
|
||||
Serial.print(temperature_gridCharger_getLatest());
|
||||
Serial.print(F("\nIn: "));
|
||||
Serial.print(temperature_intake_getLatest());
|
||||
#ifndef BATTERY_TYPE_47AhFoMoCo
|
||||
Serial.print(F("\nAmb: "));
|
||||
Serial.print(temperature_ambient_getLatest());
|
||||
Serial.print(F("\nOut: "));
|
||||
Serial.print(temperature_exhaust_getLatest());
|
||||
#endif
|
||||
#ifndef BATTERY_TYPE_47Ah
|
||||
Serial.print(F("\nAmb: "));
|
||||
Serial.print(temperature_ambient_getLatest());
|
||||
Serial.print(F("\nOut: "));
|
||||
Serial.print(temperature_exhaust_getLatest());
|
||||
#endif
|
||||
Serial.print(F("\nBatt: "));
|
||||
Serial.print(temperature_battery_getLatest());
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//JTS2doNext: add separate case for FoMoCo
|
||||
void temperature_measureAndPrintAll(void)
|
||||
{
|
||||
if (gpio_getPinState(PIN_TEMP_EN) == PIN_OUTPUT_HIGH)
|
||||
@@ -146,33 +137,34 @@ void temperature_measureAndPrintAll(void)
|
||||
Serial.print(F("\nTemperatures(C):"));
|
||||
Serial.print(F("\nBLU (Charger): "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_BLU));
|
||||
#ifdef BATTERY_TYPE_5AhG3
|
||||
Serial.print(F("\nGRN (Intake): "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_GRN));
|
||||
Serial.print(F("\nWHT (Ambient): "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_WHT));
|
||||
Serial.print(F("\nYEL (Exhaust): "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_YEL));
|
||||
Serial.print(F("\nBAY1: "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_BAY1));
|
||||
Serial.print(F("\nBAY2: "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_BAY2));
|
||||
Serial.print(F("\nBAY3: "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_BAY3));
|
||||
#elif defined BATTERY_TYPE_47AhFoMoCo
|
||||
Serial.print(F("\nGRN (Top rear battery module): "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_GRN));
|
||||
Serial.print(F("\nWHT (Intake): "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_WHT));
|
||||
Serial.print(F("\nYEL (Top middle battery module): "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_YEL));
|
||||
Serial.print(F("\nMiddle tray rail, driver side: ")); //BAY1
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_BAY1));
|
||||
Serial.print(F("\nBottom tray, middle: ")); //BAY2
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_BAY2));
|
||||
Serial.print(F("\nMiddle tray rail, passenger side: ")); //BAY3
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_BAY3));
|
||||
#endif
|
||||
|
||||
#ifdef BATTERY_TYPE_5AhG3
|
||||
Serial.print(F("\nGRN (intake): "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_GRN));
|
||||
Serial.print(F("\nWHT (ambient): "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_WHT));
|
||||
Serial.print(F("\nYEL (exhaust): "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_YEL));
|
||||
Serial.print(F("\nBAY1: "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_BAY1));
|
||||
Serial.print(F("\nBAY2: "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_BAY2));
|
||||
Serial.print(F("\nBAY3: "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_BAY3));
|
||||
#elif defined BATTERY_TYPE_47Ah
|
||||
Serial.print(F("\nGRN (top rear battery): "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_GRN));
|
||||
Serial.print(F("\nWHT (air intake): "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_WHT));
|
||||
Serial.print(F("\nYEL (top middle battery): "));
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_YEL));
|
||||
Serial.print(F("\nMiddle tray, driver: ")); //BAY1
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_BAY1));
|
||||
Serial.print(F("\nBottom tray, middle: ")); //BAY2
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_BAY2));
|
||||
Serial.print(F("\nMiddle tray, passenger: ")); //BAY3
|
||||
Serial.print(temperature_measureOneSensor_degC(PIN_TEMP_BAY3));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -250,7 +242,7 @@ void temperature_handler(void)
|
||||
|
||||
uint8_t keyState_Now = key_getSampledState(); //prevent mid-loop key state change
|
||||
|
||||
keyState_Now = turnSensorsOff_whenKeyStateChanges(keyState_Now); //JTS2doNow: function returns value meant for tempSensorState //writing to wrong variable?
|
||||
keyState_Now = turnSensorsOff_whenKeyStateChanges(keyState_Now); //JTS2doNext: function returns value meant for tempSensorState //writing to wrong variable?
|
||||
|
||||
static uint32_t latestTempMeasurement_ms = 0;
|
||||
static uint32_t latestSensorTurnon_ms = 0;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
int8_t temperature_battery_getLatest(void);
|
||||
int8_t temperature_intake_getLatest(void);
|
||||
int8_t temperature_gridCharger_getLatest(void);
|
||||
#ifndef BATTERY_TYPE_47AhFoMoCo
|
||||
#ifndef BATTERY_TYPE_47Ah
|
||||
int8_t temperature_exhaust_getLatest(void);
|
||||
int8_t temperature_ambient_getLatest(void); //IMA bay temperature
|
||||
#endif
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
#ifdef BATTERY_TYPE_5AhG3
|
||||
#define NUM_BATTERY_TEMP_SENSORS 3
|
||||
#elif defined BATTERY_TYPE_47AhFoMoCo
|
||||
#elif defined BATTERY_TYPE_47Ah
|
||||
// what were 2 OEM temp sensors (PIN_TEMP_GRN, PIN_TEMP_YEL) are now on battery modules
|
||||
#define NUM_BATTERY_TEMP_SENSORS 5
|
||||
#endif
|
||||
|
||||
@@ -36,21 +36,47 @@ void vPackSpoof_handleKeyOFF(void)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void spoofVoltageMCMe(void)
|
||||
{
|
||||
int16_t pwmCounts_MCMe = 0;
|
||||
int8_t vPackSpoof_offsetBVO_get(void) { return eeprom_getVspoofOffset_BVO(); }
|
||||
int8_t vPackSpoof_offsetMDV_get(void) { return eeprom_getVspoofOffset_MDV(); }
|
||||
int8_t vPackSpoof_offsetSPF_get(void) { return eeprom_getVspoofOffset_SPF(); }
|
||||
|
||||
uint8_t spoofedPackVoltage_MCMe = spoofedPackVoltage + ADDITIONAL_MCMe_OFFSET_VOLTS;
|
||||
|
||||
void vPackSpoof_offsetBVO_adjust(uint8_t action)
|
||||
{
|
||||
if (action == '+') { eeprom_setVspoofOffset_BVO(eeprom_getVspoofOffset_BVO() - 1); }
|
||||
else if (action == '-') { eeprom_setVspoofOffset_BVO(eeprom_getVspoofOffset_BVO() + 1); }
|
||||
else if (action == '0') { eeprom_setVspoofOffset_BVO(0); }
|
||||
}
|
||||
|
||||
void vPackSpoof_offsetMDV_adjust(uint8_t action)
|
||||
{
|
||||
if (action == '+') { eeprom_setVspoofOffset_MDV(eeprom_getVspoofOffset_MDV() + 1); }
|
||||
else if (action == '-') { eeprom_setVspoofOffset_MDV(eeprom_getVspoofOffset_MDV() - 1); }
|
||||
else if (action == '0') { eeprom_setVspoofOffset_MDV(0); }
|
||||
}
|
||||
|
||||
|
||||
void vPackSpoof_offsetSPF_adjust(uint8_t action)
|
||||
{
|
||||
if (action == '+') { eeprom_setVspoofOffset_SPF(eeprom_getVspoofOffset_SPF() + 1); }
|
||||
else if (action == '-') { eeprom_setVspoofOffset_SPF(eeprom_getVspoofOffset_SPF() - 1); }
|
||||
else if (action == '0') { eeprom_setVspoofOffset_SPF(0); }
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void spoofVoltageMCMe(void)
|
||||
{
|
||||
//Derivation, empirically determined (see: ~/Electronics/PCB (KiCAD)/RevB/V&V/voltage spoofing results.ods)
|
||||
//pwmCounts_MCMe = ( actualPackVoltage * 512) / spoofedPackVoltage_MCMe - 551
|
||||
//pwmCounts_MCMe = ( actualPackVoltage * 256) / spoofedPackVoltage_MCMe * 2 - 551 //prevent 16b overflow
|
||||
//pwmCounts_MCMe = (( ( ((uint16_t)actualPackVoltage ) * 256) / spoofedPackVoltage_MCMe) * 2 ) - 551
|
||||
pwmCounts_MCMe = (( ( ((uint16_t)LTC68042result_packVoltage_get()) << 8 ) / spoofedPackVoltage_MCMe) << 1 ) - 551;
|
||||
// pwmCounts_MCMe = ( actualPackVoltage * 512) / spoofedPackVoltage - 551
|
||||
// pwmCounts_MCMe = ( actualPackVoltage * 256) / spoofedPackVoltage * 2 - 551 //prevent 16b overflow
|
||||
// pwmCounts_MCMe = (( ( ((uint16_t)actualPackVoltage ) * 256) / spoofedPackVoltage) * 2 ) - 551
|
||||
int16_t pwmCounts_MCMe = (( ( ((uint16_t)LTC68042result_packVoltage_get()) << 8 ) / spoofedPackVoltage) << 1 ) - 551;
|
||||
|
||||
pwmCounts_MCMe += eeprom_getVspoofOffset_BVO();
|
||||
|
||||
//bounds checking
|
||||
if (pwmCounts_MCMe > 255) {pwmCounts_MCMe = 255;}
|
||||
else if (pwmCounts_MCMe < 0) {pwmCounts_MCMe = 0;}
|
||||
if (pwmCounts_MCMe > 255) { pwmCounts_MCMe = 255; }
|
||||
else if (pwmCounts_MCMe < 0) { pwmCounts_MCMe = 0; }
|
||||
|
||||
analogWrite(PIN_MCME_PWM, (uint8_t)pwmCounts_MCMe);
|
||||
}
|
||||
@@ -59,18 +85,20 @@ void spoofVoltageMCMe(void)
|
||||
|
||||
void spoofVoltage_VPINout(void)
|
||||
{
|
||||
int16_t pwmCounts_VPIN_out = 0;
|
||||
|
||||
// V_DIV_CORRECTION = RESISTANCE_MCM / RESISTANCE_R34
|
||||
// V_DIV_CORRECTION = 100k / 10k
|
||||
#define V_DIV_CORRECTION 1.1
|
||||
|
||||
uint8_t spoofedPackVoltage_VPIN = spoofedPackVoltage + ADDITIONAL_VPIN_OFFSET_VOLTS;
|
||||
|
||||
//remap measured Vpin_in value ratiometrically to desired spoofed voltage
|
||||
//It's important to look at VPIN_in, since V_PDU is different from the Vpack during keyON capacitor charging event
|
||||
uint16_t intermediateMath = (uint16_t)(adc_packVoltage_VpinIn() * spoofedPackVoltage_VPIN) * V_DIV_CORRECTION;
|
||||
pwmCounts_VPIN_out = (int16_t)( (uint16_t)intermediateMath / LTC68042result_packVoltage_get() );
|
||||
// mathematically: VpinOut = VpinIn * spoofedPackVoltage * 1.1 / actualPackvoltage
|
||||
//must use VPIN_in ratiometrically for two reasons:
|
||||
// 1) VPIN_in measures voltage inside the PDU, which ramps up during keyON capacitor charging event
|
||||
// 2) Safety. If we only used LTC6804 Vpack result, we'd lose redundancy required by ASIL-C
|
||||
uint16_t intermediateMath = (uint16_t)adc_packVoltage_VpinIn() * spoofedPackVoltage;
|
||||
intermediateMath = (intermediateMath >> 7) * 141; //multiply by 1.1 to correct for LiBCM's hardware voltage divider:
|
||||
// V_DIV_CORRECTION = RESISTANCE_MCM / RESISTANCE_R34
|
||||
// V_DIV_CORRECTION = 100k / 10k
|
||||
// V_DIV_CORRECTION = 1.1
|
||||
// V_DIV_CORRECTION = (x * 141) >> 7
|
||||
int16_t pwmCounts_VPIN_out = (int16_t)(intermediateMath / LTC68042result_packVoltage_get());
|
||||
|
||||
pwmCounts_VPIN_out += eeprom_getVspoofOffset_MDV();
|
||||
|
||||
//bounds checking
|
||||
if (pwmCounts_VPIN_out > 255) {pwmCounts_VPIN_out = 255;}
|
||||
@@ -107,6 +135,8 @@ uint8_t calculate_Vspoof_maxPossible(void)
|
||||
else if (actualPackVoltage < 245) { maxAllowedVspoof = actualPackVoltage - 20; }
|
||||
else { maxAllowedVspoof = actualPackVoltage - 21; }
|
||||
|
||||
maxAllowedVspoof += eeprom_getVspoofOffset_SPF();
|
||||
|
||||
return maxAllowedVspoof;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,15 +16,21 @@
|
||||
#define MAXIMIZE_POWER_ABOVE_CURRENT_AMPS (BEGIN_SPOOFING_VOLTAGE_ABOVE_AMPS + ADDITIONAL_AMPS_UNTIL_MAX_VSPOOF)
|
||||
|
||||
#define VSPOOF_TO_MAXIMIZE_POWER 125 //Maximum assist occurs when MCM thinks pack is at 120 volts
|
||||
|
||||
#define ADDITIONAL_VPIN_OFFSET_VOLTS 0 //this many volts are added to VPIN output //use with OBDIIC&C to make BATTSCI voltage equal to VPIN voltage
|
||||
#define ADDITIONAL_MCMe_OFFSET_VOLTS 0 //this many volts are added to MCMe output //use with OBDIIC&C to make BATTSCI voltage equal to MCMe voltage
|
||||
|
||||
void vPackSpoof_setVoltage(void);
|
||||
|
||||
void vPackSpoof_handleKeyOFF(void);
|
||||
void vPackSpoof_handleKeyON(void);
|
||||
|
||||
int8_t vPackSpoof_offsetBVO_get(void);
|
||||
int8_t vPackSpoof_offsetMDV_get(void);
|
||||
int8_t vPackSpoof_offsetSPF_get(void);
|
||||
|
||||
void vPackSpoof_offsetBVO_adjust(uint8_t action);
|
||||
void vPackSpoof_offsetMDV_adjust(uint8_t action);
|
||||
void vPackSpoof_offsetSPF_adjust(uint8_t action);
|
||||
|
||||
uint8_t vPackSpoof_getSpoofedPackVoltage(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user