Merge branch 'main' into feature/bmwi3

This commit is contained in:
Daniel 2024-03-10 19:14:11 +02:00
commit f9d85bac62
38 changed files with 1175 additions and 557 deletions

View file

@ -41,6 +41,7 @@ jobs:
- RENAULT_KANGOO_BATTERY - RENAULT_KANGOO_BATTERY
- RENAULT_ZOE_BATTERY - RENAULT_ZOE_BATTERY
- TESLA_MODEL_3_BATTERY - TESLA_MODEL_3_BATTERY
- VOLVO_SPA_BATTERY
- TEST_FAKE_BATTERY - TEST_FAKE_BATTERY
# These are the emulated inverter communication protocols for which the code will be compiled. # These are the emulated inverter communication protocols for which the code will be compiled.
inverter: inverter:

View file

@ -44,6 +44,7 @@ jobs:
- RENAULT_KANGOO_BATTERY - RENAULT_KANGOO_BATTERY
- RENAULT_ZOE_BATTERY - RENAULT_ZOE_BATTERY
- TESLA_MODEL_3_BATTERY - TESLA_MODEL_3_BATTERY
- VOLVO_SPA_BATTERY
- TEST_FAKE_BATTERY - TEST_FAKE_BATTERY
# These are the emulated inverter communication protocols for which the code will be compiled. # These are the emulated inverter communication protocols for which the code will be compiled.
inverter: inverter:

View file

@ -22,8 +22,9 @@
#include "src/devboard/webserver/webserver.h" #include "src/devboard/webserver/webserver.h"
#endif #endif
Preferences settings; // Store user settings Preferences settings; // Store user settings
const char* version_number = "5.3.RC"; // The current software version, shown on webserver // The current software version, shown on webserver
const char* version_number = "5.5.dev";
// Interval settings // Interval settings
int intervalUpdateValues = 4800; // Interval at which to update inverter values / Modbus registers int intervalUpdateValues = 4800; // Interval at which to update inverter values / Modbus registers
const int interval10 = 10; // Interval for 10ms tasks const int interval10 = 10; // Interval for 10ms tasks
@ -71,10 +72,10 @@ uint16_t system_max_discharge_power_W = 0; //Watts, 0 to 65535
uint16_t system_max_charge_power_W = 4312; //Watts, 0 to 65535 uint16_t system_max_charge_power_W = 4312; //Watts, 0 to 65535
uint16_t system_cell_max_voltage_mV = 3700; //mV, 0-5000 , Stores the highest cell millivolt value uint16_t system_cell_max_voltage_mV = 3700; //mV, 0-5000 , Stores the highest cell millivolt value
uint16_t system_cell_min_voltage_mV = 3700; //mV, 0-5000, Stores the minimum cell millivolt value uint16_t system_cell_min_voltage_mV = 3700; //mV, 0-5000, Stores the minimum cell millivolt value
uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV. Oversized to accomodate all setups uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages. Oversized to accomodate all setups
uint8_t system_bms_status = ACTIVE; //ACTIVE - [0..5]<>[STANDBY,INACTIVE,DARKSTART,ACTIVE,FAULT,UPDATING] uint8_t system_bms_status = ACTIVE; //ACTIVE - [0..5]<>[STANDBY,INACTIVE,DARKSTART,ACTIVE,FAULT,UPDATING]
uint8_t system_number_of_cells = 0; //Total number of cell voltages, set by each battery uint8_t system_number_of_cells = 0; //Total number of cell voltages, set by each battery
bool system_LFP_Chemistry = false; //Set to true or false depending on cell chemistry bool system_LFP_Chemistry = false; //Set to true or false depending on cell chemistry
// Common charger parameters // Common charger parameters
volatile float charger_setpoint_HV_VDC = 0.0f; volatile float charger_setpoint_HV_VDC = 0.0f;

View file

@ -17,6 +17,7 @@
//#define RENAULT_ZOE_BATTERY //#define RENAULT_ZOE_BATTERY
//#define SANTA_FE_PHEV_BATTERY //#define SANTA_FE_PHEV_BATTERY
//#define TESLA_MODEL_3_BATTERY //#define TESLA_MODEL_3_BATTERY
//#define VOLVO_SPA_BATTERY
//#define TEST_FAKE_BATTERY //#define TEST_FAKE_BATTERY
/* Select inverter communication protocol. See Wiki for which to use with your inverter: https://github.com/dalathegreat/BYD-Battery-Emulator-For-Gen24/wiki */ /* Select inverter communication protocol. See Wiki for which to use with your inverter: https://github.com/dalathegreat/BYD-Battery-Emulator-For-Gen24/wiki */

View file

@ -43,6 +43,10 @@
#include "TEST-FAKE-BATTERY.h" //See this file for more Fake battery settings #include "TEST-FAKE-BATTERY.h" //See this file for more Fake battery settings
#endif #endif
#ifdef VOLVO_SPA_BATTERY
#include "VOLVO-SPA-BATTERY.h" //See this file for more XC40 Recharge/Polestar2 settings
#endif
#ifdef SERIAL_LINK_RECEIVER #ifdef SERIAL_LINK_RECEIVER
#include "SERIAL-LINK-RECEIVER-FROM-BATTERY.h" //See this file for more Serial-battery settings #include "SERIAL-LINK-RECEIVER-FROM-BATTERY.h" //See this file for more Serial-battery settings
#endif #endif

View file

@ -8,26 +8,26 @@
#define BATTERY_SELECTED #define BATTERY_SELECTED
// These parameters need to be mapped for the inverter // These parameters need to be mapped for the inverter
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
void setup_battery(void); void setup_battery(void);

View file

@ -8,26 +8,26 @@
#define BATTERY_SELECTED #define BATTERY_SELECTED
// These parameters need to be mapped for the inverter // These parameters need to be mapped for the inverter
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
void setup_battery(void); void setup_battery(void);

View file

@ -8,27 +8,27 @@
#define BATTERY_SELECTED #define BATTERY_SELECTED
// These parameters need to be mapped for the inverter // These parameters need to be mapped for the inverter
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false
void setup_battery(void); void setup_battery(void);

View file

@ -45,6 +45,7 @@ static uint16_t inverterVoltageFrameHigh = 0;
static uint16_t inverterVoltage = 0; static uint16_t inverterVoltage = 0;
static uint8_t startedUp = false; static uint8_t startedUp = false;
static uint8_t counter_200 = 0; static uint8_t counter_200 = 0;
static uint16_t cellvoltages_mv[98];
CAN_frame_t KIA_HYUNDAI_200 = {.FIR = {.B = CAN_frame_t KIA_HYUNDAI_200 = {.FIR = {.B =
{ {
@ -202,6 +203,23 @@ void update_values_battery() { //This function maps all the values fetched via
set_event(EVENT_12V_LOW, leadAcidBatteryVoltage); set_event(EVENT_12V_LOW, leadAcidBatteryVoltage);
} }
//Map all cell voltages to the global array
for (int i = 0; i < 97; ++i) {
if (cellvoltages_mv[i] > 1000) {
system_cellvoltages_mV[i] = cellvoltages_mv[i];
}
}
// Check if we have 98S or 90S battery
if (system_cellvoltages_mV[97] > 0) {
system_number_of_cells = 98;
system_max_design_voltage_dV = 4040;
system_min_design_voltage_dV = 3100;
} else {
system_number_of_cells = 90;
system_max_design_voltage_dV = 3870;
system_min_design_voltage_dV = 2250;
}
// Check if cell voltages are within allowed range // Check if cell voltages are within allowed range
cell_deviation_mV = (system_cell_max_voltage_mV - system_cell_min_voltage_mV); cell_deviation_mV = (system_cell_max_voltage_mV - system_cell_min_voltage_mV);
@ -353,53 +371,53 @@ void receive_can_battery(CAN_frame_t rx_frame) {
allowedDischargePower = ((rx_frame.data.u8[5] << 8) + rx_frame.data.u8[6]); allowedDischargePower = ((rx_frame.data.u8[5] << 8) + rx_frame.data.u8[6]);
batteryRelay = rx_frame.data.u8[7]; batteryRelay = rx_frame.data.u8[7];
} else if (poll_data_pid == 2) { } else if (poll_data_pid == 2) {
system_cellvoltages_mV[0] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[0] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[1] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[1] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[2] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[2] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[3] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[3] = (rx_frame.data.u8[5] * 20);
system_cellvoltages_mV[4] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[4] = (rx_frame.data.u8[6] * 20);
system_cellvoltages_mV[5] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[5] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 3) { } else if (poll_data_pid == 3) {
system_cellvoltages_mV[32] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[32] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[33] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[33] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[34] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[34] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[35] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[35] = (rx_frame.data.u8[5] * 20);
system_cellvoltages_mV[36] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[36] = (rx_frame.data.u8[6] * 20);
system_cellvoltages_mV[37] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[37] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 4) { } else if (poll_data_pid == 4) {
system_cellvoltages_mV[64] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[64] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[65] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[65] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[66] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[66] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[67] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[67] = (rx_frame.data.u8[5] * 20);
system_cellvoltages_mV[68] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[68] = (rx_frame.data.u8[6] * 20);
system_cellvoltages_mV[69] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[69] = (rx_frame.data.u8[7] * 20);
} }
break; break;
case 0x22: //Second datarow in PID group case 0x22: //Second datarow in PID group
if (poll_data_pid == 2) { if (poll_data_pid == 2) {
system_cellvoltages_mV[6] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[6] = (rx_frame.data.u8[1] * 20);
system_cellvoltages_mV[7] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[7] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[8] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[8] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[9] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[9] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[10] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[10] = (rx_frame.data.u8[5] * 20);
system_cellvoltages_mV[11] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[11] = (rx_frame.data.u8[6] * 20);
system_cellvoltages_mV[12] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[12] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 3) { } else if (poll_data_pid == 3) {
system_cellvoltages_mV[38] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[38] = (rx_frame.data.u8[1] * 20);
system_cellvoltages_mV[39] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[39] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[40] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[40] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[41] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[41] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[42] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[42] = (rx_frame.data.u8[5] * 20);
system_cellvoltages_mV[43] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[43] = (rx_frame.data.u8[6] * 20);
system_cellvoltages_mV[44] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[44] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 4) { } else if (poll_data_pid == 4) {
system_cellvoltages_mV[70] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[70] = (rx_frame.data.u8[1] * 20);
system_cellvoltages_mV[71] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[71] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[72] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[72] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[73] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[73] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[74] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[74] = (rx_frame.data.u8[5] * 20);
system_cellvoltages_mV[75] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[75] = (rx_frame.data.u8[6] * 20);
system_cellvoltages_mV[76] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[76] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 6) { } else if (poll_data_pid == 6) {
batteryManagementMode = rx_frame.data.u8[5]; batteryManagementMode = rx_frame.data.u8[5];
} }
@ -409,29 +427,29 @@ void receive_can_battery(CAN_frame_t rx_frame) {
temperature_water_inlet = rx_frame.data.u8[6]; temperature_water_inlet = rx_frame.data.u8[6];
CellVoltMax_mV = (rx_frame.data.u8[7] * 20); //(volts *50) *20 =mV CellVoltMax_mV = (rx_frame.data.u8[7] * 20); //(volts *50) *20 =mV
} else if (poll_data_pid == 2) { } else if (poll_data_pid == 2) {
system_cellvoltages_mV[13] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[13] = (rx_frame.data.u8[1] * 20);
system_cellvoltages_mV[14] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[14] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[15] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[15] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[16] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[16] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[17] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[17] = (rx_frame.data.u8[5] * 20);
system_cellvoltages_mV[18] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[18] = (rx_frame.data.u8[6] * 20);
system_cellvoltages_mV[19] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[19] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 3) { } else if (poll_data_pid == 3) {
system_cellvoltages_mV[45] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[45] = (rx_frame.data.u8[1] * 20);
system_cellvoltages_mV[46] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[46] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[47] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[47] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[48] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[48] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[49] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[49] = (rx_frame.data.u8[5] * 20);
system_cellvoltages_mV[50] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[50] = (rx_frame.data.u8[6] * 20);
system_cellvoltages_mV[51] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[51] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 4) { } else if (poll_data_pid == 4) {
system_cellvoltages_mV[77] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[77] = (rx_frame.data.u8[1] * 20);
system_cellvoltages_mV[78] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[78] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[79] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[79] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[80] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[80] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[81] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[81] = (rx_frame.data.u8[5] * 20);
system_cellvoltages_mV[82] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[82] = (rx_frame.data.u8[6] * 20);
system_cellvoltages_mV[83] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[83] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 5) { } else if (poll_data_pid == 5) {
heatertemp = rx_frame.data.u8[7]; heatertemp = rx_frame.data.u8[7];
} }
@ -442,56 +460,55 @@ void receive_can_battery(CAN_frame_t rx_frame) {
CellVminNo = rx_frame.data.u8[3]; CellVminNo = rx_frame.data.u8[3];
CellVoltMin_mV = (rx_frame.data.u8[2] * 20); //(volts *50) *20 =mV CellVoltMin_mV = (rx_frame.data.u8[2] * 20); //(volts *50) *20 =mV
} else if (poll_data_pid == 2) { } else if (poll_data_pid == 2) {
system_cellvoltages_mV[20] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[20] = (rx_frame.data.u8[1] * 20);
system_cellvoltages_mV[21] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[21] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[22] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[22] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[23] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[23] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[24] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[24] = (rx_frame.data.u8[5] * 20);
system_cellvoltages_mV[25] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[25] = (rx_frame.data.u8[6] * 20);
system_cellvoltages_mV[26] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[26] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 3) { } else if (poll_data_pid == 3) {
system_cellvoltages_mV[52] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[52] = (rx_frame.data.u8[1] * 20);
system_cellvoltages_mV[53] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[53] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[54] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[54] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[55] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[55] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[56] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[56] = (rx_frame.data.u8[5] * 20);
system_cellvoltages_mV[57] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[57] = (rx_frame.data.u8[6] * 20);
system_cellvoltages_mV[58] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[58] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 4) { } else if (poll_data_pid == 4) {
system_cellvoltages_mV[84] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[84] = (rx_frame.data.u8[1] * 20);
system_cellvoltages_mV[85] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[85] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[86] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[86] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[87] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[87] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[88] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[88] = (rx_frame.data.u8[5] * 20);
system_cellvoltages_mV[89] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[89] = (rx_frame.data.u8[6] * 20);
system_cellvoltages_mV[90] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[90] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 5) { } else if (poll_data_pid == 5) {
batterySOH = ((rx_frame.data.u8[2] << 8) + rx_frame.data.u8[3]); batterySOH = ((rx_frame.data.u8[2] << 8) + rx_frame.data.u8[3]);
} }
break; break;
case 0x25: //Fifth datarow in PID group case 0x25: //Fifth datarow in PID group
if (poll_data_pid == 2) { if (poll_data_pid == 2) {
system_cellvoltages_mV[27] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[27] = (rx_frame.data.u8[1] * 20);
system_cellvoltages_mV[28] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[28] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[29] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[29] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[30] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[30] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[31] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[31] = (rx_frame.data.u8[5] * 20);
} else if (poll_data_pid == 3) { } else if (poll_data_pid == 3) {
system_cellvoltages_mV[59] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[59] = (rx_frame.data.u8[1] * 20);
system_cellvoltages_mV[60] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[60] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[61] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[61] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[62] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[62] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[63] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[63] = (rx_frame.data.u8[5] * 20);
} else if (poll_data_pid == 4) { } else if (poll_data_pid == 4) {
system_cellvoltages_mV[91] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[91] = (rx_frame.data.u8[1] * 20);
system_cellvoltages_mV[92] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[92] = (rx_frame.data.u8[2] * 20);
system_cellvoltages_mV[93] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[93] = (rx_frame.data.u8[3] * 20);
system_cellvoltages_mV[94] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[94] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[95] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[95] = (rx_frame.data.u8[5] * 20);
} else if (poll_data_pid == 5) { } else if (poll_data_pid == 5) {
system_cellvoltages_mV[96] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[96] = (rx_frame.data.u8[4] * 20);
system_cellvoltages_mV[97] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[97] = (rx_frame.data.u8[5] * 20);
system_number_of_cells = 98;
} }
break; break;
case 0x26: //Sixth datarow in PID group case 0x26: //Sixth datarow in PID group

View file

@ -11,27 +11,27 @@
#define MAXDISCHARGEPOWERALLOWED 10000 #define MAXDISCHARGEPOWERALLOWED 10000
// These parameters need to be mapped for the inverter // These parameters need to be mapped for the inverter
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false
void setup_battery(void); void setup_battery(void);

View file

@ -8,26 +8,26 @@
#define BATTERY_SELECTED #define BATTERY_SELECTED
// These parameters need to be mapped for the inverter // These parameters need to be mapped for the inverter
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
uint16_t Temp_fromRAW_to_F(uint16_t temperature); uint16_t Temp_fromRAW_to_F(uint16_t temperature);
bool is_message_corrupt(CAN_frame_t rx_frame); bool is_message_corrupt(CAN_frame_t rx_frame);

View file

@ -14,27 +14,27 @@
#define MAX_CELL_DEVIATION_MV 500 //LED turns yellow on the board if mv delta exceeds this value #define MAX_CELL_DEVIATION_MV 500 //LED turns yellow on the board if mv delta exceeds this value
// These parameters need to be mapped for the inverter // These parameters need to be mapped for the inverter
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
extern bool inverterAllowsContactorClosing; //Bool, true/false extern bool inverterAllowsContactorClosing; //Bool, true/false
void setup_battery(void); void setup_battery(void);

View file

@ -14,27 +14,27 @@
#define MAX_CELL_DEVIATION_MV 500 //LED turns yellow on the board if mv delta exceeds this value #define MAX_CELL_DEVIATION_MV 500 //LED turns yellow on the board if mv delta exceeds this value
// These parameters need to be mapped for the inverter // These parameters need to be mapped for the inverter
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false
void setup_battery(void); void setup_battery(void);

View file

@ -8,26 +8,26 @@
#define BATTERY_SELECTED #define BATTERY_SELECTED
// These parameters need to be mapped for the inverter // These parameters need to be mapped for the inverter
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
uint8_t CalculateCRC8(CAN_frame_t rx_frame); uint8_t CalculateCRC8(CAN_frame_t rx_frame);
void setup_battery(void); void setup_battery(void);

View file

@ -32,8 +32,8 @@ void __getData() {
system_SOH_pptt = (uint16_t)dataLinkReceive.getReceivedData(1); system_SOH_pptt = (uint16_t)dataLinkReceive.getReceivedData(1);
system_battery_voltage_dV = (uint16_t)dataLinkReceive.getReceivedData(2); system_battery_voltage_dV = (uint16_t)dataLinkReceive.getReceivedData(2);
system_battery_current_dA = (int16_t)dataLinkReceive.getReceivedData(3); system_battery_current_dA = (int16_t)dataLinkReceive.getReceivedData(3);
system_capacity_Wh = (uint32_t)dataLinkReceive.getReceivedData(4); system_capacity_Wh = (uint32_t)(dataLinkReceive.getReceivedData(4) * 10); //add back missing decimal
system_remaining_capacity_Wh = (uint32_t)dataLinkReceive.getReceivedData(5); system_remaining_capacity_Wh = (uint32_t)(dataLinkReceive.getReceivedData(5) * 10); //add back missing decimal
system_max_discharge_power_W = (uint16_t)dataLinkReceive.getReceivedData(6); system_max_discharge_power_W = (uint16_t)dataLinkReceive.getReceivedData(6);
system_max_charge_power_W = (uint16_t)dataLinkReceive.getReceivedData(7); system_max_charge_power_W = (uint16_t)dataLinkReceive.getReceivedData(7);
uint16_t _system_bms_status = (uint16_t)dataLinkReceive.getReceivedData(8); uint16_t _system_bms_status = (uint16_t)dataLinkReceive.getReceivedData(8);

View file

@ -156,9 +156,9 @@ static const char* hvilStatusState[] = {"NOT OK",
#define MIN_CELL_VOLTAGE_NCA_NCM 2950 //Battery is put into emergency stop if one cell goes below this value #define MIN_CELL_VOLTAGE_NCA_NCM 2950 //Battery is put into emergency stop if one cell goes below this value
#define MAX_CELL_DEVIATION_NCA_NCM 500 //LED turns yellow on the board if mv delta exceeds this value #define MAX_CELL_DEVIATION_NCA_NCM 500 //LED turns yellow on the board if mv delta exceeds this value
#define MAX_CELL_VOLTAGE_LFP 3520 //Battery is put into emergency stop if one cell goes over this value #define MAX_CELL_VOLTAGE_LFP 3550 //Battery is put into emergency stop if one cell goes over this value
#define MIN_CELL_VOLTAGE_LFP 2800 //Battery is put into emergency stop if one cell goes below this value #define MIN_CELL_VOLTAGE_LFP 2800 //Battery is put into emergency stop if one cell goes below this value
#define MAX_CELL_DEVIATION_LFP 150 //LED turns yellow on the board if mv delta exceeds this value #define MAX_CELL_DEVIATION_LFP 200 //LED turns yellow on the board if mv delta exceeds this value
#define REASONABLE_ENERGYAMOUNT 20 //When the BMS stops making sense on some values, they are always <20 #define REASONABLE_ENERGYAMOUNT 20 //When the BMS stops making sense on some values, they are always <20
@ -200,10 +200,22 @@ void update_values_battery() { //This function maps all the values fetched via
} }
//The allowed charge power behaves strangely. We instead estimate this value //The allowed charge power behaves strangely. We instead estimate this value
if (system_scaled_SOC_pptt == 10000) { // When scaled SOC is 100%, set allowed charge power to 0 if (system_scaled_SOC_pptt == 10000) { // When scaled SOC is 100.00%, set allowed charge power to 0
system_max_charge_power_W = 0; system_max_charge_power_W = 0;
} else if (soc_vi > 950) { // When real SOC is between 95-99.99%, ramp the value between Max<->0 } else if (soc_vi > 990) {
system_max_charge_power_W = MAXCHARGEPOWERALLOWED * (1 - (soc_vi - 950) / 50.0); system_max_charge_power_W = FLOAT_MAX_POWER_W;
} else if (soc_vi > RAMPDOWN_SOC) { // When real SOC is between RAMPDOWN_SOC-99%, ramp the value between Max<->0
system_max_charge_power_W = MAXCHARGEPOWERALLOWED * (1 - (soc_vi - RAMPDOWN_SOC) / (1000.0 - RAMPDOWN_SOC));
//If the cellvoltages start to reach overvoltage, only allow a small amount of power in
if (system_LFP_Chemistry) {
if (cell_max_v > (MAX_CELL_VOLTAGE_LFP - FLOAT_START_MV)) {
system_max_charge_power_W = FLOAT_MAX_POWER_W;
}
} else { //NCM/A
if (cell_max_v > (MAX_CELL_VOLTAGE_NCA_NCM - FLOAT_START_MV)) {
system_max_charge_power_W = FLOAT_MAX_POWER_W;
}
}
} else { // No limits, max charging power allowed } else { // No limits, max charging power allowed
system_max_charge_power_W = MAXCHARGEPOWERALLOWED; system_max_charge_power_W = MAXCHARGEPOWERALLOWED;
} }
@ -237,27 +249,19 @@ void update_values_battery() { //This function maps all the values fetched via
cell_deviation_mV = (cell_max_v - cell_min_v); cell_deviation_mV = (cell_max_v - cell_min_v);
//Determine which chemistry battery pack is using (crude method, TODO: replace with real CAN identifier later) // NCM/A batteries have 96s, LFP has 102-106s
if (soc_vi > 900) { //When SOC% is over 90.0%, we can use max cell voltage to estimate what chemistry is used // Drawback with this check is that it takes 3-5minutes before all cells have been counted!
if (cell_max_v < 3450) {
system_LFP_Chemistry = true;
}
if (cell_max_v > 3700) {
system_LFP_Chemistry = false;
}
}
// An even better way is to check how many cells are in the pack. NCM/A batteries have 96s, LFP has 102-106s
if (system_number_of_cells > 101) { if (system_number_of_cells > 101) {
system_LFP_Chemistry = true; system_LFP_Chemistry = true;
} }
//Once cell chemistry is determined, set maximum and minimum total pack voltage safety limits //Once cell chemistry is determined, set maximum and minimum total pack voltage safety limits
if (system_LFP_Chemistry) { if (system_LFP_Chemistry) {
system_max_design_voltage_dV = 3880; system_max_design_voltage_dV = MAX_PACK_VOLTAGE_LFP;
system_min_design_voltage_dV = 2968; system_min_design_voltage_dV = MIN_PACK_VOLTAGE_LFP;
} else { // NCM/A chemistry } else { // NCM/A chemistry
system_max_design_voltage_dV = 4030; system_max_design_voltage_dV = MAX_PACK_VOLTAGE_NCMA;
system_min_design_voltage_dV = 3100; system_min_design_voltage_dV = MIN_PACK_VOLTAGE_NCMA;
} }
//Check if SOC% is plausible //Check if SOC% is plausible
@ -690,8 +694,14 @@ void printDebugIfActive(uint8_t symbol, const char* message) {
void setup_battery(void) { // Performs one time setup at startup void setup_battery(void) { // Performs one time setup at startup
Serial.println("Tesla Model 3 battery selected"); Serial.println("Tesla Model 3 battery selected");
system_max_design_voltage_dV = 4030; // 403.0V, over this, charging is not possible (goes into forced discharge) #ifdef LFP_CHEMISTRY
system_min_design_voltage_dV = 3100; // 310.0V under this, discharging further is disabled system_LFP_Chemistry = true;
system_max_design_voltage_dV = MAX_PACK_VOLTAGE_LFP;
system_min_design_voltage_dV = MIN_PACK_VOLTAGE_LFP;
#else
system_max_design_voltage_dV = MAX_PACK_VOLTAGE_NCMA;
system_min_design_voltage_dV = MIN_PACK_VOLTAGE_NCMA;
#endif
} }
#endif #endif

View file

@ -7,33 +7,42 @@
#define BATTERY_SELECTED #define BATTERY_SELECTED
//#define LFP_CHEMISTRY // Enable this line to startup in LFP mode
#define RAMPDOWN_SOC 900 // 90.0 SOC% to start ramping down from max charge power towards 0 at 100.00%
#define FLOAT_MAX_POWER_W 200 // W, what power to allow for top balancing battery
#define FLOAT_START_MV 20 // mV, how many mV under overvoltage to start float charging
#define MAXCHARGEPOWERALLOWED 15000 // 15000W we use a define since the value supplied by Tesla is always 0 #define MAXCHARGEPOWERALLOWED 15000 // 15000W we use a define since the value supplied by Tesla is always 0
#define MAXDISCHARGEPOWERALLOWED \ #define MAXDISCHARGEPOWERALLOWED \
60000 // 60000W we need to cap this value to max 60kW, most inverters overflow otherwise 60000 // 60000W we need to cap this value to max 60kW, most inverters overflow otherwise
#define MAX_PACK_VOLTAGE_NCMA 4030 // V+1, if pack voltage goes over this, charge stops
#define MIN_PACK_VOLTAGE_NCMA 3100 // V+1, if pack voltage goes below this, discharge stops
#define MAX_PACK_VOLTAGE_LFP 3880 // V+1, if pack voltage goes over this, charge stops
#define MIN_PACK_VOLTAGE_LFP 2968 // V+1, if pack voltage goes below this, discharge stops
// These parameters need to be mapped for the inverter // These parameters need to be mapped for the inverter
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false
extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false
extern bool system_LFP_Chemistry; //Bool, 1=true, 0=false extern bool system_LFP_Chemistry; //Bool, 1=true, 0=false
void printFaultCodesIfActive(); void printFaultCodesIfActive();
void printDebugIfActive(uint8_t symbol, const char* message); void printDebugIfActive(uint8_t symbol, const char* message);

View file

@ -8,27 +8,27 @@
#define BATTERY_SELECTED #define BATTERY_SELECTED
// These parameters need to be mapped for the inverter // These parameters need to be mapped for the inverter
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
extern bool inverterAllowsContactorClosing; //Bool, true/false extern bool inverterAllowsContactorClosing; //Bool, true/false
void setup_battery(void); void setup_battery(void);

View file

@ -0,0 +1,388 @@
#ifdef VOLVO_SPA_BATTERY
#include "VOLVO-SPA-BATTERY.h"
#include "../devboard/utils/events.h"
#include "../lib/miwagner-ESP32-Arduino-CAN/CAN_config.h"
#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h"
/* Do not change code below unless you are sure what you are doing */
static unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was send
static unsigned long previousMillis60s = 0; // will store last time a 60s CAN Message was send
static const int interval100 = 100; // interval (ms) at which send CAN Messages
static const int interval60s = 60000; // interval (ms) at which send CAN Messages
static uint8_t CANstillAlive = 12; //counter for checking if CAN is still alive
#define MAX_CELL_VOLTAGE 4210 //Battery is put into emergency stop if one cell goes over this value
#define MIN_CELL_VOLTAGE 2700 //Battery is put into emergency stop if one cell goes below this value
#define MAX_CELL_DEVIATION 500 //LED turns yellow on the board if mv delta exceeds this value
static float BATT_U = 0; //0x3A
static float MAX_U = 0; //0x3A
static float MIN_U = 0; //0x3A
static float BATT_I = 0; //0x3A
static int32_t CHARGE_ENERGY = 0; //0x1A1
static uint8_t BATT_ERR_INDICATION = 0; //0x413
static float BATT_T_MAX = 0; //0x413
static float BATT_T_MIN = 0; //0x413
static float BATT_T_AVG = 0; //0x413
static uint16_t SOC_BMS = 0; //0X37D
static uint16_t SOC_CALC = 0;
static uint16_t CELL_U_MAX = 0; //0x37D
static uint16_t CELL_U_MIN = 0; //0x37D
static uint8_t CELL_ID_U_MAX = 0; //0x37D
static uint16_t HvBattPwrLimDchaSoft = 0; //0x369
static uint8_t batteryModuleNumber = 0x10; // First battery module
static uint8_t battery_request_idx = 0;
static uint8_t rxConsecutiveFrames = 0;
static uint16_t min_max_voltage[2]; //contains cell min[0] and max[1] values in mV
static uint16_t cell_deviation_mV = 0; //contains the deviation between highest and lowest cell in mV
static uint8_t cellcounter = 0;
static uint32_t remaining_capacity = 0;
static uint16_t cell_voltages[108]; //array with all the cellvoltages
CAN_frame_t VOLVO_536 = {.FIR = {.B =
{
.DLC = 8,
.FF = CAN_frame_std,
}},
.MsgID = 0x536,
.data = {0x00, 0x40, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Network manage frame
CAN_frame_t VOLVO_372 = {
.FIR = {.B =
{
.DLC = 8,
.FF = CAN_frame_std,
}},
.MsgID = 0x372,
.data = {0x00, 0xA6, 0x07, 0x14, 0x04, 0x00, 0x80, 0x00}}; //Ambient Temp -->>VERIFY this data content!!!<<--
CAN_frame_t VOLVO_CELL_U_Req = {.FIR = {.B =
{
.DLC = 8,
.FF = CAN_frame_std,
}},
.MsgID = 0x735,
.data = {0x03, 0x22, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Cell voltage request frame
CAN_frame_t VOLVO_FlowControl = {.FIR = {.B =
{
.DLC = 8,
.FF = CAN_frame_std,
}},
.MsgID = 0x735,
.data = {0x30, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Flowcontrol
CAN_frame_t VOLVO_SOH_Req = {.FIR = {.B =
{
.DLC = 8,
.FF = CAN_frame_std,
}},
.MsgID = 0x735,
.data = {0x03, 0x22, 0x49, 0x6D, 0x00, 0x00, 0x00, 0x00}}; //Battery SOH request frame
void update_values_battery() { //This function maps all the values fetched via CAN to the correct parameters used for the inverter
uint8_t cnt = 0;
remaining_capacity = (78200 - CHARGE_ENERGY);
//system_real_SOC_pptt = SOC_BMS; // Use BMS reported SOC, havent figured out how to get the BMS to calibrate empty/full yet
SOC_CALC = remaining_capacity / 78; // Use calculated SOC based on remaining_capacity
system_real_SOC_pptt = SOC_CALC * 10;
if (BATT_U > MAX_U) // Protect if overcharged
{
system_real_SOC_pptt = 10000;
} else if (BATT_U < MIN_U) //Protect if undercharged
{
system_real_SOC_pptt = 0;
}
system_battery_voltage_dV = BATT_U * 10;
system_battery_current_dA = BATT_I * 10;
system_capacity_Wh = BATTERY_WH_MAX;
system_remaining_capacity_Wh = remaining_capacity; // Will wrap! Known limitation due to uint16_t size.
//system_max_discharge_power_W = HvBattPwrLimDchaSoft * 1000; // Use power limit reported from BMS, not trusted ATM
system_max_discharge_power_W = 30000;
system_max_charge_power_W = 30000;
system_active_power_W = (BATT_U)*BATT_I;
system_temperature_min_dC = BATT_T_MIN;
system_temperature_max_dC = BATT_T_MAX;
system_cell_max_voltage_mV = CELL_U_MAX * 10; // Use min/max reported from BMS
system_cell_min_voltage_mV = CELL_U_MIN * 10;
//Map all cell voltages to the global array
for (int i = 0; i < 108; ++i) {
system_cellvoltages_mV[i] = cell_voltages[i];
}
/* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/
if (!CANstillAlive) {
set_event(EVENT_CAN_RX_FAILURE, 0);
} else {
CANstillAlive--;
clear_event(EVENT_CAN_RX_FAILURE);
}
#ifdef DEBUG_VIA_USB
Serial.print("BMS reported SOC%: ");
Serial.println(SOC_BMS);
Serial.print("Calculated SOC%: ");
Serial.println(SOC_CALC);
Serial.print("Rescaled SOC%: ");
Serial.println(system_scaled_SOC_pptt / 10);
Serial.print("Battery current: ");
Serial.println(BATT_I);
Serial.print("Battery voltage: ");
Serial.println(BATT_U);
Serial.print("Battery maximum voltage limit: ");
Serial.println(MAX_U);
Serial.print("Battery minimum voltage limit: ");
Serial.println(MIN_U);
Serial.print("Remaining Energy: ");
Serial.println(remaining_capacity);
Serial.print("Discharge limit: ");
Serial.println(HvBattPwrLimDchaSoft);
Serial.print("Battery Error Indication: ");
Serial.println(BATT_ERR_INDICATION);
Serial.print("Maximum battery temperature: ");
Serial.println(BATT_T_MAX / 10);
Serial.print("Minimum battery temperature: ");
Serial.println(BATT_T_MIN / 10);
Serial.print("Average battery temperature: ");
Serial.println(BATT_T_AVG / 10);
Serial.print("BMS Highest cell voltage: ");
Serial.println(CELL_U_MAX * 10);
Serial.print("BMS Lowest cell voltage: ");
Serial.println(CELL_U_MIN * 10);
Serial.print("BMS Highest cell nr: ");
Serial.println(CELL_ID_U_MAX);
Serial.print("Highest cell voltage: ");
Serial.println(min_max_voltage[1]);
Serial.print("Lowest cell voltage: ");
Serial.println(min_max_voltage[0]);
Serial.print("Cell deviation voltage: ");
Serial.println(cell_deviation_mV);
Serial.print("Cell voltage,");
while (cnt < 108) {
Serial.print(cell_voltages[cnt++]);
Serial.print(",");
}
Serial.println(";");
#endif
}
void receive_can_battery(CAN_frame_t rx_frame) {
CANstillAlive = 12;
switch (rx_frame.MsgID) {
case 0x3A:
if ((rx_frame.data.u8[6] & 0x80) == 0x80)
BATT_I = (0 - ((((rx_frame.data.u8[6] & 0x7F) * 256.0 + rx_frame.data.u8[7]) * 0.1) - 1638));
else {
BATT_I = 0;
#ifdef DEBUG_VIA_USB
Serial.println("BATT_I not valid");
#endif
}
if ((rx_frame.data.u8[2] & 0x08) == 0x08)
MAX_U = (((rx_frame.data.u8[2] & 0x07) * 256.0 + rx_frame.data.u8[3]) * 0.25);
else {
//MAX_U = 0;
//Serial.println("MAX_U not valid"); // Value toggles between true/false from BMS
}
if ((rx_frame.data.u8[4] & 0x08) == 0x08)
MIN_U = (((rx_frame.data.u8[4] & 0x07) * 256.0 + rx_frame.data.u8[5]) * 0.25);
else {
//MIN_U = 0;
//Serial.println("MIN_U not valid"); // Value toggles between true/false from BMS
}
if ((rx_frame.data.u8[0] & 0x08) == 0x08)
BATT_U = (((rx_frame.data.u8[0] & 0x07) * 256.0 + rx_frame.data.u8[1]) * 0.25);
else {
BATT_U = 0;
#ifdef DEBUG_VIA_USB
Serial.println("BATT_U not valid");
#endif
}
break;
case 0x1A1:
if ((rx_frame.data.u8[4] & 0x10) == 0x10)
CHARGE_ENERGY = ((((rx_frame.data.u8[4] & 0x0F) * 256.0 + rx_frame.data.u8[5]) * 50) - 500);
else {
CHARGE_ENERGY = 0;
set_event(EVENT_KWH_PLAUSIBILITY_ERROR, CHARGE_ENERGY);
}
break;
case 0x413:
if ((rx_frame.data.u8[0] & 0x80) == 0x80)
BATT_ERR_INDICATION = ((rx_frame.data.u8[0] & 0x40) >> 6);
else {
BATT_ERR_INDICATION = 0;
#ifdef DEBUG_VIA_USB
Serial.println("BATT_ERR_INDICATION not valid");
#endif
}
if ((rx_frame.data.u8[0] & 0x20) == 0x20) {
BATT_T_MAX = ((rx_frame.data.u8[2] & 0x1F) * 256.0 + rx_frame.data.u8[3]);
BATT_T_MIN = ((rx_frame.data.u8[4] & 0x1F) * 256.0 + rx_frame.data.u8[5]);
BATT_T_AVG = ((rx_frame.data.u8[0] & 0x1F) * 256.0 + rx_frame.data.u8[1]);
} else {
BATT_T_MAX = 0;
BATT_T_MIN = 0;
BATT_T_AVG = 0;
#ifdef DEBUG_VIA_USB
Serial.println("BATT_T not valid");
#endif
}
break;
case 0x369:
if ((rx_frame.data.u8[0] & 0x80) == 0x80) {
HvBattPwrLimDchaSoft = (((rx_frame.data.u8[6] & 0x03) * 256 + rx_frame.data.u8[6]) >> 2);
} else {
HvBattPwrLimDchaSoft = 0;
#ifdef DEBUG_VIA_USB
Serial.println("HvBattPwrLimDchaSoft not valid");
#endif
}
break;
case 0x37D:
if ((rx_frame.data.u8[0] & 0x40) == 0x40) {
SOC_BMS = ((rx_frame.data.u8[6] & 0x03) * 256 + rx_frame.data.u8[7]);
} else {
SOC_BMS = 0;
#ifdef DEBUG_VIA_USB
Serial.println("SOC_BMS not valid");
#endif
}
if ((rx_frame.data.u8[0] & 0x04) == 0x04)
CELL_U_MAX = ((rx_frame.data.u8[2] & 0x01) * 256 + rx_frame.data.u8[3]);
else {
CELL_U_MAX = 0;
#ifdef DEBUG_VIA_USB
Serial.println("CELL_U_MAX not valid");
#endif
}
if ((rx_frame.data.u8[0] & 0x02) == 0x02)
CELL_U_MIN = ((rx_frame.data.u8[0] & 0x01) * 256.0 + rx_frame.data.u8[1]);
else {
CELL_U_MIN = 0;
#ifdef DEBUG_VIA_USB
Serial.println("CELL_U_MIN not valid");
#endif
}
if ((rx_frame.data.u8[0] & 0x08) == 0x08)
CELL_ID_U_MAX = ((rx_frame.data.u8[4] & 0x01) * 256.0 + rx_frame.data.u8[5]);
else {
CELL_ID_U_MAX = 0;
#ifdef DEBUG_VIA_USB
Serial.println("CELL_ID_U_MAX not valid");
#endif
}
break;
case 0x635: // Diag request response
if ((rx_frame.data.u8[0] == 0x07) && (rx_frame.data.u8[1] == 0x62) && (rx_frame.data.u8[2] == 0x49) &&
(rx_frame.data.u8[3] == 0x6D)) // SOH response frame
{
system_SOH_pptt = ((rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]);
} else if ((rx_frame.data.u8[0] == 0x10) && (rx_frame.data.u8[1] == 0x0B) && (rx_frame.data.u8[2] == 0x62) &&
(rx_frame.data.u8[3] == 0x4B)) // First response frame of cell voltages
{
cell_voltages[battery_request_idx++] = ((rx_frame.data.u8[5] << 8) | rx_frame.data.u8[6]);
cell_voltages[battery_request_idx] = (rx_frame.data.u8[7] << 8);
ESP32Can.CANWriteFrame(&VOLVO_FlowControl); // Send flow control
rxConsecutiveFrames = 1;
} else if ((rx_frame.data.u8[0] == 0x21) && (rxConsecutiveFrames == 1)) {
cell_voltages[battery_request_idx++] = cell_voltages[battery_request_idx] | rx_frame.data.u8[1];
cell_voltages[battery_request_idx++] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3];
cell_voltages[battery_request_idx++] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
if (batteryModuleNumber <= 0x2A) // Run until last pack is read
{
VOLVO_CELL_U_Req.data.u8[3] = batteryModuleNumber++;
ESP32Can.CANWriteFrame(&VOLVO_CELL_U_Req); //Send cell voltage read request for next module
} else {
min_max_voltage[0] = 9999;
min_max_voltage[1] = 0;
for (cellcounter = 0; cellcounter < 108; cellcounter++) {
if (min_max_voltage[0] > cell_voltages[cellcounter])
min_max_voltage[0] = cell_voltages[cellcounter];
if (min_max_voltage[1] < cell_voltages[cellcounter])
min_max_voltage[1] = cell_voltages[cellcounter];
}
cell_deviation_mV = (min_max_voltage[1] - min_max_voltage[0]);
if (cell_deviation_mV > MAX_CELL_DEVIATION) {
set_event(EVENT_CELL_DEVIATION_HIGH, 0);
#ifdef DEBUG_VIA_USB
Serial.println("HIGH CELL DEVIATION!!! Inspect battery!");
#endif
}
if (min_max_voltage[1] >= MAX_CELL_VOLTAGE) {
system_bms_status = FAULT;
set_event(EVENT_CELL_OVER_VOLTAGE, 0);
#ifdef DEBUG_VIA_USB
Serial.println("CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!");
#endif
}
if (min_max_voltage[0] <= MIN_CELL_VOLTAGE) {
system_bms_status = FAULT;
set_event(EVENT_CELL_UNDER_VOLTAGE, 0);
#ifdef DEBUG_VIA_USB
Serial.println("CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!");
#endif
}
ESP32Can.CANWriteFrame(&VOLVO_SOH_Req); //Send SOH read request
}
rxConsecutiveFrames = 0;
}
break;
default:
break;
}
}
void readCellVoltages() {
battery_request_idx = 0;
batteryModuleNumber = 0x10;
rxConsecutiveFrames = 0;
VOLVO_CELL_U_Req.data.u8[3] = batteryModuleNumber++;
ESP32Can.CANWriteFrame(&VOLVO_CELL_U_Req); //Send cell voltage read request for first module
}
void send_can_battery() {
unsigned long currentMillis = millis();
// Send 100ms CAN Message
if (currentMillis - previousMillis100 >= interval100) {
previousMillis100 = currentMillis;
ESP32Can.CANWriteFrame(&VOLVO_536); //Send 0x536 Network managing frame to keep BMS alive
ESP32Can.CANWriteFrame(&VOLVO_372); //Send 0x372 ECMAmbientTempCalculated
if (system_bms_status == ACTIVE) {
batteryAllowsContactorClosing = true;
} else { //system_bms_status == FAULT or inverter requested opening contactors
batteryAllowsContactorClosing = false;
}
}
if (currentMillis - previousMillis60s >= interval60s) {
previousMillis60s = currentMillis;
if (system_bms_status == ACTIVE) {
readCellVoltages();
}
}
}
void setup_battery(void) { // Performs one time setup at startup
Serial.println("Volvo SPA XC40 Recharge / Polestar2 78kWh battery selected");
system_number_of_cells = 108;
system_max_design_voltage_dV = 4540; // 454.0V, over this, charging is not possible (goes into forced discharge)
system_min_design_voltage_dV = 2938; // 293.8V under this, discharging further is disabled
}
#endif

View file

@ -0,0 +1,34 @@
#ifndef VOLVO_SPA_BATTERY_H
#define VOLVO_SPA_BATTERY_H
#include <Arduino.h>
#include "../../USER_SETTINGS.h"
#include "../devboard/config.h" // Needed for all defines
#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h"
#define BATTERY_SELECTED
// These parameters need to be mapped for the inverter
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false
void setup_battery(void);
#endif

View file

@ -53,4 +53,7 @@
#define DISCHARGING 1 #define DISCHARGING 1
#define CHARGING 2 #define CHARGING 2
// Common definitions
#define MAX_AMOUNT_CELLS 192
#endif #endif

View file

@ -101,7 +101,8 @@ struct SensorConfig {
}; };
SensorConfig sensorConfigs[] = { SensorConfig sensorConfigs[] = {
{"SOC", "Battery Emulator SOC", "{{ value_json.SOC }}", "%", "battery"}, {"SOC", "Battery Emulator SOC (scaled)", "{{ value_json.SOC }}", "%", "battery"},
{"SOC_real", "Battery Emulator SOC (real)", "{{ value_json.SOC_real }}", "%", "battery"},
{"state_of_health", "Battery Emulator State Of Health", "{{ value_json.state_of_health }}", "%", "battery"}, {"state_of_health", "Battery Emulator State Of Health", "{{ value_json.state_of_health }}", "%", "battery"},
{"temperature_min", "Battery Emulator Temperature Min", "{{ value_json.temperature_min }}", "°C", "temperature"}, {"temperature_min", "Battery Emulator Temperature Min", "{{ value_json.temperature_min }}", "°C", "temperature"},
{"temperature_max", "Battery Emulator Temperature Max", "{{ value_json.temperature_max }}", "°C", "temperature"}, {"temperature_max", "Battery Emulator Temperature Max", "{{ value_json.temperature_max }}", "°C", "temperature"},

View file

@ -36,23 +36,24 @@
#include <Arduino.h> #include <Arduino.h>
#include "../../../USER_SETTINGS.h" #include "../../../USER_SETTINGS.h"
#include "../config.h" // Needed for defines
#define MQTT_MSG_BUFFER_SIZE (1024) #define MQTT_MSG_BUFFER_SIZE (1024)
extern const char* version_number; // The current software version, used for mqtt extern const char* version_number; // The current software version, used for mqtt
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000 , Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000 , Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern const char* mqtt_user; extern const char* mqtt_user;
extern const char* mqtt_password; extern const char* mqtt_password;

View file

@ -8,7 +8,6 @@
#include "../config.h" #include "../config.h"
#include "timer.h" #include "timer.h"
#define EE_MAGIC_HEADER_VALUE 0xA5A5
#define EE_NOF_EVENT_ENTRIES 30 #define EE_NOF_EVENT_ENTRIES 30
#define EE_EVENT_ENTRY_SIZE sizeof(EVENT_LOG_ENTRY_TYPE) #define EE_EVENT_ENTRY_SIZE sizeof(EVENT_LOG_ENTRY_TYPE)
#define EE_WRITE_PERIOD_MINUTES 10 #define EE_WRITE_PERIOD_MINUTES 10

View file

@ -8,16 +8,23 @@
// #define INCLUDE_EVENTS_TEST // Enable to run an event test loop, see events_test_on_target.cpp // #define INCLUDE_EVENTS_TEST // Enable to run an event test loop, see events_test_on_target.cpp
#define EE_MAGIC_HEADER_VALUE 0x0001 // 0x0000 to 0xFFFF
#define GENERATE_ENUM(ENUM) ENUM, #define GENERATE_ENUM(ENUM) ENUM,
#define GENERATE_STRING(STRING) #STRING, #define GENERATE_STRING(STRING) #STRING,
/** EVENT ENUMERATION /** EVENT ENUMERATION
* *
* Do not change the order! * Try not to change the order!
* When adding events, add them RIGHT BEFORE the EVENT_NOF_EVENTS enum. * When adding events, add them RIGHT BEFORE the EVENT_NOF_EVENTS enum.
* In addition, the event name must start with "EVENT_" * In addition, the event name must start with "EVENT_".
* If you don't follow this instruction, the EEPROM log will become corrupt.
* To handle this, follow the instruction for EE_MAGIC_HEADER_VALUE as
* described below.
* *
* After adding an event, assign the proper event level in events.cpp:init_events() * After adding an event:
* - Assign the proper event level in events.cpp:init_events()
* - Increment EE_MAGIC_HEADER_VALUE in case you've changed the order
*/ */
#define EVENTS_ENUM_TYPE(XX) \ #define EVENTS_ENUM_TYPE(XX) \

View file

@ -11,44 +11,146 @@ String cellmonitor_processor(const String& var) {
content += ".cell { width: 48%; margin: 1%; padding: 10px; border: 1px solid white; text-align: center; }"; content += ".cell { width: 48%; margin: 1%; padding: 10px; border: 1px solid white; text-align: center; }";
content += ".low-voltage { color: red; }"; // Style for low voltage text content += ".low-voltage { color: red; }"; // Style for low voltage text
content += ".voltage-values { margin-bottom: 10px; }"; // Style for voltage values section content += ".voltage-values { margin-bottom: 10px; }"; // Style for voltage values section
content += "#graph {display: flex;align-items: flex-end;height: 200px;border: 1px solid #ccc;position: relative;}";
content +=
".bar {margin: 0 0px;background-color: blue;display: inline-block;position: relative;cursor: pointer;border: "
"1px solid white; /* Add this line */}";
content += "#valueDisplay {text-align: left;font-weight: bold;margin-top: 10px;}";
content += "</style>"; content += "</style>";
// Start a new block with a specific background color // Start a new block with a specific background color
content += "<div style='background-color: #303E47; padding: 10px; margin-bottom: 10px; border-radius: 50px'>"; content += "<div style='background-color: #303E47; padding: 10px; margin-bottom: 10px; border-radius: 50px'>";
// Display max, min, and deviation voltage values // Display max, min, and deviation voltage values
content += "<div class='voltage-values'>"; content += "<div id='voltageValues' class='voltage-values'></div>";
content += "Max Voltage: " + String(system_cell_max_voltage_mV) + " mV<br>"; // Display cells
content += "Min Voltage: " + String(system_cell_min_voltage_mV) + " mV<br>"; content += "<div id='cellContainer' class='container'></div>";
int deviation = system_cell_max_voltage_mV - system_cell_min_voltage_mV; // Display bars
content += "Voltage Deviation: " + String(deviation) + " mV"; content += "<div id='graph'></div>";
content += "</div>"; // Display single hovered value
content += "<div id='valueDisplay'>Value: ...</div>";
// Visualize the populated cells in forward order using flexbox with conditional text color
content += "<div class='container'>";
for (int i = 0; i < 120; ++i) {
// Skip empty values
if (system_cellvoltages_mV[i] == 0) {
continue;
}
String cellContent = "Cell " + String(i + 1) + "<br>" + String(system_cellvoltages_mV[i]) + " mV";
// Check if the cell voltage is below 3000, apply red color
if (system_cellvoltages_mV[i] < 3000) {
cellContent = "<span class='low-voltage'>" + cellContent + "</span>";
}
content += "<div class='cell'>" + cellContent + "</div>";
}
content += "</div>";
// Close the block // Close the block
content += "</div>"; content += "</div>";
content += "<button onclick='goToMainPage()'>Back to main page</button>"; content += "<button onclick='goToMainPage()'>Back to main page</button>";
content += "<script>"; content += "<script>";
// Populate cell data
content += "const data = [";
for (uint8_t i = 0u; i < MAX_AMOUNT_CELLS; i++) {
if (system_cellvoltages_mV[i] == 0) {
continue;
}
content += String(system_cellvoltages_mV[i]) + ",";
}
content += "];";
content += "const min_mv = Math.min(...data) - 20;";
content += "const max_mv = Math.max(...data) + 20;";
content += "const min_index = data.indexOf(Math.min(...data));";
content += "const max_index = data.indexOf(Math.max(...data));";
content += "const graphContainer = document.getElementById('graph');";
content += "const valueDisplay = document.getElementById('valueDisplay');";
content += "const cellContainer = document.getElementById('cellContainer');";
content += "function goToMainPage() { window.location.href = '/'; }"; content += "function goToMainPage() { window.location.href = '/'; }";
// Arduino-style map() function
content +=
"function map(value, fromLow, fromHigh, toLow, toHigh) {return (value - fromLow) * (toHigh - toLow) / "
"(fromHigh - fromLow) + toLow;}";
// Mark cell and bar with highest/lowest values
content +=
"function checkMinMax(cell, bar, index) {if ((index == min_index) || (index == max_index)) "
"{cell.style.borderColor = 'red';bar.style.borderColor = 'red';}}";
// Bar function. Basically get the mV, scale the height and add a bar div to its container
content +=
"function createBars(data) {"
"data.forEach((mV, index) => {"
"const bar = document.createElement('div');"
"const mV_limited = map(mV, min_mv, max_mv, 20, 200);"
"bar.className = 'bar';"
"bar.id = `barIndex${index}`;"
"bar.style.height = `${mV_limited}px`;"
"bar.style.width = `${750/data.length}px`;"
"const cell = document.getElementById(`cellIndex${index}`);"
"checkMinMax(cell, bar, index);"
"bar.addEventListener('mouseenter', () => {"
"valueDisplay.textContent = `Value: ${mV}`;"
"bar.style.backgroundColor = `lightblue`;"
"cell.style.backgroundColor = `blue`;"
"});"
"bar.addEventListener('mouseleave', () => {"
"valueDisplay.textContent = 'Value: ...';"
"bar.style.backgroundColor = `blue`;"
"cell.style.removeProperty('background-color');"
"});"
"graphContainer.appendChild(bar);"
"});"
"}";
// Cell population function. For each value, add a cell block with its value
content +=
"function createCells(data) {"
"data.forEach((mV, index) => {"
"const cell = document.createElement('div');"
"cell.className = 'cell';"
"cell.id = `cellIndex${index}`;"
"let cellContent = `Cell ${index + 1}<br>${mV} mV`;"
"if (mV < 3000) {"
"cellContent = `<span class='low-voltage'>${cellContent}</span>`;"
"}"
"cell.innerHTML = cellContent;"
"cell.addEventListener('mouseenter', () => {"
"let bar = document.getElementById(`barIndex${index}`);"
"valueDisplay.textContent = `Value: ${mV}`;"
"bar.style.backgroundColor = `lightblue`;"
"cell.style.backgroundColor = `blue`;"
"});"
"cell.addEventListener('mouseleave', () => {"
"let bar = document.getElementById(`barIndex${index}`);"
"bar.style.backgroundColor = `blue`;"
"cell.style.removeProperty('background-color');"
"});"
"cellContainer.appendChild(cell);"
"});"
"}";
// On fetch, update the header of max/min/deviation client-side for consistency
content +=
"function updateVoltageValues(data) {"
"const min_mv = Math.min(...data);"
"const max_mv = Math.max(...data);"
"const cell_dev = max_mv - min_mv;"
"const voltVal = document.getElementById('voltageValues');"
"voltVal.innerHTML = `Max Voltage : ${max_mv} mV<br>Min Voltage: ${min_mv} mV<br>Voltage Deviation: "
"${cell_dev} mV`"
"}";
// If we have values, do the thing. Otherwise, display friendly message and wait
content += "if (data.length != 0) {";
content += "createCells(data);";
content += "createBars(data);";
content += "updateVoltageValues(data);";
content += "}";
content += "else {";
content +=
"document.getElementById('voltageValues').textContent = 'Cell information not yet fetched, or information not "
"available';";
content += "}";
// Automatic refresh is nice
content += "setTimeout(function(){ location.reload(true); }, 10000);";
content += "</script>"; content += "</script>";
return content; return content;
} }

View file

@ -3,10 +3,11 @@
#include <Arduino.h> #include <Arduino.h>
#include <stdint.h> #include <stdint.h>
#include "../config.h" // Needed for defines
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
/** /**
* @brief Replaces placeholder with content section in web page * @brief Replaces placeholder with content section in web page

View file

@ -15,11 +15,14 @@ String settings_processor(const String& var) {
// Show current settings with edit buttons and input fields // Show current settings with edit buttons and input fields
content += "<h4 style='color: white;'>Battery capacity: <span id='BATTERY_WH_MAX'>" + String(BATTERY_WH_MAX) + content += "<h4 style='color: white;'>Battery capacity: <span id='BATTERY_WH_MAX'>" + String(BATTERY_WH_MAX) +
" Wh </span> <button onclick='editWh()'>Edit</button></h4>"; " Wh </span> <button onclick='editWh()'>Edit</button></h4>";
content += "<h4 style='color: white;'>Rescale SOC: <span id='USE_SCALED_SOC'>" + String(USE_SCALED_SOC) + content += "<h4 style='color: white;'>Rescale SOC: <span id='USE_SCALED_SOC'>" +
String(USE_SCALED_SOC ? "<span>&#10003;</span>" : "<span style='color: red;'>&#10005;</span>") +
"</span> <button onclick='editUseScaledSOC()'>Edit</button></h4>"; "</span> <button onclick='editUseScaledSOC()'>Edit</button></h4>";
content += "<h4 style='color: white;'>SOC max percentage: " + String(MAXPERCENTAGE / 10.0, 1) + content += "<h4 style='color: " + String(USE_SCALED_SOC ? "white" : "darkgrey") +
";'>SOC max percentage: " + String(MAXPERCENTAGE / 10.0, 1) +
" </span> <button onclick='editSocMax()'>Edit</button></h4>"; " </span> <button onclick='editSocMax()'>Edit</button></h4>";
content += "<h4 style='color: white;'>SOC min percentage: " + String(MINPERCENTAGE / 10.0, 1) + content += "<h4 style='color: " + String(USE_SCALED_SOC ? "white" : "darkgrey") +
";'>SOC min percentage: " + String(MINPERCENTAGE / 10.0, 1) +
" </span> <button onclick='editSocMin()'>Edit</button></h4>"; " </span> <button onclick='editSocMin()'>Edit</button></h4>";
content += "<h4 style='color: white;'>Max charge speed: " + String(MAXCHARGEAMP / 10.0, 1) + content += "<h4 style='color: white;'>Max charge speed: " + String(MAXCHARGEAMP / 10.0, 1) +
" A </span> <button onclick='editMaxChargeA()'>Edit</button></h4>"; " A </span> <button onclick='editMaxChargeA()'>Edit</button></h4>";
@ -70,11 +73,21 @@ String settings_processor(const String& var) {
#endif #endif
content += "<script>"; content += "<script>";
content += "function editComplete() {";
content += " if (this.status == 200) {";
content += " window.location.reload();";
content += " }";
content += "}";
content += "function editError() {";
content += " alert('Invalid input');";
content += "}";
content += "function editWh() {"; content += "function editWh() {";
content += "var value = prompt('How much energy the battery can store. Enter new Wh value (1-120000):');"; content += "var value = prompt('How much energy the battery can store. Enter new Wh value (1-120000):');";
content += "if (value !== null) {"; content += "if (value !== null) {";
content += " if (value >= 1 && value <= 120000) {"; content += " if (value >= 1 && value <= 120000) {";
content += " var xhr = new XMLHttpRequest();"; content += " var xhr = new XMLHttpRequest();";
content += " xhr.onload = editComplete;";
content += " xhr.onerror = editError;";
content += " xhr.open('GET', '/updateBatterySize?value=' + value, true);"; content += " xhr.open('GET', '/updateBatterySize?value=' + value, true);";
content += " xhr.send();"; content += " xhr.send();";
content += " } else {"; content += " } else {";
@ -87,6 +100,8 @@ String settings_processor(const String& var) {
content += "if (value !== null) {"; content += "if (value !== null) {";
content += " if (value == 0 || value == 1) {"; content += " if (value == 0 || value == 1) {";
content += " var xhr = new XMLHttpRequest();"; content += " var xhr = new XMLHttpRequest();";
content += " xhr.onload = editComplete;";
content += " xhr.onerror = editError;";
content += " xhr.open('GET', '/updateUseScaledSOC?value=' + value, true);"; content += " xhr.open('GET', '/updateUseScaledSOC?value=' + value, true);";
content += " xhr.send();"; content += " xhr.send();";
content += " } else {"; content += " } else {";
@ -101,6 +116,8 @@ String settings_processor(const String& var) {
content += "if (value !== null) {"; content += "if (value !== null) {";
content += " if (value >= 50 && value <= 100) {"; content += " if (value >= 50 && value <= 100) {";
content += " var xhr = new XMLHttpRequest();"; content += " var xhr = new XMLHttpRequest();";
content += " xhr.onload = editComplete;";
content += " xhr.onerror = editError;";
content += " xhr.open('GET', '/updateSocMax?value=' + value, true);"; content += " xhr.open('GET', '/updateSocMax?value=' + value, true);";
content += " xhr.send();"; content += " xhr.send();";
content += " } else {"; content += " } else {";
@ -115,6 +132,8 @@ String settings_processor(const String& var) {
content += "if (value !== null) {"; content += "if (value !== null) {";
content += " if (value >= 0 && value <= 50) {"; content += " if (value >= 0 && value <= 50) {";
content += " var xhr = new XMLHttpRequest();"; content += " var xhr = new XMLHttpRequest();";
content += " xhr.onload = editComplete;";
content += " xhr.onerror = editError;";
content += " xhr.open('GET', '/updateSocMin?value=' + value, true);"; content += " xhr.open('GET', '/updateSocMin?value=' + value, true);";
content += " xhr.send();"; content += " xhr.send();";
content += " } else {"; content += " } else {";
@ -129,6 +148,8 @@ String settings_processor(const String& var) {
content += "if (value !== null) {"; content += "if (value !== null) {";
content += " if (value >= 0 && value <= 1000) {"; content += " if (value >= 0 && value <= 1000) {";
content += " var xhr = new XMLHttpRequest();"; content += " var xhr = new XMLHttpRequest();";
content += " xhr.onload = editComplete;";
content += " xhr.onerror = editError;";
content += " xhr.open('GET', '/updateMaxChargeA?value=' + value, true);"; content += " xhr.open('GET', '/updateMaxChargeA?value=' + value, true);";
content += " xhr.send();"; content += " xhr.send();";
content += " } else {"; content += " } else {";
@ -143,6 +164,8 @@ String settings_processor(const String& var) {
content += "if (value !== null) {"; content += "if (value !== null) {";
content += " if (value >= 0 && value <= 1000) {"; content += " if (value >= 0 && value <= 1000) {";
content += " var xhr = new XMLHttpRequest();"; content += " var xhr = new XMLHttpRequest();";
content += " xhr.onload = editComplete;";
content += " xhr.onerror = editError;";
content += " xhr.open('GET', '/updateMaxDischargeA?value=' + value, true);"; content += " xhr.open('GET', '/updateMaxDischargeA?value=' + value, true);";
content += " xhr.send();"; content += " xhr.send();";
content += " } else {"; content += " } else {";
@ -157,6 +180,8 @@ String settings_processor(const String& var) {
content += "if (value !== null) {"; content += "if (value !== null) {";
content += " if (value >= 0 && value <= 5000) {"; content += " if (value >= 0 && value <= 5000) {";
content += " var xhr = new XMLHttpRequest();"; content += " var xhr = new XMLHttpRequest();";
content += " xhr.onload = editComplete;";
content += " xhr.onerror = editError;";
content += " xhr.open('GET', '/updateFakeBatteryVoltage?value=' + value, true);"; content += " xhr.open('GET', '/updateFakeBatteryVoltage?value=' + value, true);";
content += " xhr.send();"; content += " xhr.send();";
content += " } else {"; content += " } else {";
@ -172,6 +197,8 @@ String settings_processor(const String& var) {
content += " if (value !== null) {"; content += " if (value !== null) {";
content += " if (value == 0 || value == 1) {"; content += " if (value == 0 || value == 1) {";
content += " var xhr = new XMLHttpRequest();"; content += " var xhr = new XMLHttpRequest();";
content += " xhr.onload = editComplete;";
content += " xhr.onerror = editError;";
content += " xhr.open('GET', '/updateChargerHvEnabled?value=' + value, true);"; content += " xhr.open('GET', '/updateChargerHvEnabled?value=' + value, true);";
content += " xhr.send();"; content += " xhr.send();";
content += " }"; content += " }";
@ -187,6 +214,8 @@ String settings_processor(const String& var) {
content += "if (value !== null) {"; content += "if (value !== null) {";
content += " if (value == 0 || value == 1) {"; content += " if (value == 0 || value == 1) {";
content += " var xhr = new XMLHttpRequest();"; content += " var xhr = new XMLHttpRequest();";
content += " xhr.onload = editComplete;";
content += " xhr.onerror = editError;";
content += " xhr.open('GET', '/updateChargerAux12vEnabled?value=' + value, true);"; content += " xhr.open('GET', '/updateChargerAux12vEnabled?value=' + value, true);";
content += " xhr.send();"; content += " xhr.send();";
content += " } else {"; content += " } else {";
@ -202,6 +231,8 @@ String settings_processor(const String& var) {
content += "if (value !== null) {"; content += "if (value !== null) {";
content += " if (value >= 0 && value <= 1000) {"; content += " if (value >= 0 && value <= 1000) {";
content += " var xhr = new XMLHttpRequest();"; content += " var xhr = new XMLHttpRequest();";
content += " xhr.onload = editComplete;";
content += " xhr.onerror = editError;";
content += " xhr.open('GET', '/updateChargeSetpointV?value=' + value, true);"; content += " xhr.open('GET', '/updateChargeSetpointV?value=' + value, true);";
content += " xhr.send();"; content += " xhr.send();";
content += " } else {"; content += " } else {";
@ -217,6 +248,8 @@ String settings_processor(const String& var) {
content += "if (value !== null) {"; content += "if (value !== null) {";
content += " if (value >= 0 && value <= 1000) {"; content += " if (value >= 0 && value <= 1000) {";
content += " var xhr = new XMLHttpRequest();"; content += " var xhr = new XMLHttpRequest();";
content += " xhr.onload = editComplete;";
content += " xhr.onerror = editError;";
content += " xhr.open('GET', '/updateChargeSetpointA?value=' + value, true);"; content += " xhr.open('GET', '/updateChargeSetpointA?value=' + value, true);";
content += " xhr.send();"; content += " xhr.send();";
content += " } else {"; content += " } else {";
@ -232,6 +265,8 @@ String settings_processor(const String& var) {
content += "if (value !== null) {"; content += "if (value !== null) {";
content += " if (value >= 0 && value <= 1000) {"; content += " if (value >= 0 && value <= 1000) {";
content += " var xhr = new XMLHttpRequest();"; content += " var xhr = new XMLHttpRequest();";
content += " xhr.onload = editComplete;";
content += " xhr.onerror = editError;";
content += " xhr.open('GET', '/updateChargeEndA?value=' + value, true);"; content += " xhr.open('GET', '/updateChargeEndA?value=' + value, true);";
content += " xhr.send();"; content += " xhr.send();";
content += " } else {"; content += " } else {";

View file

@ -450,6 +450,9 @@ String processor(const String& var) {
#ifdef TESLA_MODEL_3_BATTERY #ifdef TESLA_MODEL_3_BATTERY
content += "Tesla Model S/3/X/Y"; content += "Tesla Model S/3/X/Y";
#endif #endif
#ifdef VOLVO_SPA_BATTERY
content += "Volvo / Polestar 78kWh battery";
#endif
#ifdef TEST_FAKE_BATTERY #ifdef TEST_FAKE_BATTERY
content += "Fake battery for testing purposes"; content += "Fake battery for testing purposes";
#endif #endif

View file

@ -16,29 +16,29 @@
#include "../mqtt/mqtt.h" #include "../mqtt/mqtt.h"
#endif #endif
extern const char* version_number; // The current software version, shown on webserver extern const char* version_number; // The current software version, shown on webserver
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000 , Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000 , Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern uint8_t LEDcolor; //Enum, 0-10 extern uint8_t LEDcolor; //Enum, 0-10
extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false
extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false
extern const char* ssid; extern const char* ssid;
extern const char* password; extern const char* password;

View file

@ -6,27 +6,27 @@
#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h"
// These parameters need to be mapped for the inverter // These parameters need to be mapped for the inverter
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
extern bool inverterAllowsContactorClosing; //Bool, true/false extern bool inverterAllowsContactorClosing; //Bool, true/false
void update_values_can_byd(); void update_values_can_byd();
void send_can_byd(); void send_can_byd();

View file

@ -6,27 +6,27 @@
#define MB_RTU_NUM_VALUES 30000 #define MB_RTU_NUM_VALUES 30000
extern uint16_t mbPV[MB_RTU_NUM_VALUES]; extern uint16_t mbPV[MB_RTU_NUM_VALUES];
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
extern bool inverterAllowsContactorClosing; //Bool, true/false extern bool inverterAllowsContactorClosing; //Bool, true/false
void update_modbus_registers_luna2000(); void update_modbus_registers_luna2000();
void handle_update_data_modbus32051(); void handle_update_data_modbus32051();

View file

@ -5,27 +5,27 @@
#include "../devboard/config.h" // Needed for all defines #include "../devboard/config.h" // Needed for all defines
#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h"
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
extern bool inverterAllowsContactorClosing; //Bool, true/false extern bool inverterAllowsContactorClosing; //Bool, true/false
void update_values_can_pylon(); void update_values_can_pylon();
void receive_can_pylon(CAN_frame_t rx_frame); void receive_can_pylon(CAN_frame_t rx_frame);

View file

@ -133,8 +133,8 @@ void manageSerialLinkTransmitter() {
dataLinkTransmit.updateData(1, system_SOH_pptt); dataLinkTransmit.updateData(1, system_SOH_pptt);
dataLinkTransmit.updateData(2, system_battery_voltage_dV); dataLinkTransmit.updateData(2, system_battery_voltage_dV);
dataLinkTransmit.updateData(3, system_battery_current_dA); dataLinkTransmit.updateData(3, system_battery_current_dA);
dataLinkTransmit.updateData(4, system_capacity_Wh); dataLinkTransmit.updateData(4, system_capacity_Wh / 10); //u32, remove .0 to fit 16bit
dataLinkTransmit.updateData(5, system_remaining_capacity_Wh); dataLinkTransmit.updateData(5, system_remaining_capacity_Wh / 10); //u32, remove .0 to fit 16bit
dataLinkTransmit.updateData(6, system_max_discharge_power_W); dataLinkTransmit.updateData(6, system_max_discharge_power_W);
dataLinkTransmit.updateData(7, system_max_charge_power_W); dataLinkTransmit.updateData(7, system_max_charge_power_W);
dataLinkTransmit.updateData(8, system_bms_status); dataLinkTransmit.updateData(8, system_bms_status);

View file

@ -5,27 +5,27 @@
#include "../devboard/config.h" // Needed for all defines #include "../devboard/config.h" // Needed for all defines
#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h"
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
extern bool inverterAllowsContactorClosing; //Bool, true/false extern bool inverterAllowsContactorClosing; //Bool, true/false
#define READY_STATE 0x03 #define READY_STATE 0x03
#define STOP_STATE 0x02 #define STOP_STATE 0x02

View file

@ -5,27 +5,27 @@
#include "../devboard/config.h" // Needed for all defines #include "../devboard/config.h" // Needed for all defines
#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h"
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
extern bool inverterAllowsContactorClosing; //Bool, true/false extern bool inverterAllowsContactorClosing; //Bool, true/false
void update_values_can_sma_tripower(); void update_values_can_sma_tripower();
void send_can_sma_tripower(); void send_can_sma_tripower();

View file

@ -6,27 +6,27 @@
#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h"
// These parameters need to be mapped for the inverter // These parameters need to be mapped for the inverter
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
extern bool inverterAllowsContactorClosing; //Bool, true/false extern bool inverterAllowsContactorClosing; //Bool, true/false
extern uint16_t min_voltage; extern uint16_t min_voltage;
extern uint16_t max_voltage; extern uint16_t max_voltage;

View file

@ -8,27 +8,27 @@
extern ACAN2515 can; extern ACAN2515 can;
extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_capacity_Wh; //Wh, 0-150000Wh
extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh extern uint32_t system_remaining_capacity_Wh; //Wh, 0-150000Wh
extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_min_dC; //C+1, -50.0 - 50.0
extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0 extern int16_t system_temperature_max_dC; //C+1, -50.0 - 50.0
extern int16_t system_active_power_W; //W, -32000 to 32000 extern int16_t system_active_power_W; //W, -32000 to 32000
extern int16_t system_battery_current_dA; //A+1, -1000 - 1000 extern int16_t system_battery_current_dA; //A+1, -1000 - 1000
extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_battery_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_max_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000) extern uint16_t system_min_design_voltage_dV; //V+1, 0-500.0 (0-5000)
extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_scaled_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000) extern uint16_t system_real_SOC_pptt; //SOC%, 0-100.00 (0-10000)
extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000) extern uint16_t system_SOH_pptt; //SOH%, 0-100.00 (0-10000)
extern uint16_t system_max_discharge_power_W; //W, 0-65000 extern uint16_t system_max_discharge_power_W; //W, 0-65000
extern uint16_t system_max_charge_power_W; //W, 0-65000 extern uint16_t system_max_charge_power_W; //W, 0-65000
extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value extern uint16_t system_cell_max_voltage_mV; //mV, 0-5000, Stores the highest cell millivolt value
extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value extern uint16_t system_cell_min_voltage_mV; //mV, 0-5000, Stores the minimum cell millivolt value
extern uint16_t system_cellvoltages_mV[120]; //Array with all cell voltages in mV extern uint16_t system_cellvoltages_mV[MAX_AMOUNT_CELLS]; //Array with all cell voltages in mV
extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery extern uint8_t system_number_of_cells; //Total number of cell voltages, set by each battery
extern uint8_t system_bms_status; //Enum 0-5 extern uint8_t system_bms_status; //Enum 0-5
extern bool batteryAllowsContactorClosing; //Bool, true/false extern bool batteryAllowsContactorClosing; //Bool, true/false
extern bool inverterAllowsContactorClosing; //Bool, true/false extern bool inverterAllowsContactorClosing; //Bool, true/false
// Timeout in milliseconds // Timeout in milliseconds
#define SolaxTimeout 2000 #define SolaxTimeout 2000