firmware: recover slow BNO086 startup
This commit is contained in:
@@ -12,6 +12,7 @@ This Arduino sketch reads a BNO086 IMU and MAX-M10S GPS and publishes versioned,
|
||||
Power both sensors from 3.3V with shared ground. Required Arduino libraries are Adafruit BNO08x, TinyGPSPlus, and ArduinoJson 6.x. Enable **USB CDC On Boot** for diagnostics. GPS uses hardware UART0 at the verified 38400 baud; RS485 uses hardware UART1.
|
||||
|
||||
The BNO086 uses the verified `0x4B` I2C address on D7/D8. If initialization fails, verify 3.3V/GND, SDA/SCL wiring, and the breakout's PS0/PS1 configuration.
|
||||
Firmware retries the fixed address during power-up and periodically retries afterward, so a slow BNO086 power-up does not require cycling the XIAO. If the BNO086 resets at runtime, rotation-vector reporting is enabled again automatically.
|
||||
|
||||
The node sends `sensor_status` at 115200 baud every 200 ms. See `docs/SENSOR_NODE_PROTOCOL.md`. The initial firmware is transmit-only; add a dashboard receiver after bench-testing the node, RS485 polarity, and sensor axes.
|
||||
|
||||
|
||||
@@ -8,7 +8,14 @@ namespace {
|
||||
Adafruit_BNO08x bno086(-1);
|
||||
sh2_SensorValue_t value;
|
||||
bool initialized = false;
|
||||
unsigned long lastInitAttemptMs = 0;
|
||||
float radiansToDegrees(float r) { return r * 180.0f / PI; }
|
||||
bool tryInitImu() {
|
||||
lastInitAttemptMs = millis();
|
||||
initialized = bno086.begin_I2C(BNO086_I2C_ADDRESS, &Wire);
|
||||
if (initialized) initialized = bno086.enableReport(SH2_ROTATION_VECTOR, IMU_REPORT_INTERVAL_US);
|
||||
return initialized;
|
||||
}
|
||||
void updateEuler(ImuState& s) {
|
||||
float sinr = 2 * (s.real * s.i + s.j * s.k);
|
||||
float cosr = 1 - 2 * (s.i * s.i + s.j * s.j);
|
||||
@@ -27,13 +34,29 @@ bool initImu() {
|
||||
delay(100);
|
||||
Serial.print("Starting BNO086 at 0x");
|
||||
Serial.println(BNO086_I2C_ADDRESS, HEX);
|
||||
initialized = bno086.begin_I2C(BNO086_I2C_ADDRESS, &Wire);
|
||||
if (initialized) initialized = bno086.enableReport(SH2_ROTATION_VECTOR, IMU_REPORT_INTERVAL_US);
|
||||
return initialized;
|
||||
for (int attempt = 1; attempt <= BNO086_INIT_ATTEMPTS; attempt++) {
|
||||
if (tryInitImu()) return true;
|
||||
Serial.print("BNO086 init attempt failed: ");
|
||||
Serial.println(attempt);
|
||||
delay(BNO086_INIT_RETRY_DELAY_MS);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void maintainImu(ImuState& s) {
|
||||
if (initialized || millis() - lastInitAttemptMs < BNO086_RUNTIME_RETRY_MS) return;
|
||||
Serial.println("Retrying BNO086 initialization");
|
||||
s.online = tryInitImu();
|
||||
if (s.online) Serial.println("BNO086 recovered");
|
||||
}
|
||||
|
||||
void updateImu(ImuState& s) {
|
||||
s.online = initialized;
|
||||
if (initialized && bno086.wasReset()) {
|
||||
initialized = bno086.enableReport(SH2_ROTATION_VECTOR, IMU_REPORT_INTERVAL_US);
|
||||
s.online = initialized;
|
||||
if (!initialized) return;
|
||||
}
|
||||
if (!initialized || !bno086.getSensorEvent(&value) || value.sensorId != SH2_ROTATION_VECTOR) return;
|
||||
s.i = value.un.rotationVector.i; s.j = value.un.rotationVector.j;
|
||||
s.k = value.un.rotationVector.k; s.real = value.un.rotationVector.real;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "sensor_state.h"
|
||||
bool initImu();
|
||||
void maintainImu(ImuState& state);
|
||||
void updateImu(ImuState& state);
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#define GPS_TX_PIN D10
|
||||
#define BNO086_I2C_ADDRESS 0x4B
|
||||
#define BNO086_I2C_CLOCK_HZ 100000
|
||||
#define BNO086_INIT_ATTEMPTS 8
|
||||
#define BNO086_INIT_RETRY_DELAY_MS 250
|
||||
#define BNO086_RUNTIME_RETRY_MS 5000
|
||||
#define GPS_BAUD 38400
|
||||
#define RS485_BAUD 115200
|
||||
#define IMU_REPORT_INTERVAL_US 20000
|
||||
|
||||
@@ -20,7 +20,7 @@ void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
updateGps(gpsSerial, gpsState); updateImu(imuState);
|
||||
updateGps(gpsSerial, gpsState); maintainImu(imuState); updateImu(imuState);
|
||||
pollRs485Commands(rs485Serial, imuState);
|
||||
String calibrationResult;
|
||||
if (updateLevelCalibration(imuState, calibrationResult)) {
|
||||
|
||||
Reference in New Issue
Block a user