Change Serial logging to flexible logging (#690)

* Add Logging class
Add Logging class which inherits from Print class, to be able to route logging to USB Serial or to memory for display in the webpage. Adds a log webpage only visible when DEBUG_VIA_WEB is defined.
This commit is contained in:
mvgalen 2024-12-22 22:48:35 +01:00 committed by GitHub
parent b2aa3dc75b
commit c713d0a94e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 1020 additions and 798 deletions

View file

@ -20,6 +20,7 @@
#include "src/datalayer/datalayer.h"
#include "src/devboard/utils/events.h"
#include "src/devboard/utils/led_handler.h"
#include "src/devboard/utils/logging.h"
#include "src/devboard/utils/value_mapping.h"
#include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime.h"
#include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime_formatter.h"
@ -84,6 +85,8 @@ MyTimer check_pause_2s(INTERVAL_2_S);
TaskHandle_t main_loop_task;
TaskHandle_t connectivity_loop_task;
Logging logging;
// Initialization
void setup() {
init_serial();

View file

@ -66,6 +66,11 @@
/* Other options */
//#define DEBUG_VIA_USB //Enable this line to have the USB port output serial diagnostic data while program runs (WARNING, raises CPU load, do not use for production)
//#define DEBUG_VIA_WEB //Enable this line to log diagnostic data while program runs, which can be viewed via webpage (WARNING, slightly raises CPU load, do not use for production)
#if defined(DEBUG_VIA_USB) || defined(DEBUG_VIA_WEB)
#define DEBUG_LOG
#endif
//#define DEBUG_CAN_DATA //Enable this line to print incoming/outgoing CAN & CAN-FD messages to USB serial (WARNING, raises CPU load, do not use for production)
//#define INTERLOCK_REQUIRED //Nissan LEAF specific setting, if enabled requires both high voltage conenctors to be seated before starting
//#define CAN_ADDON //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 chip (Needed for some inverters / double battery)

View file

@ -670,8 +670,8 @@ void receive_can_battery(CAN_frame rx_frame) {
if ((rx_frame.data.u8[6] << 8 | rx_frame.data.u8[7]) == 10000 ||
(rx_frame.data.u8[8] << 8 | rx_frame.data.u8[9]) == 10000) { //Qualifier Invalid Mode - Request Reboot
#ifdef DEBUG_VIA_USB
Serial.println("Cell MinMax Qualifier Invalid - Requesting BMS Reset");
#ifdef DEBUG_LOG
logging.println("Cell MinMax Qualifier Invalid - Requesting BMS Reset");
#endif
//set_event(EVENT_BATTERY_VALUE_UNAVAILABLE, (millis())); //Eventually need new Info level event type
transmit_can(&BMWiX_6F4_REQUEST_HARD_RESET, can_config.battery);

View file

@ -197,13 +197,13 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) {
x102_chg_session.ChargingCurrentRequest = newChargingCurrentRequest;
x102_chg_session.TargetBatteryVoltage = newTargetBatteryVoltage;
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
//Note on p131
uint8_t chargingrate = 0;
if (x100_chg_lim.ConstantOfChargingRateIndication > 0) {
chargingrate = x102_chg_session.StateOfCharge / x100_chg_lim.ConstantOfChargingRateIndication * 100;
Serial.print("Charge Rate (kW): ");
Serial.println(chargingrate);
logging.print("Charge Rate (kW): ");
logging.println(chargingrate);
}
#endif
@ -217,40 +217,40 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) {
*/
if ((CHADEMO_Status == CHADEMO_INIT && vehicle_permission) ||
(x102_chg_session.s.status.StatusVehicleChargingEnabled && !vehicle_permission)) {
#ifdef DEBUG_VIA_USB
Serial.println("Inconsistent charge/discharge state.");
#ifdef DEBUG_LOG
logging.println("Inconsistent charge/discharge state.");
#endif
CHADEMO_Status = CHADEMO_FAULT;
return;
}
if (x102_chg_session.f.fault.FaultBatteryOverVoltage) {
#ifdef DEBUG_VIA_USB
Serial.println("Vehicle indicates fault, battery over voltage.");
#ifdef DEBUG_LOG
logging.println("Vehicle indicates fault, battery over voltage.");
#endif
CHADEMO_Status = CHADEMO_STOP;
return;
}
if (x102_chg_session.f.fault.FaultBatteryUnderVoltage) {
#ifdef DEBUG_VIA_USB
Serial.println("Vehicle indicates fault, battery under voltage.");
#ifdef DEBUG_LOG
logging.println("Vehicle indicates fault, battery under voltage.");
#endif
CHADEMO_Status = CHADEMO_STOP;
return;
}
if (x102_chg_session.f.fault.FaultBatteryCurrentDeviation) {
#ifdef DEBUG_VIA_USB
Serial.println("Vehicle indicates fault, battery current deviation. Possible EVSE issue?");
#ifdef DEBUG_LOG
logging.println("Vehicle indicates fault, battery current deviation. Possible EVSE issue?");
#endif
CHADEMO_Status = CHADEMO_STOP;
return;
}
if (x102_chg_session.f.fault.FaultBatteryVoltageDeviation) {
#ifdef DEBUG_VIA_USB
Serial.println("Vehicle indicates fault, battery voltage deviation. Possible EVSE issue?");
#ifdef DEBUG_LOG
logging.println("Vehicle indicates fault, battery voltage deviation. Possible EVSE issue?");
#endif
CHADEMO_Status = CHADEMO_STOP;
return;
@ -264,8 +264,8 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) {
//FIXME condition nesting or more stanzas needed here for clear determination of cessation reason
if (CHADEMO_Status == CHADEMO_POWERFLOW && EVSE_mode == CHADEMO_CHARGE && !vehicle_permission) {
#ifdef DEBUG_VIA_USB
Serial.println("State of charge ceiling reached or charging interrupted, stop charging");
#ifdef DEBUG_LOG
logging.println("State of charge ceiling reached or charging interrupted, stop charging");
#endif
CHADEMO_Status = CHADEMO_STOP;
return;
@ -273,8 +273,8 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) {
if (vehicle_permission && CHADEMO_Status == CHADEMO_NEGOTIATE) {
CHADEMO_Status = CHADEMO_EV_ALLOWED;
#ifdef DEBUG_VIA_USB
Serial.println("STATE shift to CHADEMO_EV_ALLOWED in process_vehicle_charging_session()");
#ifdef DEBUG_LOG
logging.println("STATE shift to CHADEMO_EV_ALLOWED in process_vehicle_charging_session()");
#endif
return;
}
@ -284,22 +284,22 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) {
// consider relocating
if (vehicle_permission && CHADEMO_Status == CHADEMO_EVSE_PREPARE && priorTargetBatteryVoltage == 0 &&
newTargetBatteryVoltage > 0 && x102_chg_session.s.status.StatusVehicleChargingEnabled) {
#ifdef DEBUG_VIA_USB
Serial.println("STATE SHIFT to EVSE_START reached in process_vehicle_charging_session()");
#ifdef DEBUG_LOG
logging.println("STATE SHIFT to EVSE_START reached in process_vehicle_charging_session()");
#endif
CHADEMO_Status = CHADEMO_EVSE_START;
return;
}
if (vehicle_permission && evse_permission && CHADEMO_Status == CHADEMO_POWERFLOW) {
#ifdef DEBUG_VIA_USB
Serial.println("updating vehicle request in process_vehicle_charging_session()");
#ifdef DEBUG_LOG
logging.println("updating vehicle request in process_vehicle_charging_session()");
#endif
return;
}
#ifdef DEBUG_VIA_USB
Serial.println("UNHANDLED STATE IN process_vehicle_charging_session()");
#ifdef DEBUG_LOG
logging.println("UNHANDLED STATE IN process_vehicle_charging_session()");
#endif
return;
}
@ -312,20 +312,20 @@ inline void process_vehicle_charging_limits(CAN_frame rx_frame) {
x200_discharge_limits.MinimumBatteryDischargeLevel = rx_frame.data.u8[6];
x200_discharge_limits.MaxRemainingCapacityForCharging = rx_frame.data.u8[7];
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
/* unsigned long currentMillis = millis();
if (currentMillis - previousMillis5000 >= INTERVAL_5_S) {
previousMillis5000 = currentMillis;
Serial.println("x200 Max remaining capacity for charging/discharging:");
logging.println("x200 Max remaining capacity for charging/discharging:");
// initially this is set to 0, which is represented as 0xFF
Serial.println(0xFF - x200_discharge_limits.MaxRemainingCapacityForCharging);
logging.println(0xFF - x200_discharge_limits.MaxRemainingCapacityForCharging);
}
*/
#endif
if (get_measured_voltage() <= x200_discharge_limits.MinimumDischargeVoltage && CHADEMO_Status > CHADEMO_NEGOTIATE) {
#ifdef DEBUG_VIA_USB
Serial.println("x200 minimum discharge voltage met or exceeded, stopping.");
#ifdef DEBUG_LOG
logging.println("x200 minimum discharge voltage met or exceeded, stopping.");
#endif
CHADEMO_Status = CHADEMO_STOP;
}
@ -341,13 +341,13 @@ inline void process_vehicle_discharge_estimate(CAN_frame rx_frame) {
x201_discharge_estimate.ApproxDischargeCompletionTime = ((rx_frame.data.u8[2] << 8) | rx_frame.data.u8[1]);
x201_discharge_estimate.AvailableVehicleEnergy = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[3]);
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
if (currentMillis - previousMillis5000 >= INTERVAL_5_S) {
previousMillis5000 = currentMillis;
Serial.print("x201 availabile vehicle energy, completion time: ");
Serial.println(x201_discharge_estimate.AvailableVehicleEnergy);
Serial.print("x201 approx vehicle completion time: ");
Serial.println(x201_discharge_estimate.ApproxDischargeCompletionTime);
logging.print("x201 availabile vehicle energy, completion time: ");
logging.println(x201_discharge_estimate.AvailableVehicleEnergy);
logging.print("x201 approx vehicle completion time: ");
logging.println(x201_discharge_estimate.ApproxDischargeCompletionTime);
}
#endif
}
@ -369,17 +369,17 @@ inline void process_vehicle_vendor_ID(CAN_frame rx_frame) {
void receive_can_battery(CAN_frame rx_frame) {
#ifdef CH_CAN_DEBUG
Serial.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
Serial.print(" ");
Serial.print(rx_frame.ID, HEX);
Serial.print(" ");
Serial.print(rx_frame.DLC);
Serial.print(" ");
logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
logging.print(" ");
logging.print(rx_frame.ID, HEX);
logging.print(" ");
logging.print(rx_frame.DLC);
logging.print(" ");
for (int i = 0; i < rx_frame.DLC; ++i) {
Serial.print(rx_frame.data.u8[i], HEX);
Serial.print(" ");
logging.print(rx_frame.data.u8[i], HEX);
logging.print(" ");
}
Serial.println("");
logging.println("");
#endif
// CHADEMO coexists with a CAN-based shunt. Only process CHADEMO-specific IDs
@ -713,9 +713,9 @@ void send_can_battery() {
// TODO need an update_evse_dynamic_control(..) function above before we send 118
// 110.0.0
if (x102_chg_session.ControlProtocolNumberEV >= 0x03) { //Only send the following on Chademo 2.0 vehicles?
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
//FIXME REMOVE
Serial.println("REMOVE: proto 2.0");
logging.println("REMOVE: proto 2.0");
#endif
transmit_can(&CHADEMO_118, can_config.battery);
}
@ -753,15 +753,15 @@ void handle_chademo_sequence() {
/* ------------------- State override conditions checks ------------------- */
/* ------------------------------------------------------------------------------ */
if (CHADEMO_Status >= CHADEMO_EV_ALLOWED && x102_chg_session.s.status.StatusVehicleShifterPosition) {
#ifdef DEBUG_VIA_USB
Serial.println("Vehicle is not parked, abort.");
#ifdef DEBUG_LOG
logging.println("Vehicle is not parked, abort.");
#endif
CHADEMO_Status = CHADEMO_STOP;
}
if (CHADEMO_Status >= CHADEMO_EV_ALLOWED && !vehicle_permission) {
#ifdef DEBUG_VIA_USB
Serial.println("Vehicle charge/discharge permission ended, stop.");
#ifdef DEBUG_LOG
logging.println("Vehicle charge/discharge permission ended, stop.");
#endif
CHADEMO_Status = CHADEMO_STOP;
}
@ -775,24 +775,24 @@ void handle_chademo_sequence() {
plug_inserted = digitalRead(CHADEMO_PIN_7);
if (!plug_inserted) {
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
// Commented unless needed for debug
// Serial.println("CHADEMO plug is not inserted.");
// logging.println("CHADEMO plug is not inserted.");
#endif
return;
}
CHADEMO_Status = CHADEMO_CONNECTED;
#ifdef DEBUG_VIA_USB
Serial.println("CHADEMO plug is inserted. Provide EVSE power to vehicle to trigger initialization.");
#ifdef DEBUG_LOG
logging.println("CHADEMO plug is inserted. Provide EVSE power to vehicle to trigger initialization.");
#endif
break;
case CHADEMO_CONNECTED:
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
// Commented unless needed for debug
//Serial.println("CHADEMO_CONNECTED State");
//logging.println("CHADEMO_CONNECTED State");
#endif
/* plug_inserted is .. essentially a volatile of sorts, so verify */
if (plug_inserted) {
@ -810,8 +810,8 @@ void handle_chademo_sequence() {
* with timers to have higher confidence of certain conditions hitting
* a steady state
*/
#ifdef DEBUG_VIA_USB
Serial.println("CHADEMO plug is not inserted, cannot connect d2 relay to begin initialization.");
#ifdef DEBUG_LOG
logging.println("CHADEMO plug is not inserted, cannot connect d2 relay to begin initialization.");
#endif
CHADEMO_Status = CHADEMO_IDLE;
}
@ -821,8 +821,8 @@ void handle_chademo_sequence() {
* Used for triggers/error handling elsewhere;
* State change to CHADEMO_NEGOTIATE occurs in receive_can_battery(..)
*/
#ifdef DEBUG_VIA_USB
// Serial.println("Awaiting initial vehicle CAN to trigger negotiation");
#ifdef DEBUG_LOG
// logging.println("Awaiting initial vehicle CAN to trigger negotiation");
#endif
evse_init();
break;
@ -830,16 +830,16 @@ void handle_chademo_sequence() {
/* Vehicle and EVSE dance */
//TODO if pin 4 / j goes high,
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
// Commented unless needed for debug
// Serial.println("CHADEMO_NEGOTIATE State");
// logging.println("CHADEMO_NEGOTIATE State");
#endif
x109_evse_state.s.status.ChgDischStopControl = 1;
break;
case CHADEMO_EV_ALLOWED:
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
// Commented unless needed for debug
Serial.println("CHADEMO_EV_ALLOWED State");
logging.println("CHADEMO_EV_ALLOWED State");
#endif
// If we are in this state, vehicle_permission was already set to true...but re-verify
// that pin 4 (j) reads high
@ -855,9 +855,9 @@ void handle_chademo_sequence() {
}
break;
case CHADEMO_EVSE_PREPARE:
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
// Commented unless needed for debug
Serial.println("CHADEMO_EVSE_PREPARE State");
logging.println("CHADEMO_EVSE_PREPARE State");
#endif
/* TODO voltage check of output < 20v
* insulation test hypothetically happens here before triggering PIN 10 high
@ -878,7 +878,7 @@ void handle_chademo_sequence() {
digitalWrite(CHADEMO_PIN_10, HIGH);
evse_permission = true;
} else {
Serial.println("Insulation check measures > 20v ");
logging.println("Insulation check measures > 20v ");
}
// likely unnecessary but just to be sure. consider removal
@ -891,9 +891,9 @@ void handle_chademo_sequence() {
//state changes to CHADEMO_EVSE_START only upon receipt of charging session request
break;
case CHADEMO_EVSE_START:
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
// Commented unless needed for debug
Serial.println("CHADEMO_EVSE_START State");
logging.println("CHADEMO_EVSE_START State");
#endif
datalayer.system.status.battery_allows_contactor_closing = true;
x109_evse_state.s.status.ChgDischStopControl = 1;
@ -901,8 +901,8 @@ void handle_chademo_sequence() {
CHADEMO_Status = CHADEMO_EVSE_CONTACTORS_ENABLED;
#ifdef DEBUG_VIA_USB
Serial.println("Initiating contactors");
#ifdef DEBUG_LOG
logging.println("Initiating contactors");
#endif
/* break rather than fall through because contactors are not instantaneous;
@ -911,17 +911,17 @@ void handle_chademo_sequence() {
break;
case CHADEMO_EVSE_CONTACTORS_ENABLED:
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
// Commented unless needed for debug
Serial.println("CHADEMO_EVSE_CONTACTORS State");
logging.println("CHADEMO_EVSE_CONTACTORS State");
#endif
/* check whether contactors ready, because externally dependent upon inverter allow during discharge */
if (contactors_ready) {
#ifdef DEBUG_VIA_USB
Serial.println("Contactors ready");
Serial.print("Voltage: ");
Serial.println(get_measured_voltage());
#ifdef DEBUG_LOG
logging.println("Contactors ready");
logging.print("Voltage: ");
logging.println(get_measured_voltage());
#endif
/* transition to POWERFLOW state if discharge compatible on both sides */
if (x109_evse_state.discharge_compatible && x102_chg_session.s.status.StatusVehicleDischargeCompatible &&
@ -941,9 +941,9 @@ void handle_chademo_sequence() {
/* break or fall through ? TODO */
break;
case CHADEMO_POWERFLOW:
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
// Commented unless needed for debug
Serial.println("CHADEMO_POWERFLOW State");
logging.println("CHADEMO_POWERFLOW State");
#endif
/* POWERFLOW for charging, discharging, and bidirectional */
/* Interpretation */
@ -961,8 +961,8 @@ void handle_chademo_sequence() {
}
if (get_measured_voltage() <= x200_discharge_limits.MinimumDischargeVoltage) {
#ifdef DEBUG_VIA_USB
Serial.println("x200 minimum discharge voltage met or exceeded, stopping.");
#ifdef DEBUG_LOG
logging.println("x200 minimum discharge voltage met or exceeded, stopping.");
#endif
CHADEMO_Status = CHADEMO_STOP;
}
@ -972,9 +972,9 @@ void handle_chademo_sequence() {
x109_evse_state.s.status.EVSE_status = 1;
break;
case CHADEMO_STOP:
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
// Commented unless needed for debug
Serial.println("CHADEMO_STOP State");
logging.println("CHADEMO_STOP State");
#endif
/* back to CHADEMO_IDLE after teardown */
x109_evse_state.s.status.ChgDischStopControl = 1;
@ -1000,16 +1000,16 @@ void handle_chademo_sequence() {
break;
case CHADEMO_FAULT:
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
// Commented unless needed for debug
Serial.println("CHADEMO_FAULT State");
logging.println("CHADEMO_FAULT State");
#endif
/* Once faulted, never departs CHADEMO_FAULT state unless device is power cycled as a safety measure */
x109_evse_state.s.status.EVSE_error = 1;
x109_evse_state.s.status.ChgDischError = 1;
x109_evse_state.s.status.ChgDischStopControl = 1;
#ifdef DEBUG_VIA_USB
Serial.println("CHADEMO fault encountered, tearing down to make safe");
#ifdef DEBUG_LOG
logging.println("CHADEMO fault encountered, tearing down to make safe");
#endif
digitalWrite(CHADEMO_PIN_10, LOW);
digitalWrite(CHADEMO_PIN_2, LOW);
@ -1020,8 +1020,8 @@ void handle_chademo_sequence() {
break;
default:
#ifdef DEBUG_VIA_USB
Serial.println("UNHANDLED CHADEMO_STATE, setting FAULT");
#ifdef DEBUG_LOG
logging.println("UNHANDLED CHADEMO_STATE, setting FAULT");
#endif
CHADEMO_Status = CHADEMO_FAULT;
break;

View file

@ -91,17 +91,17 @@ void ISA_handleFrame(CAN_frame* frame) {
case 0x510:
case 0x511:
Serial.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
Serial.print(" ");
Serial.print(frame->ID, HEX);
Serial.print(" ");
Serial.print(frame->DLC);
Serial.print(" ");
logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
logging.print(" ");
logging.print(frame->ID, HEX);
logging.print(" ");
logging.print(frame->DLC);
logging.print(" ");
for (int i = 0; i < frame->DLC; ++i) {
Serial.print(frame->data.u8[i], HEX);
Serial.print(" ");
logging.print(frame->data.u8[i], HEX);
logging.print(" ");
}
Serial.println("");
logging.println("");
break;
case 0x521:
@ -245,8 +245,8 @@ void ISA_initialize() {
ISA_STOP();
delay(500);
for (int i = 0; i < 8; i++) {
Serial.print("ISA Initialization ");
Serial.println(i);
logging.print("ISA Initialization ");
logging.println(i);
outframe.data.u8[0] = (0x20 + i);
outframe.data.u8[1] = 0x02;
@ -271,7 +271,7 @@ void ISA_initialize() {
}
void ISA_STOP() {
Serial.println("ISA STOP");
logging.println("ISA STOP");
outframe.data.u8[0] = 0x34;
outframe.data.u8[1] = 0x00;
@ -286,7 +286,7 @@ void ISA_STOP() {
}
void ISA_sendSTORE() {
Serial.println("ISA send STORE");
logging.println("ISA send STORE");
outframe.data.u8[0] = 0x32;
outframe.data.u8[1] = 0x00;
@ -301,7 +301,7 @@ void ISA_sendSTORE() {
}
void ISA_START() {
Serial.println("ISA START");
logging.println("ISA START");
outframe.data.u8[0] = 0x34;
outframe.data.u8[1] = 0x01;
@ -317,7 +317,7 @@ void ISA_START() {
void ISA_RESTART() {
//Has the effect of zeroing AH and KWH
Serial.println("ISA RESTART");
logging.println("ISA RESTART");
outframe.data.u8[0] = 0x3F;
outframe.data.u8[1] = 0x00;
@ -336,7 +336,7 @@ void ISA_deFAULT() {
ISA_STOP();
delay(500);
Serial.println("ISA RESTART to default");
logging.println("ISA RESTART to default");
outframe.data.u8[0] = 0x3D;
outframe.data.u8[1] = 0x00;
@ -358,7 +358,7 @@ void ISA_initCurrent() {
ISA_STOP();
delay(500);
Serial.println("ISA Initialization Current");
logging.println("ISA Initialization Current");
outframe.data.u8[0] = 0x21;
outframe.data.u8[1] = 0x02;
@ -382,8 +382,8 @@ void ISA_initCurrent() {
}
void ISA_getCONFIG(uint8_t i) {
Serial.print("ISA Get Config ");
Serial.println(i);
logging.print("ISA Get Config ");
logging.println(i);
outframe.data.u8[0] = (0x60 + i);
outframe.data.u8[1] = 0x00;
@ -398,8 +398,8 @@ void ISA_getCONFIG(uint8_t i) {
}
void ISA_getCAN_ID(uint8_t i) {
Serial.print("ISA Get CAN ID ");
Serial.println(i);
logging.print("ISA Get CAN ID ");
logging.println(i);
outframe.data.u8[0] = (0x50 + i);
if (i == 8)
@ -418,8 +418,8 @@ void ISA_getCAN_ID(uint8_t i) {
}
void ISA_getINFO(uint8_t i) {
Serial.print("ISA Get INFO ");
Serial.println(i, HEX);
logging.print("ISA Get INFO ");
logging.println(i, HEX);
outframe.data.u8[0] = (0x70 + i);
outframe.data.u8[1] = 0x00;

View file

@ -103,29 +103,29 @@ void update_values_battery() { //This function maps all the values fetched via
}
if (!BMU_Detected) {
#ifdef DEBUG_VIA_USB
Serial.println("BMU not detected, check wiring!");
#ifdef DEBUG_LOG
logging.println("BMU not detected, check wiring!");
#endif
}
#ifdef DEBUG_VIA_USB
Serial.println("Battery Values");
Serial.print("BMU SOC: ");
Serial.print(BMU_SOC);
Serial.print(" BMU Current: ");
Serial.print(BMU_Current);
Serial.print(" BMU Battery Voltage: ");
Serial.print(BMU_PackVoltage);
Serial.print(" BMU_Power: ");
Serial.print(BMU_Power);
Serial.print(" Cell max voltage: ");
Serial.print(max_volt_cel);
Serial.print(" Cell min voltage: ");
Serial.print(min_volt_cel);
Serial.print(" Cell max temp: ");
Serial.print(max_temp_cel);
Serial.print(" Cell min temp: ");
Serial.println(min_temp_cel);
#ifdef DEBUG_LOG
logging.println("Battery Values");
logging.print("BMU SOC: ");
logging.print(BMU_SOC);
logging.print(" BMU Current: ");
logging.print(BMU_Current);
logging.print(" BMU Battery Voltage: ");
logging.print(BMU_PackVoltage);
logging.print(" BMU_Power: ");
logging.print(BMU_Power);
logging.print(" Cell max voltage: ");
logging.print(max_volt_cel);
logging.print(" Cell min voltage: ");
logging.print(min_volt_cel);
logging.print(" Cell max temp: ");
logging.print(max_temp_cel);
logging.print(" Cell min temp: ");
logging.println(min_temp_cel);
#endif
}

View file

@ -57,9 +57,9 @@ CAN_frame ipace_keep_alive = {.FD = false,
.data = {0x9E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};*/
void print_units(char* header, int value, char* units) {
Serial.print(header);
Serial.print(value);
Serial.print(units);
logging.print(header);
logging.print(value);
logging.print(units);
}
void update_values_battery() {
@ -104,8 +104,8 @@ void update_values_battery() {
}
/*Finally print out values to serial if configured to do so*/
#ifdef DEBUG_VIA_USB
Serial.println("Values going to inverter");
#ifdef DEBUG_LOG
logging.println("Values going to inverter");
print_units("SOH%: ", (datalayer.battery.status.soh_pptt * 0.01), "% ");
print_units(", SOC%: ", (datalayer.battery.status.reported_soc * 0.01), "% ");
print_units(", Voltage: ", (datalayer.battery.status.voltage_dV * 0.1), "V ");
@ -115,7 +115,7 @@ void update_values_battery() {
print_units(", Min temp: ", (datalayer.battery.status.temperature_min_dC * 0.1), "°C ");
print_units(", Max cell voltage: ", datalayer.battery.status.cell_max_voltage_mV, "mV ");
print_units(", Min cell voltage: ", datalayer.battery.status.cell_min_voltage_mV, "mV ");
Serial.println("");
logging.println("");
#endif
}
@ -229,17 +229,17 @@ void receive_can_battery(CAN_frame rx_frame) {
}
// All CAN messages recieved will be logged via serial
Serial.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
Serial.print(" ");
Serial.print(rx_frame.ID, HEX);
Serial.print(" ");
Serial.print(rx_frame.DLC);
Serial.print(" ");
logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
logging.print(" ");
logging.print(rx_frame.ID, HEX);
logging.print(" ");
logging.print(rx_frame.DLC);
logging.print(" ");
for (int i = 0; i < rx_frame.DLC; ++i) {
Serial.print(rx_frame.data.u8[i], HEX);
Serial.print(" ");
logging.print(rx_frame.data.u8[i], HEX);
logging.print(" ");
}
Serial.println("");
logging.println("");
}
void send_can_battery() {

View file

@ -690,63 +690,63 @@ void update_values_battery() { //This function maps all the values fetched via
/* Safeties verified. Perform USB serial printout if configured to do so */
#ifdef DEBUG_VIA_USB
Serial.println(); //sepatator
Serial.println("Values from battery: ");
Serial.print("SOC BMS: ");
Serial.print((uint16_t)SOC_BMS / 10.0, 1);
Serial.print("% | SOC Display: ");
Serial.print((uint16_t)SOC_Display / 10.0, 1);
Serial.print("% | SOH ");
Serial.print((uint16_t)batterySOH / 10.0, 1);
Serial.println("%");
Serial.print((int16_t)batteryAmps / 10.0, 1);
Serial.print(" Amps | ");
Serial.print((uint16_t)batteryVoltage / 10.0, 1);
Serial.print(" Volts | ");
Serial.print((int16_t)datalayer.battery.status.active_power_W);
Serial.println(" Watts");
Serial.print("Allowed Charge ");
Serial.print((uint16_t)allowedChargePower * 10);
Serial.print(" W | Allowed Discharge ");
Serial.print((uint16_t)allowedDischargePower * 10);
Serial.println(" W");
Serial.print("MaxCellVolt ");
Serial.print(CellVoltMax_mV);
Serial.print(" mV No ");
Serial.print(CellVmaxNo);
Serial.print(" | MinCellVolt ");
Serial.print(CellVoltMin_mV);
Serial.print(" mV No ");
Serial.println(CellVminNo);
Serial.print("TempHi ");
Serial.print((int16_t)temperatureMax);
Serial.print("°C TempLo ");
Serial.print((int16_t)temperatureMin);
Serial.print("°C WaterInlet ");
Serial.print((int8_t)temperature_water_inlet);
Serial.print("°C PowerRelay ");
Serial.print((int8_t)powerRelayTemperature * 2);
Serial.println("°C");
Serial.print("Aux12volt: ");
Serial.print((int16_t)leadAcidBatteryVoltage / 10.0, 1);
Serial.println("V | ");
Serial.print("BmsManagementMode ");
Serial.print((uint8_t)batteryManagementMode, BIN);
#ifdef DEBUG_LOG
logging.println(); //sepatator
logging.println("Values from battery: ");
logging.print("SOC BMS: ");
logging.print((uint16_t)SOC_BMS / 10.0, 1);
logging.print("% | SOC Display: ");
logging.print((uint16_t)SOC_Display / 10.0, 1);
logging.print("% | SOH ");
logging.print((uint16_t)batterySOH / 10.0, 1);
logging.println("%");
logging.print((int16_t)batteryAmps / 10.0, 1);
logging.print(" Amps | ");
logging.print((uint16_t)batteryVoltage / 10.0, 1);
logging.print(" Volts | ");
logging.print((int16_t)datalayer.battery.status.active_power_W);
logging.println(" Watts");
logging.print("Allowed Charge ");
logging.print((uint16_t)allowedChargePower * 10);
logging.print(" W | Allowed Discharge ");
logging.print((uint16_t)allowedDischargePower * 10);
logging.println(" W");
logging.print("MaxCellVolt ");
logging.print(CellVoltMax_mV);
logging.print(" mV No ");
logging.print(CellVmaxNo);
logging.print(" | MinCellVolt ");
logging.print(CellVoltMin_mV);
logging.print(" mV No ");
logging.println(CellVminNo);
logging.print("TempHi ");
logging.print((int16_t)temperatureMax);
logging.print("°C TempLo ");
logging.print((int16_t)temperatureMin);
logging.print("°C WaterInlet ");
logging.print((int8_t)temperature_water_inlet);
logging.print("°C PowerRelay ");
logging.print((int8_t)powerRelayTemperature * 2);
logging.println("°C");
logging.print("Aux12volt: ");
logging.print((int16_t)leadAcidBatteryVoltage / 10.0, 1);
logging.println("V | ");
logging.print("BmsManagementMode ");
logging.print((uint8_t)batteryManagementMode, BIN);
if (bitRead((uint8_t)BMS_ign, 2) == 1) {
Serial.print(" | BmsIgnition ON");
logging.print(" | BmsIgnition ON");
} else {
Serial.print(" | BmsIgnition OFF");
logging.print(" | BmsIgnition OFF");
}
if (bitRead((uint8_t)batteryRelay, 0) == 1) {
Serial.print(" | PowerRelay ON");
logging.print(" | PowerRelay ON");
} else {
Serial.print(" | PowerRelay OFF");
logging.print(" | PowerRelay OFF");
}
Serial.print(" | Inverter ");
Serial.print(inverterVoltage);
Serial.println(" Volts");
logging.print(" | Inverter ");
logging.print(inverterVoltage);
logging.println(" Volts");
#endif
}
@ -808,7 +808,7 @@ void receive_can_battery(CAN_frame rx_frame) {
// print_canfd_frame(frame);
switch (rx_frame.data.u8[0]) {
case 0x10: //"PID Header"
// Serial.println ("Send ack");
// logging.println ("Send ack");
poll_data_pid = rx_frame.data.u8[4];
// if (rx_frame.data.u8[4] == poll_data_pid) {
transmit_can(&EGMP_7E4_ack, can_config.battery); //Send ack to BMS if the same frame is sent as polled

View file

@ -142,63 +142,63 @@ void update_values_battery() { //This function maps all the values fetched via
/* Safeties verified. Perform USB serial printout if configured to do so */
#ifdef DEBUG_VIA_USB
Serial.println(); //sepatator
Serial.println("Values from battery: ");
Serial.print("SOC BMS: ");
Serial.print((uint16_t)SOC_BMS / 10.0, 1);
Serial.print("% | SOC Display: ");
Serial.print((uint16_t)SOC_Display / 10.0, 1);
Serial.print("% | SOH ");
Serial.print((uint16_t)batterySOH / 10.0, 1);
Serial.println("%");
Serial.print((int16_t)batteryAmps / 10.0, 1);
Serial.print(" Amps | ");
Serial.print((uint16_t)batteryVoltage / 10.0, 1);
Serial.print(" Volts | ");
Serial.print((int16_t)datalayer.battery.status.active_power_W);
Serial.println(" Watts");
Serial.print("Allowed Charge ");
Serial.print((uint16_t)allowedChargePower * 10);
Serial.print(" W | Allowed Discharge ");
Serial.print((uint16_t)allowedDischargePower * 10);
Serial.println(" W");
Serial.print("MaxCellVolt ");
Serial.print(CellVoltMax_mV);
Serial.print(" mV No ");
Serial.print(CellVmaxNo);
Serial.print(" | MinCellVolt ");
Serial.print(CellVoltMin_mV);
Serial.print(" mV No ");
Serial.println(CellVminNo);
Serial.print("TempHi ");
Serial.print((int16_t)temperatureMax);
Serial.print("°C TempLo ");
Serial.print((int16_t)temperatureMin);
Serial.print("°C WaterInlet ");
Serial.print((int8_t)temperature_water_inlet);
Serial.print("°C PowerRelay ");
Serial.print((int8_t)powerRelayTemperature * 2);
Serial.println("°C");
Serial.print("Aux12volt: ");
Serial.print((int16_t)leadAcidBatteryVoltage / 10.0, 1);
Serial.println("V | ");
Serial.print("BmsManagementMode ");
Serial.print((uint8_t)batteryManagementMode, BIN);
#ifdef DEBUG_LOG
logging.println(); //sepatator
logging.println("Values from battery: ");
logging.print("SOC BMS: ");
logging.print((uint16_t)SOC_BMS / 10.0, 1);
logging.print("% | SOC Display: ");
logging.print((uint16_t)SOC_Display / 10.0, 1);
logging.print("% | SOH ");
logging.print((uint16_t)batterySOH / 10.0, 1);
logging.println("%");
logging.print((int16_t)batteryAmps / 10.0, 1);
logging.print(" Amps | ");
logging.print((uint16_t)batteryVoltage / 10.0, 1);
logging.print(" Volts | ");
logging.print((int16_t)datalayer.battery.status.active_power_W);
logging.println(" Watts");
logging.print("Allowed Charge ");
logging.print((uint16_t)allowedChargePower * 10);
logging.print(" W | Allowed Discharge ");
logging.print((uint16_t)allowedDischargePower * 10);
logging.println(" W");
logging.print("MaxCellVolt ");
logging.print(CellVoltMax_mV);
logging.print(" mV No ");
logging.print(CellVmaxNo);
logging.print(" | MinCellVolt ");
logging.print(CellVoltMin_mV);
logging.print(" mV No ");
logging.println(CellVminNo);
logging.print("TempHi ");
logging.print((int16_t)temperatureMax);
logging.print("°C TempLo ");
logging.print((int16_t)temperatureMin);
logging.print("°C WaterInlet ");
logging.print((int8_t)temperature_water_inlet);
logging.print("°C PowerRelay ");
logging.print((int8_t)powerRelayTemperature * 2);
logging.println("°C");
logging.print("Aux12volt: ");
logging.print((int16_t)leadAcidBatteryVoltage / 10.0, 1);
logging.println("V | ");
logging.print("BmsManagementMode ");
logging.print((uint8_t)batteryManagementMode, BIN);
if (bitRead((uint8_t)BMS_ign, 2) == 1) {
Serial.print(" | BmsIgnition ON");
logging.print(" | BmsIgnition ON");
} else {
Serial.print(" | BmsIgnition OFF");
logging.print(" | BmsIgnition OFF");
}
if (bitRead((uint8_t)batteryRelay, 0) == 1) {
Serial.print(" | PowerRelay ON");
logging.print(" | PowerRelay ON");
} else {
Serial.print(" | PowerRelay OFF");
logging.print(" | PowerRelay OFF");
}
Serial.print(" | Inverter ");
Serial.print(inverterVoltage);
Serial.println(" Volts");
logging.print(" | Inverter ");
logging.print(inverterVoltage);
logging.println(" Volts");
#endif
}

View file

@ -42,10 +42,6 @@ void update_values_battery() { //This function maps all the values fetched via
datalayer.battery.status.temperature_min_dC;
datalayer.battery.status.temperature_max_dC;
#ifdef DEBUG_VIA_USB
#endif
}
void receive_can_battery(CAN_frame rx_frame) {

View file

@ -103,36 +103,36 @@ void update_values_battery() { //This function maps all the values fetched via
datalayer.battery.status.cell_max_voltage_mV = LB_Cell_Max_Voltage;
#ifdef DEBUG_VIA_USB
Serial.println("Values going to inverter:");
Serial.print("SOH%: ");
Serial.print(datalayer.battery.status.soh_pptt);
Serial.print(", SOC% scaled: ");
Serial.print(datalayer.battery.status.reported_soc);
Serial.print(", Voltage: ");
Serial.print(datalayer.battery.status.voltage_dV);
Serial.print(", Max discharge power: ");
Serial.print(datalayer.battery.status.max_discharge_power_W);
Serial.print(", Max charge power: ");
Serial.print(datalayer.battery.status.max_charge_power_W);
Serial.print(", Max temp: ");
Serial.print(datalayer.battery.status.temperature_max_dC);
Serial.print(", Min temp: ");
Serial.print(datalayer.battery.status.temperature_min_dC);
Serial.print(", BMS Status (3=OK): ");
Serial.print(datalayer.battery.status.bms_status);
#ifdef DEBUG_LOG
logging.println("Values going to inverter:");
logging.print("SOH%: ");
logging.print(datalayer.battery.status.soh_pptt);
logging.print(", SOC% scaled: ");
logging.print(datalayer.battery.status.reported_soc);
logging.print(", Voltage: ");
logging.print(datalayer.battery.status.voltage_dV);
logging.print(", Max discharge power: ");
logging.print(datalayer.battery.status.max_discharge_power_W);
logging.print(", Max charge power: ");
logging.print(datalayer.battery.status.max_charge_power_W);
logging.print(", Max temp: ");
logging.print(datalayer.battery.status.temperature_max_dC);
logging.print(", Min temp: ");
logging.print(datalayer.battery.status.temperature_min_dC);
logging.print(", BMS Status (3=OK): ");
logging.print(datalayer.battery.status.bms_status);
Serial.println("Battery values: ");
Serial.print("Real SOC: ");
Serial.print(LB_SOC);
Serial.print(", Current: ");
Serial.print(LB_Current);
Serial.print(", kWh remain: ");
Serial.print(LB_kWh_Remaining);
Serial.print(", max mV: ");
Serial.print(LB_Cell_Max_Voltage);
Serial.print(", min mV: ");
Serial.print(LB_Cell_Min_Voltage);
logging.println("Battery values: ");
logging.print("Real SOC: ");
logging.print(LB_SOC);
logging.print(", Current: ");
logging.print(LB_Current);
logging.print(", kWh remain: ");
logging.print(LB_kWh_Remaining);
logging.print(", max mV: ");
logging.print(LB_Cell_Max_Voltage);
logging.print(", min mV: ");
logging.print(LB_Cell_Min_Voltage);
#endif
}

View file

@ -216,10 +216,6 @@ void update_values_battery() { //This function maps all the values fetched via
datalayer_extended.zoePH2.battery_pack_time = battery_pack_time;
datalayer_extended.zoePH2.battery_soc_min = battery_soc_min;
datalayer_extended.zoePH2.battery_soc_max = battery_soc_max;
#ifdef DEBUG_VIA_USB
#endif
}
void receive_can_battery(CAN_frame rx_frame) {

View file

@ -162,17 +162,17 @@ void receive_can_battery(CAN_frame rx_frame) {
/*
// All CAN messages recieved will be logged via serial
Serial.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
Serial.print(" ");
Serial.print(rx_frame.ID, HEX);
Serial.print(" ");
Serial.print(rx_frame.DLC);
Serial.print(" ");
logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
logging.print(" ");
logging.print(rx_frame.ID, HEX);
logging.print(" ");
logging.print(rx_frame.DLC);
logging.print(" ");
for (int i = 0; i < rx_frame.DLC; ++i) {
Serial.print(rx_frame.data.u8[i], HEX);
Serial.print(" ");
logging.print(rx_frame.data.u8[i], HEX);
logging.print(" ");
}
Serial.println("");
logging.println("");
*/
switch (rx_frame.ID) {
case 0xF5: // This is the only message is sent from BMS

View file

@ -94,8 +94,8 @@ void manageSerialLinkReceiver() {
bool readError = dataLinkReceive.checkReadError(true); // check for error & clear error flag
if (readError) {
Serial.print(currentTime);
Serial.println(" - ERROR: SerialDataLink - Read Error");
logging.print(currentTime);
logging.println(" - ERROR: SerialDataLink - Read Error");
lasterror = true;
errors++;
}
@ -112,8 +112,8 @@ void manageSerialLinkReceiver() {
//bms_status = ACTIVE; // just testing
if (lasterror) {
lasterror = false;
Serial.print(currentTime);
Serial.println(" - RECOVERY: SerialDataLink - Read GOOD");
logging.print(currentTime);
logging.println(" - RECOVERY: SerialDataLink - Read GOOD");
}
}
@ -134,34 +134,34 @@ void manageSerialLinkReceiver() {
// report Lost data & Max charge / Discharge reductions
if (minutesLost != last_minutesLost) {
last_minutesLost = minutesLost;
Serial.print(currentTime);
logging.print(currentTime);
if (batteryFault) {
Serial.print("Battery Fault (minutes) : ");
logging.print("Battery Fault (minutes) : ");
} else {
Serial.print(" - Minutes without data : ");
logging.print(" - Minutes without data : ");
}
Serial.print(minutesLost);
Serial.print(", max Charge = ");
Serial.print(datalayer.battery.status.max_charge_power_W);
Serial.print(", max Discharge = ");
Serial.println(datalayer.battery.status.max_discharge_power_W);
logging.print(minutesLost);
logging.print(", max Charge = ");
logging.print(datalayer.battery.status.max_charge_power_W);
logging.print(", max Discharge = ");
logging.println(datalayer.battery.status.max_discharge_power_W);
}
}
if (currentTime - reportTime > 59999) {
reportTime = currentTime;
Serial.print(currentTime);
Serial.print(" SerialDataLink-Receiver - NewData :");
Serial.print(reads);
Serial.print(" Errors : ");
Serial.println(errors);
logging.print(currentTime);
logging.print(" SerialDataLink-Receiver - NewData :");
logging.print(reads);
logging.print(" Errors : ");
logging.println(errors);
reads = 0;
errors = 0;
// --- printUsefullData();
//Serial.print("SOC = ");
//Serial.println(SOC);
#ifdef DEBUG_VIA_USB
//logging.print("SOC = ");
//logging.println(SOC);
#ifdef DEBUG_LOG
update_values_serial_link();
#endif
}
@ -179,43 +179,43 @@ void manageSerialLinkReceiver() {
}
void update_values_serial_link() {
Serial.println("Values from battery: ");
Serial.print("SOC: ");
Serial.print(datalayer.battery.status.real_soc);
Serial.print(" SOH: ");
Serial.print(datalayer.battery.status.soh_pptt);
Serial.print(" Voltage: ");
Serial.print(datalayer.battery.status.voltage_dV);
Serial.print(" Current: ");
Serial.print(datalayer.battery.status.current_dA);
Serial.print(" Capacity: ");
Serial.print(datalayer.battery.info.total_capacity_Wh);
Serial.print(" Remain cap: ");
Serial.print(datalayer.battery.status.remaining_capacity_Wh);
Serial.print(" Max discharge W: ");
Serial.print(datalayer.battery.status.max_discharge_power_W);
Serial.print(" Max charge W: ");
Serial.print(datalayer.battery.status.max_charge_power_W);
Serial.print(" BMS status: ");
Serial.print(datalayer.battery.status.bms_status);
Serial.print(" Power: ");
Serial.print(datalayer.battery.status.active_power_W);
Serial.print(" Temp min: ");
Serial.print(datalayer.battery.status.temperature_min_dC);
Serial.print(" Temp max: ");
Serial.print(datalayer.battery.status.temperature_max_dC);
Serial.print(" Cell max: ");
Serial.print(datalayer.battery.status.cell_max_voltage_mV);
Serial.print(" Cell min: ");
Serial.print(datalayer.battery.status.cell_min_voltage_mV);
Serial.print(" LFP : ");
Serial.print(datalayer.battery.info.chemistry);
Serial.print(" Battery Allows Contactor Closing: ");
Serial.print(datalayer.system.status.battery_allows_contactor_closing);
Serial.print(" Inverter Allows Contactor Closing: ");
Serial.print(datalayer.system.status.inverter_allows_contactor_closing);
logging.println("Values from battery: ");
logging.print("SOC: ");
logging.print(datalayer.battery.status.real_soc);
logging.print(" SOH: ");
logging.print(datalayer.battery.status.soh_pptt);
logging.print(" Voltage: ");
logging.print(datalayer.battery.status.voltage_dV);
logging.print(" Current: ");
logging.print(datalayer.battery.status.current_dA);
logging.print(" Capacity: ");
logging.print(datalayer.battery.info.total_capacity_Wh);
logging.print(" Remain cap: ");
logging.print(datalayer.battery.status.remaining_capacity_Wh);
logging.print(" Max discharge W: ");
logging.print(datalayer.battery.status.max_discharge_power_W);
logging.print(" Max charge W: ");
logging.print(datalayer.battery.status.max_charge_power_W);
logging.print(" BMS status: ");
logging.print(datalayer.battery.status.bms_status);
logging.print(" Power: ");
logging.print(datalayer.battery.status.active_power_W);
logging.print(" Temp min: ");
logging.print(datalayer.battery.status.temperature_min_dC);
logging.print(" Temp max: ");
logging.print(datalayer.battery.status.temperature_max_dC);
logging.print(" Cell max: ");
logging.print(datalayer.battery.status.cell_max_voltage_mV);
logging.print(" Cell min: ");
logging.print(datalayer.battery.status.cell_min_voltage_mV);
logging.print(" LFP : ");
logging.print(datalayer.battery.info.chemistry);
logging.print(" Battery Allows Contactor Closing: ");
logging.print(datalayer.system.status.battery_allows_contactor_closing);
logging.print(" Inverter Allows Contactor Closing: ");
logging.print(datalayer.system.status.inverter_allows_contactor_closing);
Serial.println("");
logging.println("");
}
void setup_battery(void) {

View file

@ -408,69 +408,69 @@ void update_values_battery() { //This function maps all the values fetched via
datalayer_extended.tesla.battery_soc_min = battery_soc_min;
datalayer_extended.tesla.battery_soc_ui = battery_soc_ui;
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
printFaultCodesIfActive();
Serial.print("STATUS: Contactor: ");
Serial.print(contactorText[battery_contactor]); //Display what state the contactor is in
Serial.print(", HVIL: ");
Serial.print(hvilStatusState[battery_hvil_status]);
Serial.print(", NegativeState: ");
Serial.print(contactorState[battery_packContNegativeState]);
Serial.print(", PositiveState: ");
Serial.print(contactorState[battery_packContPositiveState]);
Serial.print(", setState: ");
Serial.print(contactorState[battery_packContactorSetState]);
Serial.print(", close allowed: ");
Serial.print(battery_packCtrsClosingAllowed);
Serial.print(", Pyrotest: ");
Serial.println(battery_pyroTestInProgress);
logging.print("STATUS: Contactor: ");
logging.print(contactorText[battery_contactor]); //Display what state the contactor is in
logging.print(", HVIL: ");
logging.print(hvilStatusState[battery_hvil_status]);
logging.print(", NegativeState: ");
logging.print(contactorState[battery_packContNegativeState]);
logging.print(", PositiveState: ");
logging.print(contactorState[battery_packContPositiveState]);
logging.print(", setState: ");
logging.print(contactorState[battery_packContactorSetState]);
logging.print(", close allowed: ");
logging.print(battery_packCtrsClosingAllowed);
logging.print(", Pyrotest: ");
logging.println(battery_pyroTestInProgress);
Serial.print("Battery values: ");
Serial.print("Real SOC: ");
Serial.print(battery_soc_ui / 10.0, 1);
logging.print("Battery values: ");
logging.print("Real SOC: ");
logging.print(battery_soc_ui / 10.0, 1);
print_int_with_units(", Battery voltage: ", battery_volts, "V");
print_int_with_units(", Battery HV current: ", (battery_amps * 0.1), "A");
Serial.print(", Fully charged?: ");
logging.print(", Fully charged?: ");
if (battery_full_charge_complete)
Serial.print("YES, ");
logging.print("YES, ");
else
Serial.print("NO, ");
logging.print("NO, ");
if (datalayer.battery.info.chemistry == battery_chemistry_enum::LFP) {
Serial.print("LFP chemistry detected!");
logging.print("LFP chemistry detected!");
}
Serial.println("");
Serial.print("Cellstats, Max: ");
Serial.print(battery_cell_max_v);
Serial.print("mV (cell ");
Serial.print(battery_max_vno);
Serial.print("), Min: ");
Serial.print(battery_cell_min_v);
Serial.print("mV (cell ");
Serial.print(battery_min_vno);
Serial.print("), Imbalance: ");
Serial.print(battery_cell_deviation_mV);
Serial.println("mV.");
logging.println("");
logging.print("Cellstats, Max: ");
logging.print(battery_cell_max_v);
logging.print("mV (cell ");
logging.print(battery_max_vno);
logging.print("), Min: ");
logging.print(battery_cell_min_v);
logging.print("mV (cell ");
logging.print(battery_min_vno);
logging.print("), Imbalance: ");
logging.print(battery_cell_deviation_mV);
logging.println("mV.");
print_int_with_units("High Voltage Output Pins: ", battery_dcdcHvBusVolt, "V");
Serial.print(", ");
logging.print(", ");
print_int_with_units("Low Voltage: ", battery_dcdcLvBusVolt, "V");
Serial.println("");
logging.println("");
print_int_with_units("DC/DC 12V current: ", battery_dcdcLvOutputCurrent, "A");
Serial.println("");
logging.println("");
Serial.println("Values passed to the inverter: ");
logging.println("Values passed to the inverter: ");
print_SOC(" SOC: ", datalayer.battery.status.reported_soc);
print_int_with_units(" Max discharge power: ", datalayer.battery.status.max_discharge_power_W, "W");
Serial.print(", ");
logging.print(", ");
print_int_with_units(" Max charge power: ", datalayer.battery.status.max_charge_power_W, "W");
Serial.println("");
logging.println("");
print_int_with_units(" Max temperature: ", ((int16_t)datalayer.battery.status.temperature_min_dC * 0.1), "°C");
Serial.print(", ");
logging.print(", ");
print_int_with_units(" Min temperature: ", ((int16_t)datalayer.battery.status.temperature_max_dC * 0.1), "°C");
Serial.println("");
#endif //DEBUG_VIA_USB
logging.println("");
#endif //DEBUG_LOG
}
void receive_can_battery(CAN_frame rx_frame) {
@ -1087,69 +1087,69 @@ void update_values_battery2() { //This function maps all the values fetched via
}
#endif // TESLA_MODEL_3Y_BATTERY
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
printFaultCodesIfActive_battery2();
Serial.print("STATUS: Contactor: ");
Serial.print(contactorText[battery2_contactor]); //Display what state the contactor is in
Serial.print(", HVIL: ");
Serial.print(hvilStatusState[battery2_hvil_status]);
Serial.print(", NegativeState: ");
Serial.print(contactorState[battery2_packContNegativeState]);
Serial.print(", PositiveState: ");
Serial.print(contactorState[battery2_packContPositiveState]);
Serial.print(", setState: ");
Serial.print(contactorState[battery2_packContactorSetState]);
Serial.print(", close allowed: ");
Serial.print(battery2_packCtrsClosingAllowed);
Serial.print(", Pyrotest: ");
Serial.println(battery2_pyroTestInProgress);
logging.print("STATUS: Contactor: ");
logging.print(contactorText[battery2_contactor]); //Display what state the contactor is in
logging.print(", HVIL: ");
logging.print(hvilStatusState[battery2_hvil_status]);
logging.print(", NegativeState: ");
logging.print(contactorState[battery2_packContNegativeState]);
logging.print(", PositiveState: ");
logging.print(contactorState[battery2_packContPositiveState]);
logging.print(", setState: ");
logging.print(contactorState[battery2_packContactorSetState]);
logging.print(", close allowed: ");
logging.print(battery2_packCtrsClosingAllowed);
logging.print(", Pyrotest: ");
logging.println(battery2_pyroTestInProgress);
Serial.print("Battery2 values: ");
Serial.print("Real SOC: ");
Serial.print(battery2_soc_ui / 10.0, 1);
logging.print("Battery2 values: ");
logging.print("Real SOC: ");
logging.print(battery2_soc_ui / 10.0, 1);
print_int_with_units(", Battery2 voltage: ", battery2_volts, "V");
print_int_with_units(", Battery2 HV current: ", (battery2_amps * 0.1), "A");
Serial.print(", Fully charged?: ");
logging.print(", Fully charged?: ");
if (battery2_full_charge_complete)
Serial.print("YES, ");
logging.print("YES, ");
else
Serial.print("NO, ");
logging.print("NO, ");
if (datalayer.battery2.info.chemistry == battery_chemistry_enum::LFP) {
Serial.print("LFP chemistry detected!");
logging.print("LFP chemistry detected!");
}
Serial.println("");
Serial.print("Cellstats, Max: ");
Serial.print(battery2_cell_max_v);
Serial.print("mV (cell ");
Serial.print(battery2_max_vno);
Serial.print("), Min: ");
Serial.print(battery2_cell_min_v);
Serial.print("mV (cell ");
Serial.print(battery2_min_vno);
Serial.print("), Imbalance: ");
Serial.print(battery2_cell_deviation_mV);
Serial.println("mV.");
logging.println("");
logging.print("Cellstats, Max: ");
logging.print(battery2_cell_max_v);
logging.print("mV (cell ");
logging.print(battery2_max_vno);
logging.print("), Min: ");
logging.print(battery2_cell_min_v);
logging.print("mV (cell ");
logging.print(battery2_min_vno);
logging.print("), Imbalance: ");
logging.print(battery2_cell_deviation_mV);
logging.println("mV.");
print_int_with_units("High Voltage Output Pins: ", battery2_dcdcHvBusVolt, "V");
Serial.print(", ");
logging.print(", ");
print_int_with_units("Low Voltage: ", battery2_dcdcLvBusVolt, "V");
Serial.println("");
logging.println("");
print_int_with_units("DC/DC 12V current: ", battery2_dcdcLvOutputCurrent, "A");
Serial.println("");
logging.println("");
Serial.println("Values passed to the inverter: ");
logging.println("Values passed to the inverter: ");
print_SOC(" SOC: ", datalayer.battery2.status.reported_soc);
print_int_with_units(" Max discharge power: ", datalayer.battery2.status.max_discharge_power_W, "W");
Serial.print(", ");
logging.print(", ");
print_int_with_units(" Max charge power: ", datalayer.battery2.status.max_charge_power_W, "W");
Serial.println("");
logging.println("");
print_int_with_units(" Max temperature: ", ((int16_t)datalayer.battery2.status.temperature_min_dC * 0.1), "°C");
Serial.print(", ");
logging.print(", ");
print_int_with_units(" Min temperature: ", ((int16_t)datalayer.battery2.status.temperature_max_dC * 0.1), "°C");
Serial.println("");
#endif // DEBUG_VIA_USB
logging.println("");
#endif // DEBUG_LOG
}
#endif //DOUBLE_BATTERY
@ -1261,32 +1261,32 @@ the first, for a few cycles, then stop all messages which causes the contactor
}
void print_int_with_units(char* header, int value, char* units) {
Serial.print(header);
Serial.print(value);
Serial.print(units);
logging.print(header);
logging.print(value);
logging.print(units);
}
void print_SOC(char* header, int SOC) {
Serial.print(header);
Serial.print(SOC / 100);
Serial.print(".");
logging.print(header);
logging.print(SOC / 100);
logging.print(".");
int hundredth = SOC % 100;
if (hundredth < 10)
Serial.print(0);
Serial.print(hundredth);
Serial.println("%");
logging.print(0);
logging.print(hundredth);
logging.println("%");
}
void printFaultCodesIfActive() {
if (battery_packCtrsClosingAllowed == 0) {
Serial.println(
logging.println(
"ERROR: Check high voltage connectors and interlock circuit! Closing contactor not allowed! Values: ");
}
if (battery_pyroTestInProgress == 1) {
Serial.println("ERROR: Please wait for Pyro Connection check to finish, HV cables successfully seated!");
logging.println("ERROR: Please wait for Pyro Connection check to finish, HV cables successfully seated!");
}
if (datalayer.system.status.inverter_allows_contactor_closing == false) {
Serial.println(
logging.println(
"ERROR: Solar inverter does not allow for contactor closing. Check communication connection to the inverter "
"OR "
"disable the inverter protocol to proceed with contactor closing");
@ -1355,14 +1355,14 @@ void printFaultCodesIfActive() {
#ifdef DOUBLE_BATTERY
void printFaultCodesIfActive_battery2() {
if (battery2_packCtrsClosingAllowed == 0) {
Serial.println(
logging.println(
"ERROR: Check high voltage connectors and interlock circuit! Closing contactor not allowed! Values: ");
}
if (battery2_pyroTestInProgress == 1) {
Serial.println("ERROR: Please wait for Pyro Connection check to finish, HV cables successfully seated!");
logging.println("ERROR: Please wait for Pyro Connection check to finish, HV cables successfully seated!");
}
if (datalayer.system.status.inverter_allows_contactor_closing == false) {
Serial.println(
logging.println(
"ERROR: Solar inverter does not allow for contactor closing. Check communication connection to the inverter "
"OR "
"disable the inverter protocol to proceed with contactor closing");
@ -1433,7 +1433,7 @@ void printFaultCodesIfActive_battery2() {
void printDebugIfActive(uint8_t symbol, const char* message) {
if (symbol == 1) {
Serial.println(message);
logging.println(message);
}
}

View file

@ -15,9 +15,9 @@ CAN_frame TEST = {.FD = false,
.data = {0x10, 0x64, 0x00, 0xB0, 0x00, 0x1E, 0x00, 0x8F}};
void print_units(char* header, int value, char* units) {
Serial.print(header);
Serial.print(value);
Serial.print(units);
logging.print(header);
logging.print(value);
logging.print(units);
}
void update_values_battery() { /* This function puts fake values onto the parameters sent towards the inverter */
@ -54,8 +54,8 @@ void update_values_battery() { /* This function puts fake values onto the parame
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
/*Finally print out values to serial if configured to do so*/
#ifdef DEBUG_VIA_USB
Serial.println("FAKE Values going to inverter");
#ifdef DEBUG_LOG
logging.println("FAKE Values going to inverter");
print_units("SOH%: ", (datalayer.battery.status.soh_pptt * 0.01), "% ");
print_units(", SOC%: ", (datalayer.battery.status.reported_soc * 0.01), "% ");
print_units(", Voltage: ", (datalayer.battery.status.voltage_dV * 0.1), "V ");
@ -65,7 +65,7 @@ void update_values_battery() { /* This function puts fake values onto the parame
print_units(", Min temp: ", (datalayer.battery.status.temperature_min_dC * 0.1), "°C ");
print_units(", Max cell voltage: ", datalayer.battery.status.cell_max_voltage_mV, "mV ");
print_units(", Min cell voltage: ", datalayer.battery.status.cell_min_voltage_mV, "mV ");
Serial.println("");
logging.println("");
#endif
}
@ -107,8 +107,8 @@ void update_values_battery2() { // Handle the values coming in from battery #2
datalayer.battery2.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
/*Finally print out values to serial if configured to do so*/
#ifdef DEBUG_VIA_USB
Serial.println("FAKE Values battery 2 going to inverter");
#ifdef DEBUG_LOG
logging.println("FAKE Values battery 2 going to inverter");
print_units("SOH 2 %: ", (datalayer.battery2.status.soh_pptt * 0.01), "% ");
print_units(", SOC 2 %: ", (datalayer.battery2.status.reported_soc * 0.01), "% ");
print_units(", Voltage 2: ", (datalayer.battery2.status.voltage_dV * 0.1), "V ");
@ -118,7 +118,7 @@ void update_values_battery2() { // Handle the values coming in from battery #2
print_units(", Min temp 2: ", (datalayer.battery2.status.temperature_min_dC * 0.1), "°C ");
print_units(", Max cell voltage 2: ", datalayer.battery2.status.cell_max_voltage_mV, "mV ");
print_units(", Min cell voltage 2: ", datalayer.battery2.status.cell_min_voltage_mV, "mV ");
Serial.println("");
logging.println("");
#endif
}

View file

@ -94,49 +94,49 @@ void update_values_battery() { //This function maps all the values fetched via
datalayer.battery.status.cell_voltages_mV[i] = cell_voltages[i];
}
#ifdef DEBUG_VIA_USB
Serial.print("BMS reported SOC%: ");
Serial.println(SOC_BMS);
Serial.print("Calculated SOC%: ");
Serial.println(SOC_CALC);
Serial.print("Rescaled SOC%: ");
Serial.println(datalayer.battery.status.reported_soc / 100);
Serial.print("Battery current: ");
Serial.println(BATT_I);
Serial.print("Battery voltage: ");
Serial.println(BATT_U);
Serial.print("Battery maximum voltage limit: ");
Serial.println(MAX_U);
Serial.print("Battery minimum voltage limit: ");
Serial.println(MIN_U);
Serial.print("Remaining Energy: ");
Serial.println(remaining_capacity);
Serial.print("Discharge limit: ");
Serial.println(HvBattPwrLimDchaSoft);
Serial.print("Battery Error Indication: ");
Serial.println(BATT_ERR_INDICATION);
Serial.print("Maximum battery temperature: ");
Serial.println(BATT_T_MAX / 10);
Serial.print("Minimum battery temperature: ");
Serial.println(BATT_T_MIN / 10);
Serial.print("Average battery temperature: ");
Serial.println(BATT_T_AVG / 10);
Serial.print("BMS Highest cell voltage: ");
Serial.println(CELL_U_MAX * 10);
Serial.print("BMS Lowest cell voltage: ");
Serial.println(CELL_U_MIN * 10);
Serial.print("BMS Highest cell nr: ");
Serial.println(CELL_ID_U_MAX);
Serial.print("Highest cell voltage: ");
Serial.println(min_max_voltage[1]);
Serial.print("Lowest cell voltage: ");
Serial.println(min_max_voltage[0]);
Serial.print("Cell voltage,");
#ifdef DEBUG_LOG
logging.print("BMS reported SOC%: ");
logging.println(SOC_BMS);
logging.print("Calculated SOC%: ");
logging.println(SOC_CALC);
logging.print("Rescaled SOC%: ");
logging.println(datalayer.battery.status.reported_soc / 100);
logging.print("Battery current: ");
logging.println(BATT_I);
logging.print("Battery voltage: ");
logging.println(BATT_U);
logging.print("Battery maximum voltage limit: ");
logging.println(MAX_U);
logging.print("Battery minimum voltage limit: ");
logging.println(MIN_U);
logging.print("Remaining Energy: ");
logging.println(remaining_capacity);
logging.print("Discharge limit: ");
logging.println(HvBattPwrLimDchaSoft);
logging.print("Battery Error Indication: ");
logging.println(BATT_ERR_INDICATION);
logging.print("Maximum battery temperature: ");
logging.println(BATT_T_MAX / 10);
logging.print("Minimum battery temperature: ");
logging.println(BATT_T_MIN / 10);
logging.print("Average battery temperature: ");
logging.println(BATT_T_AVG / 10);
logging.print("BMS Highest cell voltage: ");
logging.println(CELL_U_MAX * 10);
logging.print("BMS Lowest cell voltage: ");
logging.println(CELL_U_MIN * 10);
logging.print("BMS Highest cell nr: ");
logging.println(CELL_ID_U_MAX);
logging.print("Highest cell voltage: ");
logging.println(min_max_voltage[1]);
logging.print("Lowest cell voltage: ");
logging.println(min_max_voltage[0]);
logging.print("Cell voltage,");
while (cnt < 108) {
Serial.print(cell_voltages[cnt++]);
Serial.print(",");
logging.print(cell_voltages[cnt++]);
logging.print(",");
}
Serial.println(";");
logging.println(";");
#endif
}
@ -148,8 +148,8 @@ void receive_can_battery(CAN_frame rx_frame) {
BATT_I = (0 - ((((rx_frame.data.u8[6] & 0x7F) * 256.0 + rx_frame.data.u8[7]) * 0.1) - 1638));
else {
BATT_I = 0;
#ifdef DEBUG_VIA_USB
Serial.println("BATT_I not valid");
#ifdef DEBUG_LOG
logging.println("BATT_I not valid");
#endif
}
@ -157,22 +157,22 @@ void receive_can_battery(CAN_frame rx_frame) {
MAX_U = (((rx_frame.data.u8[2] & 0x07) * 256.0 + rx_frame.data.u8[3]) * 0.25);
else {
//MAX_U = 0;
//Serial.println("MAX_U not valid"); // Value toggles between true/false from BMS
//logging.println("MAX_U not valid"); // Value toggles between true/false from BMS
}
if ((rx_frame.data.u8[4] & 0x08) == 0x08)
MIN_U = (((rx_frame.data.u8[4] & 0x07) * 256.0 + rx_frame.data.u8[5]) * 0.25);
else {
//MIN_U = 0;
//Serial.println("MIN_U not valid"); // Value toggles between true/false from BMS
//logging.println("MIN_U not valid"); // Value toggles between true/false from BMS
}
if ((rx_frame.data.u8[0] & 0x08) == 0x08)
BATT_U = (((rx_frame.data.u8[0] & 0x07) * 256.0 + rx_frame.data.u8[1]) * 0.25);
else {
BATT_U = 0;
#ifdef DEBUG_VIA_USB
Serial.println("BATT_U not valid");
#ifdef DEBUG_LOG
logging.println("BATT_U not valid");
#endif
}
break;
@ -189,8 +189,8 @@ void receive_can_battery(CAN_frame rx_frame) {
BATT_ERR_INDICATION = ((rx_frame.data.u8[0] & 0x40) >> 6);
else {
BATT_ERR_INDICATION = 0;
#ifdef DEBUG_VIA_USB
Serial.println("BATT_ERR_INDICATION not valid");
#ifdef DEBUG_LOG
logging.println("BATT_ERR_INDICATION not valid");
#endif
}
if ((rx_frame.data.u8[0] & 0x20) == 0x20) {
@ -201,8 +201,8 @@ void receive_can_battery(CAN_frame rx_frame) {
BATT_T_MAX = 0;
BATT_T_MIN = 0;
BATT_T_AVG = 0;
#ifdef DEBUG_VIA_USB
Serial.println("BATT_T not valid");
#ifdef DEBUG_LOG
logging.println("BATT_T not valid");
#endif
}
break;
@ -211,8 +211,8 @@ void receive_can_battery(CAN_frame rx_frame) {
HvBattPwrLimDchaSoft = (((rx_frame.data.u8[6] & 0x03) * 256 + rx_frame.data.u8[6]) >> 2);
} else {
HvBattPwrLimDchaSoft = 0;
#ifdef DEBUG_VIA_USB
Serial.println("HvBattPwrLimDchaSoft not valid");
#ifdef DEBUG_LOG
logging.println("HvBattPwrLimDchaSoft not valid");
#endif
}
break;
@ -221,8 +221,8 @@ void receive_can_battery(CAN_frame rx_frame) {
SOC_BMS = ((rx_frame.data.u8[6] & 0x03) * 256 + rx_frame.data.u8[7]);
} else {
SOC_BMS = 0;
#ifdef DEBUG_VIA_USB
Serial.println("SOC_BMS not valid");
#ifdef DEBUG_LOG
logging.println("SOC_BMS not valid");
#endif
}
@ -230,8 +230,8 @@ void receive_can_battery(CAN_frame rx_frame) {
CELL_U_MAX = ((rx_frame.data.u8[2] & 0x01) * 256 + rx_frame.data.u8[3]);
else {
CELL_U_MAX = 0;
#ifdef DEBUG_VIA_USB
Serial.println("CELL_U_MAX not valid");
#ifdef DEBUG_LOG
logging.println("CELL_U_MAX not valid");
#endif
}
@ -239,8 +239,8 @@ void receive_can_battery(CAN_frame rx_frame) {
CELL_U_MIN = ((rx_frame.data.u8[0] & 0x01) * 256.0 + rx_frame.data.u8[1]);
else {
CELL_U_MIN = 0;
#ifdef DEBUG_VIA_USB
Serial.println("CELL_U_MIN not valid");
#ifdef DEBUG_LOG
logging.println("CELL_U_MIN not valid");
#endif
}
@ -248,8 +248,8 @@ void receive_can_battery(CAN_frame rx_frame) {
CELL_ID_U_MAX = ((rx_frame.data.u8[4] & 0x01) * 256.0 + rx_frame.data.u8[5]);
else {
CELL_ID_U_MAX = 0;
#ifdef DEBUG_VIA_USB
Serial.println("CELL_ID_U_MAX not valid");
#ifdef DEBUG_LOG
logging.println("CELL_ID_U_MAX not valid");
#endif
}
break;

View file

@ -101,8 +101,8 @@ void receive_can_charger(CAN_frame rx_frame) {
case 0x308:
break;
default:
#ifdef DEBUG_VIA_USB
Serial.printf("CAN Rcv unknown frame MsgID=%x\n", rx_frame.MsgID);
#ifdef DEBUG_LOG
logging.printf("CAN Rcv unknown frame MsgID=%x\n", rx_frame.MsgID);
#endif
break;
}
@ -177,15 +177,15 @@ void send_can_charger() {
transmit_can(&charger_set_targets, can_config.charger);
}
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
/* Serial echo every 5s of charger stats */
if (currentMillis - previousMillis5000ms >= INTERVAL_5_S) {
previousMillis5000ms = currentMillis;
Serial.printf("Charger AC in IAC=%fA VAC=%fV\n", charger_stat_ACcur, charger_stat_ACvol);
Serial.printf("Charger HV out IDC=%fA VDC=%fV\n", charger_stat_HVcur, charger_stat_HVvol);
Serial.printf("Charger LV out IDC=%fA VDC=%fV\n", charger_stat_LVcur, charger_stat_LVvol);
Serial.printf("Charger mode=%s\n", (charger_mode > MODE_DISABLED) ? "Enabled" : "Disabled");
Serial.printf("Charger HVset=%uV,%uA finishCurrent=%uA\n", setpoint_HV_VDC, setpoint_HV_IDC, setpoint_HV_IDC_END);
logging.printf("Charger AC in IAC=%fA VAC=%fV\n", charger_stat_ACcur, charger_stat_ACvol);
logging.printf("Charger HV out IDC=%fA VDC=%fV\n", charger_stat_HVcur, charger_stat_HVvol);
logging.printf("Charger LV out IDC=%fA VDC=%fV\n", charger_stat_LVcur, charger_stat_LVvol);
logging.printf("Charger mode=%s\n", (charger_mode > MODE_DISABLED) ? "Enabled" : "Disabled");
logging.printf("Charger HVset=%uV,%uA finishCurrent=%uA\n", setpoint_HV_VDC, setpoint_HV_IDC, setpoint_HV_IDC_END);
}
#endif
}

View file

@ -35,31 +35,31 @@ void init_CAN() {
ESP32Can.CANInit();
#ifdef CAN_ADDON
#ifdef DEBUG_VIA_USB
Serial.println("Dual CAN Bus (ESP32+MCP2515) selected");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.println("Dual CAN Bus (ESP32+MCP2515) selected");
#endif // DEBUG_LOG
gBuffer.initWithSize(25);
SPI.begin(MCP2515_SCK, MCP2515_MISO, MCP2515_MOSI);
ACAN2515Settings settings(QUARTZ_FREQUENCY, 500UL * 1000UL); // CAN bit rate 500 kb/s
settings.mRequestedMode = ACAN2515Settings::NormalMode;
const uint16_t errorCodeMCP = can.begin(settings, [] { can.isr(); });
if (errorCodeMCP == 0) {
#ifdef DEBUG_VIA_USB
Serial.println("Can ok");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.println("Can ok");
#endif // DEBUG_LOG
} else {
#ifdef DEBUG_VIA_USB
Serial.print("Error Can: 0x");
Serial.println(errorCodeMCP, HEX);
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.print("Error Can: 0x");
logging.println(errorCodeMCP, HEX);
#endif // DEBUG_LOG
set_event(EVENT_CANMCP_INIT_FAILURE, (uint8_t)errorCodeMCP);
}
#endif // CAN_ADDON
#ifdef CANFD_ADDON
#ifdef DEBUG_VIA_USB
Serial.println("CAN FD add-on (ESP32+MCP2517) selected");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.println("CAN FD add-on (ESP32+MCP2517) selected");
#endif // DEBUG_LOG
SPI.begin(MCP2517_SCK, MCP2517_SDO, MCP2517_SDI);
ACAN2517FDSettings settings(CANFD_ADDON_CRYSTAL_FREQUENCY_MHZ, 500 * 1000,
DataBitRateFactor::x4); // Arbitration bit rate: 500 kbit/s, data bit rate: 2 Mbit/s
@ -71,29 +71,29 @@ void init_CAN() {
const uint32_t errorCode = canfd.begin(settings, [] { canfd.isr(); });
canfd.poll();
if (errorCode == 0) {
#ifdef DEBUG_VIA_USB
Serial.print("Bit Rate prescaler: ");
Serial.println(settings.mBitRatePrescaler);
Serial.print("Arbitration Phase segment 1: ");
Serial.println(settings.mArbitrationPhaseSegment1);
Serial.print("Arbitration Phase segment 2: ");
Serial.println(settings.mArbitrationPhaseSegment2);
Serial.print("Arbitration SJW:");
Serial.println(settings.mArbitrationSJW);
Serial.print("Actual Arbitration Bit Rate: ");
Serial.print(settings.actualArbitrationBitRate());
Serial.println(" bit/s");
Serial.print("Exact Arbitration Bit Rate ? ");
Serial.println(settings.exactArbitrationBitRate() ? "yes" : "no");
Serial.print("Arbitration Sample point: ");
Serial.print(settings.arbitrationSamplePointFromBitStart());
Serial.println("%");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.print("Bit Rate prescaler: ");
logging.println(settings.mBitRatePrescaler);
logging.print("Arbitration Phase segment 1: ");
logging.print(settings.mArbitrationPhaseSegment1);
logging.print(" segment 2: ");
logging.print(settings.mArbitrationPhaseSegment2);
logging.print(" SJW: ");
logging.println(settings.mArbitrationSJW);
logging.print("Actual Arbitration Bit Rate: ");
logging.print(settings.actualArbitrationBitRate());
logging.print(" bit/s");
logging.print(" (Exact:");
logging.println(settings.exactArbitrationBitRate() ? "yes)" : "no)");
logging.print("Arbitration Sample point: ");
logging.print(settings.arbitrationSamplePointFromBitStart());
logging.println("%");
#endif // DEBUG_LOG
} else {
#ifdef DEBUG_VIA_USB
Serial.print("CAN-FD Configuration error 0x");
Serial.println(errorCode, HEX);
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.print("CAN-FD Configuration error 0x");
logging.println(errorCode, HEX);
#endif // DEBUG_LOG
set_event(EVENT_CANFD_INIT_FAILURE, (uint8_t)errorCode);
}
#endif // CANFD_ADDON
@ -153,6 +153,8 @@ void transmit_can(CAN_frame* tx_frame, int interface) {
send_ok = canfd.tryToSend(MCP2518Frame);
if (!send_ok) {
set_event(EVENT_CANFD_BUFFER_FULL, interface);
} else {
clear_event(EVENT_CANFD_BUFFER_FULL);
}
#else // Interface not compiled, and settings try to use it
set_event(EVENT_INTERFACE_MISSING, interface);

View file

@ -194,9 +194,9 @@ static void publish_common_info(void) {
#endif // DOUBLE_BATTERY
serializeJson(doc, mqtt_msg);
if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) {
#ifdef DEBUG_VIA_USB
Serial.println("Common info MQTT msg could not be sent");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.println("Common info MQTT msg could not be sent");
#endif // DEBUG_LOG
}
doc.clear();
#ifdef HA_AUTODISCOVERY
@ -292,9 +292,9 @@ static void publish_cell_voltages(void) {
serializeJson(doc, mqtt_msg, sizeof(mqtt_msg));
if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) {
#ifdef DEBUG_VIA_USB
Serial.println("Cell voltage MQTT msg could not be sent");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.println("Cell voltage MQTT msg could not be sent");
#endif // DEBUG_LOG
}
doc.clear();
}
@ -312,9 +312,9 @@ static void publish_cell_voltages(void) {
serializeJson(doc, mqtt_msg, sizeof(mqtt_msg));
if (!mqtt_publish(state_topic_2.c_str(), mqtt_msg, false)) {
#ifdef DEBUG_VIA_USB
Serial.println("Cell voltage MQTT msg could not be sent");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.println("Cell voltage MQTT msg could not be sent");
#endif // DEBUG_LOG
}
doc.clear();
}
@ -384,9 +384,9 @@ void publish_events() {
serializeJson(doc, mqtt_msg);
if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) {
#ifdef DEBUG_VIA_USB
Serial.println("Common info MQTT msg could not be sent");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.println("Common info MQTT msg could not be sent");
#endif // DEBUG_LOG
} else {
set_event_MQTTpublished(event_handle);
}
@ -402,9 +402,9 @@ void publish_events() {
/* If we lose the connection, get it back */
static bool reconnect() {
// attempt one reconnection
#ifdef DEBUG_VIA_USB
Serial.print("Attempting MQTT connection... ");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.print("Attempting MQTT connection... ");
#endif // DEBUG_LOG
char clientId[64]; // Adjust the size as needed
snprintf(clientId, sizeof(clientId), "BatteryEmulatorClient-%s", WiFi.getHostname());
// Attempt to connect
@ -413,19 +413,19 @@ static bool reconnect() {
clear_event(EVENT_MQTT_DISCONNECT);
set_event(EVENT_MQTT_CONNECT, 0);
reconnectAttempts = 0; // Reset attempts on successful connection
#ifdef DEBUG_VIA_USB
Serial.println("connected");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.println("connected");
#endif // DEBUG_LOG
clear_event(EVENT_MQTT_CONNECT);
} else {
if (connected_once)
set_event(EVENT_MQTT_DISCONNECT, 0);
reconnectAttempts++; // Count failed attempts
#ifdef DEBUG_VIA_USB
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.print("failed, rc=");
logging.print(client.state());
logging.println(" try again in 5 seconds");
#endif // DEBUG_LOG
// Wait 5 seconds before retrying
}
return client.connected();
@ -449,9 +449,9 @@ void init_mqtt(void) {
#endif
client.setServer(MQTT_SERVER, MQTT_PORT);
#ifdef DEBUG_VIA_USB
Serial.println("MQTT initialized");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.println("MQTT initialized");
#endif // DEBUG_LOG
client.setKeepAlive(30); // Increase keepalive to manage network latency better. default is 15
@ -478,8 +478,8 @@ void mqtt_loop(void) {
if (reconnect()) {
lastReconnectAttempt = 0;
} else if (reconnectAttempts >= maxReconnectAttempts) {
#ifdef DEBUG_VIA_USB
Serial.println("Too many failed reconnect attempts, restarting client.");
#ifdef DEBUG_LOG
logging.println("Too many failed reconnect attempts, restarting client.");
#endif
client.disconnect(); // Force close the MQTT client connection
reconnectAttempts = 0; // Reset attempts to avoid infinite loop

View file

@ -118,15 +118,15 @@ void init_events(void) {
// Push changes to eeprom
EEPROM.commit();
#ifdef DEBUG_VIA_USB
Serial.println("EEPROM wasn't ready");
#ifdef DEBUG_LOG
logging.println("EEPROM wasn't ready");
#endif
} else {
events.event_log_head_index = EEPROM.readUShort(EE_EVENT_LOG_HEAD_INDEX_ADDRESS);
events.event_log_tail_index = EEPROM.readUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS);
#ifdef DEBUG_VIA_USB
Serial.println("EEPROM was initialized for event logging");
Serial.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index));
#ifdef DEBUG_LOG
logging.println("EEPROM was initialized for event logging");
logging.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index));
#endif
print_event_log();
}
@ -471,6 +471,10 @@ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) {
if (events.entries[event].log) {
log_event(event, events.entries[event].millisrolloverCount, events.entries[event].timestamp, data);
}
#ifdef DEBUG_LOG
logging.print("Event: ");
logging.println(get_event_message_string(event));
#endif
}
// We should set the event, update event info
@ -484,10 +488,6 @@ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) {
events.level = max(events.level, events.entries[event].level);
update_bms_status();
#ifdef DEBUG_VIA_USB
Serial.println(get_event_message_string(event));
#endif
}
static void update_bms_status(void) {
@ -561,8 +561,8 @@ static void log_event(EVENTS_ENUM_TYPE event, uint8_t millisrolloverCount, uint3
// Store the new indices
EEPROM.writeUShort(EE_EVENT_LOG_HEAD_INDEX_ADDRESS, events.event_log_head_index);
EEPROM.writeUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS, events.event_log_tail_index);
//Serial.println("Wrote event " + String(event) + " to " + String(entry_address));
//Serial.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index));
//logging.println("Wrote event " + String(event) + " to " + String(entry_address));
//logging.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index));
// We don't need the exact number, it's just for deciding to store or not
events.nof_logged_events += (events.nof_logged_events < 255) ? 1 : 0;
@ -571,8 +571,8 @@ static void log_event(EVENTS_ENUM_TYPE event, uint8_t millisrolloverCount, uint3
static void print_event_log(void) {
// If the head actually points to the tail, the log is probably blank
if (events.event_log_head_index == events.event_log_tail_index) {
#ifdef DEBUG_VIA_USB
Serial.println("No events in log");
#ifdef DEBUG_LOG
logging.println("No events in log");
#endif
return;
}
@ -588,8 +588,8 @@ static void print_event_log(void) {
// The entry is a blank that has been left behind somehow
continue;
}
#ifdef DEBUG_VIA_USB
Serial.println("Event: " + String(get_event_enum_string(entry.event)) + ", data: " + String(entry.data) +
#ifdef DEBUG_LOG
logging.println("Event: " + String(get_event_enum_string(entry.event)) + ", data: " + String(entry.data) +
", time: " + String(entry.timestamp));
#endif
if (index == events.event_log_head_index) {

View file

@ -25,9 +25,9 @@ void run_sequence_on_target(void) {
case ETOT_INIT:
timer.set_interval(10000);
events_test_state = ETOT_FIRST_WAIT;
Serial.println("Events test: initialized");
Serial.print("datalayer.battery.status.bms_status: ");
Serial.println(datalayer.battery.status.bms_status);
logging.println("Events test: initialized");
logging.print("datalayer.battery.status.bms_status: ");
logging.println(datalayer.battery.status.bms_status);
break;
case ETOT_FIRST_WAIT:
if (timer.elapsed()) {
@ -35,9 +35,9 @@ void run_sequence_on_target(void) {
events_test_state = ETOT_INFO;
set_event(EVENT_DUMMY_INFO, 123);
set_event(EVENT_DUMMY_INFO, 234); // 234 should show, occurrence 1
Serial.println("Events test: info event set, data: 234");
Serial.print("datalayer.battery.status.bms_status: ");
Serial.println(datalayer.battery.status.bms_status);
logging.println("Events test: info event set, data: 234");
logging.print("datalayer.battery.status.bms_status: ");
logging.println(datalayer.battery.status.bms_status);
}
break;
case ETOT_INFO:
@ -45,9 +45,9 @@ void run_sequence_on_target(void) {
timer.set_interval(8000);
clear_event(EVENT_DUMMY_INFO);
events_test_state = ETOT_INFO_CLEAR;
Serial.println("Events test : info event cleared");
Serial.print("datalayer.battery.status.bms_status: ");
Serial.println(datalayer.battery.status.bms_status);
logging.println("Events test : info event cleared");
logging.print("datalayer.battery.status.bms_status: ");
logging.println(datalayer.battery.status.bms_status);
}
break;
case ETOT_INFO_CLEAR:
@ -56,9 +56,9 @@ void run_sequence_on_target(void) {
events_test_state = ETOT_DEBUG;
set_event(EVENT_DUMMY_DEBUG, 111);
set_event(EVENT_DUMMY_DEBUG, 222); // 222 should show, occurrence 1
Serial.println("Events test : debug event set, data: 222");
Serial.print("datalayer.battery.status.bms_status: ");
Serial.println(datalayer.battery.status.bms_status);
logging.println("Events test : debug event set, data: 222");
logging.print("datalayer.battery.status.bms_status: ");
logging.println(datalayer.battery.status.bms_status);
}
break;
case ETOT_DEBUG:
@ -66,9 +66,9 @@ void run_sequence_on_target(void) {
timer.set_interval(8000);
clear_event(EVENT_DUMMY_DEBUG);
events_test_state = ETOT_DEBUG_CLEAR;
Serial.println("Events test : info event cleared");
Serial.print("datalayer.battery.status.bms_status: ");
Serial.println(datalayer.battery.status.bms_status);
logging.println("Events test : info event cleared");
logging.print("datalayer.battery.status.bms_status: ");
logging.println(datalayer.battery.status.bms_status);
}
break;
case ETOT_DEBUG_CLEAR:
@ -77,9 +77,9 @@ void run_sequence_on_target(void) {
events_test_state = ETOT_WARNING;
set_event(EVENT_DUMMY_WARNING, 234);
set_event(EVENT_DUMMY_WARNING, 121); // 121 should show, occurrence 1
Serial.println("Events test : warning event set, data: 121");
Serial.print("datalayer.battery.status.bms_status: ");
Serial.println(datalayer.battery.status.bms_status);
logging.println("Events test : warning event set, data: 121");
logging.print("datalayer.battery.status.bms_status: ");
logging.println(datalayer.battery.status.bms_status);
}
break;
case ETOT_WARNING:
@ -87,9 +87,9 @@ void run_sequence_on_target(void) {
timer.set_interval(8000);
clear_event(EVENT_DUMMY_WARNING);
events_test_state = ETOT_WARNING_CLEAR;
Serial.println("Events test : warning event cleared");
Serial.print("datalayer.battery.status.bms_status: ");
Serial.println(datalayer.battery.status.bms_status);
logging.println("Events test : warning event cleared");
logging.print("datalayer.battery.status.bms_status: ");
logging.println(datalayer.battery.status.bms_status);
}
break;
case ETOT_WARNING_CLEAR:
@ -98,9 +98,9 @@ void run_sequence_on_target(void) {
events_test_state = ETOT_ERROR;
set_event(EVENT_DUMMY_ERROR, 221);
set_event(EVENT_DUMMY_ERROR, 133); // 133 should show, occurrence 1
Serial.println("Events test : error event set, data: 133");
Serial.print("datalayer.battery.status.bms_status: ");
Serial.println(datalayer.battery.status.bms_status);
logging.println("Events test : error event set, data: 133");
logging.print("datalayer.battery.status.bms_status: ");
logging.println(datalayer.battery.status.bms_status);
}
break;
case ETOT_ERROR:
@ -108,9 +108,9 @@ void run_sequence_on_target(void) {
timer.set_interval(8000);
clear_event(EVENT_DUMMY_ERROR);
events_test_state = ETOT_ERROR_CLEAR;
Serial.println("Events test : error event cleared");
Serial.print("datalayer.battery.status.bms_status: ");
Serial.println(datalayer.battery.status.bms_status);
logging.println("Events test : error event cleared");
logging.print("datalayer.battery.status.bms_status: ");
logging.println(datalayer.battery.status.bms_status);
}
break;
case ETOT_ERROR_CLEAR:
@ -119,9 +119,9 @@ void run_sequence_on_target(void) {
events_test_state = ETOT_ERROR_LATCHED;
set_event_latched(EVENT_DUMMY_ERROR, 221);
set_event_latched(EVENT_DUMMY_ERROR, 133); // 133 should show, occurrence 1
Serial.println("Events test : latched error event set, data: 133");
Serial.print("datalayer.battery.status.bms_status: ");
Serial.println(datalayer.battery.status.bms_status);
logging.println("Events test : latched error event set, data: 133");
logging.print("datalayer.battery.status.bms_status: ");
logging.println(datalayer.battery.status.bms_status);
}
break;
case ETOT_ERROR_LATCHED:
@ -129,9 +129,9 @@ void run_sequence_on_target(void) {
timer.set_interval(8000);
clear_event(EVENT_DUMMY_ERROR);
events_test_state = ETOT_DONE;
Serial.println("Events test : latched error event cleared?");
Serial.print("datalayer.battery.status.bms_status: ");
Serial.println(datalayer.battery.status.bms_status);
logging.println("Events test : latched error event cleared?");
logging.print("datalayer.battery.status.bms_status: ");
logging.println(datalayer.battery.status.bms_status);
}
break;
case ETOT_DONE:

View file

@ -0,0 +1,86 @@
#include "logging.h"
#include "../../datalayer/datalayer.h"
size_t Logging::write(const uint8_t* buffer, size_t size) {
#ifdef DEBUG_LOG
char* message_string = datalayer.system.info.logged_can_messages;
int offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer
size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages);
unsigned long currentTime = millis();
#ifdef DEBUG_VIA_USB
size_t n = 0;
while (size--) {
if (Serial.write(*buffer++))
n++;
else
break;
}
return n;
#endif
#ifdef DEBUG_VIA_WEB
if (datalayer.system.info.can_logging_active) {
return 0;
}
if (offset + size + 13 > sizeof(datalayer.system.info.logged_can_messages)) {
offset = 0;
}
if (buffer[0] != '\r' && buffer[0] != '\n' &&
(offset == 0 || message_string[offset - 1] == '\r' || message_string[offset - 1] == '\n')) {
offset += snprintf(message_string + offset, message_string_size - offset - 1, "%8lu.%03lu ", currentTime / 1000,
currentTime % 1000);
}
memcpy(message_string + offset, buffer, size);
datalayer.system.info.logged_can_messages_offset = offset + size; // Update offset in buffer
return size;
#endif // DEBUG_VIA_WEB
#endif // DEBUG_LOG
return 0;
}
void Logging::printf(const char* fmt, ...) {
#ifdef DEBUG_LOG
char* message_string = datalayer.system.info.logged_can_messages;
int offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer
size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages);
#ifdef DEBUG_VIA_USB
static char buf[128];
message_string = buf;
offset = 0;
message_string_size = sizeof(buf);
#endif
#ifdef DEBUG_VIA_WEB
if (datalayer.system.info.can_logging_active) {
return;
}
message_string = datalayer.system.info.logged_can_messages;
offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer
message_string_size = sizeof(datalayer.system.info.logged_can_messages);
#endif
if (offset + 128 > sizeof(datalayer.system.info.logged_can_messages)) {
// Not enough space, reset and start from the beginning
offset = 0;
}
unsigned long currentTime = millis();
// Add timestamp
offset += snprintf(message_string + offset, message_string_size - offset - 1, "%8lu.%03lu ", currentTime / 1000,
currentTime % 1000);
va_list(args);
va_start(args, fmt);
offset += vsnprintf(message_string + offset, message_string_size - offset - 1, fmt, args);
va_end(args);
if (datalayer.system.info.can_logging_active) {
size_t size = offset;
size_t n = 0;
while (size--) {
if (Serial.write(*message_string++))
n++;
else
break;
}
} else {
datalayer.system.info.logged_can_messages_offset = offset; // Update offset in buffer
}
#endif // DEBUG_LOG
}

View file

@ -0,0 +1,16 @@
#ifndef __LOGGING_H__
#define __LOGGING_H__
#include <inttypes.h>
#include "Print.h"
class Logging : public Print {
public:
virtual size_t write(const uint8_t* buffer, size_t size);
virtual size_t write(uint8_t) { return 0; }
void printf(const char* fmt, ...);
Logging() {}
};
extern Logging logging;
#endif // __LOGGING_H__

View file

@ -4,6 +4,10 @@
String can_logger_processor(const String& var) {
if (var == "X") {
if (!datalayer.system.info.can_logging_active) {
datalayer.system.info.logged_can_messages_offset = 0;
datalayer.system.info.logged_can_messages[0] = '\0';
}
datalayer.system.info.can_logging_active =
true; // Signal to main loop that we should log messages. Disabled by default for performance reasons
String content = "";
@ -19,7 +23,7 @@ String can_logger_processor(const String& var) {
"monospace; }";
content += "</style>";
content += "<button onclick='refreshPage()'>Refresh data</button> ";
content += "<button onclick='exportLogs()'>Export to .txt</button> ";
content += "<button onclick='exportLog()'>Export to .txt</button> ";
content += "<button onclick='stopLoggingAndGoToMainPage()'>Back to main page</button>";
// Start a new block for the CAN messages
@ -47,9 +51,9 @@ String can_logger_processor(const String& var) {
// Add JavaScript for navigation
content += "<script>";
content += "function refreshPage(){ location.reload(true); }";
content += "function exportLogs() { window.location.href = '/export_logs'; }";
content += "function exportLog() { window.location.href = '/export_can_log'; }";
content += "function stopLoggingAndGoToMainPage() {";
content += " fetch('/stop_logging').then(() => window.location.href = '/');";
content += " fetch('/stop_can_logging').then(() => window.location.href = '/');";
content += "}";
content += "</script>";
return content;

View file

@ -0,0 +1,36 @@
#include "debug_logging_html.h"
#include <Arduino.h>
#include "../../datalayer/datalayer.h"
#ifdef DEBUG_VIA_WEB
String debug_logger_processor(const String& var) {
String content = "";
// Page format
content += "<style>";
content += "body { background-color: black; color: white; font-family: Arial, sans-serif; }";
content +=
"button { background-color: #505E67; color: white; border: none; padding: 10px 20px; margin-bottom: 20px; "
"cursor: pointer; border-radius: 10px; }";
content += "button:hover { background-color: #3A4A52; }";
content +=
".can-message { background-color: #404E57; margin-bottom: 5px; padding: 10px; border-radius: 5px; font-family: "
"monospace; }";
content += "</style>";
content += "<button onclick='refreshPage()'>Refresh data</button> ";
content += "<button onclick='exportLog()'>Export to .txt</button> ";
content += "<button onclick='goToMainPage()'>Back to main page</button>";
// Start a new block for the debug log messages
content += "<PRE style='text-align: left'>";
content += String(datalayer.system.info.logged_can_messages);
content += "</PRE>";
// Add JavaScript for navigation
content += "<script>";
content += "function refreshPage(){ location.reload(true); }";
content += "function exportLog() { window.location.href = '/export_log'; }";
content += "function goToMainPage() { window.location.href = '/'; }";
content += "</script>";
return content;
}
#endif // DEBUG_VIA_WEB

View file

@ -0,0 +1,16 @@
#ifndef DEBUGLOGGER_H
#define DEBUGLOGGER_H
#include <Arduino.h>
#include <string>
/**
* @brief Replaces placeholder with content section in web page
*
* @param[in] var
*
* @return String
*/
String debug_logger_processor(const String& var);
#endif

View file

@ -39,8 +39,8 @@ String events_processor(const String& var) {
for (const auto& event : order_events) {
EVENTS_ENUM_TYPE event_handle = event.event_handle;
event_pointer = event.event_pointer;
#ifdef DEBUG_VIA_USB
Serial.println("Event: " + String(get_event_enum_string(event_handle)) +
#ifdef DEBUG_LOG
logging.println("Showing Event: " + String(get_event_enum_string(event_handle)) +
" count: " + String(event_pointer->occurences) + " seconds: " + String(event_pointer->timestamp) +
" data: " + String(event_pointer->data) +
" level: " + String(get_event_level_string(event_handle)));

View file

@ -17,6 +17,7 @@ unsigned long ota_progress_millis = 0;
#include "advanced_battery_html.h"
#include "can_logging_html.h"
#include "cellmonitor_html.h"
#include "debug_logging_html.h"
#include "events_html.h"
#include "index_html.cpp"
#include "settings_html.h"
@ -63,14 +64,21 @@ void init_webserver() {
request->send_P(200, "text/html", index_html, can_logger_processor);
});
// Define the handler to stop logging
server.on("/stop_logging", HTTP_GET, [](AsyncWebServerRequest* request) {
#ifdef DEBUG_VIA_WEB
// Route for going to debug logging web page
server.on("/log", HTTP_GET, [](AsyncWebServerRequest* request) {
request->send_P(200, "text/html", index_html, debug_logger_processor);
});
#endif // DEBUG_VIA_WEB
// Define the handler to stop can logging
server.on("/stop_can_logging", HTTP_GET, [](AsyncWebServerRequest* request) {
datalayer.system.info.can_logging_active = false;
request->send_P(200, "text/plain", "Logging stopped");
});
// Define the handler to export logs
server.on("/export_logs", HTTP_GET, [](AsyncWebServerRequest* request) {
// Define the handler to export can log
server.on("/export_can_log", HTTP_GET, [](AsyncWebServerRequest* request) {
String logs = String(datalayer.system.info.logged_can_messages);
if (logs.length() == 0) {
logs = "No logs available.";
@ -96,6 +104,33 @@ void init_webserver() {
request->send(response);
});
// Define the handler to export debug log
server.on("/export_log", HTTP_GET, [](AsyncWebServerRequest* request) {
String logs = String(datalayer.system.info.logged_can_messages);
if (logs.length() == 0) {
logs = "No logs available.";
}
// Get the current time
time_t now = time(nullptr);
struct tm timeinfo;
localtime_r(&now, &timeinfo);
// Ensure time retrieval was successful
char filename[32];
if (strftime(filename, sizeof(filename), "log_%H-%M-%S.txt", &timeinfo)) {
// Valid filename created
} else {
// Fallback filename if automatic timestamping failed
strcpy(filename, "battery_emulator_log.txt");
}
// Use request->send with dynamic headers
AsyncWebServerResponse* response = request->beginResponse(200, "text/plain", logs);
response->addHeader("Content-Disposition", String("attachment; filename=\"") + String(filename) + "\"");
request->send(response);
});
// Route for going to cellmonitor web page
server.on("/cellmonitor", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
@ -535,14 +570,15 @@ String processor(const String& var) {
content += "<div style='background-color: #303E47; padding: 10px; margin-bottom: 10px;border-radius: 50px'>";
// Show version number
content += "<h4>Software: " + String(version_number) + "</h4>";
content += "<h4>Software: " + String(version_number);
// Show hardware used:
#ifdef HW_LILYGO
content += "<h4>Hardware: LilyGo T-CAN485</h4>";
content += " Hardware: LilyGo T-CAN485";
#endif // HW_LILYGO
#ifdef HW_STARK
content += "<h4>Hardware: Stark CMR Module</h4>";
content += " Hardware: Stark CMR Module";
#endif // HW_STARK
content += "</h4>";
content += "<h4>Uptime: " + uptime_formatter::getUptime() + "</h4>";
#ifdef FUNCTION_TIME_MEASUREMENT
// Load information
@ -566,11 +602,14 @@ String processor(const String& var) {
wl_status_t status = WiFi.status();
// Display ssid of network connected to and, if connected to the WiFi, its own IP
content += "<h4>SSID: " + String(ssid.c_str()) + "</h4>";
content += "<h4>SSID: " + String(ssid.c_str());
if (status == WL_CONNECTED) {
// Get and display the signal strength (RSSI) and channel
content += " RSSI:" + String(WiFi.RSSI()) + " dBm Ch: " + String(WiFi.channel());
}
content += "</h4>";
if (status == WL_CONNECTED) {
content += "<h4>IP: " + WiFi.localIP().toString() + "</h4>";
// Get and display the signal strength (RSSI) and channel
content += "<h4>Signal strength: " + String(WiFi.RSSI()) + " dBm, at channel " + String(WiFi.channel()) + "</h4>";
} else {
content += "<h4>Wifi state: " + getConnectResultString(status) + "</h4>";
}
@ -692,13 +731,30 @@ String processor(const String& var) {
}
content += "<h4>Temperature max: " + String(tempMaxFloat, 1) + " C</h4>";
content += "<h4>Temperature min: " + String(tempMinFloat, 1) + " C</h4>";
if (datalayer.battery.status.bms_status == ACTIVE) {
content += "<h4>System status: OK </h4>";
} else if (datalayer.battery.status.bms_status == UPDATING) {
content += "<h4>System status: UPDATING </h4>";
} else {
content += "<h4>System status: FAULT </h4>";
content += "<h4>System status: ";
switch (datalayer.battery.status.bms_status) {
case ACTIVE:
content += String("OK");
break;
case UPDATING:
content += String("UPDATING");
break;
case FAULT:
content += String("FAULT");
break;
case INACTIVE:
content += String("INACTIVE");
break;
case STANDBY:
content += String("STANDBY");
break;
default:
content += String("??");
break;
}
content += "</h4>";
if (datalayer.battery.status.current_dA == 0) {
content += "<h4>Battery idle</h4>";
} else if (datalayer.battery.status.current_dA < 0) {
@ -977,6 +1033,9 @@ String processor(const String& var) {
content += "<button onclick='Settings()'>Change Settings</button> ";
content += "<button onclick='Advanced()'>More Battery Info</button> ";
content += "<button onclick='CANlog()'>CAN logger</button> ";
#ifdef DEBUG_VIA_WEB
content += "<button onclick='Log()'>Log</button> ";
#endif // DEBUG_VIA_WEB
content += "<button onclick='Cellmon()'>Cellmonitor</button> ";
content += "<button onclick='Events()'>Events</button> ";
content += "<button onclick='askReboot()'>Reboot Emulator</button>";
@ -1002,6 +1061,7 @@ String processor(const String& var) {
content += "function Settings() { window.location.href = '/settings'; }";
content += "function Advanced() { window.location.href = '/advanced'; }";
content += "function CANlog() { window.location.href = '/canlog'; }";
content += "function Log() { window.location.href = '/log'; }";
content += "function Events() { window.location.href = '/events'; }";
content +=
"function askReboot() { if (window.confirm('Are you sure you want to reboot the emulator? NOTE: If "
@ -1062,9 +1122,9 @@ void onOTAProgress(size_t current, size_t final) {
// Log every 1 second
if (millis() - ota_progress_millis > 1000) {
ota_progress_millis = millis();
#ifdef DEBUG_VIA_USB
Serial.printf("OTA Progress Current: %u bytes, Final: %u bytes\n", current, final);
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.printf("OTA Progress Current: %u bytes, Final: %u bytes\n", current, final);
#endif // DEBUG_LOG
// Reset the "watchdog"
ota_timeout_timer.reset();
}
@ -1081,13 +1141,13 @@ void onOTAEnd(bool success) {
// Max Charge/Discharge = 0; CAN = stop; contactors = open
setBatteryPause(true, true, true, false);
// a reboot will be done by the OTA library. no need to do anything here
#ifdef DEBUG_VIA_USB
Serial.println("OTA update finished successfully!");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.println("OTA update finished successfully!");
#endif // DEBUG_LOG
} else {
#ifdef DEBUG_VIA_USB
Serial.println("There was an error during OTA update!");
#endif // DEBUG_VIA_USB
#ifdef DEBUG_LOG
logging.println("There was an error during OTA update!");
#endif // DEBUG_LOG
//try to Resume the battery pause and CAN communication
setBatteryPause(false, false);
}

View file

@ -72,28 +72,28 @@ void wifi_monitor() {
// Increase the current check interval if it's not at the maximum
if (current_check_interval + STEP_WIFI_CHECK_INTERVAL <= MAX_STEP_WIFI_CHECK_INTERVAL)
current_check_interval += STEP_WIFI_CHECK_INTERVAL;
#ifdef DEBUG_VIA_USB
Serial.println("Wi-Fi not connected, attempting to reconnect...");
#ifdef DEBUG_LOG
logging.println("Wi-Fi not connected, attempting to reconnect...");
#endif
// Try WiFi.reconnect() if it was successfully connected at least once
if (hasConnectedBefore) {
lastReconnectAttempt = millis(); // Reset reconnection attempt timer
#ifdef DEBUG_VIA_USB
Serial.println("Wi-Fi reconnect attempt...");
#ifdef DEBUG_LOG
logging.println("Wi-Fi reconnect attempt...");
#endif
if (WiFi.reconnect()) {
#ifdef DEBUG_VIA_USB
Serial.println("Wi-Fi reconnect attempt sucess...");
#ifdef DEBUG_LOG
logging.println("Wi-Fi reconnect attempt sucess...");
#endif
reconnectAttempts = 0; // Reset the attempt counter on successful reconnect
} else {
#ifdef DEBUG_VIA_USB
Serial.println("Wi-Fi reconnect attempt error...");
#ifdef DEBUG_LOG
logging.println("Wi-Fi reconnect attempt error...");
#endif
reconnectAttempts++;
if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
#ifdef DEBUG_VIA_USB
Serial.println("Failed to reconnect multiple times, forcing a full connection attempt...");
#ifdef DEBUG_LOG
logging.println("Failed to reconnect multiple times, forcing a full connection attempt...");
#endif
FullReconnectToWiFi();
}
@ -101,8 +101,8 @@ void wifi_monitor() {
} else {
// If no previous connection, force a full connection attempt
if (currentMillis - lastReconnectAttempt > current_full_reconnect_interval) {
#ifdef DEBUG_VIA_USB
Serial.println("No previous OK connection, force a full connection attempt...");
#ifdef DEBUG_LOG
logging.println("No previous OK connection, force a full connection attempt...");
#endif
FullReconnectToWiFi();
}
@ -127,13 +127,13 @@ static void FullReconnectToWiFi() {
static void connectToWiFi() {
if (WiFi.status() != WL_CONNECTED) {
lastReconnectAttempt = millis(); // Reset the reconnect attempt timer
#ifdef DEBUG_VIA_USB
Serial.println("Connecting to Wi-Fi...");
#ifdef DEBUG_LOG
logging.println("Connecting to Wi-Fi...");
#endif
WiFi.begin(ssid.c_str(), password.c_str(), wifi_channel);
} else {
#ifdef DEBUG_VIA_USB
Serial.println("Wi-Fi already connected.");
#ifdef DEBUG_LOG
logging.println("Wi-Fi already connected.");
#endif
}
}
@ -143,10 +143,11 @@ static void onWifiConnect(WiFiEvent_t event, WiFiEventInfo_t info) {
clear_event(EVENT_WIFI_DISCONNECT);
set_event(EVENT_WIFI_CONNECT, 0);
connected_once = true;
#ifdef DEBUG_VIA_USB
Serial.println("Wi-Fi connected.");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
#ifdef DEBUG_LOG
logging.print("Wi-Fi connected. RSSI: ");
logging.print(-WiFi.RSSI());
logging.print(" dBm, IP address: ");
logging.println(WiFi.localIP().toString());
#endif
hasConnectedBefore = true; // Mark as successfully connected at least once
reconnectAttempts = 0; // Reset the attempt counter
@ -159,10 +160,10 @@ static void onWifiConnect(WiFiEvent_t event, WiFiEventInfo_t info) {
static void onWifiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
//clear disconnects events if we got a IP
clear_event(EVENT_WIFI_DISCONNECT);
#ifdef DEBUG_VIA_USB
Serial.println("Wi-Fi Got IP.");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
#ifdef DEBUG_LOG
logging.print("Wi-Fi Got IP. ");
logging.print("IP address: ");
logging.println(WiFi.localIP().toString());
#endif
}
@ -170,8 +171,8 @@ static void onWifiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
static void onWifiDisconnect(WiFiEvent_t event, WiFiEventInfo_t info) {
if (connected_once)
set_event(EVENT_WIFI_DISCONNECT, 0);
#ifdef DEBUG_VIA_USB
Serial.println("Wi-Fi disconnected.");
#ifdef DEBUG_LOG
logging.println("Wi-Fi disconnected.");
#endif
//we dont do anything here, the reconnect will be handled by the monitor
//too many events received when the connection is lost
@ -188,8 +189,8 @@ void init_mDNS() {
// Initialize mDNS .local resolution
if (!MDNS.begin(mdnsHost)) {
#ifdef DEBUG_VIA_USB
Serial.println("Error setting up MDNS responder!");
#ifdef DEBUG_LOG
logging.println("Error setting up MDNS responder!");
#endif
} else {
// Advertise via bonjour the service so we can auto discover these battery emulators on the local network.
@ -200,16 +201,16 @@ void init_mDNS() {
#ifdef WIFIAP
void init_WiFi_AP() {
#ifdef DEBUG_VIA_USB
Serial.println("Creating Access Point: " + String(ssidAP));
Serial.println("With password: " + String(passwordAP));
#ifdef DEBUG_LOG
logging.println("Creating Access Point: " + String(ssidAP));
logging.println("With password: " + String(passwordAP));
#endif
WiFi.softAP(ssidAP, passwordAP);
IPAddress IP = WiFi.softAPIP();
#ifdef DEBUG_VIA_USB
Serial.println("Access Point created.");
Serial.print("IP address: ");
Serial.println(IP);
#ifdef DEBUG_LOG
logging.println("Access Point created.");
logging.print("IP address: ");
logging.println(IP);
#endif
}
#endif // WIFIAP

View file

@ -9,6 +9,7 @@
#include "devboard/hal/hal.h"
#include "devboard/safety/safety.h"
#include "devboard/utils/logging.h"
#include "devboard/utils/time_meas.h"
#include "devboard/utils/types.h"

View file

@ -153,13 +153,13 @@ void update_values_can_inverter() { //This function maps all the values fetched
BYD_210.data.u8[2] = (datalayer.battery.status.temperature_min_dC >> 8);
BYD_210.data.u8[3] = (datalayer.battery.status.temperature_min_dC & 0x00FF);
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
if (inverter_name[0] != 0) {
Serial.print("Detected inverter: ");
logging.print("Detected inverter: ");
for (uint8_t i = 0; i < 7; i++) {
Serial.print((char)inverter_name[i]);
logging.print((char)inverter_name[i]);
}
Serial.println();
logging.println();
}
#endif
}

View file

@ -595,8 +595,8 @@ void send_can_inverter() { // This function loops as fast as possible
// Send a subset of messages per iteration to avoid overloading the CAN bus / transmit buffer
switch (can_message_cellvolt_index) {
case 0:
#ifdef DEBUG_VIA_USB
Serial.println("Sending large batch");
#ifdef DEBUG_LOG
logging.println("Sending large batch");
#endif
transmit_can(&FOXESS_0C1D, can_config.inverter);
transmit_can(&FOXESS_0C21, can_config.inverter);
@ -655,8 +655,8 @@ void send_can_inverter() { // This function loops as fast as possible
transmit_can(&FOXESS_0D49, can_config.inverter);
transmit_can(&FOXESS_0D51, can_config.inverter);
transmit_can(&FOXESS_0D59, can_config.inverter);
#ifdef DEBUG_VIA_USB
Serial.println("Sending completed");
#ifdef DEBUG_LOG
logging.println("Sending completed");
#endif
send_cellvoltages = false;
break;
@ -679,14 +679,14 @@ void receive_can_inverter(CAN_frame rx_frame) {
if (rx_frame.data.u8[0] == 0x03) { //0x1871 [0x03, 0x06, 0x17, 0x05, 0x09, 0x09, 0x28, 0x22]
//This message is sent by the inverter every '6' seconds (0.5s after the pack serial numbers)
//and contains a timestamp in bytes 2-7 i.e. <YY>,<MM>,<DD>,<HH>,<mm>,<ss>
#ifdef DEBUG_VIA_USB
Serial.println("Inverter sends current time and date");
#ifdef DEBUG_LOG
logging.println("Inverter sends current time and date");
#endif
} else if (rx_frame.data.u8[0] == 0x01) {
if (rx_frame.data.u8[4] == 0x00) {
// Inverter wants to know bms info (every 1s)
#ifdef DEBUG_VIA_USB
Serial.println("Inverter requests 1s BMS info, we reply");
#ifdef DEBUG_LOG
logging.println("Inverter requests 1s BMS info, we reply");
#endif
transmit_can(&FOXESS_1872, can_config.inverter);
transmit_can(&FOXESS_1873, can_config.inverter);
@ -698,8 +698,8 @@ void receive_can_inverter(CAN_frame rx_frame) {
transmit_can(&FOXESS_1879, can_config.inverter);
} else if (rx_frame.data.u8[4] == 0x01) { // b4 0x01 , 0x1871 [0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00]
//Inverter wants to know all individual cellvoltages (occurs 6 seconds after valid BMS reply)
#ifdef DEBUG_VIA_USB
Serial.println("Inverter requests individual battery pack status, we reply");
#ifdef DEBUG_LOG
logging.println("Inverter requests individual battery pack status, we reply");
#endif
transmit_can(&FOXESS_0C05, can_config.inverter); //TODO, should we limit this incase NUMBER_OF_PACKS =! 8?
transmit_can(&FOXESS_0C06, can_config.inverter);
@ -711,19 +711,19 @@ void receive_can_inverter(CAN_frame rx_frame) {
transmit_can(&FOXESS_0C0C, can_config.inverter);
} else if (rx_frame.data.u8[4] == 0x04) { // b4 0x01 , 0x1871 [0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00]
//Inverter wants to know all individual cellvoltages (occurs 6 seconds after valid BMS reply)
#ifdef DEBUG_VIA_USB
Serial.println("Inverter requests cellvoltages and temps, we reply");
#ifdef DEBUG_LOG
logging.println("Inverter requests cellvoltages and temps, we reply");
#endif
send_cellvoltages = true;
}
} else if (rx_frame.data.u8[0] == 0x02) { //0x1871 [0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00]
// Ack message
#ifdef DEBUG_VIA_USB
Serial.println("Inverter acks, no reply needed");
#ifdef DEBUG_LOG
logging.println("Inverter acks, no reply needed");
#endif
} else if (rx_frame.data.u8[0] == 0x05) { //0x1871 [0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00]
#ifdef DEBUG_VIA_USB
Serial.println("Inverter wants to know serial numbers, we reply");
#ifdef DEBUG_LOG
logging.println("Inverter wants to know serial numbers, we reply");
#endif
for (uint8_t i = 0; i < (NUMBER_OF_PACKS + 1); i++) {
FOXESS_1881.data.u8[0] = (uint8_t)i;

View file

@ -119,15 +119,15 @@ void float2frameMSB(byte* arr, float value, byte framepointer) {
void send_kostal(byte* arr, int alen) {
#ifdef DEBUG_KOSTAL_RS485_DATA
Serial.print("TX: ");
logging.print("TX: ");
for (int i = 0; i < alen; i++) {
if (arr[i] < 0x10) {
Serial.print("0");
logging.print("0");
}
Serial.print(arr[i], HEX);
Serial.print(" ");
logging.print(arr[i], HEX);
logging.print(" ");
}
Serial.println("\n");
logging.println("\n");
#endif
Serial2.write(arr, alen);
}
@ -274,12 +274,12 @@ void receive_RS485() // Runs as fast as possible to handle the serial stream
if (RS485_RXFRAME[rx_index - 1] == 0x00) {
if ((rx_index == 10) && (RS485_RXFRAME[0] == 0x09) && register_content_ok) {
#ifdef DEBUG_KOSTAL_RS485_DATA
Serial.print("RX: ");
logging.print("RX: ");
for (uint8_t i = 0; i < 10; i++) {
Serial.print(RS485_RXFRAME[i], HEX);
Serial.print(" ");
logging.print(RS485_RXFRAME[i], HEX);
logging.print(" ");
}
Serial.println("");
logging.println("");
#endif
rx_index = 0;
if (check_kostal_frame_crc()) {

View file

@ -60,8 +60,8 @@ void manageSerialLinkTransmitter() {
}
bool sendError = dataLinkTransmit.checkTransmissionError(true);
if (sendError) {
Serial.print(currentTime);
Serial.println(" - ERROR: Serial Data Link - SEND Error");
logging.print(currentTime);
logging.println(" - ERROR: Serial Data Link - SEND Error");
lasterror = true;
transmitGoodSince = currentTime;
}
@ -82,17 +82,17 @@ void manageSerialLinkTransmitter() {
if (lasterror && (ackReceived > 0)) {
lasterror = false;
Serial.print(currentTime);
Serial.println(" - RECOVERY: Serial Data Link - Send GOOD");
logging.print(currentTime);
logging.println(" - RECOVERY: Serial Data Link - Send GOOD");
}
//--- reporting every 60 seconds that transmission is good
if (currentTime - transmitGoodSince > INTERVAL_60_S) {
transmitGoodSince = currentTime;
Serial.print(currentTime);
Serial.println(" - Transmit Good");
logging.print(currentTime);
logging.println(" - Transmit Good");
// printUsefullData();
#ifdef DEBUG_VIA_USB
#ifdef DEBUG_LOG
void printSendingValues();
#endif
}
@ -100,13 +100,13 @@ void manageSerialLinkTransmitter() {
//--- report that Errors been ocurring for > 60 seconds
if (currentTime - lastGood > INTERVAL_60_S) {
lastGood = currentTime;
Serial.print(currentTime);
Serial.println(" - Transmit Failed : 60 seconds");
logging.print(currentTime);
logging.println(" - Transmit Failed : 60 seconds");
// print the max_ data
Serial.println("SerialDataLink : bms_status=4");
Serial.println("SerialDataLink : LEDcolor = RED");
Serial.println("SerialDataLink : max_target_discharge_power = 0");
Serial.println("SerialDataLink : max_target_charge_power = 0");
logging.println("SerialDataLink : bms_status=4");
logging.println("SerialDataLink : LEDcolor = RED");
logging.println("SerialDataLink : max_target_discharge_power = 0");
logging.println("SerialDataLink : max_target_charge_power = 0");
datalayer.battery.status.max_discharge_power_W = 0;
datalayer.battery.status.max_charge_power_W = 0;
@ -117,8 +117,8 @@ void manageSerialLinkTransmitter() {
// lastMessageReceived from CAN bus (Battery)
if (currentTime - lastMessageReceived > (5 * 60000) ) // 5 minutes
{
Serial.print(millis());
Serial.println(" - Data Stale : 5 minutes");
logging.print(millis());
logging.println(" - Data Stale : 5 minutes");
// throw error
// stop transmitting until fresh
@ -154,42 +154,42 @@ void manageSerialLinkTransmitter() {
}
void printSendingValues() {
Serial.println("Values from battery: ");
Serial.print("SOC: ");
Serial.print(datalayer.battery.status.real_soc);
Serial.print(" SOH: ");
Serial.print(datalayer.battery.status.soh_pptt);
Serial.print(" Voltage: ");
Serial.print(datalayer.battery.status.voltage_dV);
Serial.print(" Current: ");
Serial.print(datalayer.battery.status.current_dA);
Serial.print(" Capacity: ");
Serial.print(datalayer.battery.info.total_capacity_Wh);
Serial.print(" Remain cap: ");
Serial.print(datalayer.battery.status.remaining_capacity_Wh);
Serial.print(" Max discharge W: ");
Serial.print(datalayer.battery.status.max_discharge_power_W);
Serial.print(" Max charge W: ");
Serial.print(datalayer.battery.status.max_charge_power_W);
Serial.print(" BMS status: ");
Serial.print(datalayer.battery.status.bms_status);
Serial.print(" Power: ");
Serial.print(datalayer.battery.status.active_power_W);
Serial.print(" Temp min: ");
Serial.print(datalayer.battery.status.temperature_min_dC);
Serial.print(" Temp max: ");
Serial.print(datalayer.battery.status.temperature_max_dC);
Serial.print(" Cell max: ");
Serial.print(datalayer.battery.status.cell_max_voltage_mV);
Serial.print(" Cell min: ");
Serial.print(datalayer.battery.status.cell_min_voltage_mV);
Serial.print(" LFP : ");
Serial.print(datalayer.battery.info.chemistry);
Serial.print(" Battery Allows Contactor Closing: ");
Serial.print(datalayer.system.status.battery_allows_contactor_closing);
Serial.print(" Inverter Allows Contactor Closing: ");
Serial.print(datalayer.system.status.inverter_allows_contactor_closing);
logging.println("Values from battery: ");
logging.print("SOC: ");
logging.print(datalayer.battery.status.real_soc);
logging.print(" SOH: ");
logging.print(datalayer.battery.status.soh_pptt);
logging.print(" Voltage: ");
logging.print(datalayer.battery.status.voltage_dV);
logging.print(" Current: ");
logging.print(datalayer.battery.status.current_dA);
logging.print(" Capacity: ");
logging.print(datalayer.battery.info.total_capacity_Wh);
logging.print(" Remain cap: ");
logging.print(datalayer.battery.status.remaining_capacity_Wh);
logging.print(" Max discharge W: ");
logging.print(datalayer.battery.status.max_discharge_power_W);
logging.print(" Max charge W: ");
logging.print(datalayer.battery.status.max_charge_power_W);
logging.print(" BMS status: ");
logging.print(datalayer.battery.status.bms_status);
logging.print(" Power: ");
logging.print(datalayer.battery.status.active_power_W);
logging.print(" Temp min: ");
logging.print(datalayer.battery.status.temperature_min_dC);
logging.print(" Temp max: ");
logging.print(datalayer.battery.status.temperature_max_dC);
logging.print(" Cell max: ");
logging.print(datalayer.battery.status.cell_max_voltage_mV);
logging.print(" Cell min: ");
logging.print(datalayer.battery.status.cell_min_voltage_mV);
logging.print(" LFP : ");
logging.print(datalayer.battery.info.chemistry);
logging.print(" Battery Allows Contactor Closing: ");
logging.print(datalayer.system.status.battery_allows_contactor_closing);
logging.print(" Inverter Allows Contactor Closing: ");
logging.print(datalayer.system.status.inverter_allows_contactor_closing);
Serial.println("");
logging.println("");
}
#endif

View file

@ -207,8 +207,8 @@ void receive_can_inverter(CAN_frame rx_frame) {
LastFrameTime = millis();
switch (STATE) {
case (BATTERY_ANNOUNCE):
#ifdef DEBUG_VIA_USB
Serial.println("Solax Battery State: Announce");
#ifdef DEBUG_LOG
logging.println("Solax Battery State: Announce");
#endif
datalayer.system.status.inverter_allows_contactor_closing = false;
SOLAX_1875.data.u8[4] = (0x00); // Inform Inverter: Contactor 0=off, 1=on.
@ -239,8 +239,8 @@ void receive_can_inverter(CAN_frame rx_frame) {
transmit_can(&SOLAX_1878, can_config.inverter);
transmit_can(&SOLAX_1801, can_config.inverter); // Announce that the battery will be connected
STATE = CONTACTOR_CLOSED; // Jump to Contactor Closed State
#ifdef DEBUG_VIA_USB
Serial.println("Solax Battery State: Contactor Closed");
#ifdef DEBUG_LOG
logging.println("Solax Battery State: Contactor Closed");
#endif
break;
@ -267,13 +267,13 @@ void receive_can_inverter(CAN_frame rx_frame) {
if (rx_frame.ID == 0x1871 && rx_frame.data.u64 == __builtin_bswap64(0x0500010000000000)) {
transmit_can(&SOLAX_1881, can_config.inverter);
transmit_can(&SOLAX_1882, can_config.inverter);
#ifdef DEBUG_VIA_USB
Serial.println("1871 05-frame received from inverter");
#ifdef DEBUG_LOG
logging.println("1871 05-frame received from inverter");
#endif
}
if (rx_frame.ID == 0x1871 && rx_frame.data.u8[0] == (0x03)) {
#ifdef DEBUG_VIA_USB
Serial.println("1871 03-frame received from inverter");
#ifdef DEBUG_LOG
logging.println("1871 03-frame received from inverter");
#endif
}
}