Add Foxess class

This commit is contained in:
Jaakko Haakana 2025-05-31 09:08:21 +03:00
parent 4d2c2cbc71
commit 147ce38b62
2 changed files with 98 additions and 86 deletions

View file

@ -1,5 +1,6 @@
#include "../include.h"
#ifdef FOXESS_BATTERY
#include "../communication/can/comm_can.h"
#include "../datalayer/datalayer.h"
#include "../devboard/utils/events.h"
#include "FOXESS-BATTERY.h"
@ -12,81 +13,8 @@ TODO:
- Check that current is signed right way
*/
/* Do not change code below unless you are sure what you are doing */
static unsigned long previousMillis500 = 0; // will store last time a 500ms CAN Message was send
CAN_frame FOX_1871 = {.FD = false, //Inverter request data from battery. Content varies depending on state
.ext_ID = true,
.DLC = 8,
.ID = 0x1871,
.data = {0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}};
static uint32_t total_watt_hours = 0;
static uint16_t max_charge_power_dA = 0;
static uint16_t max_discharge_power_dA = 0;
static uint16_t cut_mv_max = 0;
static uint16_t cut_mv_min = 0;
static uint16_t cycle_count = 0;
static uint16_t max_ac_voltage = 0;
static uint16_t cellvoltages_mV[128] = {0};
static int16_t temperature_average = 0;
static int16_t pack1_current_sensor = 0;
static int16_t pack2_current_sensor = 0;
static int16_t pack3_current_sensor = 0;
static int16_t pack4_current_sensor = 0;
static int16_t pack5_current_sensor = 0;
static int16_t pack6_current_sensor = 0;
static int16_t pack7_current_sensor = 0;
static int16_t pack8_current_sensor = 0;
static int16_t pack1_temperature_avg_high = 0;
static int16_t pack2_temperature_avg_high = 0;
static int16_t pack3_temperature_avg_high = 0;
static int16_t pack4_temperature_avg_high = 0;
static int16_t pack5_temperature_avg_high = 0;
static int16_t pack6_temperature_avg_high = 0;
static int16_t pack7_temperature_avg_high = 0;
static int16_t pack8_temperature_avg_high = 0;
static int16_t pack1_temperature_avg_low = 0;
static int16_t pack2_temperature_avg_low = 0;
static int16_t pack3_temperature_avg_low = 0;
static int16_t pack4_temperature_avg_low = 0;
static int16_t pack5_temperature_avg_low = 0;
static int16_t pack6_temperature_avg_low = 0;
static int16_t pack7_temperature_avg_low = 0;
static int16_t pack8_temperature_avg_low = 0;
static uint16_t pack1_voltage = 0;
static uint16_t pack2_voltage = 0;
static uint16_t pack3_voltage = 0;
static uint16_t pack4_voltage = 0;
static uint16_t pack5_voltage = 0;
static uint16_t pack6_voltage = 0;
static uint16_t pack7_voltage = 0;
static uint16_t pack8_voltage = 0;
static uint8_t pack1_SOC = 0;
static uint8_t pack2_SOC = 0;
static uint8_t pack3_SOC = 0;
static uint8_t pack4_SOC = 0;
static uint8_t pack5_SOC = 0;
static uint8_t pack6_SOC = 0;
static uint8_t pack7_SOC = 0;
static uint8_t pack8_SOC = 0;
static uint8_t pack_error = 0;
static uint8_t firmware_pack_minor = 0;
static uint8_t firmware_pack_major = 0;
static uint8_t STATUS_OPERATIONAL_PACKS =
0; //0x1875 b2 contains status for operational packs (responding) in binary so 01111111 is pack 8 not operational, 11101101 is pack 5 & 2 not operational
static uint8_t NUMBER_OF_PACKS = 0; //1-8
static uint8_t contactor_status = 0;
static uint8_t statemachine_polling = 0;
static bool charging_disabled = false;
static bool b0_idle = false;
static bool b1_ok_discharge = false;
static bool b2_ok_charge = false;
static bool b3_discharging = false;
static bool b4_charging = false;
static bool b5_operational = false;
static bool b6_active_error = false;
void update_values_battery() { //This function maps all the values fetched via CAN to the correct parameters used for modbus
void FoxessBattery::
update_values() { //This function maps all the values fetched via CAN to the correct parameters used for modbus
datalayer.battery.status.remaining_capacity_Wh = static_cast<uint32_t>(
(static_cast<double>(datalayer.battery.status.real_soc) / 10000) * datalayer.battery.info.total_capacity_Wh);
@ -146,7 +74,7 @@ void update_values_battery() { //This function maps all the values fetched via
}
}
void handle_incoming_can_frame_battery(CAN_frame rx_frame) {
void FoxessBattery::handle_incoming_can_frame(CAN_frame rx_frame) {
switch (rx_frame.ID) {
case 0x1872: //BMS_Limits
datalayer.battery.info.max_design_voltage_dV = (uint16_t)(rx_frame.data.u8[1] << 8 | rx_frame.data.u8[0]);
@ -474,7 +402,8 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) {
break;
}
}
void transmit_can_battery(unsigned long currentMillis) {
void FoxessBattery::transmit_can(unsigned long currentMillis) {
// Send 500ms CAN Message
if (currentMillis - previousMillis500 >= INTERVAL_500_MS) {
previousMillis500 = currentMillis;
@ -643,7 +572,7 @@ void transmit_can_battery(unsigned long currentMillis) {
}
}
void setup_battery(void) { // Performs one time setup at startup
void FoxessBattery::setup(void) { // Performs one time setup at startup
strncpy(datalayer.system.info.battery_protocol, "FoxESS HV2600/ECS4100 OEM battery", 63);
datalayer.system.info.battery_protocol[63] = '\0';
datalayer.battery.info.number_of_cells = 0; //Startup with no cells, populates later when we know packsize

View file

@ -3,14 +3,97 @@
#include <Arduino.h>
#include "../include.h"
#define BATTERY_SELECTED
#include "CanBattery.h"
#define MAX_PACK_VOLTAGE_DV 4672 //467.2V for HS20.8 (used during startup, refined later)
#define MIN_PACK_VOLTAGE_DV 800 //80.V for HS5.2 (used during startup, refined later)
#define MAX_CELL_DEVIATION_MV 250
#define MAX_CELL_VOLTAGE_MV 3800 //LiFePO4 Prismaticc Cell
#define MIN_CELL_VOLTAGE_MV 2700 //LiFePO4 Prismatic Cell
void setup_battery(void);
void transmit_can_frame(CAN_frame* tx_frame, int interface);
#define BATTERY_SELECTED
#define SELECTED_BATTERY_CLASS FoxessBattery
class FoxessBattery : public CanBattery {
public:
virtual void setup(void);
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
virtual void update_values();
virtual void transmit_can(unsigned long currentMillis);
private:
static const int MAX_PACK_VOLTAGE_DV = 4672; //467.2V for HS20.8 (used during startup, refined later)
static const int MIN_PACK_VOLTAGE_DV = 800; //80.V for HS5.2 (used during startup, refined later)
static const int MAX_CELL_DEVIATION_MV = 250;
static const int MAX_CELL_VOLTAGE_MV = 3800; //LiFePO4 Prismaticc Cell
static const int MIN_CELL_VOLTAGE_MV = 2700; //LiFePO4 Prismatic Cell
unsigned long previousMillis500 = 0; // will store last time a 500ms CAN Message was send
CAN_frame FOX_1871 = {.FD = false, //Inverter request data from battery. Content varies depending on state
.ext_ID = true,
.DLC = 8,
.ID = 0x1871,
.data = {0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}};
uint32_t total_watt_hours = 0;
uint16_t max_charge_power_dA = 0;
uint16_t max_discharge_power_dA = 0;
uint16_t cut_mv_max = 0;
uint16_t cut_mv_min = 0;
uint16_t cycle_count = 0;
uint16_t max_ac_voltage = 0;
uint16_t cellvoltages_mV[128] = {0};
int16_t temperature_average = 0;
int16_t pack1_current_sensor = 0;
int16_t pack2_current_sensor = 0;
int16_t pack3_current_sensor = 0;
int16_t pack4_current_sensor = 0;
int16_t pack5_current_sensor = 0;
int16_t pack6_current_sensor = 0;
int16_t pack7_current_sensor = 0;
int16_t pack8_current_sensor = 0;
int16_t pack1_temperature_avg_high = 0;
int16_t pack2_temperature_avg_high = 0;
int16_t pack3_temperature_avg_high = 0;
int16_t pack4_temperature_avg_high = 0;
int16_t pack5_temperature_avg_high = 0;
int16_t pack6_temperature_avg_high = 0;
int16_t pack7_temperature_avg_high = 0;
int16_t pack8_temperature_avg_high = 0;
int16_t pack1_temperature_avg_low = 0;
int16_t pack2_temperature_avg_low = 0;
int16_t pack3_temperature_avg_low = 0;
int16_t pack4_temperature_avg_low = 0;
int16_t pack5_temperature_avg_low = 0;
int16_t pack6_temperature_avg_low = 0;
int16_t pack7_temperature_avg_low = 0;
int16_t pack8_temperature_avg_low = 0;
uint16_t pack1_voltage = 0;
uint16_t pack2_voltage = 0;
uint16_t pack3_voltage = 0;
uint16_t pack4_voltage = 0;
uint16_t pack5_voltage = 0;
uint16_t pack6_voltage = 0;
uint16_t pack7_voltage = 0;
uint16_t pack8_voltage = 0;
uint8_t pack1_SOC = 0;
uint8_t pack2_SOC = 0;
uint8_t pack3_SOC = 0;
uint8_t pack4_SOC = 0;
uint8_t pack5_SOC = 0;
uint8_t pack6_SOC = 0;
uint8_t pack7_SOC = 0;
uint8_t pack8_SOC = 0;
uint8_t pack_error = 0;
uint8_t firmware_pack_minor = 0;
uint8_t firmware_pack_major = 0;
uint8_t STATUS_OPERATIONAL_PACKS =
0; //0x1875 b2 contains status for operational packs (responding) in binary so 01111111 is pack 8 not operational, 11101101 is pack 5 & 2 not operational
uint8_t NUMBER_OF_PACKS = 0; //1-8
uint8_t contactor_status = 0;
uint8_t statemachine_polling = 0;
bool charging_disabled = false;
bool b0_idle = false;
bool b1_ok_discharge = false;
bool b2_ok_charge = false;
bool b3_discharging = false;
bool b4_charging = false;
bool b5_operational = false;
bool b6_active_error = false;
};
#endif