firmware: harden XIAO RS485 telemetry
This commit is contained in:
@@ -14,6 +14,6 @@ Power both sensors from 3.3V with shared ground. Required Arduino libraries are
|
||||
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.
|
||||
The node sends `sensor_status` at 115200 baud every 250 ms. See `docs/SENSOR_NODE_PROTOCOL.md`. It also listens between frames for the documented level-calibration commands. Add a dashboard receiver after bench-testing the node, RS485 polarity, and sensor axes.
|
||||
|
||||
During bring-up, `USB_TELEMETRY_ENABLED` mirrors each RS485 JSON frame to the Arduino Serial Monitor at 115200 baud. Set it to `0` in `sensor_node_config.h` when continuous USB output is no longer wanted.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <ArduinoJson.h>
|
||||
#include <esp_system.h>
|
||||
#include "rs485_transport.h"
|
||||
#include "sensor_node_config.h"
|
||||
#include "calibration.h"
|
||||
@@ -6,9 +7,28 @@
|
||||
namespace {
|
||||
String commandBuffer;
|
||||
bool discardCommandUntilNewline = false;
|
||||
uint32_t bootId = 0;
|
||||
uint32_t frameSequence = 0;
|
||||
|
||||
void drainTransmitEcho(HardwareSerial& serial) {
|
||||
while (serial.available()) serial.read();
|
||||
}
|
||||
|
||||
void sendJson(HardwareSerial& serial, JsonDocument& doc) {
|
||||
digitalWrite(RS485_DE_PIN, HIGH); delayMicroseconds(20);
|
||||
if (doc.overflowed() || measureJson(doc) + 1 > RS485_MAX_FRAME_BYTES) {
|
||||
#if USB_TELEMETRY_ENABLED
|
||||
Serial.println("{\"type\":\"rs485_error\",\"error\":\"frame_too_large\"}");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
digitalWrite(RS485_DE_PIN, HIGH);
|
||||
delayMicroseconds(RS485_DRIVER_ENABLE_SETTLE_US);
|
||||
serializeJson(doc, serial); serial.write('\n'); serial.flush();
|
||||
// This expansion board can echo TX into RX. At flush completion the
|
||||
// entire transmitted line has left the UART, so discard that local echo
|
||||
// before returning the transceiver to receive mode.
|
||||
drainTransmitEcho(serial);
|
||||
digitalWrite(RS485_DE_PIN, LOW);
|
||||
#if USB_TELEMETRY_ENABLED
|
||||
serializeJson(doc, Serial); Serial.println();
|
||||
@@ -18,13 +38,17 @@ void sendJson(HardwareSerial& serial, JsonDocument& doc) {
|
||||
|
||||
void initRs485(HardwareSerial& serial) {
|
||||
pinMode(RS485_DE_PIN, OUTPUT); digitalWrite(RS485_DE_PIN, LOW);
|
||||
serial.setRxBufferSize(RS485_RX_BUFFER_BYTES);
|
||||
serial.begin(RS485_BAUD, SERIAL_8N1, RS485_RX_PIN, RS485_TX_PIN);
|
||||
bootId = esp_random();
|
||||
}
|
||||
|
||||
void publishSensorStatus(HardwareSerial& serial, const ImuState& imu, const GpsState& gps) {
|
||||
StaticJsonDocument<2048> doc;
|
||||
doc["type"] = "sensor_status"; doc["schema_version"] = SENSOR_NODE_SCHEMA_VERSION;
|
||||
doc["node_id"] = SENSOR_NODE_NAME; doc["firmware_version"] = SENSOR_NODE_FIRMWARE_VERSION;
|
||||
doc["boot_id"] = bootId;
|
||||
doc["frame_sequence"] = frameSequence++;
|
||||
doc["uptime_ms"] = millis();
|
||||
JsonObject i = doc.createNestedObject("imu");
|
||||
i["online"] = imu.online; i["valid"] = imu.valid && millis() - imu.lastUpdateMs <= SENSOR_STALE_MS;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#define SENSOR_NODE_NAME "xiao_c6_sensor_node"
|
||||
#define SENSOR_NODE_FIRMWARE_VERSION "0.1.0"
|
||||
#define SENSOR_NODE_FIRMWARE_VERSION "0.2.0"
|
||||
#define SENSOR_NODE_SCHEMA_VERSION 1
|
||||
#define RS485_DE_PIN D2
|
||||
#define RS485_TX_PIN D4
|
||||
@@ -18,9 +18,12 @@
|
||||
#define BNO086_RUNTIME_RETRY_MS 5000
|
||||
#define GPS_BAUD 38400
|
||||
#define RS485_BAUD 115200
|
||||
#define RS485_RX_BUFFER_BYTES 512
|
||||
#define RS485_MAX_FRAME_BYTES 1900
|
||||
#define RS485_DRIVER_ENABLE_SETTLE_US 20
|
||||
#define IMU_REPORT_INTERVAL_US 20000
|
||||
#define IMU_STABILITY_INTERVAL_US 100000
|
||||
#define TELEMETRY_INTERVAL_MS 200
|
||||
#define TELEMETRY_INTERVAL_MS 250
|
||||
#define SENSOR_STALE_MS 2000
|
||||
#define USB_TELEMETRY_ENABLED 1
|
||||
#define LEVEL_CALIBRATION_DURATION_MS 5000
|
||||
|
||||
Reference in New Issue
Block a user