mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 09:49:32 +02:00
Make USB/WEB debug configurable
This commit is contained in:
parent
a1e5bc57d0
commit
aa9a4d429e
14 changed files with 115 additions and 162 deletions
|
@ -64,7 +64,7 @@ void setup() {
|
||||||
|
|
||||||
init_serial();
|
init_serial();
|
||||||
|
|
||||||
// We print this after setting up serial, such that is also printed to serial with DEBUG_VIA_USB set.
|
// We print this after setting up serial, so that is also printed if configured to do so
|
||||||
logging.printf("Battery emulator %s build " __DATE__ " " __TIME__ "\n", version_number);
|
logging.printf("Battery emulator %s build " __DATE__ " " __TIME__ "\n", version_number);
|
||||||
|
|
||||||
init_events();
|
init_events();
|
||||||
|
@ -352,9 +352,6 @@ void init_serial() {
|
||||||
// Init Serial monitor
|
// Init Serial monitor
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
while (!Serial) {}
|
while (!Serial) {}
|
||||||
#ifdef DEBUG_VIA_USB
|
|
||||||
Serial.println("__ OK __");
|
|
||||||
#endif // DEBUG_VIA_USB
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_interconnect_available() {
|
void check_interconnect_available() {
|
||||||
|
|
|
@ -109,10 +109,6 @@
|
||||||
//#define INTERLOCK_REQUIRED //Nissan LEAF specific setting, if enabled requires both high voltage conenctors to be seated before starting
|
//#define INTERLOCK_REQUIRED //Nissan LEAF specific setting, if enabled requires both high voltage conenctors to be seated before starting
|
||||||
//#define LOG_TO_SD //Enable this line to log diagnostic data to SD card (WARNING, raises CPU load, do not use for production)
|
//#define LOG_TO_SD //Enable this line to log diagnostic data to SD card (WARNING, raises CPU load, do not use for production)
|
||||||
//#define LOG_CAN_TO_SD //Enable this line to log incoming/outgoing CAN & CAN-FD messages to SD card (WARNING, raises CPU load, do not use for production)
|
//#define LOG_CAN_TO_SD //Enable this line to log incoming/outgoing CAN & CAN-FD messages to SD card (WARNING, raises CPU load, do not use for production)
|
||||||
//#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)
|
|
||||||
//#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)
|
|
||||||
|
|
||||||
/* CAN options */
|
/* CAN options */
|
||||||
//#define CAN_ADDON //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 chip (Needed for some inverters / double battery)
|
//#define CAN_ADDON //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 chip (Needed for some inverters / double battery)
|
||||||
#define CRYSTAL_FREQUENCY_MHZ 8 //CAN_ADDON option, what is your MCP2515 add-on boards crystal frequency?
|
#define CRYSTAL_FREQUENCY_MHZ 8 //CAN_ADDON option, what is your MCP2515 add-on boards crystal frequency?
|
||||||
|
@ -225,7 +221,7 @@ extern IPAddress gateway;
|
||||||
extern IPAddress subnet;
|
extern IPAddress subnet;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(DEBUG_VIA_USB) || defined(DEBUG_VIA_WEB) || defined(LOG_TO_SD)
|
#if defined(DEBUG_VIA_USB) || defined(LOG_TO_SD)
|
||||||
#define DEBUG_LOG
|
#define DEBUG_LOG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "../communication/can/comm_can.h"
|
#include "../communication/can/comm_can.h"
|
||||||
#include "../datalayer/datalayer.h"
|
#include "../datalayer/datalayer.h"
|
||||||
|
#include "../devboard/utils/logging.h"
|
||||||
|
|
||||||
uint8_t reverse_bits(uint8_t byte) {
|
uint8_t reverse_bits(uint8_t byte) {
|
||||||
uint8_t reversed = 0;
|
uint8_t reversed = 0;
|
||||||
|
@ -122,9 +123,7 @@ void BmwSbox::transmit_can(unsigned long currentMillis) {
|
||||||
SBOX_100.data.u8[0] = 0x86; // Precharge relay only
|
SBOX_100.data.u8[0] = 0x86; // Precharge relay only
|
||||||
prechargeStartTime = currentMillis;
|
prechargeStartTime = currentMillis;
|
||||||
contactorStatus = NEGATIVE;
|
contactorStatus = NEGATIVE;
|
||||||
#ifdef DEBUG_VIA_USB
|
logging.println("S-BOX Precharge relay engaged");
|
||||||
Serial.println("S-BOX Precharge relay engaged");
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case NEGATIVE:
|
case NEGATIVE:
|
||||||
if (currentMillis - prechargeStartTime >= CONTACTOR_CONTROL_T1) {
|
if (currentMillis - prechargeStartTime >= CONTACTOR_CONTROL_T1) {
|
||||||
|
@ -132,9 +131,7 @@ void BmwSbox::transmit_can(unsigned long currentMillis) {
|
||||||
negativeStartTime = currentMillis;
|
negativeStartTime = currentMillis;
|
||||||
contactorStatus = POSITIVE;
|
contactorStatus = POSITIVE;
|
||||||
datalayer.shunt.precharging = true;
|
datalayer.shunt.precharging = true;
|
||||||
#ifdef DEBUG_VIA_USB
|
logging.println("S-BOX Negative relay engaged");
|
||||||
Serial.println("S-BOX Negative relay engaged");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case POSITIVE:
|
case POSITIVE:
|
||||||
|
@ -145,18 +142,14 @@ void BmwSbox::transmit_can(unsigned long currentMillis) {
|
||||||
positiveStartTime = currentMillis;
|
positiveStartTime = currentMillis;
|
||||||
contactorStatus = PRECHARGE_OFF;
|
contactorStatus = PRECHARGE_OFF;
|
||||||
datalayer.shunt.precharging = false;
|
datalayer.shunt.precharging = false;
|
||||||
#ifdef DEBUG_VIA_USB
|
logging.println("S-BOX Positive relay engaged");
|
||||||
Serial.println("S-BOX Positive relay engaged");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PRECHARGE_OFF:
|
case PRECHARGE_OFF:
|
||||||
if (currentMillis - positiveStartTime >= CONTACTOR_CONTROL_T3) {
|
if (currentMillis - positiveStartTime >= CONTACTOR_CONTROL_T3) {
|
||||||
SBOX_100.data.u8[0] = 0x6A; // Negative + Positive
|
SBOX_100.data.u8[0] = 0x6A; // Negative + Positive
|
||||||
contactorStatus = COMPLETED;
|
contactorStatus = COMPLETED;
|
||||||
#ifdef DEBUG_VIA_USB
|
logging.println("S-BOX Precharge relay released");
|
||||||
Serial.println("S-BOX Precharge relay released");
|
|
||||||
#endif
|
|
||||||
datalayer.shunt.contactors_engaged = true;
|
datalayer.shunt.contactors_engaged = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -108,18 +108,16 @@ uint32_t decode_uint32be(uint8_t data[8], uint8_t offset) {
|
||||||
((uint32_t)data[offset + 3]);
|
((uint32_t)data[offset + 3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
|
||||||
void dump_buff(const char* msg, uint8_t* buff, uint8_t len) {
|
void dump_buff(const char* msg, uint8_t* buff, uint8_t len) {
|
||||||
Serial.print("[DALY-BMS] ");
|
logging.print("[DALY-BMS] ");
|
||||||
Serial.print(msg);
|
logging.print(msg);
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
Serial.print(buff[i] >> 4, HEX);
|
logging.print(buff[i] >> 4, HEX);
|
||||||
Serial.print(buff[i] & 0xf, HEX);
|
logging.print(buff[i] & 0xf, HEX);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
}
|
}
|
||||||
Serial.println();
|
logging.println();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void decode_packet(uint8_t command, uint8_t data[8]) {
|
void decode_packet(uint8_t command, uint8_t data[8]) {
|
||||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
@ -180,9 +178,7 @@ void DalyBms::transmit_rs485(unsigned long currentMillis) {
|
||||||
tx_buff[2] = nextCommand;
|
tx_buff[2] = nextCommand;
|
||||||
tx_buff[3] = 8;
|
tx_buff[3] = 8;
|
||||||
tx_buff[12] = calculate_checksum(tx_buff);
|
tx_buff[12] = calculate_checksum(tx_buff);
|
||||||
#ifdef DEBUG_VIA_USB
|
|
||||||
dump_buff("transmitting: ", tx_buff, 13);
|
dump_buff("transmitting: ", tx_buff, 13);
|
||||||
#endif
|
|
||||||
Serial2.write(tx_buff, 13);
|
Serial2.write(tx_buff, 13);
|
||||||
nextCommand++;
|
nextCommand++;
|
||||||
if (nextCommand > 0x98)
|
if (nextCommand > 0x98)
|
||||||
|
@ -202,17 +198,12 @@ void DalyBms::receive() {
|
||||||
if (recv_len > 0 && recv_buff[0] != 0xA5 || recv_len > 1 && recv_buff[1] != 0x01 ||
|
if (recv_len > 0 && recv_buff[0] != 0xA5 || recv_len > 1 && recv_buff[1] != 0x01 ||
|
||||||
recv_len > 2 && (recv_buff[2] < 0x90 || recv_buff[2] > 0x98) || recv_len > 3 && recv_buff[3] != 8 ||
|
recv_len > 2 && (recv_buff[2] < 0x90 || recv_buff[2] > 0x98) || recv_len > 3 && recv_buff[3] != 8 ||
|
||||||
recv_len > 12 && recv_buff[12] != calculate_checksum(recv_buff)) {
|
recv_len > 12 && recv_buff[12] != calculate_checksum(recv_buff)) {
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
|
||||||
dump_buff("dropping partial rx: ", recv_buff, recv_len);
|
dump_buff("dropping partial rx: ", recv_buff, recv_len);
|
||||||
#endif
|
|
||||||
recv_len = 0;
|
recv_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recv_len > 12) {
|
if (recv_len > 12) {
|
||||||
#ifdef DEBUG_VIA_USB
|
|
||||||
dump_buff("decoding successfull rx: ", recv_buff, recv_len);
|
dump_buff("decoding successfull rx: ", recv_buff, recv_len);
|
||||||
#endif
|
|
||||||
decode_packet(recv_buff[2], &recv_buff[4]);
|
decode_packet(recv_buff[2], &recv_buff[4]);
|
||||||
recv_len = 0;
|
recv_len = 0;
|
||||||
lastPacket = millis();
|
lastPacket = millis();
|
||||||
|
|
|
@ -135,6 +135,9 @@ void init_stored_settings() {
|
||||||
remote_bms_reset = settings.getBool("REMBMSRESET", false);
|
remote_bms_reset = settings.getBool("REMBMSRESET", false);
|
||||||
use_canfd_as_can = settings.getBool("CANFDASCAN", false);
|
use_canfd_as_can = settings.getBool("CANFDASCAN", false);
|
||||||
|
|
||||||
|
datalayer.system.info.usb_logging_active = settings.getBool("USBENABLED", false);
|
||||||
|
datalayer.system.info.web_logging_active = settings.getBool("WEBENABLED", false);
|
||||||
|
|
||||||
// WIFI AP is enabled by default unless disabled in the settings
|
// WIFI AP is enabled by default unless disabled in the settings
|
||||||
wifiap_enabled = settings.getBool("WIFIAPENABLED", true);
|
wifiap_enabled = settings.getBool("WIFIAPENABLED", true);
|
||||||
passwordAP = settings.getString("APPASSWORD", "123456789").c_str();
|
passwordAP = settings.getString("APPASSWORD", "123456789").c_str();
|
||||||
|
|
|
@ -241,6 +241,10 @@ struct DATALAYER_SYSTEM_INFO_TYPE {
|
||||||
size_t logged_can_messages_offset = 0;
|
size_t logged_can_messages_offset = 0;
|
||||||
/** bool, determines if CAN messages should be logged for webserver */
|
/** bool, determines if CAN messages should be logged for webserver */
|
||||||
bool can_logging_active = false;
|
bool can_logging_active = false;
|
||||||
|
/** bool, determines if USB serial logging should occur */
|
||||||
|
bool usb_logging_active = false;
|
||||||
|
/** bool, determines if general logging should be active for webserver */
|
||||||
|
bool web_logging_active = false;
|
||||||
/** uint8_t, enumeration which CAN interface should be used for log playback */
|
/** uint8_t, enumeration which CAN interface should be used for log playback */
|
||||||
uint8_t can_replay_interface = CAN_NATIVE;
|
uint8_t can_replay_interface = CAN_NATIVE;
|
||||||
/** bool, determines if CAN replay should loop or not */
|
/** bool, determines if CAN replay should loop or not */
|
||||||
|
|
|
@ -3,19 +3,17 @@
|
||||||
#include "../../datalayer/datalayer.h"
|
#include "../../datalayer/datalayer.h"
|
||||||
#include "../sdcard/sdcard.h"
|
#include "../sdcard/sdcard.h"
|
||||||
|
|
||||||
#if defined(LOG_CAN_TO_SD) || defined(LOG_TO_SD)
|
|
||||||
#if !defined(HW_LILYGO)
|
|
||||||
#error The SD card logging feature is only available on LilyGo hardware
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_LINE_LENGTH_PRINTF 128
|
#define MAX_LINE_LENGTH_PRINTF 128
|
||||||
#define MAX_LENGTH_TIME_STR 14
|
#define MAX_LENGTH_TIME_STR 14
|
||||||
|
|
||||||
bool previous_message_was_newline = true;
|
bool previous_message_was_newline = true;
|
||||||
|
|
||||||
void Logging::add_timestamp(size_t size) {
|
void Logging::add_timestamp(size_t size) {
|
||||||
#ifdef DEBUG_LOG
|
// Check if any logging is enabled at runtime
|
||||||
|
if (!datalayer.system.info.web_logging_active && !datalayer.system.info.usb_logging_active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
char* message_string = datalayer.system.info.logged_can_messages;
|
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
|
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);
|
size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages);
|
||||||
|
@ -23,43 +21,44 @@ void Logging::add_timestamp(size_t size) {
|
||||||
char* timestr;
|
char* timestr;
|
||||||
static char timestr_buffer[MAX_LENGTH_TIME_STR];
|
static char timestr_buffer[MAX_LENGTH_TIME_STR];
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_WEB
|
if (datalayer.system.info.web_logging_active) {
|
||||||
if (!datalayer.system.info.can_logging_active) {
|
if (!datalayer.system.info.can_logging_active) {
|
||||||
/* If web debug is active and can logging is inactive,
|
/* If web debug is active and can logging is inactive,
|
||||||
* we use the debug logging memory directly for writing the timestring */
|
* we use the debug logging memory directly for writing the timestring */
|
||||||
if (offset + size + MAX_LENGTH_TIME_STR > message_string_size) {
|
if (offset + size + MAX_LENGTH_TIME_STR > message_string_size) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
}
|
||||||
|
timestr = datalayer.system.info.logged_can_messages + offset;
|
||||||
|
} else {
|
||||||
|
timestr = timestr_buffer;
|
||||||
}
|
}
|
||||||
timestr = datalayer.system.info.logged_can_messages + offset;
|
|
||||||
} else {
|
} else {
|
||||||
timestr = timestr_buffer;
|
timestr = timestr_buffer;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
timestr = timestr_buffer;
|
|
||||||
#endif // DEBUG_VIA_WEB
|
|
||||||
|
|
||||||
offset += min(MAX_LENGTH_TIME_STR - 1,
|
offset += min(MAX_LENGTH_TIME_STR - 1,
|
||||||
snprintf(timestr, MAX_LENGTH_TIME_STR, "%8lu.%03lu ", currentTime / 1000, currentTime % 1000));
|
snprintf(timestr, MAX_LENGTH_TIME_STR, "%8lu.%03lu ", currentTime / 1000, currentTime % 1000));
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_WEB
|
if (datalayer.system.info.web_logging_active && !datalayer.system.info.can_logging_active) {
|
||||||
if (!datalayer.system.info.can_logging_active) {
|
|
||||||
datalayer.system.info.logged_can_messages_offset = offset; // Update offset in buffer
|
datalayer.system.info.logged_can_messages_offset = offset; // Update offset in buffer
|
||||||
}
|
}
|
||||||
#endif // DEBUG_VIA_WEB
|
|
||||||
|
|
||||||
|
// LOG_TO_SD remains as compile-time option for now
|
||||||
#ifdef LOG_TO_SD
|
#ifdef LOG_TO_SD
|
||||||
add_log_to_buffer((uint8_t*)timestr, MAX_LENGTH_TIME_STR);
|
add_log_to_buffer((uint8_t*)timestr, MAX_LENGTH_TIME_STR);
|
||||||
#endif // LOG_TO_SD
|
#endif // LOG_TO_SD
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
if (datalayer.system.info.usb_logging_active) {
|
||||||
Serial.write(timestr);
|
Serial.write(timestr);
|
||||||
#endif // DEBUG_VIA_USB
|
}
|
||||||
|
|
||||||
#endif // DEBUG_LOG
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Logging::write(const uint8_t* buffer, size_t size) {
|
size_t Logging::write(const uint8_t* buffer, size_t size) {
|
||||||
#ifdef DEBUG_LOG
|
// Check if any logging is enabled at runtime
|
||||||
|
if (!datalayer.system.info.web_logging_active && !datalayer.system.info.usb_logging_active) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (previous_message_was_newline) {
|
if (previous_message_was_newline) {
|
||||||
add_timestamp(size);
|
add_timestamp(size);
|
||||||
}
|
}
|
||||||
|
@ -67,11 +66,12 @@ size_t Logging::write(const uint8_t* buffer, size_t size) {
|
||||||
#ifdef LOG_TO_SD
|
#ifdef LOG_TO_SD
|
||||||
add_log_to_buffer(buffer, size);
|
add_log_to_buffer(buffer, size);
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG_VIA_USB
|
|
||||||
Serial.write(buffer, size);
|
if (datalayer.system.info.usb_logging_active) {
|
||||||
#endif
|
Serial.write(buffer, size);
|
||||||
#ifdef DEBUG_VIA_WEB
|
}
|
||||||
if (!datalayer.system.info.can_logging_active) {
|
|
||||||
|
if (datalayer.system.info.web_logging_active && !datalayer.system.info.can_logging_active) {
|
||||||
char* message_string = datalayer.system.info.logged_can_messages;
|
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
|
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);
|
size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages);
|
||||||
|
@ -82,16 +82,17 @@ size_t Logging::write(const uint8_t* buffer, size_t size) {
|
||||||
memcpy(message_string + offset, buffer, size);
|
memcpy(message_string + offset, buffer, size);
|
||||||
datalayer.system.info.logged_can_messages_offset = offset + size; // Update offset in buffer
|
datalayer.system.info.logged_can_messages_offset = offset + size; // Update offset in buffer
|
||||||
}
|
}
|
||||||
#endif // DEBUG_VIA_WEB
|
|
||||||
|
|
||||||
previous_message_was_newline = buffer[size - 1] == '\n';
|
previous_message_was_newline = buffer[size - 1] == '\n';
|
||||||
return size;
|
return size;
|
||||||
#endif // DEBUG_LOG
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logging::printf(const char* fmt, ...) {
|
void Logging::printf(const char* fmt, ...) {
|
||||||
#ifdef DEBUG_LOG
|
// Check if any logging is enabled at runtime
|
||||||
|
if (!datalayer.system.info.web_logging_active && !datalayer.system.info.usb_logging_active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (previous_message_was_newline) {
|
if (previous_message_was_newline) {
|
||||||
add_timestamp(MAX_LINE_LENGTH_PRINTF);
|
add_timestamp(MAX_LINE_LENGTH_PRINTF);
|
||||||
}
|
}
|
||||||
|
@ -101,21 +102,22 @@ void Logging::printf(const char* fmt, ...) {
|
||||||
int offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer
|
int offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer
|
||||||
static char buffer[MAX_LINE_LENGTH_PRINTF];
|
static char buffer[MAX_LINE_LENGTH_PRINTF];
|
||||||
char* message_buffer;
|
char* message_buffer;
|
||||||
#ifdef DEBUG_VIA_WEB
|
|
||||||
if (!datalayer.system.info.can_logging_active) {
|
if (datalayer.system.info.web_logging_active) {
|
||||||
/* If web debug is active and can logging is inactive,
|
if (!datalayer.system.info.can_logging_active) {
|
||||||
* we use the debug logging memory directly for writing the output */
|
/* If web debug is active and can logging is inactive,
|
||||||
if (offset + MAX_LINE_LENGTH_PRINTF > message_string_size) {
|
* we use the debug logging memory directly for writing the output */
|
||||||
// Not enough space, reset and start from the beginning
|
if (offset + MAX_LINE_LENGTH_PRINTF > message_string_size) {
|
||||||
offset = 0;
|
// Not enough space, reset and start from the beginning
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
message_buffer = message_string + offset;
|
||||||
|
} else {
|
||||||
|
message_buffer = buffer;
|
||||||
}
|
}
|
||||||
message_buffer = message_string + offset;
|
|
||||||
} else {
|
} else {
|
||||||
message_buffer = buffer;
|
message_buffer = buffer;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
message_buffer = buffer;
|
|
||||||
#endif // DEBUG_VIA_WEB
|
|
||||||
|
|
||||||
va_list(args);
|
va_list(args);
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
@ -126,18 +128,15 @@ void Logging::printf(const char* fmt, ...) {
|
||||||
add_log_to_buffer((uint8_t*)message_buffer, size);
|
add_log_to_buffer((uint8_t*)message_buffer, size);
|
||||||
#endif // LOG_TO_SD
|
#endif // LOG_TO_SD
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
if (datalayer.system.info.usb_logging_active) {
|
||||||
Serial.write(message_buffer, size);
|
Serial.write(message_buffer, size);
|
||||||
#endif // DEBUG_VIA_USB
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_WEB
|
if (datalayer.system.info.web_logging_active && !datalayer.system.info.can_logging_active) {
|
||||||
if (!datalayer.system.info.can_logging_active) {
|
|
||||||
// Data was already added to buffer, just move offset
|
// Data was already added to buffer, just move offset
|
||||||
datalayer.system.info.logged_can_messages_offset =
|
datalayer.system.info.logged_can_messages_offset =
|
||||||
offset + size; // Keeps track of the current position in the buffer
|
offset + size; // Keeps track of the current position in the buffer
|
||||||
}
|
}
|
||||||
#endif // DEBUG_VIA_WEB
|
|
||||||
|
|
||||||
previous_message_was_newline = message_buffer[size - 1] == '\n';
|
previous_message_was_newline = message_buffer[size - 1] == '\n';
|
||||||
#endif // DEBUG_LOG
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <Print.h>
|
#include <Print.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "../../../USER_SETTINGS.h"
|
#include "../../../USER_SETTINGS.h"
|
||||||
|
#include "../../datalayer/datalayer.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
class Logging : public Print {
|
class Logging : public Print {
|
||||||
|
@ -13,18 +14,23 @@ class Logging : public Print {
|
||||||
virtual size_t write(const uint8_t* buffer, size_t size);
|
virtual size_t write(const uint8_t* buffer, size_t size);
|
||||||
virtual size_t write(uint8_t) { return 0; }
|
virtual size_t write(uint8_t) { return 0; }
|
||||||
void printf(const char* fmt, ...);
|
void printf(const char* fmt, ...);
|
||||||
void log_bms_status(real_bms_status_enum bms_status);
|
|
||||||
Logging() {}
|
Logging() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Logging logging;
|
extern Logging logging;
|
||||||
|
|
||||||
#ifdef DEBUG_LOG
|
// Replace compile-time macros with runtime checks
|
||||||
#define DEBUG_PRINTF(fmt, ...) logging.printf(fmt, ##__VA_ARGS__)
|
#define DEBUG_PRINTF(fmt, ...) \
|
||||||
#define DEBUG_PRINTLN(str) logging.println(str)
|
do { \
|
||||||
#else
|
if (datalayer.system.info.web_logging_active || datalayer.system.info.usb_logging_active) { \
|
||||||
#define DEBUG_PRINTF(fmt, ...) ((void)0)
|
logging.printf(fmt, ##__VA_ARGS__); \
|
||||||
#define DEBUG_PRINTLN(str) ((void)0)
|
} \
|
||||||
#endif
|
} while (0)
|
||||||
|
|
||||||
|
#define DEBUG_PRINTLN(str) \
|
||||||
|
do { \
|
||||||
|
if (datalayer.system.info.web_logging_active || datalayer.system.info.usb_logging_active) { \
|
||||||
|
logging.println(str); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
#endif // __LOGGING_H__
|
#endif // __LOGGING_H__
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include "../../datalayer/datalayer.h"
|
#include "../../datalayer/datalayer.h"
|
||||||
#include "index_html.h"
|
#include "index_html.h"
|
||||||
|
|
||||||
#if defined(DEBUG_VIA_WEB) || defined(LOG_TO_SD)
|
|
||||||
char* strnchr(const char* s, int c, size_t n) {
|
char* strnchr(const char* s, int c, size_t n) {
|
||||||
// Like strchr, but only searches the first 'n' bytes of the string.
|
// Like strchr, but only searches the first 'n' bytes of the string.
|
||||||
|
|
||||||
|
@ -54,9 +53,9 @@ String debug_logger_processor(void) {
|
||||||
".can-message { background-color: #404E57; margin-bottom: 5px; padding: 10px; border-radius: 5px; font-family: "
|
".can-message { background-color: #404E57; margin-bottom: 5px; padding: 10px; border-radius: 5px; font-family: "
|
||||||
"monospace; }";
|
"monospace; }";
|
||||||
content += "</style>";
|
content += "</style>";
|
||||||
#ifdef DEBUG_VIA_WEB
|
if (datalayer.system.info.web_logging_active) {
|
||||||
content += "<button onclick='refreshPage()'>Refresh data</button> ";
|
content += "<button onclick='refreshPage()'>Refresh data</button> ";
|
||||||
#endif
|
}
|
||||||
content += "<button onclick='exportLog()'>Export to .txt</button> ";
|
content += "<button onclick='exportLog()'>Export to .txt</button> ";
|
||||||
#ifdef LOG_TO_SD
|
#ifdef LOG_TO_SD
|
||||||
content += "<button onclick='deleteLog()'>Delete log file</button> ";
|
content += "<button onclick='deleteLog()'>Delete log file</button> ";
|
||||||
|
@ -107,4 +106,3 @@ String debug_logger_processor(void) {
|
||||||
content += index_html_footer;
|
content += index_html_footer;
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
|
@ -254,6 +254,14 @@ String settings_processor(const String& var, BatteryEmulatorSettingsStore& setti
|
||||||
return settings.getBool("WIFIAPENABLED", wifiap_enabled) ? "checked" : "";
|
return settings.getBool("WIFIAPENABLED", wifiap_enabled) ? "checked" : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (var == "USBENABLED") {
|
||||||
|
return settings.getBool("USBENABLED") ? "checked" : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var == "WEBENABLED") {
|
||||||
|
return settings.getBool("WEBENABLED") ? "checked" : "";
|
||||||
|
}
|
||||||
|
|
||||||
if (var == "MQTTENABLED") {
|
if (var == "MQTTENABLED") {
|
||||||
return settings.getBool("MQTTENABLED") ? "checked" : "";
|
return settings.getBool("MQTTENABLED") ? "checked" : "";
|
||||||
}
|
}
|
||||||
|
@ -862,6 +870,12 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
||||||
<label>Custom hostname: </label>
|
<label>Custom hostname: </label>
|
||||||
<input type='text' name='HOSTNAME' value="%HOSTNAME%" />
|
<input type='text' name='HOSTNAME' value="%HOSTNAME%" />
|
||||||
|
|
||||||
|
<label>Enable USB serial: </label>
|
||||||
|
<input type='checkbox' name='USBENABLED' value='on' style='margin-left: 0;' %USBENABLED% />
|
||||||
|
|
||||||
|
<label>Enable WEB logging: </label>
|
||||||
|
<input type='checkbox' name='WEBENABLED' value='on' style='margin-left: 0;' %WEBENABLED% />
|
||||||
|
|
||||||
<label>Enable MQTT: </label>
|
<label>Enable MQTT: </label>
|
||||||
<input type='checkbox' name='MQTTENABLED' value='on' style='margin-left: 0;' %MQTTENABLED% />
|
<input type='checkbox' name='MQTTENABLED' value='on' style='margin-left: 0;' %MQTTENABLED% />
|
||||||
|
|
||||||
|
|
|
@ -267,13 +267,13 @@ void init_webserver() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
#if defined(DEBUG_VIA_WEB) || defined(LOG_TO_SD)
|
if (datalayer.system.info.web_logging_active) { //|| defined(LOG_TO_SD)
|
||||||
// Route for going to debug logging web page
|
// Route for going to debug logging web page
|
||||||
server.on("/log", HTTP_GET, [](AsyncWebServerRequest* request) {
|
server.on("/log", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
AsyncWebServerResponse* response = request->beginResponse(200, "text/html", debug_logger_processor());
|
AsyncWebServerResponse* response = request->beginResponse(200, "text/html", debug_logger_processor());
|
||||||
request->send(response);
|
request->send(response);
|
||||||
});
|
});
|
||||||
#endif // DEBUG_VIA_WEB
|
}
|
||||||
|
|
||||||
// Define the handler to stop can logging
|
// Define the handler to stop can logging
|
||||||
server.on("/stop_can_logging", HTTP_GET, [](AsyncWebServerRequest* request) {
|
server.on("/stop_can_logging", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
|
@ -413,8 +413,8 @@ void init_webserver() {
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* boolSettingNames[] = {
|
const char* boolSettingNames[] = {
|
||||||
"DBLBTR", "CNTCTRL", "CNTCTRLDBL", "PWMCNTCTRL", "PERBMSRESET", "REMBMSRESET",
|
"DBLBTR", "CNTCTRL", "CNTCTRLDBL", "PWMCNTCTRL", "PERBMSRESET", "REMBMSRESET", "USBENABLED",
|
||||||
"CANFDASCAN", "WIFIAPENABLED", "MQTTENABLED", "HADISC", "MQTTTOPICS", "INVICNT",
|
"WEBENABLED", "CANFDASCAN", "WIFIAPENABLED", "MQTTENABLED", "HADISC", "MQTTTOPICS", "INVICNT",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handles the form POST from UI to save settings of the common image
|
// Handles the form POST from UI to save settings of the common image
|
||||||
|
@ -1388,9 +1388,9 @@ String processor(const String& var) {
|
||||||
content += "<button onclick='Advanced()'>More Battery Info</button> ";
|
content += "<button onclick='Advanced()'>More Battery Info</button> ";
|
||||||
content += "<button onclick='CANlog()'>CAN logger</button> ";
|
content += "<button onclick='CANlog()'>CAN logger</button> ";
|
||||||
content += "<button onclick='CANreplay()'>CAN replay</button> ";
|
content += "<button onclick='CANreplay()'>CAN replay</button> ";
|
||||||
#if defined(DEBUG_VIA_WEB) || defined(LOG_TO_SD)
|
if (datalayer.system.info.web_logging_active) { //|| defined(LOG_TO_SD)
|
||||||
content += "<button onclick='Log()'>Log</button> ";
|
content += "<button onclick='Log()'>Log</button> ";
|
||||||
#endif // DEBUG_VIA_WEB
|
}
|
||||||
content += "<button onclick='Cellmon()'>Cellmonitor</button> ";
|
content += "<button onclick='Cellmon()'>Cellmonitor</button> ";
|
||||||
content += "<button onclick='Events()'>Events</button> ";
|
content += "<button onclick='Events()'>Events</button> ";
|
||||||
content += "<button onclick='askReboot()'>Reboot Emulator</button>";
|
content += "<button onclick='askReboot()'>Reboot Emulator</button>";
|
||||||
|
|
|
@ -14,16 +14,13 @@ void KostalInverterProtocol::float2frame(uint8_t* arr, float value, uint8_t fram
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dbg_timestamp(void) {
|
static void dbg_timestamp(void) {
|
||||||
#ifdef DEBUG_KOSTAL_RS485_DATA
|
|
||||||
logging.print("[");
|
logging.print("[");
|
||||||
logging.print(millis());
|
logging.print(millis());
|
||||||
logging.print(" ms] ");
|
logging.print(" ms] ");
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dbg_frame(uint8_t* frame, int len, const char* prefix) {
|
static void dbg_frame(uint8_t* frame, int len, const char* prefix) {
|
||||||
dbg_timestamp();
|
dbg_timestamp();
|
||||||
#ifdef DEBUG_KOSTAL_RS485_DATA
|
|
||||||
logging.print(prefix);
|
logging.print(prefix);
|
||||||
logging.print(": ");
|
logging.print(": ");
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
|
@ -34,26 +31,11 @@ static void dbg_frame(uint8_t* frame, int len, const char* prefix) {
|
||||||
logging.print(" ");
|
logging.print(" ");
|
||||||
}
|
}
|
||||||
logging.println("");
|
logging.println("");
|
||||||
#endif
|
|
||||||
#ifdef DEBUG_KOSTAL_RS485_DATA_USB
|
|
||||||
Serial.print(prefix);
|
|
||||||
Serial.print(": ");
|
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
|
||||||
if (frame[i] < 0x10) {
|
|
||||||
Serial.print("0");
|
|
||||||
}
|
|
||||||
Serial.print(frame[i], HEX);
|
|
||||||
Serial.print(" ");
|
|
||||||
}
|
|
||||||
Serial.println("");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dbg_message(const char* msg) {
|
static void dbg_message(const char* msg) {
|
||||||
dbg_timestamp();
|
dbg_timestamp();
|
||||||
#ifdef DEBUG_KOSTAL_RS485_DATA
|
|
||||||
logging.println(msg);
|
logging.println(msg);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing#Encoding_examples */
|
/* https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing#Encoding_examples */
|
||||||
|
|
|
@ -8,13 +8,6 @@
|
||||||
#define SELECTED_INVERTER_CLASS KostalInverterProtocol
|
#define SELECTED_INVERTER_CLASS KostalInverterProtocol
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#define DEBUG_KOSTAL_RS485_DATA // Enable this line to get TX / RX printed out via logging
|
|
||||||
//#define DEBUG_KOSTAL_RS485_DATA_USB // Enable this line to get TX / RX printed out via USB
|
|
||||||
|
|
||||||
#if defined(DEBUG_KOSTAL_RS485_DATA) && !defined(DEBUG_LOG)
|
|
||||||
#error "enable LOG_TO_SD, DEBUG_VIA_USB or DEBUG_VIA_WEB in order to use DEBUG_KOSTAL_RS485_DATA"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class KostalInverterProtocol : public Rs485InverterProtocol {
|
class KostalInverterProtocol : public Rs485InverterProtocol {
|
||||||
public:
|
public:
|
||||||
const char* name() override { return Name; }
|
const char* name() override { return Name; }
|
||||||
|
|
|
@ -107,34 +107,11 @@ void PylonLvInverter::map_can_frame_to_variable(CAN_frame rx_frame) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
|
||||||
void dump_frame(CAN_frame* frame) {
|
|
||||||
Serial.print("[PYLON-LV] sending CAN frame ");
|
|
||||||
Serial.print(frame->ID, HEX);
|
|
||||||
Serial.print(": ");
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
Serial.print(frame->data.u8[i] >> 4, HEX);
|
|
||||||
Serial.print(frame->data.u8[i] & 0xf, HEX);
|
|
||||||
Serial.print(" ");
|
|
||||||
}
|
|
||||||
Serial.println();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void PylonLvInverter::transmit_can(unsigned long currentMillis) {
|
void PylonLvInverter::transmit_can(unsigned long currentMillis) {
|
||||||
|
|
||||||
if (currentMillis - previousMillis1000ms >= 1000) {
|
if (currentMillis - previousMillis1000ms >= 1000) {
|
||||||
previousMillis1000ms = currentMillis;
|
previousMillis1000ms = currentMillis;
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
|
||||||
dump_frame(&PYLON_351);
|
|
||||||
dump_frame(&PYLON_355);
|
|
||||||
dump_frame(&PYLON_356);
|
|
||||||
dump_frame(&PYLON_359);
|
|
||||||
dump_frame(&PYLON_35C);
|
|
||||||
dump_frame(&PYLON_35E);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
transmit_can_frame(&PYLON_351);
|
transmit_can_frame(&PYLON_351);
|
||||||
transmit_can_frame(&PYLON_355);
|
transmit_can_frame(&PYLON_355);
|
||||||
transmit_can_frame(&PYLON_356);
|
transmit_can_frame(&PYLON_356);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue