Dev #26

Open
overseer wants to merge 65 commits from dev into main
2 changed files with 111 additions and 2 deletions
Showing only changes of commit 996ef87dfd - Show all commits
+3 -1
View File
@@ -65,7 +65,9 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/
board = seeed_xiao_esp32c6
framework = arduino
monitor_speed = 115200
lib_deps = ${common.lib_deps}
lib_deps =
${common.lib_deps}
olikraus/U8g2 @ ^2.35
build_flags = ${common.build_flags}
-D CONFIG_ARDUINO_LOOP_STACK_SIZE=8192
-D ARDUINO_USB_MODE=1
+108 -1
View File
@@ -31,6 +31,8 @@
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <SPIFFS.h>
#include <Wire.h>
#include <U8g2lib.h>
// ────────────────────────────────────────────
// Configuration (SPIFFS)
@@ -91,9 +93,58 @@ bool saveConfig() {
#define UART_TX_PIN D6
// Camera-online indicator → green channel of the RGB STAT LED.
// (Full RGB/OLED status-panel bring-up is not implemented yet.)
#define STAT_LED_PIN D1
// ────────────────────────────────────────────
// Status OLED — 1.3" I2C panel on D4(SDA)/D5(SCL)
// ────────────────────────────────────────────
// 1.3" 128x64 modules are SH1106. If the image is shifted ~2px or
// wrapped, the panel is an SSD1306 — swap the constructor below to
// U8G2_SSD1306_128X64_NONAME_F_HW_I2C.
#define OLED_SDA_PIN D4
#define OLED_SCL_PIN D5
#define OLED_I2C_ADDR 0x3C
U8G2_SH1106_128X64_NONAME_F_HW_I2C oled(U8G2_R0, U8X8_PIN_NONE);
bool oledReady = false;
// Last-known camera status, mirrored for the display.
int dispBatteryRaw = 0;
bool dispRecording = false;
int dispVideoRemain = 0; // seconds
unsigned long recStartMs = 0; // 0 = not recording
// Walk the bus and log every responder — confirms the OLED address
// (and wiring) independent of the display driver.
void i2cScan() {
Serial.println("[I2C] Scanning...");
byte found = 0;
for (byte a = 1; a < 127; a++) {
Wire.beginTransmission(a);
if (Wire.endTransmission() == 0) {
Serial.printf("[I2C] device @ 0x%02X\n", a);
found++;
}
}
if (!found) Serial.println("[I2C] none found — check wiring/power");
}
void displayInit() {
Wire.begin(OLED_SDA_PIN, OLED_SCL_PIN);
i2cScan();
oled.setI2CAddress(OLED_I2C_ADDR << 1);
oledReady = oled.begin();
Serial.printf("[OLED] begin %s\n", oledReady ? "ok" : "FAILED");
if (!oledReady) return;
oled.clearBuffer();
oled.setFont(u8g2_font_7x14B_tr);
oled.drawStr(0, 14, "RemoteRig");
oled.setFont(u8g2_font_6x10_tr);
oled.drawStr(0, 32, "Camera node");
oled.drawStr(0, 46, "booting...");
oled.sendBuffer();
}
void sendCmdToESP8266(const String& command) {
JsonDocument doc;
doc["type"] = "cmd";
@@ -201,6 +252,48 @@ bool connectMQTT() {
return true;
}
// ────────────────────────────────────────────
// Status screen
// ────────────────────────────────────────────
void renderStatus() {
if (!oledReady) return;
oled.clearBuffer();
// Camera id (top, bold)
oled.setFont(u8g2_font_7x14B_tr);
String id = cfg.camera_id.length() ? cfg.camera_id : clientID();
oled.drawStr(0, 13, id.c_str());
oled.setFont(u8g2_font_6x10_tr);
char line[24];
// REC state + session timer
if (dispRecording) {
unsigned long s = recStartMs ? (millis() - recStartMs) / 1000 : 0;
oled.drawBox(0, 19, 6, 6); // filled square = REC
snprintf(line, sizeof(line), "REC %02lu:%02lu", s / 60, s % 60);
oled.drawStr(10, 26, line);
} else {
oled.drawStr(0, 26, "IDLE");
}
// Battery (raw until calibrated) + video remaining (minutes)
snprintf(line, sizeof(line), "BAT %d VID %dm", dispBatteryRaw, dispVideoRemain / 60);
oled.drawStr(0, 38, line);
// Uplink to the hub
const char* link = mqtt.connected() ? "LINK: MQTT ok"
: WiFi.status() == WL_CONNECTED ? "LINK: wifi only"
: "LINK: offline";
oled.drawStr(0, 50, link);
// Camera reachability
oled.drawStr(0, 62, cameraOnline ? "CAM: online" : "CAM: --");
oled.sendBuffer();
}
// ────────────────────────────────────────────
// Setup
// ────────────────────────────────────────────
@@ -214,6 +307,8 @@ void setup() {
pinMode(STAT_LED_PIN, OUTPUT); // RGB STAT LED — green = camera online
digitalWrite(STAT_LED_PIN, LOW);
displayInit(); // I2C scan + OLED splash
loadConfig();
// UART to ESP-01S
@@ -251,6 +346,10 @@ void loop() {
static unsigned long lastBeat = 0, lastRecon = 0;
static int reconDelay = 1;
// ── OLED refresh (always — keep the panel live even when offline) ──
static unsigned long lastDisp = 0;
if (now - lastDisp > 500) { lastDisp = now; renderStatus(); }
// ── Wi-Fi watchdog ──
if (WiFi.status() != WL_CONNECTED) {
if (now - lastRecon > 5000) { lastRecon = now; WiFi.reconnect(); }
@@ -288,6 +387,14 @@ void loop() {
digitalWrite(STAT_LED_PIN, online ? HIGH : LOW);
}
// Mirror status onto the OLED fields
dispBatteryRaw = doc["battery_raw"] | 0;
dispVideoRemain = doc["video_remaining_sec"] | 0;
bool rec = doc["recording"] | false;
if (rec && !dispRecording) recStartMs = millis();
if (!rec) recStartMs = 0;
dispRecording = rec;
if (cfg.camera_id.length() > 0) {
// Build the MQTT status payload per contract
JsonDocument mqttDoc;