mirror of
https://github.com/doppelhub/Honda_Insight_LiBCM.git
synced 2026-06-10 23:47:28 -04:00
wattHour feature
This commit is contained in:
@@ -7,8 +7,8 @@
|
||||
#define config_h
|
||||
#include "src/libcm.h"
|
||||
|
||||
#define FW_VERSION "0.9.5e"
|
||||
#define BUILD_DATE "2024NOV27"
|
||||
#define FW_VERSION "0.9.5f"
|
||||
#define BUILD_DATE "2025JUN02"
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -25,19 +25,19 @@
|
||||
|
||||
//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_47AhFoMoCo
|
||||
|
||||
//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_60S //FoMoCo 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_1500W //'faster' 47Ah FoMoCo Kits only
|
||||
|
||||
//choose ONE of the following
|
||||
//must match actual "current hack" hardware configuration:
|
||||
//#define SET_CURRENT_HACK_40 //actually +45.8% //most LiBCM users installed this hardware option
|
||||
#define SET_CURRENT_HACK_40 //actually +45.8% //most LiBCM users installed this hardware option
|
||||
//#define SET_CURRENT_HACK_20 //actually +25.0%
|
||||
//#define SET_CURRENT_HACK_00 //OEM configuration (no current hack installed inside MCM)
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ void loop()
|
||||
LiDisplay_handler();
|
||||
batteryHistory_handler();
|
||||
cellBalance_handler();
|
||||
energy_handler();
|
||||
|
||||
if (key_getSampledState() == KEYSTATE_ON)
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ void serialUSB_waitForEmptyBuffer(void)
|
||||
|
||||
void serialUSB_waitForAnyUserInput(void)
|
||||
{
|
||||
const uint32_t maxTestPeriod_ms = 60000; //prevent overcharging modules if user walks off mid-test
|
||||
const uint32_t maxTestPeriod_ms = 120000; //prevent overcharging modules if user walks off mid-test
|
||||
uint32_t timestamp_testStartTime_ms = millis();
|
||||
static bool hasTooMuchTimePassed = false;
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
uint8_t adc_packVoltage_VpinIn(void);
|
||||
|
||||
int16_t adc_getLatestBatteryCurrent_amps (void);
|
||||
int16_t adc_getLatestBatteryCurrent_deciAmps(void);
|
||||
int16_t adc_getLatestBatteryCurrent_amps (void); //assist is positive
|
||||
int16_t adc_getLatestBatteryCurrent_deciAmps(void); //regen is negative
|
||||
|
||||
int16_t adc_getLatestSpoofedCurrent_amps(void);
|
||||
int16_t adc_getLatestSpoofedCurrent_deciAmps(void);
|
||||
|
||||
@@ -19,15 +19,18 @@ const uint16_t EEPROM_LAST_USABLE_ADDRESS = 0xF9F; //atmega2560 has 4kB
|
||||
//EEPROM address map:
|
||||
const uint16_t EEPROM_ADDRESS_COMPILE_DATE = 0x000; //EEPROM range is 0x000:0x00B (12B)
|
||||
const uint16_t EEPROM_ADDRESS_HOURS_SINCE_UPDATE = 0x00C; //EEPROM range is 0x00C:0x00D ( 2B)
|
||||
const uint16_t EEPROM_ADDRESS_FIRMWARE_STATUS = 0x00E; //EEPROM range is 0x00E:0x00E ( 1B)
|
||||
const uint16_t EEPROM_ADDRESS_BATTSCI_REGEN = 0x00F; //EEPROM range is 0x00F:0x00F ( 1B)
|
||||
const uint16_t EEPROM_ADDRESS_BATTSCI_ASSIST = 0x010; //EEPROM range is 0x010:0x010 ( 1B)
|
||||
const uint16_t EEPROM_ADDRESS_KEYON_DELAY = 0x011; //EEPROM range is 0x011:0x011 ( 1B)
|
||||
const uint16_t EEPROM_ADDRESS_unused = 0x012; //EEPROM range is 0x012:0x012 ( 1B)
|
||||
const uint16_t EEPROM_ADDRESS_FIRMWARE_STATUS = 0x00E; //EEPROM range is 0x00E ( 1B)
|
||||
const uint16_t EEPROM_ADDRESS_BATTSCI_REGEN = 0x00F; //EEPROM range is 0x00F ( 1B)
|
||||
const uint16_t EEPROM_ADDRESS_BATTSCI_ASSIST = 0x010; //EEPROM range is 0x010 ( 1B)
|
||||
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)
|
||||
//this EEPROM space still available
|
||||
const uint16_t EEPROM_ADDRESS_BATT_HISTORY = EEPROM_LAST_USABLE_ADDRESS - NUM_BYTES_BATTERY_HISTORY; //stored last
|
||||
const uint16_t EEPROM_ADDRESS_BATT_HISTORY_UNINITIALIZED = EEPROM_ADDRESS_BATT_HISTORY - 1; //0xFF if updating from old version
|
||||
//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)
|
||||
const uint16_t EEPROM_ADDRESS_BATT_HISTORY_UNINIT = EEPROM_ADDRESS_BATT_HISTORY - 1; //0xA56 ( 1B)
|
||||
const uint16_t EEPROM_ADDRESS_Wh_RECORDS = EEPROM_ADDRESS_BATT_HISTORY_UNINIT - 1 - NUM_BYTES_Wh_HISTORY; //0x455:0xA55 (1536B)
|
||||
const uint16_t EEPROM_ADDRESS_Wh_RECORDS_UNINIT = EEPROM_ADDRESS_Wh_RECORDS - 1; //0x454 ( 1B)
|
||||
|
||||
//compile date & time stored in EEPROM the last time the firmware was updated
|
||||
uint8_t compileDateEEPROM[BYTES_IN_DATE] = {}; //JTS2doLater: Move these into single function (to save RAM)
|
||||
@@ -262,26 +265,67 @@ void eeprom_batteryHistory_incrementValue(uint8_t indexTemperature, uint8_t inde
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eeprom_batteryHistory_reset(void)
|
||||
void eeprom_eraseRange(uint16_t minAddress, uint16_t maxAddress)
|
||||
{
|
||||
uint16_t minAddress = EEPROM_ADDRESS_BATT_HISTORY;
|
||||
uint16_t maxAddress = EEPROM_ADDRESS_BATT_HISTORY + NUM_BYTES_BATTERY_HISTORY;
|
||||
|
||||
Serial.print(F("\nInitializing battery history"));
|
||||
|
||||
Serial.print('\n');
|
||||
|
||||
for (uint16_t address=minAddress; address<=maxAddress; address++)
|
||||
{
|
||||
EEPROM.update(address, EEPROM_ADDRESS_FORMATTED_VALUE);
|
||||
|
||||
Serial.print('.');
|
||||
|
||||
if ((address & 0b1111111) == 0) //divisible by 128
|
||||
if ((address & 0b01111111) == 0) //if divisible by 128
|
||||
{
|
||||
wdt_reset();
|
||||
Serial.print('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eeprom_batteryHistory_reset(void)
|
||||
{
|
||||
uint16_t minAddress = EEPROM_ADDRESS_BATT_HISTORY;
|
||||
uint16_t maxAddress = EEPROM_ADDRESS_BATT_HISTORY + NUM_BYTES_BATTERY_HISTORY;
|
||||
|
||||
Serial.print(F("\nInitializing battery history"));
|
||||
eeprom_eraseRange(minAddress, maxAddress);
|
||||
Serial.print(F("\nDone"));
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eeprom_wattHourHistory_storeSession(uint16_t assist_Wh, uint16_t regen_Wh, uint16_t time_s)
|
||||
{
|
||||
uint8_t recordNumber = EEPROM.read(EEPROM_ADDRESS_NEXT_Wh_RECORD);
|
||||
|
||||
uint16_t baseAddress = EEPROM_ADDRESS_Wh_RECORDS + recordNumber * NUM_BYTES_PER_Wh_RECORD;
|
||||
|
||||
writeToEEPROM_uint16(baseAddress + 0, assist_Wh);
|
||||
writeToEEPROM_uint16(baseAddress + 2, regen_Wh );
|
||||
writeToEEPROM_uint16(baseAddress + 4, time_s );
|
||||
|
||||
EEPROM.update(EEPROM_ADDRESS_NEXT_Wh_RECORD, ++recordNumber);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eeprom_wattHourHistory_printSession(uint8_t sessionNumber)
|
||||
{
|
||||
//JTS2doNow: add print history here
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eeprom_wattHourHistory_reset(void)
|
||||
{
|
||||
uint16_t minAddress = EEPROM_ADDRESS_Wh_RECORDS;
|
||||
uint16_t maxAddress = EEPROM_ADDRESS_Wh_RECORDS + NUM_BYTES_BATTERY_HISTORY;
|
||||
|
||||
Serial.print(F("\nInitializing energy history"));
|
||||
eeprom_eraseRange(minAddress, maxAddress);
|
||||
Serial.print(F("\nDone"));
|
||||
}
|
||||
|
||||
@@ -332,12 +376,18 @@ void eeprom_begin(void)
|
||||
{
|
||||
eeprom_verifyDataValid();
|
||||
|
||||
if (EEPROM.read(EEPROM_ADDRESS_BATT_HISTORY_UNINITIALIZED) == EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE)
|
||||
if (EEPROM.read(EEPROM_ADDRESS_BATT_HISTORY_UNINIT) == EEPROM_ADDRESS_FACTORY_DEFAULT_VALUE)
|
||||
{
|
||||
eeprom_batteryHistory_reset();
|
||||
|
||||
EEPROM.update(EEPROM_ADDRESS_BATT_HISTORY_UNINITIALIZED, EEPROM_ADDRESS_FORMATTED_VALUE);
|
||||
EEPROM.update(EEPROM_ADDRESS_BATT_HISTORY_UNINIT, EEPROM_ADDRESS_FORMATTED_VALUE);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -5,24 +5,84 @@
|
||||
|
||||
#include "libcm.h"
|
||||
|
||||
uint16_t wattHours_assist = 0;
|
||||
uint16_t wattHours_regen = 0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void energy_integrate_centiJoules(void)
|
||||
uint16_t energy_getAssist_Wh(void) { return wattHours_assist; }
|
||||
uint16_t energy_getRegen_Wh (void) { return wattHours_regen; }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int32_t energySinceLastCall_uWh(void)
|
||||
{
|
||||
static uint32_t timestamp_lastCall_ms = 0;
|
||||
|
||||
uint32_t milliseconds_now = millis();
|
||||
uint8_t periodBetweenCalls_ms = (uint8_t)(milliseconds_now - timestamp_lastCall_ms);
|
||||
uint8_t period_ms = (uint8_t)(milliseconds_now - timestamp_lastCall_ms);
|
||||
timestamp_lastCall_ms = milliseconds_now;
|
||||
|
||||
if (period_ms > (time_loopPeriod_ms_get() << 2)) { return 0; } //ignore keyOn, chargeOn
|
||||
|
||||
int32_t power_deciWatts = (int32_t)adc_getLatestBatteryCurrent_deciAmps() * LTC68042result_packVoltage_get();
|
||||
|
||||
int32_t uWh_sinceLastUpdate = (power_deciWatts * period_ms * 114) >> 12; //divide by 36
|
||||
|
||||
uint32_t power_deciWatts = LTC68042result_packVoltage_get() * (uint32_t)adc_getLatestBatteryCurrent_deciAmps();
|
||||
|
||||
// centiJoules_sinceLastUpdate = (power_deciWatts / 10) * (loopPeriod_ms / 1000) * (100 cJ/J)
|
||||
// centiJoules_sinceLastUpdate = (power_deciWatts * loopPeriod_ms ) / 100
|
||||
// centiJoules_sinceLastUpdate = (power_deciWatts * loopPeriod_ms ) * 0.01
|
||||
// centiJoules_sinceLastUpdate = ((power_deciWatts * loopPeriod_ms ) * 41) >> 12
|
||||
uint16_t centiJoules_sinceLastUpdate = (uint16_t)((power_deciWatts * periodBetweenCalls_ms ) * 41) >> 12;
|
||||
return uWh_sinceLastUpdate;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void energy_keyOn(void)
|
||||
{
|
||||
wattHours_assist = 0;
|
||||
wattHours_regen = 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void accumulate_uWh_to_Wh(void)
|
||||
{
|
||||
static uint32_t uWh_remainder_assist = 0;
|
||||
static uint32_t uWh_remainder_regen = 0;
|
||||
int32_t uWh_thisLoop = energySinceLastCall_uWh();
|
||||
|
||||
if (uWh_thisLoop < 0)
|
||||
{
|
||||
//regen
|
||||
uint32_t uWh_helper = uWh_remainder_regen - uWh_thisLoop; //adding, uWh_thisLoop is negative
|
||||
|
||||
while (uWh_helper >= 1000000)
|
||||
{
|
||||
uWh_helper -= 1000000;
|
||||
if (wattHours_regen < 32767) { wattHours_regen++; } //MSb stores charge source: grid or regen
|
||||
}
|
||||
uWh_remainder_regen = uWh_helper;
|
||||
}
|
||||
else
|
||||
{
|
||||
//assist
|
||||
uint32_t uWh_helper = uWh_remainder_assist + uWh_thisLoop;
|
||||
|
||||
while (uWh_helper >= 1000000)
|
||||
{
|
||||
uWh_helper -= 1000000;
|
||||
if (wattHours_assist < 65535) { wattHours_assist++; }
|
||||
}
|
||||
uWh_remainder_assist = uWh_helper;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void energy_handler(void)
|
||||
{
|
||||
if ((key_getSampledState() == KEYSTATE_ON) ||
|
||||
(gpio_isGridChargerChargingNow() == YES ) )
|
||||
{
|
||||
accumulate_uWh_to_Wh();
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -4,6 +4,14 @@
|
||||
#ifndef wattHours_h
|
||||
#define wattHours_h
|
||||
|
||||
void energy_integrate_centiJoules(void);
|
||||
#define NUM_BYTES_PER_Wh_RECORD 6
|
||||
#define NUM_Wh_RECORDS 256
|
||||
#define NUM_BYTES_Wh_HISTORY (NUM_BYTES_PER_Wh_RECORD * NUM_Wh_RECORDS)
|
||||
|
||||
uint16_t energy_getAssist_Wh(void);
|
||||
uint16_t energy_getRegen_Wh (void);
|
||||
|
||||
void energy_keyOn(void);
|
||||
void energy_handler(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -45,6 +45,7 @@ void key_handleKeyEvent_on(void)
|
||||
LTC68042configure_programVolatileDefaults(); //turn discharge resistors off, set ADC LPF, etc.
|
||||
LTC68042configure_handleKeyStateChange();
|
||||
vPackSpoof_handleKeyON();
|
||||
energy_keyOn();
|
||||
LED(1,HIGH);
|
||||
|
||||
time_latestKeyOn_ms_set(millis()); //MUST RUN LAST!
|
||||
|
||||
@@ -163,12 +163,9 @@ bool lcd_printWattHours(void)
|
||||
|
||||
lcd2.setCursor(12,3);
|
||||
|
||||
uint16_t wattHoursAssist = 12345; //JTS2doNow: Add total watt hour math function
|
||||
uint16_t wattHoursRegen = 5; //JTS2doNow: Add total watt hour math function
|
||||
|
||||
uint16_t wattHours_new = 0;
|
||||
if (cycleFrameNumber == CYCLEFRAME_A) { wattHours_new = wattHoursAssist; }
|
||||
else if (cycleFrameNumber == CYCLEFRAME_B) { wattHours_new = wattHoursRegen; }
|
||||
if (cycleFrameNumber == CYCLEFRAME_A) { wattHours_new = energy_getAssist_Wh(); }
|
||||
else if (cycleFrameNumber == CYCLEFRAME_B) { wattHours_new = energy_getRegen_Wh(); }
|
||||
|
||||
|
||||
if (wattHours_new != wattHours_onScreen)
|
||||
@@ -444,7 +441,7 @@ bool lcd_printCurrent(void)
|
||||
else { lcd2.print(' '); }
|
||||
#elif defined DISPLAY_POSITIVE_SIGN_DURING_ASSIST
|
||||
if (deciAmps > 0) { lcd2.print('+'); } //When discharging battery (i.e. assist), we display '+' symbol
|
||||
else if (deciAmps < 0) { lcd2.print('-'); } //When charging battery (i.e. regen ), we display '+' symbol
|
||||
else if (deciAmps < 0) { lcd2.print('-'); } //When charging battery (i.e. regen ), we display '-' symbol
|
||||
else { lcd2.print(' '); }
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user