mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-04 18:29:48 +02:00
BYD CAN inverter protocol class
This commit is contained in:
parent
2b608e48b9
commit
d934a3b796
5 changed files with 153 additions and 95 deletions
|
@ -1,91 +1,13 @@
|
|||
#include "../include.h"
|
||||
#ifdef BYD_CAN
|
||||
#include "../communication/can/comm_can.h"
|
||||
#include "../datalayer/datalayer.h"
|
||||
#include "BYD-CAN.h"
|
||||
|
||||
/* Do not change code below unless you are sure what you are doing */
|
||||
static unsigned long previousMillis2s = 0; // will store last time a 2s CAN Message was send
|
||||
static unsigned long previousMillis10s = 0; // will store last time a 10s CAN Message was send
|
||||
static unsigned long previousMillis60s = 0; // will store last time a 60s CAN Message was send
|
||||
|
||||
#define VOLTAGE_OFFSET_DV 20
|
||||
|
||||
CAN_frame BYD_250 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x250,
|
||||
.data = {FW_MAJOR_VERSION, FW_MINOR_VERSION, 0x00, 0x66, (uint8_t)((BATTERY_WH_MAX / 100) >> 8),
|
||||
(uint8_t)(BATTERY_WH_MAX / 100), 0x02,
|
||||
0x09}}; //0-1 FW version , Capacity kWh byte4&5 (example 24kWh = 240)
|
||||
CAN_frame BYD_290 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x290,
|
||||
.data = {0x06, 0x37, 0x10, 0xD9, 0x00, 0x00, 0x00, 0x00}};
|
||||
CAN_frame BYD_2D0 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x2D0,
|
||||
.data = {0x00, 0x42, 0x59, 0x44, 0x00, 0x00, 0x00, 0x00}}; //BYD
|
||||
CAN_frame BYD_3D0_0 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x3D0,
|
||||
.data = {0x00, 0x42, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79}}; //Battery
|
||||
CAN_frame BYD_3D0_1 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x3D0,
|
||||
.data = {0x01, 0x2D, 0x42, 0x6F, 0x78, 0x20, 0x50, 0x72}}; //-Box Pr
|
||||
CAN_frame BYD_3D0_2 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x3D0,
|
||||
.data = {0x02, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x20, 0x48}}; //emium H
|
||||
CAN_frame BYD_3D0_3 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x3D0,
|
||||
.data = {0x03, 0x56, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00}}; //VS
|
||||
//Actual content messages
|
||||
CAN_frame BYD_110 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x110,
|
||||
.data = {0x01, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
CAN_frame BYD_150 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x150,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00}};
|
||||
CAN_frame BYD_190 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x190,
|
||||
.data = {0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
CAN_frame BYD_1D0 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x1D0,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08}};
|
||||
CAN_frame BYD_210 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x210,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static int16_t temperature_average = 0;
|
||||
static uint16_t inverter_voltage = 0;
|
||||
static uint16_t inverter_SOC = 0;
|
||||
static int16_t inverter_current = 0;
|
||||
static int16_t inverter_temperature = 0;
|
||||
static uint16_t remaining_capacity_ah = 0;
|
||||
static uint16_t fully_charged_capacity_ah = 0;
|
||||
static long inverter_timestamp = 0;
|
||||
static bool initialDataSent = false;
|
||||
static bool inverterStartedUp = false;
|
||||
|
||||
void update_values_can_inverter() { //This function maps all the values fetched from battery CAN to the correct CAN messages
|
||||
void BydCanInverter::
|
||||
update_values() { //This function maps all the values fetched from battery CAN to the correct CAN messages
|
||||
|
||||
/* Calculate temperature */
|
||||
temperature_average =
|
||||
|
@ -167,7 +89,7 @@ void update_values_can_inverter() { //This function maps all the values fetched
|
|||
BYD_210.data.u8[3] = (datalayer.battery.status.temperature_min_dC & 0x00FF);
|
||||
}
|
||||
|
||||
void map_can_frame_to_variable_inverter(CAN_frame rx_frame) {
|
||||
void BydCanInverter::map_can_frame_to_variable(CAN_frame rx_frame) {
|
||||
switch (rx_frame.ID) {
|
||||
case 0x151: //Message originating from BYD HVS compatible inverter. Reply with CAN identifier!
|
||||
inverterStartedUp = true;
|
||||
|
@ -204,7 +126,7 @@ void map_can_frame_to_variable_inverter(CAN_frame rx_frame) {
|
|||
}
|
||||
}
|
||||
|
||||
void transmit_can_inverter(unsigned long currentMillis) {
|
||||
void BydCanInverter::transmit_can(unsigned long currentMillis) {
|
||||
|
||||
if (!inverterStartedUp) {
|
||||
//Avoid sending messages towards inverter, unless it has woken up and sent something to us first
|
||||
|
@ -239,7 +161,7 @@ void transmit_can_inverter(unsigned long currentMillis) {
|
|||
}
|
||||
}
|
||||
|
||||
void send_intial_data() {
|
||||
void BydCanInverter::send_intial_data() {
|
||||
transmit_can_frame(&BYD_250, can_config.inverter);
|
||||
transmit_can_frame(&BYD_290, can_config.inverter);
|
||||
transmit_can_frame(&BYD_2D0, can_config.inverter);
|
||||
|
@ -248,7 +170,8 @@ void send_intial_data() {
|
|||
transmit_can_frame(&BYD_3D0_2, can_config.inverter);
|
||||
transmit_can_frame(&BYD_3D0_3, can_config.inverter);
|
||||
}
|
||||
void setup_inverter(void) { // Performs one time setup at startup over CAN bus
|
||||
|
||||
void BydCanInverter::setup(void) { // Performs one time setup at startup over CAN bus
|
||||
strncpy(datalayer.system.info.inverter_protocol, "BYD Battery-Box Premium HVS over CAN Bus", 63);
|
||||
datalayer.system.info.inverter_protocol[63] = '\0';
|
||||
}
|
||||
|
|
|
@ -3,11 +3,101 @@
|
|||
#include "../include.h"
|
||||
|
||||
#define CAN_INVERTER_SELECTED
|
||||
#define SELECTED_INVERTER_CLASS BydCanInverter
|
||||
|
||||
#define FW_MAJOR_VERSION 0x03
|
||||
#define FW_MINOR_VERSION 0x29
|
||||
|
||||
class BydCanInverter : public CanInverterProtocol {
|
||||
public:
|
||||
void setup();
|
||||
void send_intial_data();
|
||||
void transmit_can_frame(CAN_frame* tx_frame, int interface);
|
||||
void setup_inverter(void);
|
||||
void transmit_can(unsigned long currentMillis);
|
||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||
|
||||
private:
|
||||
void update_values();
|
||||
|
||||
unsigned long previousMillis2s = 0; // will store last time a 2s CAN Message was send
|
||||
unsigned long previousMillis10s = 0; // will store last time a 10s CAN Message was send
|
||||
unsigned long previousMillis60s = 0; // will store last time a 60s CAN Message was send
|
||||
|
||||
#define VOLTAGE_OFFSET_DV 20
|
||||
|
||||
CAN_frame BYD_250 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x250,
|
||||
.data = {FW_MAJOR_VERSION, FW_MINOR_VERSION, 0x00, 0x66, (uint8_t)((BATTERY_WH_MAX / 100) >> 8),
|
||||
(uint8_t)(BATTERY_WH_MAX / 100), 0x02,
|
||||
0x09}}; //0-1 FW version , Capacity kWh byte4&5 (example 24kWh = 240)
|
||||
CAN_frame BYD_290 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x290,
|
||||
.data = {0x06, 0x37, 0x10, 0xD9, 0x00, 0x00, 0x00, 0x00}};
|
||||
CAN_frame BYD_2D0 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x2D0,
|
||||
.data = {0x00, 0x42, 0x59, 0x44, 0x00, 0x00, 0x00, 0x00}}; //BYD
|
||||
CAN_frame BYD_3D0_0 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x3D0,
|
||||
.data = {0x00, 0x42, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79}}; //Battery
|
||||
CAN_frame BYD_3D0_1 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x3D0,
|
||||
.data = {0x01, 0x2D, 0x42, 0x6F, 0x78, 0x20, 0x50, 0x72}}; //-Box Pr
|
||||
CAN_frame BYD_3D0_2 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x3D0,
|
||||
.data = {0x02, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x20, 0x48}}; //emium H
|
||||
CAN_frame BYD_3D0_3 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x3D0,
|
||||
.data = {0x03, 0x56, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00}}; //VS
|
||||
//Actual content messages
|
||||
CAN_frame BYD_110 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x110,
|
||||
.data = {0x01, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
CAN_frame BYD_150 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x150,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00}};
|
||||
CAN_frame BYD_190 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x190,
|
||||
.data = {0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
CAN_frame BYD_1D0 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x1D0,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08}};
|
||||
CAN_frame BYD_210 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x210,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
int16_t temperature_average = 0;
|
||||
uint16_t inverter_voltage = 0;
|
||||
uint16_t inverter_SOC = 0;
|
||||
int16_t inverter_current = 0;
|
||||
int16_t inverter_temperature = 0;
|
||||
uint16_t remaining_capacity_ah = 0;
|
||||
uint16_t fully_charged_capacity_ah = 0;
|
||||
long inverter_timestamp = 0;
|
||||
bool initialDataSent = false;
|
||||
bool inverterStartedUp = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "../include.h"
|
||||
|
||||
#define MODBUS_INVERTER_SELECTED
|
||||
#define OO_INVERTER_PROTOCOL_SELECTED
|
||||
#define SELECTED_INVERTER_CLASS BydModbusInverter
|
||||
|
||||
#define MB_RTU_NUM_VALUES 13100
|
||||
#define MAX_POWER 40960 //BYD Modbus specific value
|
||||
|
|
|
@ -3,22 +3,54 @@
|
|||
// These functions adapt the old C-style global functions inverter-API to the
|
||||
// object-oriented inverter protocol API.
|
||||
|
||||
#ifdef OO_INVERTER_PROTOCOL_SELECTED
|
||||
#ifdef SELECTED_INVERTER_CLASS
|
||||
|
||||
ModbusInverterProtocol* inverter;
|
||||
InverterProtocol* inverter;
|
||||
|
||||
#ifdef CAN_INVERTER_SELECTED
|
||||
CanInverterProtocol* can_inverter;
|
||||
#endif
|
||||
|
||||
#ifdef MODBUS_INVERTER_SELECTED
|
||||
ModbusInverterProtocol* modbus_inverter;
|
||||
#endif
|
||||
|
||||
void setup_inverter() {
|
||||
// Currently only a single inverter protocol is implemented as a class
|
||||
inverter = new BydModbusInverter();
|
||||
#ifdef MODBUS_INVERTER_SELECTED
|
||||
modbus_inverter = new SELECTED_INVERTER_CLASS();
|
||||
inverter = modbus_inverter;
|
||||
#endif
|
||||
|
||||
#ifdef CAN_INVERTER_SELECTED
|
||||
can_inverter = new SELECTED_INVERTER_CLASS();
|
||||
inverter = can_inverter;
|
||||
#endif
|
||||
|
||||
inverter->setup();
|
||||
}
|
||||
|
||||
#ifdef MODBUS_INVERTER_SELECTED
|
||||
void update_modbus_registers_inverter() {
|
||||
inverter->update_modbus_registers();
|
||||
modbus_inverter->update_modbus_registers();
|
||||
}
|
||||
|
||||
void handle_static_data_modbus() {
|
||||
inverter->handle_static_data();
|
||||
modbus_inverter->handle_static_data();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CAN_INVERTER_SELECTED
|
||||
void update_values_can_inverter() {
|
||||
can_inverter->update_values();
|
||||
}
|
||||
|
||||
void map_can_frame_to_variable_inverter(CAN_frame rx_frame) {
|
||||
can_inverter->map_can_frame_to_variable(rx_frame);
|
||||
}
|
||||
|
||||
void transmit_can_inverter(unsigned long currentMillis) {
|
||||
can_inverter->transmit_can(currentMillis);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,18 @@ class ModbusInverterProtocol : public InverterProtocol {
|
|||
virtual void handle_static_data();
|
||||
};
|
||||
|
||||
class CanInverterProtocol : public InverterProtocol {
|
||||
public:
|
||||
virtual void send_intial_data() = 0;
|
||||
|
||||
//This function maps all the values fetched from battery CAN to the correct CAN messages
|
||||
virtual void update_values() = 0;
|
||||
|
||||
virtual void transmit_can(unsigned long currentMillis) = 0;
|
||||
|
||||
virtual void map_can_frame_to_variable(CAN_frame rx_frame) = 0;
|
||||
};
|
||||
|
||||
#include "../../USER_SETTINGS.h"
|
||||
|
||||
#ifdef AFORE_CAN
|
||||
|
@ -96,6 +108,7 @@ class ModbusInverterProtocol : public InverterProtocol {
|
|||
void update_values_can_inverter();
|
||||
void map_can_frame_to_variable_inverter(CAN_frame rx_frame);
|
||||
void transmit_can_inverter(unsigned long currentMillis);
|
||||
void setup_inverter();
|
||||
#endif
|
||||
|
||||
#ifdef MODBUS_INVERTER_SELECTED
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue