Latest fixes from Andy

This commit is contained in:
Daniel 2023-11-24 00:01:36 +02:00
parent 6fd2ca52db
commit 744db66f49
10 changed files with 97 additions and 45 deletions

View file

@ -131,7 +131,7 @@ void loop() {
#ifdef DUAL_CAN #ifdef DUAL_CAN
receive_can2(); receive_can2();
#endif #endif
#ifdef SERIAL_LINK_TRANSMITTER_INVERTER #ifdef SERIAL_LINK_RECEIVER
receive_serial(); receive_serial();
#endif #endif
@ -156,7 +156,7 @@ void loop() {
#ifdef DUAL_CAN #ifdef DUAL_CAN
send_can2(); send_can2();
#endif #endif
#ifdef SERIAL_LINK_RECEIVER_FROM_BATTERY #ifdef SERIAL_LINK_TRANSMITTER
send_serial(); send_serial();
#endif #endif
} }
@ -226,8 +226,8 @@ void init_modbus() {
pinMode(PIN_5V_EN, OUTPUT); pinMode(PIN_5V_EN, OUTPUT);
digitalWrite(PIN_5V_EN, HIGH); digitalWrite(PIN_5V_EN, HIGH);
#if defined(SERIAL_LINK_RECEIVER_FROM_BATTERY) || defined(SERIAL_LINK_TRANSMITTER_INVERTER) #if defined(SERIAL_LINK_RECEIVER) || defined(SERIAL_LINK_TRANSMITTER)
Serial2.begin(9600); // If the Modbus RTU port will be used for serial link Serial2.begin(9600, SERIAL_8N1, RS485_RX_PIN, RS485_TX_PIN); // If the Modbus RTU port will be used for serial link
#if defined(BYD_MODBUS) || defined(LUNA2000_MODBUS) #if defined(BYD_MODBUS) || defined(LUNA2000_MODBUS)
#error Modbus pins cannot be used for Serial and Modbus at the same time! #error Modbus pins cannot be used for Serial and Modbus at the same time!
#endif #endif
@ -399,20 +399,22 @@ void send_can() {
#endif #endif
} }
#ifdef SERIAL_LINK_RECEIVER_FROM_BATTERY #ifdef SERIAL_LINK_RECEIVER
void send_serial() { //---- Receives serial data and transfers to the Inverter
void receive_serial() {
static unsigned long currentMillis = millis(); static unsigned long currentMillis = millis();
if (currentMillis - previousMillis1ms >= interval1) { if (currentMillis - previousMillis1ms > interval1) { //--- try 2 second
previousMillis1ms = currentMillis; previousMillis1ms = currentMillis;
manageSerialLinkReceiver(); manageSerialLinkReceiver();
} }
} }
#endif #endif
#ifdef SERIAL_LINK_TRANSMITTER_INVERTER #ifdef SERIAL_LINK_TRANSMITTER
void receive_serial() { //---- Gets data from Battery and serial Transmits the data to the Receiver
void send_serial() {
static unsigned long currentMillis = millis(); static unsigned long currentMillis = millis();
if (currentMillis - previousMillis1ms >= interval1) { if (currentMillis - previousMillis1ms > interval1) { //--- try 2 second
previousMillis1ms = currentMillis; previousMillis1ms = currentMillis;
manageSerialLinkTransmitter(); manageSerialLinkTransmitter();
} }

View file

@ -42,7 +42,7 @@
//#define CONTACTOR_CONTROL //Enable this line to have pins 25,32,33 handle automatic precharge/contactor+/contactor- closing sequence //#define CONTACTOR_CONTROL //Enable this line to have pins 25,32,33 handle automatic 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 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) //#define DUAL_CAN //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 controller (Needed for FoxESS inverters)
//#define SERIAL_LINK_RECEIVER_FROM_BATTERY //Enable this line to send battery data over Modbus pins to another Lilygo (This LilyGo interfaces with battery) //#define SERIAL_LINK_RECEIVER //Enable this line to receive battery data over RS485 pins from another Lilygo (This LilyGo interfaces with inverter)
//#define SERIAL_LINK_TRANSMITTER_INVERTER //Enable this line to receive battery data over Modbus pins from another Lilygo (This LilyGo interfaces with inverter) //#define SERIAL_LINK_TRANSMITTER //Enable this line to send battery data over RS485 pins to another Lilygo (This LilyGo interfaces with battery)
#endif #endif

View file

@ -33,7 +33,7 @@
#include "TEST-FAKE-BATTERY.h" //See this file for more Fake battery settings #include "TEST-FAKE-BATTERY.h" //See this file for more Fake battery settings
#endif #endif
#ifdef SERIAL_LINK_RECEIVER_FROM_BATTERY #ifdef SERIAL_LINK_RECEIVER
#include "SERIAL-LINK-RECEIVER-FROM-BATTERY.h" #include "SERIAL-LINK-RECEIVER-FROM-BATTERY.h"
#endif #endif

View file

@ -50,6 +50,7 @@ void updateData() {
void manageSerialLinkReceiver() { void manageSerialLinkReceiver() {
static bool lasterror = false; static bool lasterror = false;
static unsigned long last_minutesLost = 0;
static unsigned long lastGood; static unsigned long lastGood;
static uint16_t lastGoodMaxCharge; static uint16_t lastGoodMaxCharge;
static uint16_t lastGoodMaxDischarge; static uint16_t lastGoodMaxDischarge;
@ -67,10 +68,8 @@ void manageSerialLinkReceiver() {
} }
dataLinkReceive.run(); dataLinkReceive.run();
bool readError = dataLinkReceive.checkReadError(true); // check for error & clear error flag bool readError = dataLinkReceive.checkReadError(true); // check for error & clear error flag
LEDcolor = GREEN;
if (readError) { if (readError) {
LEDcolor = RED;
bms_status = 4; //FAULT
Serial.print(currentTime); Serial.print(currentTime);
Serial.println(" - ERROR: Serial Data Link - Read Error"); Serial.println(" - ERROR: Serial Data Link - Read Error");
lasterror = true; lasterror = true;
@ -80,13 +79,13 @@ void manageSerialLinkReceiver() {
Serial.print(currentTime); Serial.print(currentTime);
Serial.println(" - RECOVERY: Serial Data Link - Read GOOD"); Serial.println(" - RECOVERY: Serial Data Link - Read GOOD");
} }
lastGood = currentTime;
} }
if (dataLinkReceive.checkNewData(true)) // true = clear Flag if (dataLinkReceive.checkNewData(true)) // true = clear Flag
{ {
__getData(); __getData();
lastGoodMaxCharge = max_target_charge_power; lastGoodMaxCharge = max_target_charge_power;
lastGoodMaxDischarge = max_target_discharge_power; lastGoodMaxDischarge = max_target_discharge_power;
lastGood = currentTime;
} }
unsigned long minutesLost = (currentTime - lastGood) / 60000UL; unsigned long minutesLost = (currentTime - lastGood) / 60000UL;
@ -99,6 +98,20 @@ void manageSerialLinkReceiver() {
} else { } else {
max_target_charge_power = 0; max_target_charge_power = 0;
max_target_discharge_power = 0; max_target_discharge_power = 0;
bms_status = 4; //Fault state
LEDcolor = RED;
//----- Throw Error
}
// report Lost data & Max charge / Discharge reductions
if (minutesLost != last_minutesLost) {
last_minutesLost = minutesLost;
Serial.print(currentTime);
Serial.print(" - Minutes without data : ");
Serial.print(minutesLost);
Serial.print(", max Charge = ");
Serial.print(max_target_charge_power);
Serial.print(", max Discharge = ");
Serial.println(max_target_discharge_power);
} }
} }

