dashboard: expand CAN diagnostics
This commit is contained in:
@@ -75,3 +75,14 @@ The dashboard uses field-filtered `/api/v1/status` calls:
|
||||
- Slow poll: `/api/v1/status?fields=network,system,config`
|
||||
|
||||
This keeps the endpoint model simple while reducing payload size, JSON parsing, and UI churn.
|
||||
|
||||
## OBD-II / CAN Diagnostics
|
||||
|
||||
The hidden diagnostics overlay distinguishes raw CAN traffic from parsed
|
||||
OBD-II coolant responses. It reports request successes and failures, total
|
||||
raw frames received, the last frame identifier and DLC, TWAI queue depth,
|
||||
controller error counters, missed or overrun frames, arbitration losses,
|
||||
and bus errors.
|
||||
|
||||
Raw RX activity confirms that the display is receiving CAN frames even when
|
||||
the vehicle does not return a matching Mode 01 PID 05 coolant response.
|
||||
|
||||
@@ -47,7 +47,13 @@ static unsigned long last_obd_poll_ms = 0;
|
||||
static unsigned long last_obd_rx_ms = 0;
|
||||
static unsigned long last_obd_tx_ms = 0;
|
||||
static uint32_t obd_tx_count = 0;
|
||||
static uint32_t obd_tx_fail_count = 0;
|
||||
static uint32_t obd_rx_count = 0;
|
||||
static uint32_t obd_raw_rx_count = 0;
|
||||
static uint32_t obd_last_rx_identifier = 0;
|
||||
static uint8_t obd_last_rx_dlc = 0;
|
||||
static bool obd_last_rx_extended = false;
|
||||
static unsigned long last_obd_raw_rx_ms = 0;
|
||||
static int obd_coolant_temp_f = -999;
|
||||
static int last_rendered_obd_coolant_temp_f = -1000;
|
||||
static String obd_last_error = "not initialized";
|
||||
@@ -491,6 +497,7 @@ static void send_obd_coolant_request()
|
||||
last_obd_tx_ms = millis();
|
||||
obd_last_error = "coolant request sent";
|
||||
} else {
|
||||
obd_tx_fail_count++;
|
||||
obd_last_error = "tx failed: " + String((int)result);
|
||||
}
|
||||
}
|
||||
@@ -539,6 +546,12 @@ static void process_obd_can()
|
||||
|
||||
twai_message_t message = {};
|
||||
while (twai_receive(&message, 0) == ESP_OK) {
|
||||
obd_raw_rx_count++;
|
||||
obd_last_rx_identifier = message.identifier;
|
||||
obd_last_rx_dlc = message.data_length_code;
|
||||
obd_last_rx_extended = message.extd;
|
||||
last_obd_raw_rx_ms = millis();
|
||||
|
||||
handle_obd_can_message(message);
|
||||
}
|
||||
|
||||
@@ -625,15 +638,95 @@ static void update_diagnostics_overlay()
|
||||
text += "\n\nOBD-II / CAN\n";
|
||||
text += " TWAI: ";
|
||||
text += obd_can_started ? "started" : "offline";
|
||||
text += " @ 500 kbps";
|
||||
text += "\n Pins: TX GPIO15 / RX GPIO16";
|
||||
text += "\n Coolant: ";
|
||||
text += obd_coolant_temp_f > -100 ? String(obd_coolant_temp_f) + "°F" : String("--");
|
||||
text += "\n TX/RX: ";
|
||||
|
||||
text += "\n Requests OK/fail: ";
|
||||
text += String(obd_tx_count);
|
||||
text += "/";
|
||||
text += String(obd_tx_fail_count);
|
||||
|
||||
text += "\n Raw RX/coolant RX: ";
|
||||
text += String(obd_raw_rx_count);
|
||||
text += "/";
|
||||
text += String(obd_rx_count);
|
||||
text += "\n Last RX age: ";
|
||||
text += last_obd_rx_ms > 0 ? String((millis() - last_obd_rx_ms) / 1000) + "s" : String("--");
|
||||
|
||||
text += "\n Last frame: ";
|
||||
if (obd_raw_rx_count > 0) {
|
||||
text += obd_last_rx_extended ? "EXT 0x" : "STD 0x";
|
||||
text += String(obd_last_rx_identifier, HEX);
|
||||
text += " DLC ";
|
||||
text += String(obd_last_rx_dlc);
|
||||
} else {
|
||||
text += "--";
|
||||
}
|
||||
|
||||
text += "\n Raw RX age: ";
|
||||
text += last_obd_raw_rx_ms > 0
|
||||
? String((millis() - last_obd_raw_rx_ms) / 1000) + "s"
|
||||
: String("--");
|
||||
|
||||
text += "\n Coolant RX age: ";
|
||||
text += last_obd_rx_ms > 0
|
||||
? String((millis() - last_obd_rx_ms) / 1000) + "s"
|
||||
: String("--");
|
||||
|
||||
if (obd_can_started) {
|
||||
twai_status_info_t can_status = {};
|
||||
esp_err_t status_result = twai_get_status_info(&can_status);
|
||||
|
||||
if (status_result == ESP_OK) {
|
||||
const char *state_text = "unknown";
|
||||
|
||||
switch (can_status.state) {
|
||||
case TWAI_STATE_STOPPED:
|
||||
state_text = "stopped";
|
||||
break;
|
||||
case TWAI_STATE_RUNNING:
|
||||
state_text = "running";
|
||||
break;
|
||||
case TWAI_STATE_BUS_OFF:
|
||||
state_text = "bus-off";
|
||||
break;
|
||||
case TWAI_STATE_RECOVERING:
|
||||
state_text = "recovering";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
text += "\n State: ";
|
||||
text += state_text;
|
||||
|
||||
text += " TXq/RXq ";
|
||||
text += String(can_status.msgs_to_tx);
|
||||
text += "/";
|
||||
text += String(can_status.msgs_to_rx);
|
||||
|
||||
text += "\n TEC/REC: ";
|
||||
text += String(can_status.tx_error_counter);
|
||||
text += "/";
|
||||
text += String(can_status.rx_error_counter);
|
||||
|
||||
text += "\n Fail/miss/overrun: ";
|
||||
text += String(can_status.tx_failed_count);
|
||||
text += "/";
|
||||
text += String(can_status.rx_missed_count);
|
||||
text += "/";
|
||||
text += String(can_status.rx_overrun_count);
|
||||
|
||||
text += "\n Arb lost/bus errors: ";
|
||||
text += String(can_status.arb_lost_count);
|
||||
text += "/";
|
||||
text += String(can_status.bus_error_count);
|
||||
} else {
|
||||
text += "\n Driver status error: ";
|
||||
text += String((int)status_result);
|
||||
}
|
||||
}
|
||||
|
||||
text += "\n Last status: ";
|
||||
text += obd_last_error;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user