mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-05 02:39:57 +02:00
Refactor for merge to main
This commit is contained in:
parent
961e33033e
commit
f9ca90b20e
3 changed files with 109 additions and 69 deletions
|
@ -31,18 +31,18 @@ CAN_frame_t SOLAX_100A001 = {.FIR = {.B = {.DLC = 0,.FF = CAN_frame_ext,}},.MsgI
|
|||
void CAN_WriteFrame(CAN_frame_t* tx_frame)
|
||||
{
|
||||
#ifdef DUAL_CAN
|
||||
CANMessage MCP2515Frame; //Struct with ACAN2515 library format, needed to use the MCP2515 library
|
||||
MCP2515Frame.id = tx_frame->MsgID;
|
||||
MCP2515Frame.ext = tx_frame->FIR.B.FF;
|
||||
MCP2515Frame.len = tx_frame->FIR.B.DLC;
|
||||
for (uint8_t i=0 ; i<MCP2515Frame.len ; i++) {
|
||||
MCP2515Frame.data[i] = tx_frame->data.u8[i];
|
||||
}
|
||||
can.tryToSend(MCP2515Frame);
|
||||
//Serial.println("Solax CAN Frame sent in Bus 2");
|
||||
CANMessage MCP2515Frame; //Struct with ACAN2515 library format, needed to use the MCP2515 library
|
||||
MCP2515Frame.id = tx_frame->MsgID;
|
||||
MCP2515Frame.ext = tx_frame->FIR.B.FF;
|
||||
MCP2515Frame.len = tx_frame->FIR.B.DLC;
|
||||
for (uint8_t i=0 ; i<MCP2515Frame.len ; i++) {
|
||||
MCP2515Frame.data[i] = tx_frame->data.u8[i];
|
||||
}
|
||||
can.tryToSend(MCP2515Frame);
|
||||
//Serial.println("Solax CAN Frame sent in Bus 2");
|
||||
#else
|
||||
ESP32Can.CANWriteFrame(tx_frame);
|
||||
//Serial.println("Solax CAN Frame sent in Bus 1");
|
||||
ESP32Can.CANWriteFrame(tx_frame);
|
||||
//Serial.println("Solax CAN Frame sent in Bus 1");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,6 @@ void update_values_can_solax()
|
|||
}
|
||||
|
||||
//Put the values into the CAN messages
|
||||
|
||||
//BMS_Limits
|
||||
SOLAX_1872.data.u8[0] = (uint8_t) max_volt_solax_can; //Todo, scaling OK?
|
||||
SOLAX_1872.data.u8[1] = (max_volt_solax_can >> 8);
|
||||
|
@ -155,11 +154,6 @@ void update_values_can_solax()
|
|||
|
||||
}
|
||||
|
||||
void send_can_solax() {
|
||||
// Deprecated - All transmissions should be initiated in response to inverter polling.
|
||||
}
|
||||
|
||||
|
||||
void receive_can_solax(CAN_frame_t rx_frame)
|
||||
{
|
||||
if (rx_frame.MsgID == 0x1871) {
|
||||
|
|
|
@ -1,5 +1,26 @@
|
|||
/* Select battery used */
|
||||
#define BATTERY_TYPE_LEAF // See NISSAN-LEAF-BATTERY.h for more LEAF battery settings
|
||||
//#define TESLA_MODEL_3_BATTERY // See TESLA-MODEL-3-BATTERY.h for more Tesla battery settings
|
||||
//#define RENAULT_ZOE_BATTERY // See RENAULT-ZOE-BATTERY.h for more Zoe battery settings
|
||||
//#define BMW_I3_BATTERY // See BMW-I3-BATTERY.h for more i3 battery settings
|
||||
//#define IMIEV_ION_CZERO_BATTERY // See IMIEV-CZERO-ION-BATTERY.h for more triplet battery settings
|
||||
//#define KIA_HYUNDAI_64_BATTERY // See KIA-HYUNDAI-64-BATTERY.h for more battery settings
|
||||
//#define CHADEMO // See CHADEMO.h for more Chademo related settings
|
||||
|
||||
/* Select inverter communication protocol. See Wiki for which to use with your inverter: https://github.com/dalathegreat/BYD-Battery-Emulator-For-Gen24/wiki */
|
||||
#define MODBUS_BYD //Enable this line to emulate a "BYD 11kWh HVM battery" over Modbus RTU
|
||||
//#define CAN_BYD //Enable this line to emulate a "BYD Battery-Box Premium HVS" over CAN Bus
|
||||
//#define SOLAX_CAN //Enable this line to emulate a "SolaX Triple Power LFP" over CAN bus
|
||||
//#define PYLON_CAN //Enable this line to emulate a "Pylontech battery" over CAN bus
|
||||
|
||||
/* Other options */
|
||||
#define CONTACTOR_CONTROL //Enable this line to have pins 25,32,33 handle precharge/contactor+/contactor- closing sequence
|
||||
#define PWM_CONTACTOR_CONTROL //Enable this line to use PWM logic for contactors, which lower power consumption and heat generation
|
||||
//#define DUAL_CAN //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 controller (Needed for FoxESS inverters)
|
||||
|
||||
/* Do not change any code below this line unless you are sure what you are doing */
|
||||
/* Only change battery specific settings and limits in their respective .h files */
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "HardwareSerial.h"
|
||||
#include "config.h"
|
||||
|
@ -96,6 +117,7 @@ enum State {
|
|||
};
|
||||
State contactorStatus = DISCONNECTED;
|
||||
|
||||
#define MAX_ALLOWED_FAULT_TICKS 500
|
||||
#define PRECHARGE_TIME_MS 160
|
||||
#define NEGATIVE_CONTACTOR_TIME_MS 1000
|
||||
#define POSITIVE_CONTACTOR_TIME_MS 2000
|
||||
|
@ -108,7 +130,7 @@ unsigned long prechargeStartTime = 0;
|
|||
unsigned long negativeStartTime = 0;
|
||||
unsigned long timeSpentInFaultedMode = 0;
|
||||
uint8_t batteryAllowsContactorClosing = 0;
|
||||
uint8_t inverterAllowsContactorClosing = 0;
|
||||
uint8_t inverterAllowsContactorClosing = 1;
|
||||
|
||||
// Setup() - initialization happens here
|
||||
void setup()
|
||||
|
@ -132,6 +154,7 @@ void setup()
|
|||
Serial.println(CAN_cfg.speed);
|
||||
|
||||
#ifdef DUAL_CAN
|
||||
Serial.println("Dual CAN Bus (ESP32+MCP2515) selected");
|
||||
gBuffer.initWithSize(25);
|
||||
SPI.begin(MCP2515_SCK, MCP2515_MISO, MCP2515_MOSI);
|
||||
Serial.println ("Configure ACAN2515") ;
|
||||
|
@ -141,19 +164,22 @@ void setup()
|
|||
#endif
|
||||
|
||||
//Init contactor pins
|
||||
|
||||
|
||||
ledcSetup(POSITIVE_PWM_Ch, PWM_Freq, PWM_Res); // Setup PWM Channel Frequency and Resolution
|
||||
ledcSetup(NEGATIVE_PWM_Ch, PWM_Freq, PWM_Res); // Setup PWM Channel Frequency and Resolution
|
||||
|
||||
ledcAttachPin(POSITIVE_CONTACTOR_PIN, POSITIVE_PWM_Ch); // Attach Positive Contactor Pin to Hardware PWM Channel
|
||||
ledcAttachPin(NEGATIVE_CONTACTOR_PIN, NEGATIVE_PWM_Ch); // Attach Positive Contactor Pin to Hardware PWM Channel
|
||||
|
||||
ledcWrite(POSITIVE_PWM_Ch, 0); // Set Positive PWM to 0%
|
||||
ledcWrite(NEGATIVE_PWM_Ch, 0); // Set Negative PWM to 0%
|
||||
|
||||
#ifdef CONTACTOR_CONTROL
|
||||
pinMode(POSITIVE_CONTACTOR_PIN, OUTPUT);
|
||||
digitalWrite(POSITIVE_CONTACTOR_PIN, LOW);
|
||||
pinMode(NEGATIVE_CONTACTOR_PIN, OUTPUT);
|
||||
digitalWrite(NEGATIVE_CONTACTOR_PIN, LOW);
|
||||
#ifdef PWM_CONTACTOR_CONTROL
|
||||
ledcSetup(POSITIVE_PWM_Ch, PWM_Freq, PWM_Res); // Setup PWM Channel Frequency and Resolution
|
||||
ledcSetup(NEGATIVE_PWM_Ch, PWM_Freq, PWM_Res); // Setup PWM Channel Frequency and Resolution
|
||||
ledcAttachPin(POSITIVE_CONTACTOR_PIN, POSITIVE_PWM_Ch); // Attach Positive Contactor Pin to Hardware PWM Channel
|
||||
ledcAttachPin(NEGATIVE_CONTACTOR_PIN, NEGATIVE_PWM_Ch); // Attach Positive Contactor Pin to Hardware PWM Channel
|
||||
ledcWrite(POSITIVE_PWM_Ch, 0); // Set Positive PWM to 0%
|
||||
ledcWrite(NEGATIVE_PWM_Ch, 0); // Set Negative PWM to 0%
|
||||
#endif
|
||||
pinMode(PRECHARGE_PIN, OUTPUT);
|
||||
digitalWrite(PRECHARGE_PIN, LOW);
|
||||
#endif
|
||||
|
||||
|
||||
//Set up Modbus RTU Server
|
||||
|
@ -182,23 +208,36 @@ void setup()
|
|||
// Init LED control
|
||||
pixels.begin();
|
||||
|
||||
//Inform user what setup is used
|
||||
#ifdef DUAL_CAN
|
||||
Serial.println("Dual CAN Bus (ESP32+MCP2515) selected");
|
||||
//Inform user what Inverter is used
|
||||
#ifdef SOLAX_CAN
|
||||
inverterAllowsContactorClosing = 0; //The inverter needs to allow first on this protocol
|
||||
Serial.println("SOLAX CAN protocol selected");
|
||||
#endif
|
||||
|
||||
#ifdef MODBUS_BYD
|
||||
Serial.println("BYD Modbus RTU protocol selected");
|
||||
#endif
|
||||
#ifdef CAN_BYD
|
||||
Serial.println("BYD CAN protocol selected");
|
||||
#endif
|
||||
//Inform user what battery is used
|
||||
#ifdef BATTERY_TYPE_LEAF
|
||||
Serial.println("Nissan LEAF battery selected");
|
||||
#endif
|
||||
#endif
|
||||
#ifdef TESLA_MODEL_3_BATTERY
|
||||
Serial.println("Tesla Model 3 battery selected");
|
||||
#endif
|
||||
#ifdef RENAULT_ZOE_BATTERY
|
||||
Serial.println("Renault Zoe / Kangoo battery selected");
|
||||
#endif
|
||||
#endif
|
||||
#ifdef BMW_I3_BATTERY
|
||||
Serial.println("BMW i3 battery selected");
|
||||
#endif
|
||||
#ifdef IMIEV_ION_CZERO_BATTERY
|
||||
Serial.println("Mitsubishi i-MiEV / Citroen C-Zero / Peugeot Ion battery selected");
|
||||
#endif
|
||||
#ifdef KIA_HYUNDAI_64_BATTERY
|
||||
Serial.println("Kia Niro / Hyundai Kona 64kWh battery selected");
|
||||
#endif
|
||||
}
|
||||
|
||||
// perform main program functions
|
||||
|
@ -214,7 +253,9 @@ void loop()
|
|||
{
|
||||
previousMillis10ms = millis();
|
||||
handle_LED_state(); //Set the LED color according to state
|
||||
#ifdef CONTACTOR_CONTROL
|
||||
handle_contactors(); //Take care of startup precharge/contactor closing
|
||||
#endif
|
||||
}
|
||||
|
||||
if (millis() - previousMillisInverter >= intervalInverterTask) //every 5s
|
||||
|
@ -372,14 +413,18 @@ void handle_inverter()
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONTACTOR_CONTROL
|
||||
void handle_contactors()
|
||||
{
|
||||
//First check if we have any active errors, incase we do, turn off the battery after 5 seconds
|
||||
if(bms_status == FAULT)
|
||||
{
|
||||
//First check if we have any active errors, incase we do, turn off the battery
|
||||
if(bms_status == FAULT){
|
||||
timeSpentInFaultedMode++;
|
||||
}
|
||||
if(timeSpentInFaultedMode > 500)
|
||||
else{
|
||||
timeSpentInFaultedMode = 0;
|
||||
}
|
||||
|
||||
if(timeSpentInFaultedMode > MAX_ALLOWED_FAULT_TICKS)
|
||||
{
|
||||
contactorStatus = SHUTDOWN_REQUESTED;
|
||||
}
|
||||
|
@ -388,15 +433,17 @@ void handle_contactors()
|
|||
digitalWrite(PRECHARGE_PIN, LOW);
|
||||
digitalWrite(NEGATIVE_CONTACTOR_PIN, LOW);
|
||||
digitalWrite(POSITIVE_CONTACTOR_PIN, LOW);
|
||||
return;
|
||||
return; //A fault scenario latches the contactor control. It is not possible to recover without a powercycle (and investigation why fault occured)
|
||||
}
|
||||
|
||||
//After that, check if we are OK to start turning on the battery
|
||||
if(contactorStatus == DISCONNECTED)
|
||||
{
|
||||
digitalWrite(PRECHARGE_PIN, LOW);
|
||||
ledcWrite(POSITIVE_PWM_Ch, 0);
|
||||
ledcWrite(NEGATIVE_PWM_Ch, 0);
|
||||
#ifdef PWM_CONTACTOR_CONTROL
|
||||
ledcWrite(POSITIVE_PWM_Ch, 0);
|
||||
ledcWrite(NEGATIVE_PWM_Ch, 0);
|
||||
#endif
|
||||
|
||||
if(batteryAllowsContactorClosing && inverterAllowsContactorClosing)
|
||||
{
|
||||
|
@ -404,6 +451,7 @@ void handle_contactors()
|
|||
}
|
||||
}
|
||||
|
||||
//Incase the inverter requests contactors to open, set the state accordingly
|
||||
if(contactorStatus == COMPLETED)
|
||||
{
|
||||
if (!inverterAllowsContactorClosing) contactorStatus = DISCONNECTED;
|
||||
|
@ -422,7 +470,10 @@ void handle_contactors()
|
|||
|
||||
case NEGATIVE:
|
||||
if (currentTime - prechargeStartTime >= PRECHARGE_TIME_MS) {
|
||||
ledcWrite(NEGATIVE_PWM_Ch, 1023);
|
||||
digitalWrite(NEGATIVE_CONTACTOR_PIN, HIGH);
|
||||
#ifdef PWM_CONTACTOR_CONTROL
|
||||
ledcWrite(NEGATIVE_PWM_Ch, 1023);
|
||||
#endif
|
||||
negativeStartTime = currentTime;
|
||||
contactorStatus = POSITIVE;
|
||||
}
|
||||
|
@ -430,7 +481,10 @@ void handle_contactors()
|
|||
|
||||
case POSITIVE:
|
||||
if (currentTime - negativeStartTime >= NEGATIVE_CONTACTOR_TIME_MS) {
|
||||
ledcWrite(POSITIVE_PWM_Ch, 1023);
|
||||
digitalWrite(POSITIVE_CONTACTOR_PIN, HIGH);
|
||||
#ifdef PWM_CONTACTOR_CONTROL
|
||||
ledcWrite(POSITIVE_PWM_Ch, 1023);
|
||||
#endif
|
||||
contactorStatus = PRECHARGE_OFF;
|
||||
}
|
||||
break;
|
||||
|
@ -438,8 +492,10 @@ void handle_contactors()
|
|||
case PRECHARGE_OFF:
|
||||
if (currentTime - negativeStartTime >= POSITIVE_CONTACTOR_TIME_MS) {
|
||||
digitalWrite(PRECHARGE_PIN, LOW);
|
||||
ledcWrite(NEGATIVE_PWM_Ch, PWM_Hold_Duty);
|
||||
ledcWrite(POSITIVE_PWM_Ch, PWM_Hold_Duty);
|
||||
#ifdef PWM_CONTACTOR_CONTROL
|
||||
ledcWrite(NEGATIVE_PWM_Ch, PWM_Hold_Duty);
|
||||
ledcWrite(POSITIVE_PWM_Ch, PWM_Hold_Duty);
|
||||
#endif
|
||||
contactorStatus = COMPLETED;
|
||||
}
|
||||
break;
|
||||
|
@ -447,6 +503,7 @@ void handle_contactors()
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MODBUS_BYD
|
||||
void handle_static_data_modbus_byd() {
|
||||
|
|
|
@ -1,21 +1,6 @@
|
|||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
/* Select battery used */
|
||||
#define BATTERY_TYPE_LEAF // See NISSAN-LEAF-BATTERY.h for more LEAF battery settings
|
||||
//#define TESLA_MODEL_3_BATTERY // See TESLA-MODEL-3-BATTERY.h for more Tesla battery settings
|
||||
//#define RENAULT_ZOE_BATTERY // See RENAULT-ZOE-BATTERY.h for more Zoe battery settings
|
||||
//#define IMIEV_ION_CZERO_BATTERY // See IMIEV-CZERO-ION-BATTERY.h for more triplet battery settings
|
||||
//#define CHADEMO // See CHADEMO.h for more Chademo related settings
|
||||
|
||||
/* Select inverter communication protocol. See Wiki for which to use with your inverter: https://github.com/dalathegreat/BYD-Battery-Emulator-For-Gen24/wiki */
|
||||
//#define MODBUS_BYD //Enable this line to emulate a "BYD 11kWh HVM battery" over Modbus RTU
|
||||
//#define CAN_BYD //Enable this line to emulate a "BYD Battery-Box Premium HVS" over CAN Bus
|
||||
#define SOLAX_CAN //Enable this line to emulate a "SolaX Triple Power LFP" over CAN bus
|
||||
//#define PYLON_CAN //Enable this line to emulate a "Pylontech battery" over CAN bus
|
||||
|
||||
#define DUAL_CAN //Enable this line to activate an isolated secondary CAN Bus using MCP2515 controller (Needed for FoxESS inverts)
|
||||
|
||||
// PIN
|
||||
#define PIN_5V_EN 16
|
||||
|
||||
|
@ -23,20 +8,24 @@
|
|||
#define CAN_RX_PIN 26
|
||||
#define CAN_SE_PIN 23
|
||||
|
||||
#define MCP2515_SCK 12 // SCK input of MCP2515
|
||||
#define MCP2515_MOSI 5 // SDI input of MCP2515
|
||||
#define MCP2515_MISO 34 // SDO output of MCP2515 | Pin 34 is input only, without pullup/down resistors
|
||||
#define MCP2515_CS 18 // CS input of MCP2515
|
||||
#define MCP2515_INT 35 // INT output of MCP2515 | | Pin 35 is input only, without pullup/down resistors
|
||||
#ifdef DUAL_CAN
|
||||
#define MCP2515_SCK 12 // SCK input of MCP2515
|
||||
#define MCP2515_MOSI 5 // SDI input of MCP2515
|
||||
#define MCP2515_MISO 34 // SDO output of MCP2515 | Pin 34 is input only, without pullup/down resistors
|
||||
#define MCP2515_CS 18 // CS input of MCP2515
|
||||
#define MCP2515_INT 35 // INT output of MCP2515 | | Pin 35 is input only, without pullup/down resistors
|
||||
#endif
|
||||
|
||||
#define RS485_EN_PIN 17 // 17 /RE
|
||||
#define RS485_TX_PIN 22 // 21
|
||||
#define RS485_RX_PIN 21 // 22
|
||||
#define RS485_SE_PIN 19 // 22 /SHDN
|
||||
|
||||
#define POSITIVE_CONTACTOR_PIN 32
|
||||
#define NEGATIVE_CONTACTOR_PIN 33
|
||||
#define PRECHARGE_PIN 25
|
||||
#ifdef CONTACTOR_CONTROL
|
||||
#define POSITIVE_CONTACTOR_PIN 32
|
||||
#define NEGATIVE_CONTACTOR_PIN 33
|
||||
#define PRECHARGE_PIN 25
|
||||
#endif
|
||||
|
||||
#define SD_MISO_PIN 2
|
||||
#define SD_MOSI_PIN 15
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue