mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 17:59:27 +02:00
Merge branch 'main' into feature/bmwi3
This commit is contained in:
commit
f9d85bac62
38 changed files with 1175 additions and 557 deletions
1
.github/workflows/compile-all-batteries.yml
vendored
1
.github/workflows/compile-all-batteries.yml
vendored
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
388
Software/src/battery/VOLVO-SPA-BATTERY.cpp
Normal file
388
Software/src/battery/VOLVO-SPA-BATTERY.cpp
Normal 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
|
34
Software/src/battery/VOLVO-SPA-BATTERY.h
Normal file
34
Software/src/battery/VOLVO-SPA-BATTERY.h
Normal 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
|
|
@ -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
|
||||||
|
|
|
@ -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"},
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) \
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>✓</span>" : "<span style='color: red;'>✕</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 {";
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue