From f9fe949bb929301bb32cd510750450da076d10ce Mon Sep 17 00:00:00 2001 From: root Date: Wed, 3 Jun 2026 01:04:11 -0600 Subject: [PATCH] Add initial ESP32 controller firmware --- firmware/esp32/xterra-controller/config.h | 18 +++ firmware/esp32/xterra-controller/protocol.h | 6 + firmware/esp32/xterra-controller/relays.cpp | 17 +++ firmware/esp32/xterra-controller/relays.h | 11 ++ firmware/esp32/xterra-controller/sensors.cpp | 10 ++ firmware/esp32/xterra-controller/sensors.h | 13 ++ .../xterra-controller/xterra-controller.ino | 130 ++++++++++++++++++ 7 files changed, 205 insertions(+) create mode 100644 firmware/esp32/xterra-controller/config.h create mode 100644 firmware/esp32/xterra-controller/protocol.h create mode 100644 firmware/esp32/xterra-controller/relays.cpp create mode 100644 firmware/esp32/xterra-controller/relays.h create mode 100644 firmware/esp32/xterra-controller/sensors.cpp create mode 100644 firmware/esp32/xterra-controller/sensors.h create mode 100644 firmware/esp32/xterra-controller/xterra-controller.ino diff --git a/firmware/esp32/xterra-controller/config.h b/firmware/esp32/xterra-controller/config.h new file mode 100644 index 0000000..a61ce5a --- /dev/null +++ b/firmware/esp32/xterra-controller/config.h @@ -0,0 +1,18 @@ +#pragma once + +#define DEVICE_NAME "Xterra Controller" + +// Relay Outputs +#define RELAY_STARLINK_PIN 16 +#define RELAY_FRIDGE_PIN 17 + +// DS18B20 Bus +#define ONEWIRE_PIN 4 + +// Ignition Sense +#define IGNITION_PIN 34 + +// Future RS485 +#define RS485_TX_PIN 21 +#define RS485_RX_PIN 22 +#define RS485_DE_PIN 23 diff --git a/firmware/esp32/xterra-controller/protocol.h b/firmware/esp32/xterra-controller/protocol.h new file mode 100644 index 0000000..cb86ede --- /dev/null +++ b/firmware/esp32/xterra-controller/protocol.h @@ -0,0 +1,6 @@ +#pragma once + +#define MSG_STATUS_REQUEST "status_request" +#define MSG_STATUS_RESPONSE "status_response" +#define MSG_SET_RELAY "set_relay" +#define MSG_RELAY_RESPONSE "relay_response" diff --git a/firmware/esp32/xterra-controller/relays.cpp b/firmware/esp32/xterra-controller/relays.cpp new file mode 100644 index 0000000..e89dcf8 --- /dev/null +++ b/firmware/esp32/xterra-controller/relays.cpp @@ -0,0 +1,17 @@ +#include +#include "config.h" +#include "relays.h" + +RelayState relays; + +void initRelays() { + pinMode(RELAY_STARLINK_PIN, OUTPUT); + pinMode(RELAY_FRIDGE_PIN, OUTPUT); + + updateRelayOutputs(); +} + +void updateRelayOutputs() { + digitalWrite(RELAY_STARLINK_PIN, relays.starlink); + digitalWrite(RELAY_FRIDGE_PIN, relays.fridge); +} diff --git a/firmware/esp32/xterra-controller/relays.h b/firmware/esp32/xterra-controller/relays.h new file mode 100644 index 0000000..cc5ac27 --- /dev/null +++ b/firmware/esp32/xterra-controller/relays.h @@ -0,0 +1,11 @@ +#pragma once + +struct RelayState { + bool starlink = false; + bool fridge = true; +}; + +extern RelayState relays; + +void initRelays(); +void updateRelayOutputs(); diff --git a/firmware/esp32/xterra-controller/sensors.cpp b/firmware/esp32/xterra-controller/sensors.cpp new file mode 100644 index 0000000..276756f --- /dev/null +++ b/firmware/esp32/xterra-controller/sensors.cpp @@ -0,0 +1,10 @@ +#include "sensors.h" + +SensorData sensors; + +void initSensors() { +} + +void updateSensors() { + // Placeholder until DS18B20 support is added +} diff --git a/firmware/esp32/xterra-controller/sensors.h b/firmware/esp32/xterra-controller/sensors.h new file mode 100644 index 0000000..3870430 --- /dev/null +++ b/firmware/esp32/xterra-controller/sensors.h @@ -0,0 +1,13 @@ +#pragma once + +struct SensorData { + float fridgeZone1 = 36.0; + float fridgeZone2 = 12.0; + float rearSeat = 78.0; + float outsideAir = 88.0; +}; + +extern SensorData sensors; + +void initSensors(); +void updateSensors(); diff --git a/firmware/esp32/xterra-controller/xterra-controller.ino b/firmware/esp32/xterra-controller/xterra-controller.ino new file mode 100644 index 0000000..68face4 --- /dev/null +++ b/firmware/esp32/xterra-controller/xterra-controller.ino @@ -0,0 +1,130 @@ +#include +#include +#include + +#include "config.h" +#include "relays.h" +#include "sensors.h" + +WebServer server(80); + +float batterySOC = 82.0; +float batteryVoltage = 13.2; +float batteryCurrent = -6.4; +float batteryRemainingAh = 82.0; +float batteryRuntimeHours = 12.0; +float batteryTemp = 76.0; + +void handleStatus() { + + DynamicJsonDocument doc(2048); + + doc["timestamp"] = millis(); + + JsonObject battery = doc.createNestedObject("battery"); + battery["soc"] = batterySOC; + battery["voltage"] = batteryVoltage; + battery["current"] = batteryCurrent; + battery["remaining_ah"] = batteryRemainingAh; + battery["runtime_hours"] = batteryRuntimeHours; + battery["temperature_f"] = batteryTemp; + + JsonObject temps = doc.createNestedObject("temps"); + temps["fridge_zone_1"] = sensors.fridgeZone1; + temps["fridge_zone_2"] = sensors.fridgeZone2; + temps["rear_seat"] = sensors.rearSeat; + temps["outside"] = sensors.outsideAir; + + JsonObject relayObj = doc.createNestedObject("relays"); + relayObj["starlink"] = relays.starlink; + relayObj["fridge"] = relays.fridge; + + JsonObject vehicle = doc.createNestedObject("vehicle"); + vehicle["ignition_on"] = digitalRead(IGNITION_PIN); + + JsonObject network = doc.createNestedObject("network"); + network["wifi_enabled"] = true; + network["rs485_connected"] = true; + + String output; + serializeJsonPretty(doc, output); + + server.send(200, "application/json", output); +} + +void handleStarlinkOn() { + relays.starlink = true; + updateRelayOutputs(); + server.send(200, "text/plain", "OK"); +} + +void handleStarlinkOff() { + relays.starlink = false; + updateRelayOutputs(); + server.send(200, "text/plain", "OK"); +} + +void handleFridgeOn() { + relays.fridge = true; + updateRelayOutputs(); + server.send(200, "text/plain", "OK"); +} + +void handleFridgeOff() { + relays.fridge = false; + updateRelayOutputs(); + server.send(200, "text/plain", "OK"); +} + +void setup() { + + Serial.begin(115200); + + Serial.println(); + Serial.println("=================================="); + Serial.println("Xterra Controller Booting"); + Serial.println("=================================="); + + pinMode(IGNITION_PIN, INPUT); + + initRelays(); + initSensors(); + + WiFi.mode(WIFI_AP); + + bool apResult = WiFi.softAP("XterraController"); + + if (apResult) { + Serial.println("AP Started"); + Serial.print("IP: "); + Serial.println(WiFi.softAPIP()); + } + + server.on("/status", handleStatus); + + server.on("/relay/starlink/on", handleStarlinkOn); + server.on("/relay/starlink/off", handleStarlinkOff); + + server.on("/relay/fridge/on", handleFridgeOn); + server.on("/relay/fridge/off", handleFridgeOff); + + server.begin(); + + Serial.println("Web Server Started"); +} + +void loop() { + + server.handleClient(); + + static unsigned long lastSensorUpdate = 0; + + if (millis() - lastSensorUpdate > 5000) { + + updateSensors(); + + lastSensorUpdate = millis(); + + Serial.println("Sensor Update"); + } +}