mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 17:59:27 +02:00
Add separate handling of static/dynamic data
Performance gains
This commit is contained in:
parent
ede6cde1c2
commit
f8a6e176de
1 changed files with 304 additions and 250 deletions
|
@ -45,33 +45,46 @@ uint16_t SOC = 5000; //SOC 0-100.00% //Updates later on from CAN
|
|||
uint16_t capacity_Wh = BATTERY_WH_MAX; //Updates later on from CAN
|
||||
uint16_t remaining_capacity_Wh = BATTERY_WH_MAX; //Updates later on from CAN
|
||||
uint16_t max_target_discharge_power = 0; //0W (0W > restricts to no discharge) //Updates later on from CAN
|
||||
uint16_t max_target_charge_power = 4312; //4.3kW (during charge), both 307&308 can be set (>0) at the same time //Updates later on from CAN
|
||||
uint16_t max_target_charge_power = 4312;
|
||||
//4.3kW (during charge), both 307&308 can be set (>0) at the same time //Updates later on from CAN
|
||||
uint16_t TemperatureMax = 50; //Todo, read from LEAF pack, uint not ok
|
||||
uint16_t TemperatureMin = 60; //Todo, read from LEAF pack, uint not ok
|
||||
|
||||
// Store the data into the array
|
||||
//16-bit int in these modbus-register, two letters at a time. Example p101[1]....(ascii for S) * 256 + (ascii for I) = 21321
|
||||
uint16_t p101_data[] = {21321, 1, 16985, 17408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16985, 17408, 16993, 29812, 25970, 31021, 17007, 30720, 20594, 25965, 26997, 27904, 18518, 0, 0, 0, 13614, 12288, 0, 0, 0, 0, 0, 0, 13102, 12598, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0};
|
||||
//uint16_t p101_data[] = {21321, 1, 16985, 17408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16985, 17440!17408, 16993, 29812, 25970, 31021, 17007, 30752!30720, 20594, 25965, 26997, 27936!27904, 18518, 0, 0, 0, 13614, 12288, 0, 0, 0, 0, 0, 0, 13102, 12598, 0, 0, 0, 0, 0, 0, 20581, 27756, 25856, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0};
|
||||
//uint16_t p101_data[] = {21321, 1, 16985, 17408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16985, 17408, 16993, 29812, 25970, 31021, 17007, 30720, 20594, 25965, 26997, 27904, 18518, 0, 0, 0, 13614, 12288, 0, 0, 0, 0, 0, 0, 13102, 12598, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0};
|
||||
//Delete the following lines once we know this works :)
|
||||
//uint16_t p101_data[] = {21321, 1}; //SI
|
||||
//uint16_t p103_data[] = {16985, 17408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //BY D
|
||||
//uint16_t p119_data[] = {16985, 17408, 16993, 29812, 25970, 31021, 17007, 30720, 20594, 25965, 26997, 27904, 18518, 0, 0, 0}; //BY D Ba tt er y- Bo x Pr em iu m HV
|
||||
//uint16_t p135_data[] = {13614, 12288, 0, 0, 0, 0, 0, 0, 13102, 12598, 0, 0, 0, 0, 0, 0}; //5.0 3.16
|
||||
//uint16_t p151_data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //Serial number for battery
|
||||
//uint16_t p167_data[] = {1, 0};
|
||||
uint16_t p201_data[] = {0, 0, capacity_Wh_startup, MaxPower, MaxPower, MaxVoltage, MinVoltage, 53248, 10, 53248, 10, 0, 0};
|
||||
uint16_t p301_data[] = {Status, 0, 128, SOC, capacity_Wh, remaining_capacity_Wh, max_target_discharge_power, max_target_charge_power, 0, 0, 2058, 0, TemperatureMin, TemperatureMax, 0, 0, 16, 22741, 0, 0, 13, 52064, 80, 9900};
|
||||
uint16_t p101_data[] = {21321, 1}; //SI
|
||||
uint16_t p103_data[] = {16985, 17408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //BY D
|
||||
uint16_t p119_data[] = {
|
||||
16985, 17440, 16993, 29812, 25970, 31021, 17007, 30752, 20594, 25965, 26997, 27936, 18518, 0, 0, 0
|
||||
}; //BY D Ba tt er y- Bo x Pr em iu m HV
|
||||
uint16_t p135_data[] = {13614, 12288, 0, 0, 0, 0, 0, 0, 13102, 12598, 0, 0, 0, 0, 0, 0}; //5.0 3.16
|
||||
uint16_t p151_data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //Serial number for battery
|
||||
uint16_t p167_data[] = {1, 0};
|
||||
uint16_t p201_data[] = {
|
||||
0, 0, capacity_Wh_startup, MaxPower, MaxPower, MaxVoltage, MinVoltage, 53248, 10, 53248, 10, 0, 0
|
||||
};
|
||||
uint16_t p301_data[] = {
|
||||
Status, 0, 128, SOC, capacity_Wh, remaining_capacity_Wh, max_target_discharge_power, max_target_charge_power, 0, 0,
|
||||
2058, 0, TemperatureMin, TemperatureMax, 0, 0, 16, 22741, 0, 0, 13, 52064, 80, 9900
|
||||
};
|
||||
//These registers get written to
|
||||
uint16_t p401_data[] = {1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint16_t p1001_data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint16_t p1001_data[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
uint16_t i;
|
||||
static unsigned long currentMillis;
|
||||
|
||||
// Create a ModbusRTU server instance listening on Serial2 with 2000ms timeout
|
||||
ModbusServerRTU MBserver(Serial2, 2000);
|
||||
|
||||
// Setup() - initialization happens here
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
//CAN pins
|
||||
pinMode(CAN_SE_PIN, OUTPUT);
|
||||
digitalWrite(CAN_SE_PIN, LOW);
|
||||
|
@ -94,9 +107,12 @@ void setup() {
|
|||
digitalWrite(PIN_5V_EN, HIGH);
|
||||
// Init Serial monitor
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {}
|
||||
while (!Serial)
|
||||
{
|
||||
}
|
||||
Serial.println("__ OK __");
|
||||
|
||||
// Init Static data to the RTU Modbus
|
||||
handle_StaticDataModbus();
|
||||
// Init Serial2 connected to the RTU Modbus
|
||||
// (Fill in your data here!)
|
||||
Serial2.begin(9600, SERIAL_8N1, RS485_RX_PIN, RS485_TX_PIN);
|
||||
|
@ -110,13 +126,21 @@ void setup() {
|
|||
}
|
||||
|
||||
// perform main program functions
|
||||
void loop() {
|
||||
handle_modbus();
|
||||
void loop()
|
||||
{
|
||||
handle_can();
|
||||
update_values();
|
||||
currentMillis = millis();
|
||||
if (currentMillis - previousMillisModbus >= intervalModbusTask)
|
||||
{
|
||||
//every 10s
|
||||
previousMillisModbus = currentMillis;
|
||||
handle_UpdateDataModbus();
|
||||
}
|
||||
}
|
||||
|
||||
void update_values(){
|
||||
void update_values()
|
||||
{
|
||||
MaxPower = (LB_Discharge_Power_Limit * 1000); //kW to W
|
||||
SOC = (LB_SOC * 10); //increase range from 0-100.0 -> 100.00
|
||||
capacity_Wh = (LB_Max_GIDS * WH_PER_GID);
|
||||
|
@ -127,33 +151,61 @@ void update_values(){
|
|||
TemperatureMax = 60; //hardcoded, todo, read from 5C0
|
||||
}
|
||||
|
||||
void handle_modbus(){
|
||||
static unsigned long currentMillis = millis();
|
||||
if (currentMillis - previousMillisModbus >= intervalModbusTask)
|
||||
{ //every 10s
|
||||
previousMillisModbus = currentMillis;
|
||||
|
||||
//Print value of holfing register 40001
|
||||
Serial.println(mbPV[0]);
|
||||
|
||||
i = 0;
|
||||
// Copy the contents of the original arrays uint16_to the new array
|
||||
for (uint16_t j = 0; j < sizeof(p101_data) / sizeof(uint16_t); j++) {
|
||||
void handle_StaticDataModbus()
|
||||
{
|
||||
i = 100;
|
||||
// --- Copy the contents of the static data from the original arrays to the new modbus array ---
|
||||
for (uint16_t j = 0; j < sizeof(p101_data) / sizeof(uint16_t); j++)
|
||||
{
|
||||
mbPV[i] = p101_data[j];
|
||||
i++;
|
||||
}
|
||||
for (uint16_t j = 0; j < sizeof(p201_data) / sizeof(uint16_t); j++) {
|
||||
for (uint16_t j = 0; j < sizeof(p103_data) / sizeof(uint16_t); j++)
|
||||
{
|
||||
mbPV[i] = p103_data[j];
|
||||
i++;
|
||||
}
|
||||
for (uint16_t j = 0; j < sizeof(p119_data) / sizeof(uint16_t); j++)
|
||||
{
|
||||
mbPV[i] = p119_data[j];
|
||||
i++;
|
||||
}
|
||||
for (uint16_t j = 0; j < sizeof(p135_data) / sizeof(uint16_t); j++)
|
||||
{
|
||||
mbPV[i] = p135_data[j];
|
||||
i++;
|
||||
}
|
||||
for (uint16_t j = 0; j < sizeof(p151_data) / sizeof(uint16_t); j++)
|
||||
{
|
||||
mbPV[i] = p151_data[j];
|
||||
i++;
|
||||
}
|
||||
for (uint16_t j = 0; j < sizeof(p167_data) / sizeof(uint16_t); j++)
|
||||
{
|
||||
mbPV[i] = p167_data[j];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_UpdateDataModbus()
|
||||
{
|
||||
i = 200;
|
||||
// --- Copy the data contents arrays to the new modbus array ---
|
||||
for (uint16_t j = 0; j < sizeof(p201_data) / sizeof(uint16_t); j++)
|
||||
{
|
||||
mbPV[i] = p201_data[j];
|
||||
i++;
|
||||
}
|
||||
for (uint16_t j = 0; j < sizeof(p301_data) / sizeof(uint16_t); j++) {
|
||||
i = 300;
|
||||
for (uint16_t j = 0; j < sizeof(p301_data) / sizeof(uint16_t); j++)
|
||||
{
|
||||
mbPV[i] = p301_data[j];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handle_can() {
|
||||
void handle_can()
|
||||
{
|
||||
CAN_frame_t rx_frame;
|
||||
|
||||
static unsigned long currentMillis = millis();
|
||||
|
@ -161,18 +213,19 @@ void handle_can() {
|
|||
// Receive next CAN frame from queue
|
||||
if (xQueueReceive(CAN_cfg.rx_queue, &rx_frame, 3 * portTICK_PERIOD_MS) == pdTRUE)
|
||||
{
|
||||
|
||||
if (rx_frame.FIR.B.FF == CAN_frame_std)
|
||||
{
|
||||
//printf("New standard frame");
|
||||
switch (rx_frame.MsgID) {
|
||||
switch (rx_frame.MsgID)
|
||||
{
|
||||
case 0x1DB:
|
||||
LB_Current = (rx_frame.data.u8[0] << 3) | (rx_frame.data.u8[1] & 0xe0) >> 5;
|
||||
LB_Total_Voltage = ((rx_frame.data.u8[2] << 2) | (rx_frame.data.u8[3] & 0xc0) >> 6) / 2;
|
||||
break;
|
||||
case 0x1DC:
|
||||
LB_Discharge_Power_Limit = ((rx_frame.data.u8[0] << 2 | rx_frame.data.u8[1] >> 6) / 4.0);
|
||||
LB_MAX_POWER_FOR_CHARGER = ( ( ( (rx_frame.data.u8[2] & 0x0F) << 6 | rx_frame.data.u8[3] >> 2 ) / 10.0 ) - 10); //check if -10 is correct offset
|
||||
LB_MAX_POWER_FOR_CHARGER = ((((rx_frame.data.u8[2] & 0x0F) << 6 | rx_frame.data.u8[3] >> 2) / 10.0) -
|
||||
10); //check if -10 is correct offset
|
||||
break;
|
||||
case 0x55B:
|
||||
LB_SOC = (rx_frame.data.u8[0] << 2 | rx_frame.data.u8[1] >> 6);
|
||||
|
@ -186,7 +239,8 @@ void handle_can() {
|
|||
//Only the 30/40/62kWh packs have this mux
|
||||
}
|
||||
else
|
||||
{ //Normal current GIDS value is transmitted
|
||||
{
|
||||
//Normal current GIDS value is transmitted
|
||||
LB_GIDS = (rx_frame.data.u8[0] << 2) | ((rx_frame.data.u8[1] & 0xC0) >> 6);
|
||||
LB_Wh_Remaining = (LB_GIDS * WH_PER_GID);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue