mirror of
https://github.com/hatlabs/SH-ESP32-nmea2000-gateway.git
synced 2025-05-16 07:30:19 -07:00
Merge pull request #9 from hatlabs/bus_off_2
Try to recover from BUS-OFF
This commit is contained in:
commit
09a8cabceb
@ -21,6 +21,7 @@ lib_deps =
|
||||
ttlappalainen/NMEA2000-library
|
||||
ttlappalainen/NMEA2000_esp32
|
||||
Adafruit SSD1306
|
||||
pfeerick/elapsedMillis
|
||||
|
||||
[espressif32_base]
|
||||
platform = espressif32
|
||||
|
59
src/main.cpp
59
src/main.cpp
@ -15,6 +15,8 @@
|
||||
#include <esp_int_wdt.h>
|
||||
#include <esp_task_wdt.h>
|
||||
|
||||
#include "elapsedMillis.h"
|
||||
|
||||
using namespace reactesp;
|
||||
|
||||
ReactESP app;
|
||||
@ -22,6 +24,8 @@ ReactESP app;
|
||||
#define SCREEN_WIDTH 128 // OLED display width, in pixels
|
||||
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
|
||||
|
||||
#define RECOVERY_RETRY_MS 1000 // How long to attempt CAN bus recovery
|
||||
|
||||
TwoWire *i2c;
|
||||
|
||||
Stream *read_stream = &Serial;
|
||||
@ -33,20 +37,26 @@ Adafruit_SSD1306 *display;
|
||||
|
||||
tNMEA2000 *nmea2000;
|
||||
|
||||
int num_n2k_messages = 0;
|
||||
int num_actisense_messages = 0;
|
||||
elapsedMillis time_since_last_can_rx = 0;
|
||||
|
||||
// Time after which we should reboot if we haven't received any CAN messages
|
||||
#define MAX_RX_WAIT_TIME_MS 30000
|
||||
|
||||
void ToggleLed() {
|
||||
static bool led_state = false;
|
||||
digitalWrite(LED_BUILTIN, led_state);
|
||||
led_state = !led_state;
|
||||
}
|
||||
|
||||
int num_n2k_messages = 0;
|
||||
void HandleStreamN2kMsg(const tN2kMsg &message) {
|
||||
// N2kMsg.Print(&Serial);
|
||||
num_n2k_messages++;
|
||||
time_since_last_can_rx = 0;
|
||||
ToggleLed();
|
||||
}
|
||||
|
||||
int num_actisense_messages = 0;
|
||||
void HandleStreamActisenseMsg(const tN2kMsg &message) {
|
||||
// N2kMsg.Print(&Serial);
|
||||
num_actisense_messages++;
|
||||
@ -56,6 +66,29 @@ void HandleStreamActisenseMsg(const tN2kMsg &message) {
|
||||
|
||||
String can_state;
|
||||
|
||||
void RecoverFromCANBusOff() {
|
||||
// This recovery routine first discussed in
|
||||
// https://www.esp32.com/viewtopic.php?t=5010 and also implemented in
|
||||
// https://github.com/wellenvogel/esp32-nmea2000
|
||||
static bool recovery_in_progress = false;
|
||||
static elapsedMillis recovery_timer;
|
||||
if (recovery_in_progress && recovery_timer < RECOVERY_RETRY_MS) {
|
||||
return;
|
||||
}
|
||||
recovery_in_progress = true;
|
||||
recovery_timer = 0;
|
||||
// Abort transmission
|
||||
MODULE_CAN->CMR.B.AT = 1;
|
||||
// read SR after write to CMR to settle register changes
|
||||
(void)MODULE_CAN->SR.U;
|
||||
|
||||
// Reset error counters
|
||||
MODULE_CAN->TXERR.U = 127;
|
||||
MODULE_CAN->RXERR.U = 0;
|
||||
// Release Reset mode
|
||||
MODULE_CAN->MOD.B.RM = 0;
|
||||
}
|
||||
|
||||
void PollCANStatus() {
|
||||
// CAN controller registers are SJA1000 compatible.
|
||||
// Bus status value 0 indicates bus-on; value 1 indicates bus-off.
|
||||
@ -67,13 +100,8 @@ void PollCANStatus() {
|
||||
break;
|
||||
case 1:
|
||||
can_state = "BUS-OFF";
|
||||
// try to automatically recover by rebooting
|
||||
app.onDelay(2000, []() {
|
||||
esp_task_wdt_init(1, true);
|
||||
esp_task_wdt_add(NULL);
|
||||
while (true)
|
||||
;
|
||||
});
|
||||
// try to automatically recover
|
||||
RecoverFromCANBusOff();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -131,12 +159,21 @@ void setup() {
|
||||
|
||||
// No need to parse the messages at every single loop iteration; 1 ms will do
|
||||
app.onRepeat(1, []() {
|
||||
PollCANStatus();
|
||||
nmea2000->ParseMessages();
|
||||
actisense_reader.ParseMessages();
|
||||
});
|
||||
|
||||
// enable CAN status polling
|
||||
app.onRepeat(100, []() { PollCANStatus(); });
|
||||
app.onRepeat(100, []() {
|
||||
if (time_since_last_can_rx > MAX_RX_WAIT_TIME_MS) {
|
||||
// No CAN messages received in a while; reboot
|
||||
esp_task_wdt_init(1, true);
|
||||
esp_task_wdt_add(NULL);
|
||||
while (true) {
|
||||
// wait for watchdog to trigger
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// initialize the display
|
||||
i2c = new TwoWire(0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user