View file

@ -30,8 +30,8 @@ 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 bool 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
void manageSerialLinkReceiver(); void manageSerialLinkReceiver();

View file

@ -29,7 +29,7 @@
#include "SOLAX-CAN.h" #include "SOLAX-CAN.h"
#endif #endif
#ifdef SERIAL_LINK_TRANSMITTER_INVERTER #ifdef SERIAL_LINK_TRANSMITTER
#include "SERIAL-LINK-TRANSMITTER-INVERTER.h" #include "SERIAL-LINK-TRANSMITTER-INVERTER.h"
#endif #endif

View file

@ -32,6 +32,10 @@ void manageSerialLinkTransmitter() {
static bool initLink = false; static bool initLink = false;
static unsigned long updateTime = 0; static unsigned long updateTime = 0;
static bool lasterror = false; static bool lasterror = false;
static unsigned long lastNoError = 0;
static unsigned long transmitGoodSince = 0;
unsigned long currentTime = millis();
dataLinkTransmit.run(); dataLinkTransmit.run();
@ -43,28 +47,56 @@ void manageSerialLinkTransmitter() {
} }
#endif #endif
if (millis() - updateTime > 100) { if (currentTime - updateTime > 100) {
updateTime = millis(); updateTime = currentTime;
if (!initLink) { if (!initLink) {
initLink = true; initLink = true;
// sends variables every 5000mS even if no change // sends variables every 5000mS even if no change
dataLinkTransmit.setUpdateInterval(5000); dataLinkTransmit.setUpdateInterval(5000);
} }
bool sendError = dataLinkTransmit.checkTransmissionError(true); bool sendError = dataLinkTransmit.checkTransmissionError(true);
LEDcolor = GREEN;
if (sendError) { if (sendError) {
LEDcolor = RED; Serial.print(currentTime);
Serial.print(millis());
Serial.println(" - ERROR: Serial Data Link - SEND Error"); Serial.println(" - ERROR: Serial Data Link - SEND Error");
lasterror = true; lasterror = true;
transmitGoodSince = currentTime;
} else { } else {
if (lasterror) { if (lasterror) {
lasterror = false; lasterror = false;
Serial.print(millis()); Serial.print(currentTime);
Serial.println(" - RECOVERY: Serial Data Link - Send GOOD"); Serial.println(" - RECOVERY: Serial Data Link - Send GOOD");
} }
lastNoError = currentTime;
} }
//--- reporting every 60 seconds that transmission is good
if (currentTime - transmitGoodSince > 60000) {
transmitGoodSince = currentTime;
Serial.print(currentTime);
Serial.println(" - Transmit Good");
}
//--- report that Errors been ocurring for > 60 seconds
if (currentTime - lastNoError > 60000) // 60 seconds
{
Serial.print(currentTime);
Serial.println(" - Transmit Failed : 60 seconds");
bms_status = 4; //FAULT
LEDcolor = RED;
// throw error
}
/*
// lastMessageReceived from CAN bus (Battery)
if (currentTime - lastMessageReceived > (5 * 60000) ) // 5 minutes
{
Serial.print(millis());
Serial.println(" - Data Stale : 5 minutes");
// throw error
// stop transmitting until fresh
}
*/
dataLinkTransmit.updateData(0, SOC); dataLinkTransmit.updateData(0, SOC);
dataLinkTransmit.updateData(1, StateOfHealth); dataLinkTransmit.updateData(1, StateOfHealth);
dataLinkTransmit.updateData(2, battery_voltage); dataLinkTransmit.updateData(2, battery_voltage);

View file

@ -24,8 +24,8 @@ 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 bool 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
void manageSerialLinkTransmitter(); void manageSerialLinkTransmitter();

View file

@ -49,9 +49,12 @@ union Convert
}; };
}convert; }convert;
/*
#define SET_PA6() (GPIOA->BSRR = GPIO_BSRR_BS6)
#define CLEAR_PA6() (GPIOA->BSRR = GPIO_BSRR_BR6)
// Macro to toggle PA6
#define TOGGLE_PA6() (GPIOA->ODR ^= GPIO_ODR_ODR6)
*/
// Constructor // Constructor
SerialDataLink::SerialDataLink(Stream &serial, uint8_t transmitID, uint8_t receiveID, uint8_t maxIndexTX, uint8_t maxIndexRX, bool enableRetransmit) SerialDataLink::SerialDataLink(Stream &serial, uint8_t transmitID, uint8_t receiveID, uint8_t maxIndexTX, uint8_t maxIndexRX, bool enableRetransmit)
@ -167,10 +170,9 @@ void SerialDataLink::run()
} }
else else
{ {
constructPacket(); // Construct a new packet if not currently transmitting constructPacket(); // Construct a new packet if not currently transmitting
if (muteAcknowledgement) if (muteAcknowledgement && (needToACK || needToNACK))
{ {
needToACK = false; needToACK = false;
needToNACK = false; needToNACK = false;
@ -269,13 +271,11 @@ void SerialDataLink::constructPacket()
{ {
lastTransmissionTime = millis(); lastTransmissionTime = millis();
txBufferIndex = 0; // Reset the TX buffer index txBufferIndex = 0; // Reset the TX buffer index
addToTxBuffer(headerChar); addToTxBuffer(headerChar);
addToTxBuffer(transmitID); addToTxBuffer(transmitID);
addToTxBuffer(0); // EOT position - place holder addToTxBuffer(0); // EOT position - place holder
unsigned long currentTime = millis(); unsigned long currentTime = millis();
int count = txBufferIndex; int count = txBufferIndex;
for (uint8_t i = 0; i < maxIndexTX; i++) for (uint8_t i = 0; i < maxIndexTX; i++)
{ {
if (dataUpdated[i] || (currentTime - lastSent[i] >= updateInterval)) if (dataUpdated[i] || (currentTime - lastSent[i] >= updateInterval))
@ -352,6 +352,7 @@ bool SerialDataLink::ackReceived()
if (nextByte == headerChar) if (nextByte == headerChar)
{ {
requestToSend = true; requestToSend = true;
transmissionError = true;
return false; return false;
} }
@ -372,12 +373,11 @@ bool SerialDataLink::ackReceived()
requestToSend = true; requestToSend = true;
case NACK_CODE: case NACK_CODE:
transmissionError = true; transmissionError = true;
return false; return true;
default: default:
break; break;
} }
} }
return false; // No ACK, NACK, or new packet received return false; // No ACK, NACK, or new packet received
@ -386,7 +386,9 @@ bool SerialDataLink::ackReceived()
bool SerialDataLink::ackTimeout() bool SerialDataLink::ackTimeout()
{ {
// Check if the current time has exceeded the last transmission time by the ACK timeout period // Check if the current time has exceeded the last transmission time by the ACK timeout period
if (millis() - lastTransmissionTime > ACK_TIMEOUT) {
if (millis() - lastTransmissionTime > ACK_TIMEOUT)
{
return true; // Timeout occurred return true; // Timeout occurred
} }
return false; // No timeout return false; // No timeout
@ -397,9 +399,10 @@ bool SerialDataLink::ackTimeout()
void SerialDataLink::read() void SerialDataLink::read()
{ {
if (maxIndexRX < 1) return; if (maxIndexRX < 1) return;
if (serial.available()) int count = 0;
while (serial.available() && count < 10)
{ {
//Serial.print("."); count++;
if (millis() - lastHeaderTime > PACKET_TIMEOUT && rxBufferIndex > 0) if (millis() - lastHeaderTime > PACKET_TIMEOUT && rxBufferIndex > 0)
{ {
// Timeout occurred, reset buffer and pointer // Timeout occurred, reset buffer and pointer

View file

@ -50,6 +50,8 @@
#include <Arduino.h> #include <Arduino.h>
class SerialDataLink { class SerialDataLink {
public: public:
// Constructor // Constructor
@ -128,12 +130,12 @@ private:
bool dataUpdated[dataArraySizeTX]; bool dataUpdated[dataArraySizeTX];
unsigned long lastSent[dataArraySizeTX]; unsigned long lastSent[dataArraySizeTX];
unsigned long updateInterval = 500; unsigned long updateInterval = 1000;
unsigned long ACK_TIMEOUT = 100; unsigned long ACK_TIMEOUT = 200;
unsigned long PACKET_TIMEOUT = 100; // Timeout in milliseconds unsigned long PACKET_TIMEOUT = 200; // Timeout in milliseconds
unsigned long lastStateChangeTime = 0; unsigned long lastStateChangeTime = 0;
unsigned long stateChangeTimeout = 200; unsigned long stateChangeTimeout = 300;
// Special characters for packet framing // Special characters for packet framing
char headerChar = '<'; char headerChar = '<';