Merge branch 'main' into feature/test-mode

This commit is contained in:
Daniel Öster 2023-11-15 17:23:03 +02:00 committed by GitHub
commit 8dbf3960c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 58 additions and 52 deletions

View file

@ -82,6 +82,7 @@ const uint8_t maxBrightness = 100;
uint8_t LEDcolor = GREEN; uint8_t LEDcolor = GREEN;
// Contactor parameters // Contactor parameters
#ifdef CONTACTOR_CONTROL
enum State { DISCONNECTED, PRECHARGE, NEGATIVE, POSITIVE, PRECHARGE_OFF, COMPLETED, SHUTDOWN_REQUESTED }; enum State { DISCONNECTED, PRECHARGE, NEGATIVE, POSITIVE, PRECHARGE_OFF, COMPLETED, SHUTDOWN_REQUESTED };
State contactorStatus = DISCONNECTED; State contactorStatus = DISCONNECTED;
@ -89,16 +90,19 @@ State contactorStatus = DISCONNECTED;
#define PRECHARGE_TIME_MS 160 #define PRECHARGE_TIME_MS 160
#define NEGATIVE_CONTACTOR_TIME_MS 1000 #define NEGATIVE_CONTACTOR_TIME_MS 1000
#define POSITIVE_CONTACTOR_TIME_MS 2000 #define POSITIVE_CONTACTOR_TIME_MS 2000
#ifdef PWM_CONTACTOR_CONTROL
#define PWM_Freq 20000 // 20 kHz frequency, beyond audible range #define PWM_Freq 20000 // 20 kHz frequency, beyond audible range
#define PWM_Res 10 // 10 Bit resolution 0 to 1023, maps 'nicely' to 0% 100% #define PWM_Res 10 // 10 Bit resolution 0 to 1023, maps 'nicely' to 0% 100%
#define PWM_Hold_Duty 250 #define PWM_Hold_Duty 250
#define POSITIVE_PWM_Ch 0 #define POSITIVE_PWM_Ch 0
#define NEGATIVE_PWM_Ch 1 #define NEGATIVE_PWM_Ch 1
#endif
unsigned long prechargeStartTime = 0; unsigned long prechargeStartTime = 0;
unsigned long negativeStartTime = 0; unsigned long negativeStartTime = 0;
unsigned long timeSpentInFaultedMode = 0; unsigned long timeSpentInFaultedMode = 0;
uint8_t batteryAllowsContactorClosing = 0; #endif
uint8_t inverterAllowsContactorClosing = 1; bool batteryAllowsContactorClosing = false;
bool inverterAllowsContactorClosing = true;
// Initialization // Initialization
void setup() { void setup() {
@ -252,8 +256,8 @@ void inform_user_on_inverter() {
Serial.println("SOFAR CAN protocol selected"); Serial.println("SOFAR CAN protocol selected");
#endif #endif
#ifdef SOLAX_CAN #ifdef SOLAX_CAN
inverterAllowsContactorClosing = 0; // The inverter needs to allow first on this protocol inverterAllowsContactorClosing = false; // The inverter needs to allow first on this protocol
intervalUpdateValues = 800; // This protocol also requires the values to be updated faster intervalUpdateValues = 800; // This protocol also requires the values to be updated faster
Serial.println("SOLAX CAN protocol selected"); Serial.println("SOLAX CAN protocol selected");
#endif #endif
} }

View file

@ -2,7 +2,7 @@
#include "../lib/miwagner-ESP32-Arduino-CAN/CAN_config.h" #include "../lib/miwagner-ESP32-Arduino-CAN/CAN_config.h"
#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h"
//TODO before using //TODO: before using
// Map the final values in update_values_i3_battery, set some to static values if not available (current, discharge max , charge max) // Map the final values in update_values_i3_battery, set some to static values if not available (current, discharge max , charge max)
// Check if I3 battery stays alive with only 10B and 512. If not, add 12F. If that doesn't help, add more from CAN log (ask Dala) // Check if I3 battery stays alive with only 10B and 512. If not, add 12F. If that doesn't help, add more from CAN log (ask Dala)
@ -80,7 +80,7 @@ void update_values_i3_battery() { //This function maps all the values fetched v
{ {
max_target_charge_power = 0; max_target_charge_power = 0;
} else { } else {
max_target_charge_power = 5000; //Hardcoded value for testing. TODO, read real value from battery when discovered max_target_charge_power = 5000; //Hardcoded value for testing. TODO: read real value from battery when discovered
} }
if (SOC < 500) //If Soc is under 5%, stop dicharging if (SOC < 500) //If Soc is under 5%, stop dicharging
@ -88,16 +88,16 @@ void update_values_i3_battery() { //This function maps all the values fetched v
max_target_discharge_power = 0; max_target_discharge_power = 0;
} else { } else {
max_target_discharge_power = max_target_discharge_power =
5000; //Hardcoded value for testing. TODO, read real value from battery when discovered 5000; //Hardcoded value for testing. TODO: read real value from battery when discovered
} }
Battery_Power = (Battery_Current * (Battery_Volts / 10)); Battery_Power = (Battery_Current * (Battery_Volts / 10));
stat_batt_power = Battery_Power; //TODO, is mapping OK? stat_batt_power = Battery_Power; //TODO:, is mapping OK?
temperature_min; //hardcoded to 5*C in startup, TODO, find from battery CAN later temperature_min; //hardcoded to 5*C in startup, TODO:, find from battery CAN later
temperature_max; //hardcoded to 6*C in startup, TODO, find from battery CAN later temperature_max; //hardcoded to 6*C in startup, TODO:, find from battery CAN later
/* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/ /* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/
if (!CANstillAlive) { if (!CANstillAlive) {

View file

@ -23,7 +23,7 @@ extern uint16_t stat_batt_power;
extern uint16_t temperature_min; extern uint16_t temperature_min;
extern uint16_t temperature_max; extern uint16_t temperature_max;
extern uint16_t CANerror; extern uint16_t CANerror;
extern uint8_t batteryAllowsContactorClosing; extern bool batteryAllowsContactorClosing;
// Definitions for BMS status // Definitions for BMS status
#define STANDBY 0 #define STANDBY 0
#define INACTIVE 1 #define INACTIVE 1

View file

@ -95,7 +95,7 @@ void update_values_chademo_battery() { //This function maps all the values fetc
max_target_discharge_power = (MaximumDischargeCurrent * MaximumBatteryVoltage); //In Watts, Convert A to P max_target_discharge_power = (MaximumDischargeCurrent * MaximumBatteryVoltage); //In Watts, Convert A to P
battery_voltage = TargetBatteryVoltage; //Todo, scaling? battery_voltage = TargetBatteryVoltage; //TODO: scaling?
capacity_Wh = ((RatedBatteryCapacity / 0.11) * capacity_Wh = ((RatedBatteryCapacity / 0.11) *
1000); //(Added in CHAdeMO v1.0.1), maybe handle hardcoded on lower protocol version? 1000); //(Added in CHAdeMO v1.0.1), maybe handle hardcoded on lower protocol version?

View file

@ -32,8 +32,8 @@ static double voltage2 = 0;
static double BMU_Current = 0; static double BMU_Current = 0;
static double BMU_PackVoltage = 0; static double BMU_PackVoltage = 0;
static double BMU_Power = 0; static double BMU_Power = 0;
static double cell_voltages[89]; //array with all the cellvoltages //Todo, what is max array size? 80/88 cells? static double cell_voltages[89]; //array with all the cellvoltages //TODO: what is max array size? 80/88 cells?
static double cell_temperatures[89]; //array with all the celltemperatures //Todo, what is max array size? 80/88cells? static double cell_temperatures[89]; //array with all the celltemperatures //TODO: what is max array size? 80/88cells?
static double max_volt_cel = 3.70; static double max_volt_cel = 3.70;
static double min_volt_cel = 3.70; static double min_volt_cel = 3.70;
static double max_temp_cel = 20.00; static double max_temp_cel = 20.00;
@ -65,7 +65,7 @@ void update_values_imiev_battery() { //This function maps all the values fetche
max_target_discharge_power = 10000; //Otherwise we can discharge 10kW from the pack! max_target_discharge_power = 10000; //Otherwise we can discharge 10kW from the pack!
} }
stat_batt_power = BMU_Power; //TODO, Scaling? stat_batt_power = BMU_Power; //TODO: Scaling?
static int n = sizeof(cell_voltages) / sizeof(cell_voltages[0]); static int n = sizeof(cell_voltages) / sizeof(cell_voltages[0]);
max_volt_cel = cell_voltages[0]; // Initialize max with the first element of the array max_volt_cel = cell_voltages[0]; // Initialize max with the first element of the array
@ -164,7 +164,7 @@ void update_values_imiev_battery() { //This function maps all the values fetche
void receive_can_imiev_battery(CAN_frame_t rx_frame) { void receive_can_imiev_battery(CAN_frame_t rx_frame) {
CANstillAlive = CANstillAlive =
12; //Todo, move this inside a known message ID to prevent CAN inverter from keeping battery alive detection going 12; //TODO: move this inside a known message ID to prevent CAN inverter from keeping battery alive detection going
switch (rx_frame.MsgID) { switch (rx_frame.MsgID) {
case 0x374: //BMU message, 10ms - SOC case 0x374: //BMU message, 10ms - SOC
temp_value = ((rx_frame.data.u8[1] - 10) / 2); temp_value = ((rx_frame.data.u8[1] - 10) / 2);

View file

@ -25,7 +25,7 @@ extern uint16_t temperature_max;
extern uint16_t CANerror; extern uint16_t CANerror;
extern uint16_t cell_max_voltage; extern uint16_t cell_max_voltage;
extern uint16_t cell_min_voltage; extern uint16_t cell_min_voltage;
extern uint8_t batteryAllowsContactorClosing; extern bool batteryAllowsContactorClosing;
extern uint8_t LEDcolor; extern uint8_t LEDcolor;
// Definitions for BMS status // Definitions for BMS status
#define STANDBY 0 #define STANDBY 0

View file

@ -23,7 +23,7 @@ extern uint16_t stat_batt_power;
extern uint16_t temperature_min; extern uint16_t temperature_min;
extern uint16_t temperature_max; extern uint16_t temperature_max;
extern uint16_t CANerror; extern uint16_t CANerror;
extern uint8_t batteryAllowsContactorClosing; extern bool batteryAllowsContactorClosing;
// Definitions for BMS status // Definitions for BMS status
#define STANDBY 0 #define STANDBY 0
#define INACTIVE 1 #define INACTIVE 1

View file

@ -405,9 +405,9 @@ void receive_can_leaf_battery(CAN_frame_t rx_frame) {
LB_Failsafe_Status = (rx_frame.data.u8[1] & 0x07); LB_Failsafe_Status = (rx_frame.data.u8[1] & 0x07);
LB_MainRelayOn_flag = (byte)((rx_frame.data.u8[3] & 0x20) >> 5); LB_MainRelayOn_flag = (byte)((rx_frame.data.u8[3] & 0x20) >> 5);
if (LB_MainRelayOn_flag) { if (LB_MainRelayOn_flag) {
batteryAllowsContactorClosing = 1; batteryAllowsContactorClosing = true;
} else { } else {
batteryAllowsContactorClosing = 0; batteryAllowsContactorClosing = false;
} }
LB_Full_CHARGE_flag = (byte)((rx_frame.data.u8[3] & 0x10) >> 4); LB_Full_CHARGE_flag = (byte)((rx_frame.data.u8[3] & 0x10) >> 4);
LB_Interlock = (byte)((rx_frame.data.u8[3] & 0x08) >> 3); LB_Interlock = (byte)((rx_frame.data.u8[3] & 0x08) >> 3);

View file

@ -25,8 +25,9 @@ extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 funct
extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385)
extern uint16_t cell_max_voltage; //mV, 0-4350 extern uint16_t cell_max_voltage; //mV, 0-4350
extern uint16_t cell_min_voltage; //mV, 0-4350 extern uint16_t cell_min_voltage; //mV, 0-4350
extern uint8_t batteryAllowsContactorClosing; //Bool, 1=true, 0=false
extern uint8_t LEDcolor; //Enum, 0-10 extern uint8_t LEDcolor; //Enum, 0-10
extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false
// Definitions for bms_status // Definitions for bms_status
#define STANDBY 0 #define STANDBY 0
#define INACTIVE 1 #define INACTIVE 1

View file

@ -71,7 +71,7 @@ static uint8_t packContactorSetState = 0;
static uint8_t packCtrsClosingAllowed = 0; static uint8_t packCtrsClosingAllowed = 0;
static uint8_t pyroTestInProgress = 0; static uint8_t pyroTestInProgress = 0;
static uint8_t send221still = 10; static uint8_t send221still = 10;
static uint8_t LFP_Chemistry = 0; static bool LFP_Chemistry = false;
//Fault codes //Fault codes
static uint8_t WatchdogReset = 0; //Warns if the processor has experienced a reset due to watchdog reset. static uint8_t WatchdogReset = 0; //Warns if the processor has experienced a reset due to watchdog reset.
static uint8_t PowerLossReset = 0; //Warns if the processor has experienced a reset due to power loss. static uint8_t PowerLossReset = 0; //Warns if the processor has experienced a reset due to power loss.
@ -177,7 +177,7 @@ void update_values_tesla_model_3_battery() { //This function maps all the value
battery_voltage = (volts * 10); //One more decimal needed (370 -> 3700) battery_voltage = (volts * 10); //One more decimal needed (370 -> 3700)
battery_current = amps; //TODO, this needs verifying if scaling is right battery_current = (amps * 10); //Increase decimal (13A -> 13.0A)
capacity_Wh = (nominal_full_pack_energy * 100); //Scale up 75.2kWh -> 75200Wh capacity_Wh = (nominal_full_pack_energy * 100); //Scale up 75.2kWh -> 75200Wh
if (capacity_Wh > 60000) { if (capacity_Wh > 60000) {
@ -201,7 +201,7 @@ void update_values_tesla_model_3_battery() { //This function maps all the value
max_target_charge_power = 15000; //Otherwise we can push 15kW into the pack! max_target_charge_power = 15000; //Otherwise we can push 15kW into the pack!
} }
stat_batt_power = (volts * amps); //TODO, check if scaling is OK stat_batt_power = (volts * amps); //TODO: check if scaling is OK
min_temp = (min_temp * 10); min_temp = (min_temp * 10);
temperature_min = convert2unsignedInt16(min_temp); temperature_min = convert2unsignedInt16(min_temp);
@ -232,13 +232,13 @@ void update_values_tesla_model_3_battery() { //This function maps all the value
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 data later) //Determine which chemistry battery pack is using (crude method, TODO: replace with real CAN data later)
if (soc_vi > 900) { //When SOC% is over 90.0%, we can use max cell voltage to estimate what chemistry is used if (soc_vi > 900) { //When SOC% is over 90.0%, we can use max cell voltage to estimate what chemistry is used
if (cell_max_v < 3450) { if (cell_max_v < 3450) {
LFP_Chemistry = 1; LFP_Chemistry = true;
} }
if (cell_max_v > 3700) { if (cell_max_v > 3700) {
LFP_Chemistry = 0; LFP_Chemistry = false;
} }
} }

View file

@ -37,14 +37,14 @@ void handle_update_data_modbus39500() {
system_data[9] = system_data[9] =
1; //Running status, equiv to register 37762, 0 = Offline, 1 = Standby,2 = Running, 3 = Fault, 4 = sleep mode 1; //Running status, equiv to register 37762, 0 = Offline, 1 = Standby,2 = Running, 3 = Fault, 4 = sleep mode
system_data[10] = battery_voltage; //Battery bus voltage (766.5V = 7665) system_data[10] = battery_voltage; //Battery bus voltage (766.5V = 7665)
system_data[11] = 9; //TODO, GOES LOWER WITH LOW SOC system_data[11] = 9; //TODO: GOES LOWER WITH LOW SOC
system_data[12] = 0; system_data[12] = 0;
system_data[13] = 699; //TODO, GOES LOWER WITH LOW SOC system_data[13] = 699; //TODO: GOES LOWER WITH LOW SOC
system_data[14] = 1; //Always 1 in logs system_data[14] = 1; //Always 1 in logs
system_data[15] = 18; //Always 18 in logs system_data[15] = 18; //Always 18 in logs
system_data[16] = 8066; //TODO, GOES HIGHER WITH LOW SOC (max allowed charge W?) system_data[16] = 8066; //TODO: GOES HIGHER WITH LOW SOC (max allowed charge W?)
system_data[17] = 17; system_data[17] = 17;
system_data[18] = 44027; //TODO, GOES LOWER WITH LOW SOC system_data[18] = 44027; //TODO: GOES LOWER WITH LOW SOC
system_data[19] = 0; system_data[19] = 0;
system_data[20] = 435; //Always 435 in logs system_data[20] = 435; //Always 435 in logs
system_data[21] = 0; system_data[21] = 0;

View file

@ -185,7 +185,7 @@ void update_values_can_pylon() { //This function maps all the values fetched fr
PYLON_4211.data.u8[0] = (battery_voltage >> 8); PYLON_4211.data.u8[0] = (battery_voltage >> 8);
PYLON_4211.data.u8[1] = (battery_voltage & 0x00FF); PYLON_4211.data.u8[1] = (battery_voltage & 0x00FF);
//Current (TODO, SIGNED? Or looks like it could be just offset, in that case the below line wont work) //Current (TODO: SIGNED? Or looks like it could be just offset, in that case the below line wont work)
PYLON_4210.data.u8[2] = (battery_current >> 8); PYLON_4210.data.u8[2] = (battery_current >> 8);
PYLON_4210.data.u8[3] = (battery_current & 0x00FF); PYLON_4210.data.u8[3] = (battery_current & 0x00FF);
PYLON_4211.data.u8[2] = (battery_current >> 8); PYLON_4211.data.u8[2] = (battery_current >> 8);

View file

@ -2,7 +2,7 @@
#include "../lib/miwagner-ESP32-Arduino-CAN/CAN_config.h" #include "../lib/miwagner-ESP32-Arduino-CAN/CAN_config.h"
#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h"
//TODO, change CAN sending routine once confirmed that 500ms interval is OK for this battery type //TODO: change CAN sending routine once confirmed that 500ms interval is OK for this battery type
/* Do not change code below unless you are sure what you are doing */ /* Do not change code below unless you are sure what you are doing */
static unsigned long previousMillis1s = 0; // will store last time a Xs CAN Message was send static unsigned long previousMillis1s = 0; // will store last time a Xs CAN Message was send
@ -167,7 +167,7 @@ void update_values_can_sma() { //This function maps all the values fetched from
//Voltage (370.0) //Voltage (370.0)
SMA_4D8.data.u8[0] = (battery_voltage >> 8); SMA_4D8.data.u8[0] = (battery_voltage >> 8);
SMA_4D8.data.u8[1] = (battery_voltage & 0x00FF); SMA_4D8.data.u8[1] = (battery_voltage & 0x00FF);
//Current (TODO, signed OK?) //Current (TODO: signed OK?)
SMA_4D8.data.u8[2] = (battery_current >> 8); SMA_4D8.data.u8[2] = (battery_current >> 8);
SMA_4D8.data.u8[3] = (battery_current & 0x00FF); SMA_4D8.data.u8[3] = (battery_current & 0x00FF);
//Temperature average //Temperature average
@ -176,7 +176,7 @@ void update_values_can_sma() { //This function maps all the values fetched from
//Error bits //Error bits
//SMA_158.data.u8[0] = //bit12 Fault high temperature, bit34Battery cellundervoltage, bit56 Battery cell overvoltage, bit78 batterysystemdefect //SMA_158.data.u8[0] = //bit12 Fault high temperature, bit34Battery cellundervoltage, bit56 Battery cell overvoltage, bit78 batterysystemdefect
//TODO, add all error bits //TODO: add all error bits
} }
void receive_can_sma(CAN_frame_t rx_frame) { void receive_can_sma(CAN_frame_t rx_frame) {

View file

@ -307,7 +307,7 @@ void update_values_can_sofar() { //This function maps all the values fetched fr
} }
void receive_can_sofar(CAN_frame_t rx_frame) { void receive_can_sofar(CAN_frame_t rx_frame) {
switch (rx_frame.MsgID) { //In here we need to respond to the inverter. TODO make logic switch (rx_frame.MsgID) { //In here we need to respond to the inverter. TODO: make logic
case 0x605: case 0x605:
//frame1_605 = rx_frame.data.u8[1]; //frame1_605 = rx_frame.data.u8[1];
//frame3_605 = rx_frame.data.u8[3]; //frame3_605 = rx_frame.data.u8[3];

View file

@ -20,8 +20,9 @@ extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 funct
extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385)
extern uint16_t cell_max_voltage; //mV, 0-4350 extern uint16_t cell_max_voltage; //mV, 0-4350
extern uint16_t cell_min_voltage; //mV, 0-4350 extern uint16_t cell_min_voltage; //mV, 0-4350
extern uint8_t batteryAllowsContactorClosing; //Bool, 1=true, 0=false
extern uint8_t LEDcolor; //Enum, 0-10 extern uint8_t LEDcolor; //Enum, 0-10
extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false
extern uint16_t min_voltage; extern uint16_t min_voltage;
extern uint16_t max_voltage; extern uint16_t max_voltage;
// Definitions for BMS status // Definitions for BMS status

View file

@ -118,7 +118,7 @@ void CAN_WriteFrame(CAN_frame_t* tx_frame) {
void update_values_can_solax() { //This function maps all the values fetched from battery CAN to the correct CAN messages void update_values_can_solax() { //This function maps all the values fetched from battery CAN to the correct CAN messages
// If not receiveing any communication from the inverter, open contactors and return to battery announce state // If not receiveing any communication from the inverter, open contactors and return to battery announce state
if (millis() - LastFrameTime >= SolaxTimeout) { if (millis() - LastFrameTime >= SolaxTimeout) {
inverterAllowsContactorClosing = 0; inverterAllowsContactorClosing = false;
STATE = BATTERY_ANNOUNCE; STATE = BATTERY_ANNOUNCE;
} }
//Calculate the required values //Calculate the required values
@ -150,13 +150,13 @@ void update_values_can_solax() { //This function maps all the values fetched fr
//Put the values into the CAN messages //Put the values into the CAN messages
//BMS_Limits //BMS_Limits
SOLAX_1872.data.u8[0] = (uint8_t)max_voltage; //Todo, scaling OK? SOLAX_1872.data.u8[0] = (uint8_t)max_voltage; //TODO: scaling OK?
SOLAX_1872.data.u8[1] = (max_voltage >> 8); SOLAX_1872.data.u8[1] = (max_voltage >> 8);
SOLAX_1872.data.u8[2] = (uint8_t)min_voltage; //Todo, scaling OK? SOLAX_1872.data.u8[2] = (uint8_t)min_voltage; //TODO: scaling OK?
SOLAX_1872.data.u8[3] = (min_voltage >> 8); SOLAX_1872.data.u8[3] = (min_voltage >> 8);
SOLAX_1872.data.u8[4] = (uint8_t)(max_charge_rate_amp * 10); //Todo, scaling OK? SOLAX_1872.data.u8[4] = (uint8_t)(max_charge_rate_amp * 10); //TODO: scaling OK?
SOLAX_1872.data.u8[5] = ((max_charge_rate_amp * 10) >> 8); SOLAX_1872.data.u8[5] = ((max_charge_rate_amp * 10) >> 8);
SOLAX_1872.data.u8[6] = (uint8_t)(max_discharge_rate_amp * 10); //Todo, scaling OK? SOLAX_1872.data.u8[6] = (uint8_t)(max_discharge_rate_amp * 10); //TODO: scaling OK?
SOLAX_1872.data.u8[7] = ((max_discharge_rate_amp * 10) >> 8); SOLAX_1872.data.u8[7] = ((max_discharge_rate_amp * 10) >> 8);
//BMS_PackData //BMS_PackData
@ -166,7 +166,7 @@ void update_values_can_solax() { //This function maps all the values fetched fr
SOLAX_1873.data.u8[3] = (battery_current >> 8); SOLAX_1873.data.u8[3] = (battery_current >> 8);
SOLAX_1873.data.u8[4] = (uint8_t)(SOC / 100); //SOC (100.00%) SOLAX_1873.data.u8[4] = (uint8_t)(SOC / 100); //SOC (100.00%)
//SOLAX_1873.data.u8[5] = //Seems like this is not required? Or shall we put SOC decimals here? //SOLAX_1873.data.u8[5] = //Seems like this is not required? Or shall we put SOC decimals here?
SOLAX_1873.data.u8[6] = (uint8_t)(remaining_capacity_Wh / 100); //Todo, scaling OK? SOLAX_1873.data.u8[6] = (uint8_t)(remaining_capacity_Wh / 100); //TODO: scaling OK?
SOLAX_1873.data.u8[7] = ((remaining_capacity_Wh / 100) >> 8); SOLAX_1873.data.u8[7] = ((remaining_capacity_Wh / 100) >> 8);
//BMS_CellData //BMS_CellData
@ -175,10 +175,10 @@ void update_values_can_solax() { //This function maps all the values fetched fr
SOLAX_1874.data.u8[2] = (uint8_t)temperature_min; SOLAX_1874.data.u8[2] = (uint8_t)temperature_min;
SOLAX_1874.data.u8[3] = (temperature_min >> 8); SOLAX_1874.data.u8[3] = (temperature_min >> 8);
SOLAX_1874.data.u8[4] = SOLAX_1874.data.u8[4] =
(uint8_t)(cell_max_voltage); //Todo, scaling OK? Supposed to be alarm trigger absolute cell max? (uint8_t)(cell_max_voltage); //TODO: scaling OK? Supposed to be alarm trigger absolute cell max?
SOLAX_1874.data.u8[5] = (cell_max_voltage >> 8); SOLAX_1874.data.u8[5] = (cell_max_voltage >> 8);
SOLAX_1874.data.u8[6] = SOLAX_1874.data.u8[6] =
(uint8_t)(cell_min_voltage); //Todo, scaling OK? Supposed to be alarm trigger absolute cell min? (uint8_t)(cell_min_voltage); //TODO: scaling OK? Supposed to be alarm trigger absolute cell min?
SOLAX_1874.data.u8[7] = (cell_min_voltage >> 8); SOLAX_1874.data.u8[7] = (cell_min_voltage >> 8);
//BMS_Status //BMS_Status
@ -188,10 +188,10 @@ void update_values_can_solax() { //This function maps all the values fetched fr
SOLAX_1875.data.u8[4] = (uint8_t)0; // Contactor Status 0=off, 1=on. SOLAX_1875.data.u8[4] = (uint8_t)0; // Contactor Status 0=off, 1=on.
//BMS_PackTemps (strange name, since it has voltages?) //BMS_PackTemps (strange name, since it has voltages?)
SOLAX_1876.data.u8[2] = (uint8_t)cell_max_voltage; //Todo, scaling OK? SOLAX_1876.data.u8[2] = (uint8_t)cell_max_voltage; //TODO: scaling OK?
SOLAX_1876.data.u8[3] = (cell_min_voltage >> 8); SOLAX_1876.data.u8[3] = (cell_min_voltage >> 8);
SOLAX_1876.data.u8[6] = (uint8_t)cell_min_voltage; //Todo, scaling OK? SOLAX_1876.data.u8[6] = (uint8_t)cell_min_voltage; //TODO: scaling OK?
SOLAX_1876.data.u8[7] = (cell_min_voltage >> 8); SOLAX_1876.data.u8[7] = (cell_min_voltage >> 8);
//Unknown //Unknown
@ -201,10 +201,10 @@ void update_values_can_solax() { //This function maps all the values fetched fr
(uint8_t)0x02; // The above firmware version applies to:02 = Master BMS, 10 = S1, 20 = S2, 30 = S3, 40 = S4 (uint8_t)0x02; // The above firmware version applies to:02 = Master BMS, 10 = S1, 20 = S2, 30 = S3, 40 = S4
//BMS_PackStats //BMS_PackStats
SOLAX_1878.data.u8[0] = (uint8_t)(battery_voltage); //TODO, should this be max or current voltage? SOLAX_1878.data.u8[0] = (uint8_t)(battery_voltage); //TODO: should this be max or current voltage?
SOLAX_1878.data.u8[1] = ((battery_voltage) >> 8); SOLAX_1878.data.u8[1] = ((battery_voltage) >> 8);
SOLAX_1878.data.u8[4] = (uint8_t)capacity_Wh; //TODO, scaling OK? SOLAX_1878.data.u8[4] = (uint8_t)capacity_Wh; //TODO: scaling OK?
SOLAX_1878.data.u8[5] = (capacity_Wh >> 8); SOLAX_1878.data.u8[5] = (capacity_Wh >> 8);
// BMS_Answer // BMS_Answer
@ -220,7 +220,7 @@ void receive_can_solax(CAN_frame_t rx_frame) {
switch (STATE) { switch (STATE) {
case (BATTERY_ANNOUNCE): case (BATTERY_ANNOUNCE):
Serial.println("Solax Battery State: Announce"); Serial.println("Solax Battery State: Announce");
inverterAllowsContactorClosing = 0; inverterAllowsContactorClosing = false;
SOLAX_1875.data.u8[4] = (0x00); // Inform Inverter: Contactor 0=off, 1=on. SOLAX_1875.data.u8[4] = (0x00); // Inform Inverter: Contactor 0=off, 1=on.
for (int i = 0; i <= number_of_batteries; i++) { for (int i = 0; i <= number_of_batteries; i++) {
CAN_WriteFrame(&SOLAX_1872); CAN_WriteFrame(&SOLAX_1872);
@ -253,7 +253,7 @@ void receive_can_solax(CAN_frame_t rx_frame) {
break; break;
case (CONTACTOR_CLOSED): case (CONTACTOR_CLOSED):
inverterAllowsContactorClosing = 1; inverterAllowsContactorClosing = true;
SOLAX_1875.data.u8[4] = (0x01); // Inform Inverter: Contactor 0=off, 1=on. SOLAX_1875.data.u8[4] = (0x01); // Inform Inverter: Contactor 0=off, 1=on.
CAN_WriteFrame(&SOLAX_1872); CAN_WriteFrame(&SOLAX_1872);
CAN_WriteFrame(&SOLAX_1873); CAN_WriteFrame(&SOLAX_1873);

View file

@ -26,7 +26,7 @@ extern uint16_t min_voltage;
extern uint16_t max_voltage; extern uint16_t max_voltage;
extern uint16_t cell_max_voltage; extern uint16_t cell_max_voltage;
extern uint16_t cell_min_voltage; extern uint16_t cell_min_voltage;
extern uint8_t inverterAllowsContactorClosing; extern bool inverterAllowsContactorClosing;
// Timeout in milliseconds // Timeout in milliseconds
#define SolaxTimeout 2000 #define SolaxTimeout 2000