Refactor for merge to main

This commit is contained in:
Daniel 2023-08-27 12:33:12 +03:00
parent 961e33033e
commit f9ca90b20e
3 changed files with 109 additions and 69 deletions

View file

@ -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) void CAN_WriteFrame(CAN_frame_t* tx_frame)
{ {
#ifdef DUAL_CAN #ifdef DUAL_CAN
CANMessage MCP2515Frame; //Struct with ACAN2515 library format, needed to use the MCP2515 library CANMessage MCP2515Frame; //Struct with ACAN2515 library format, needed to use the MCP2515 library
MCP2515Frame.id = tx_frame->MsgID; MCP2515Frame.id = tx_frame->MsgID;
MCP2515Frame.ext = tx_frame->FIR.B.FF; MCP2515Frame.ext = tx_frame->FIR.B.FF;
MCP2515Frame.len = tx_frame->FIR.B.DLC; MCP2515Frame.len = tx_frame->FIR.B.DLC;
for (uint8_t i=0 ; i<MCP2515Frame.len ; i++) { for (uint8_t i=0 ; i<MCP2515Frame.len ; i++) {
MCP2515Frame.data[i] = tx_frame->data.u8[i]; MCP2515Frame.data[i] = tx_frame->data.u8[i];
} }
can.tryToSend(MCP2515Frame); can.tryToSend(MCP2515Frame);
//Serial.println("Solax CAN Frame sent in Bus 2"); //Serial.println("Solax CAN Frame sent in Bus 2");
#else #else
ESP32Can.CANWriteFrame(tx_frame); ESP32Can.CANWriteFrame(tx_frame);
//Serial.println("Solax CAN Frame sent in Bus 1"); //Serial.println("Solax CAN Frame sent in Bus 1");
#endif #endif
} }
@ -92,7 +92,6 @@ void update_values_can_solax()
} }
//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_volt_solax_can; //Todo, scaling OK? SOLAX_1872.data.u8[0] = (uint8_t) max_volt_solax_can; //Todo, scaling OK?
SOLAX_1872.data.u8[1] = (max_volt_solax_can >> 8); 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) void receive_can_solax(CAN_frame_t rx_frame)
{ {
if (rx_frame.MsgID == 0x1871) { if (rx_frame.MsgID == 0x1871) {

View file

@ -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 */ /* 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 */ /* Only change battery specific settings and limits in their respective .h files */
#include <Arduino.h> #include <Arduino.h>
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "config.h" #include "config.h"
@ -96,6 +117,7 @@ enum State {
}; };
State contactorStatus = DISCONNECTED; State contactorStatus = DISCONNECTED;
#define MAX_ALLOWED_FAULT_TICKS 500
#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
@ -108,7 +130,7 @@ unsigned long prechargeStartTime = 0;
unsigned long negativeStartTime = 0; unsigned long negativeStartTime = 0;
unsigned long timeSpentInFaultedMode = 0; unsigned long timeSpentInFaultedMode = 0;
uint8_t batteryAllowsContactorClosing = 0; uint8_t batteryAllowsContactorClosing = 0;
uint8_t inverterAllowsContactorClosing = 0; uint8_t inverterAllowsContactorClosing = 1;
// Setup() - initialization happens here // Setup() - initialization happens here
void setup() void setup()
@ -132,6 +154,7 @@ void setup()
Serial.println(CAN_cfg.speed); Serial.println(CAN_cfg.speed);
#ifdef DUAL_CAN #ifdef DUAL_CAN
Serial.println("Dual CAN Bus (ESP32+MCP2515) selected");
gBuffer.initWithSize(25); gBuffer.initWithSize(25);
SPI.begin(MCP2515_SCK, MCP2515_MISO, MCP2515_MOSI); SPI.begin(MCP2515_SCK, MCP2515_MISO, MCP2515_MOSI);
Serial.println ("Configure ACAN2515") ; Serial.println ("Configure ACAN2515") ;
@ -141,19 +164,22 @@ void setup()
#endif #endif
//Init contactor pins //Init contactor pins
#ifdef CONTACTOR_CONTROL
pinMode(POSITIVE_CONTACTOR_PIN, OUTPUT);
ledcSetup(POSITIVE_PWM_Ch, PWM_Freq, PWM_Res); // Setup PWM Channel Frequency and Resolution digitalWrite(POSITIVE_CONTACTOR_PIN, LOW);
ledcSetup(NEGATIVE_PWM_Ch, PWM_Freq, PWM_Res); // Setup PWM Channel Frequency and Resolution pinMode(NEGATIVE_CONTACTOR_PIN, OUTPUT);
digitalWrite(NEGATIVE_CONTACTOR_PIN, LOW);
ledcAttachPin(POSITIVE_CONTACTOR_PIN, POSITIVE_PWM_Ch); // Attach Positive Contactor Pin to Hardware PWM Channel #ifdef PWM_CONTACTOR_CONTROL
ledcAttachPin(NEGATIVE_CONTACTOR_PIN, NEGATIVE_PWM_Ch); // Attach Positive Contactor Pin to Hardware PWM Channel 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
ledcWrite(POSITIVE_PWM_Ch, 0); // Set Positive PWM to 0% ledcAttachPin(POSITIVE_CONTACTOR_PIN, POSITIVE_PWM_Ch); // Attach Positive Contactor Pin to Hardware PWM Channel
ledcWrite(NEGATIVE_PWM_Ch, 0); // Set Negative PWM to 0% 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); pinMode(PRECHARGE_PIN, OUTPUT);
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(PRECHARGE_PIN, LOW);
#endif
//Set up Modbus RTU Server //Set up Modbus RTU Server
@ -182,11 +208,18 @@ void setup()
// Init LED control // Init LED control
pixels.begin(); pixels.begin();
//Inform user what setup is used //Inform user what Inverter is used
#ifdef DUAL_CAN #ifdef SOLAX_CAN
Serial.println("Dual CAN Bus (ESP32+MCP2515) selected"); inverterAllowsContactorClosing = 0; //The inverter needs to allow first on this protocol
Serial.println("SOLAX CAN protocol selected");
#endif #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 #ifdef BATTERY_TYPE_LEAF
Serial.println("Nissan LEAF battery selected"); Serial.println("Nissan LEAF battery selected");
#endif #endif
@ -196,9 +229,15 @@ void setup()
#ifdef RENAULT_ZOE_BATTERY #ifdef RENAULT_ZOE_BATTERY
Serial.println("Renault Zoe / Kangoo battery selected"); 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 #ifdef IMIEV_ION_CZERO_BATTERY
Serial.println("Mitsubishi i-MiEV / Citroen C-Zero / Peugeot Ion battery selected"); Serial.println("Mitsubishi i-MiEV / Citroen C-Zero / Peugeot Ion battery selected");
#endif #endif
#ifdef KIA_HYUNDAI_64_BATTERY
Serial.println("Kia Niro / Hyundai Kona 64kWh battery selected");
#endif
} }
// perform main program functions // perform main program functions
@ -214,7 +253,9 @@ void loop()
{ {
previousMillis10ms = millis(); previousMillis10ms = millis();
handle_LED_state(); //Set the LED color according to state handle_LED_state(); //Set the LED color according to state
#ifdef CONTACTOR_CONTROL
handle_contactors(); //Take care of startup precharge/contactor closing handle_contactors(); //Take care of startup precharge/contactor closing
#endif
} }
if (millis() - previousMillisInverter >= intervalInverterTask) //every 5s if (millis() - previousMillisInverter >= intervalInverterTask) //every 5s
@ -372,14 +413,18 @@ void handle_inverter()
#endif #endif
} }
#ifdef CONTACTOR_CONTROL
void handle_contactors() void handle_contactors()
{ {
//First check if we have any active errors, incase we do, turn off the battery after 5 seconds //First check if we have any active errors, incase we do, turn off the battery
if(bms_status == FAULT) if(bms_status == FAULT){
{
timeSpentInFaultedMode++; timeSpentInFaultedMode++;
} }
if(timeSpentInFaultedMode > 500) else{
timeSpentInFaultedMode = 0;
}
if(timeSpentInFaultedMode > MAX_ALLOWED_FAULT_TICKS)
{ {
contactorStatus = SHUTDOWN_REQUESTED; contactorStatus = SHUTDOWN_REQUESTED;
} }
@ -388,15 +433,17 @@ void handle_contactors()
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(PRECHARGE_PIN, LOW);
digitalWrite(NEGATIVE_CONTACTOR_PIN, LOW); digitalWrite(NEGATIVE_CONTACTOR_PIN, LOW);
digitalWrite(POSITIVE_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 //After that, check if we are OK to start turning on the battery
if(contactorStatus == DISCONNECTED) if(contactorStatus == DISCONNECTED)
{ {
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(PRECHARGE_PIN, LOW);
ledcWrite(POSITIVE_PWM_Ch, 0); #ifdef PWM_CONTACTOR_CONTROL
ledcWrite(NEGATIVE_PWM_Ch, 0); ledcWrite(POSITIVE_PWM_Ch, 0);
ledcWrite(NEGATIVE_PWM_Ch, 0);
#endif
if(batteryAllowsContactorClosing && inverterAllowsContactorClosing) 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(contactorStatus == COMPLETED)
{ {
if (!inverterAllowsContactorClosing) contactorStatus = DISCONNECTED; if (!inverterAllowsContactorClosing) contactorStatus = DISCONNECTED;
@ -422,7 +470,10 @@ void handle_contactors()
case NEGATIVE: case NEGATIVE:
if (currentTime - prechargeStartTime >= PRECHARGE_TIME_MS) { 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; negativeStartTime = currentTime;
contactorStatus = POSITIVE; contactorStatus = POSITIVE;
} }
@ -430,7 +481,10 @@ void handle_contactors()
case POSITIVE: case POSITIVE:
if (currentTime - negativeStartTime >= NEGATIVE_CONTACTOR_TIME_MS) { 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; contactorStatus = PRECHARGE_OFF;
} }
break; break;
@ -438,8 +492,10 @@ void handle_contactors()
case PRECHARGE_OFF: case PRECHARGE_OFF:
if (currentTime - negativeStartTime >= POSITIVE_CONTACTOR_TIME_MS) { if (currentTime - negativeStartTime >= POSITIVE_CONTACTOR_TIME_MS) {
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(PRECHARGE_PIN, LOW);
ledcWrite(NEGATIVE_PWM_Ch, PWM_Hold_Duty); #ifdef PWM_CONTACTOR_CONTROL
ledcWrite(POSITIVE_PWM_Ch, PWM_Hold_Duty); ledcWrite(NEGATIVE_PWM_Ch, PWM_Hold_Duty);
ledcWrite(POSITIVE_PWM_Ch, PWM_Hold_Duty);
#endif
contactorStatus = COMPLETED; contactorStatus = COMPLETED;
} }
break; break;
@ -447,6 +503,7 @@ void handle_contactors()
break; break;
} }
} }
#endif
#ifdef MODBUS_BYD #ifdef MODBUS_BYD
void handle_static_data_modbus_byd() { void handle_static_data_modbus_byd() {

View file

@ -1,21 +1,6 @@
#ifndef __CONFIG_H__ #ifndef __CONFIG_H__
#define __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 // PIN
#define PIN_5V_EN 16 #define PIN_5V_EN 16
@ -23,20 +8,24 @@
#define CAN_RX_PIN 26 #define CAN_RX_PIN 26
#define CAN_SE_PIN 23 #define CAN_SE_PIN 23
#define MCP2515_SCK 12 // SCK input of MCP2515 #ifdef DUAL_CAN
#define MCP2515_MOSI 5 // SDI input of MCP2515 #define MCP2515_SCK 12 // SCK input of MCP2515
#define MCP2515_MISO 34 // SDO output of MCP2515 | Pin 34 is input only, without pullup/down resistors #define MCP2515_MOSI 5 // SDI input of MCP2515
#define MCP2515_CS 18 // CS input of MCP2515 #define MCP2515_MISO 34 // SDO output of MCP2515 | Pin 34 is input only, without pullup/down resistors
#define MCP2515_INT 35 // INT output of MCP2515 | | Pin 35 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_EN_PIN 17 // 17 /RE
#define RS485_TX_PIN 22 // 21 #define RS485_TX_PIN 22 // 21
#define RS485_RX_PIN 21 // 22 #define RS485_RX_PIN 21 // 22
#define RS485_SE_PIN 19 // 22 /SHDN #define RS485_SE_PIN 19 // 22 /SHDN
#define POSITIVE_CONTACTOR_PIN 32 #ifdef CONTACTOR_CONTROL
#define NEGATIVE_CONTACTOR_PIN 33 #define POSITIVE_CONTACTOR_PIN 32
#define PRECHARGE_PIN 25 #define NEGATIVE_CONTACTOR_PIN 33
#define PRECHARGE_PIN 25
#endif
#define SD_MISO_PIN 2 #define SD_MISO_PIN 2
#define SD_MOSI_PIN 15 #define SD_MOSI_PIN 15