Skip to content

About

BLE readers for caravan batteries: PowerQueen LiFePO4 BMS + Victron Instant Readout (SmartSolar MPPT, Blue Smart Charger)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

51 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Caravan Automation System

Low-power monitoring and automation system for a towable caravan, built around an ESP32-C6 SuperMini running OpenThread Border Router with Matter-compatible sensors.


Project Goals

  • Monitor battery state, solar production, temperatures, water level, doors, leaks, motion
  • Detect power source (shore power, car connection, off-grid)
  • Alert via SMS for critical events (leak, intrusion, low battery)
  • Display status on local AMOLED screen (T-Encoder Pro)
  • Control via phone app (BLE) or rotary encoder
  • Level caravan using gyroscope with audio feedback
  • Track GPS location while towing
  • Future-proof for relay control without implementing it now

Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    ESP32-C6 SuperMini HUB                       β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚  β”‚ Thread β”‚ β”‚ Matter β”‚ β”‚ Wi-Fi  β”‚ β”‚  BLE   β”‚ β”‚ State  β”‚         β”‚
β”‚  β”‚  OTBR  β”‚ β”‚  Ctrl  β”‚ β”‚ + OTA  β”‚ β”‚  C+P   β”‚ β”‚Machine β”‚         β”‚
β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚       β”‚          β”‚                     β”‚                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚  β”‚ 802.15.4 Radio    β”‚  β”‚ BLE 5.3 Radio    β”‚  β”‚ VE.Dir β”‚        β”‚
β”‚  β”‚ (native)          β”‚  β”‚                  β”‚  β”‚ Parser β”‚        β”‚
β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”˜        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                      β”‚                     β”‚
        β–Ό                      β–Ό                     β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  IKEA   β”‚            β”‚ Power   β”‚           β”‚ Victron β”‚
   β”‚ Thread  β”‚            β”‚ Queen   β”‚           β”‚  MPPT   β”‚
   β”‚ Sensors β”‚            β”‚  BMS    β”‚           β”‚VE.Directβ”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Hardware Components

Component Purpose Interface
ESP32-C6 SuperMini Main controller (Thread + Wi-Fi + BLE + Matter) β€”
T-Encoder Pro AMOLED display + rotary encoder + buzzer UART (JST)
SIM7600SA-MNSE 4G LTE + GPS UART (AT mode + GPS-via-AT)
MPU6500 Gyroscope/accelerometer I2C
Victron MPPT 75/15 Solar charge controller VE.Direct
Victron IP65 12V 25A Shore power charger β€”
Power Queen 100Ah LiFePO4 battery with BLE BMS BLE
Dometic SMP 301-01 230V AC β†’ 12V DC β€”
13-pin Euro connector Tow vehicle interface β€”
Water level gauge 0-190Ξ© resistive ADC
SimBase data SIM 4G connectivity β€”
INA219 Γ—2 Current/power monitor (main bus, fridge) I2C
PC817 Γ—3 Optocoupler isolation (shore/car detect) GPIO
HLK-PM01 230V AC β†’ 5V DC for shore detection β€”
AO3401 P-channel MOSFET, SIM7600 power gate GPIO
TXS0102 Bidirectional level shifter (VE.Direct) β€”
DS18B20 Waterproof outdoor temp sensor 1-Wire
IKEA TIMMERFLOTTE Indoor temp/humidity Thread
IKEA MYGGBETT Γ—2 Door/window sensor Thread
IKEA KLIPPBOK Water leak sensor (built-in siren) Thread
IKEA MYGGSPRAY Motion sensor Thread
Resistors, JST-PH connectors, prototype PCB Assembly β€”

GPIO Assignments

GPIO Function Direction Protocol Notes
0 Water level Input ADC A0, voltage divider
1 Shore power detect Input GPIO Active LOW (PC817)
2 Car connection detect Input GPIO Active LOW (PC817)
3 DS18B20 outdoor temp Bidir 1-Wire 4.7 kΞ© pull-up to 3.3V
4 I2C SDA Bidir I2C INA219 Γ—2, MPU6500
5 I2C SCL Output I2C 400 kHz
6 LP_UART RX Input UART SIM7600 β†’ C6
7 LP_UART TX Output UART C6 β†’ SIM7600, 115200 baud
8 SIM7600 power gate Output GPIO AO3401 P-FET (disables onboard RGB LED)
14 Reserved β€” β€” Future relay channel
20 UART1 RX Input UART VE.Direct from MPPT, 19200 baud
21 UART1 TX Output UART VE.Direct via TXS0102 level shifter
22 T-Encoder TX Output SW UART JST connector to display
23 T-Encoder RX Input SW UART 115200 baud
USB USB-Serial-JTAG β€” USB Flashing + console + JTAG
BLE Power Queen + Phone β€” BLE 5.3 Central + Peripheral
RF IKEA sensors β€” 802.15.4 Native, Matter-over-Thread

Reserved / cannot use: GPIO 9 (BOOT button), 12, 13 (USB D-/D+), 15 (status LED), 18, 19 (internal SPI flash).


I2C Device Addresses

Address Device Data
0x40 INA219 #1 Main bus voltage, current, power
0x41 INA219 #2 Fridge circuit voltage, current, power
0x68 MPU6500 Pitch, roll, acceleration

Detection Circuits

Shore Power Detection (230V AC)

230V AC ──► HLK-PM01 ──► 5V ──► 1kΞ© ──► PC817 LED
                                              β”‚
                                             GND

3.3V ──► 10kΞ© pull-up ──┬──► GPIO1
                        β”‚
                   PC817 collector
                        β”‚
                       GND

Logic: Shore ON β†’ GPIO1 LOW | Shore OFF β†’ GPIO1 HIGH

Car Connection Detection (13-Pin Connector)

Pin 10 (12V) ──► 10kΞ© ──┬──► 10kΞ© ──► GND     (voltage divider)
                        β”‚
                        └──► 1kΞ© ──► PC817 LED
                                          β”‚
                                         GND

3.3V ──► 10kΞ© pull-up ──┬──► GPIO2
                        β”‚
                   PC817 collector
                        β”‚
                       GND

Logic: Car ON β†’ GPIO2 LOW | Car OFF β†’ GPIO2 HIGH

Water Level Sensing

3.3V ──► 100Ξ© ──┬──► GPIO0 (ADC)
                β”‚
           Tank Sensor (0-190Ξ©)
                β”‚
               GND

Voltage: Empty (0Ξ©) = 0.00V | Full (190Ξ©) = 2.16V
ADC: Empty β‰ˆ 0 | Full β‰ˆ 2680 (of 4095)

Outdoor Temperature (DS18B20)

3.3V ──► 4.7kΞ© ──┬──► GPIO3 (1-Wire data)
                 β”‚
            DS18B20 DATA (yellow)
            DS18B20 VCC (red) ──► 3.3V
            DS18B20 GND (black) ──► GND

VE.Direct Connection

Victron MPPT uses 5V TTL; ESP32-C6 uses 3.3V. Level shifter required.

Victron JST-PH          TXS0102              ESP32-C6
─────────────          ─────────             ────────
Pin 1: GND ──────────► GND ◄────────────────► GND
Pin 2: RX  ◄───────── HV1 ◄──── LV1 ◄─────── GPIO21 (TX)
Pin 3: TX  ──────────► HV2 ────► LV2 ───────► GPIO20 (RX)
Pin 4: +5V ──────────► HV (ref)
                       LV (ref) ◄───────────► 3.3V

State Machine

GPIO1 (Shore) GPIO2 (Car) State Description
HIGH HIGH OFFGRID Battery only, wild camping
LOW HIGH CAMPSITE Shore power connected
HIGH LOW TOWING Car connected, driving
LOW LOW ARRIVED Both connected, just parked

State Behaviors

Feature OFFGRID CAMPSITE TOWING ARRIVED
Sleep mode Light sleep Off Off Off
GPS tracking On request Off Continuous Off
Motion alerts On Optional Suppressed Off
Sway detection Off Off Active Off
Leveling mode Off On request Off Active
Display On-demand Always on Speed/stability Always on
SIM7600 Power-gated Power-gated On Power-gated

Data Points

Thread Sensors (IKEA Matter-over-Thread)

Sensor Model Data Location
Indoor climate TIMMERFLOTTE Temperature, humidity Living area
Main door MYGGBETT Open/closed Entry door
Storage door MYGGBETT Open/closed External storage
Water leak KLIPPBOK Leak detected, built-in siren Under sink
Motion MYGGSPRAY Motion detected Living area

Wired Sensors

Sensor Interface Data
Outdoor temp DS18B20 (1-Wire) Temperature Β°C
Water tank Resistive (ADC) Level 0-100%
Main current INA219 #1 (I2C) Voltage, current, power
Fridge current INA219 #2 (I2C) Voltage, current, power
Pitch/Roll MPU6500 (I2C) Orientation, acceleration

BLE Sensors

Sensor Protocol Data
Power Queen BMS BLE (proprietary) SoC, voltage, current, cell voltages, temp, cycles

Serial Sensors

Sensor Interface Data
Victron MPPT VE.Direct (UART) Panel V/I, battery V/I, yield, charge state
SIM7600 GPS USB (NMEA) Latitude, longitude, speed, heading

Communication Protocols

Link Protocol Speed Purpose
C6 ↔ Victron MPPT UART1 19200 VE.Direct text protocol
C6 ↔ T-Encoder Pro SW UART 115200 JSON status + buzzer commands
C6 ↔ SIM7600 LP_UART 115200 AT commands, SMS, GPS-via-AT
C6 ↔ Power Queen BLE β€” Proprietary BMS protocol
C6 ↔ Phone BLE GATT β€” Status read, config write
C6 ↔ IKEA sensors 802.15.4 (Matter) β€” Native, no RCP
C6 ↔ Wi-Fi AP Wi-Fi 6 STA β€” OTA + home backhaul

T-Encoder Pro Protocol

C6 β†’ T-Encoder (status updates + buzzer)

{
  "ts": 1711700000,
  "state": "CAMPSITE",
  "battery": {"soc": 78, "voltage": 13.2, "current": 2.5, "power": 33},
  "solar": {"voltage": 18.5, "power": 45, "daily": 320},
  "temp": {"indoor": 22.5, "outdoor": 18.2, "humidity": 55},
  "water": {"level": 65},
  "doors": {"main": "closed", "storage": "closed"},
  "level": {"pitch": 1.2, "roll": -0.5}
}

Buzzer commands (sent in addition to status updates β€” display fires its onboard buzzer):

{"buzzer": {"pattern": "level_ok"}}
{"buzzer": {"pattern": "level_warning"}}
{"buzzer": {"pattern": "alert"}}
{"buzzer": {"freq": 2000, "duration_ms": 100}}

T-Encoder β†’ C6 (user input)

{"event": "encoder", "direction": "cw", "clicks": 3}
{"event": "button", "action": "press"}
{"event": "button", "action": "long_press"}
{"event": "touch", "x": 120, "y": 80}
{"event": "menu", "select": "level_mode"}

SMS Commands

Command Response
STATUS Battery SoC, voltage, solar power, temperatures, GPS
POWER Detailed power info (main bus, fridge, charging)
GPS Coordinates + Google Maps link
HELP List available commands

Alert Conditions (Configurable)

Condition Default Threshold Action
Low battery SoC < 20% SMS alert
Water leak Detected SMS alert + buzzer
Door open (OFFGRID) Any door SMS alert
Motion (OFFGRID) Detected SMS alert
Excessive sway > 0.3g lateral Buzzer warning
High temperature > 35Β°C indoor SMS alert
Freezing risk < 5Β°C indoor SMS alert

Power Budget

State Mode Estimated avg current Notes
OFFGRID Light sleep, Thread router awake 30–50 mA Conservative; instrument early in firmware
CAMPSITE Active, Wi-Fi connected 80–120 mA Display always on
TOWING Active, GPS continuous 100–150 mA SMS standby
ARRIVED Active, similar to CAMPSITE 80–120 mA

With a 100 Ah battery: roughly 80–140 days OFFGRID standby. The previous architecture's ~520 day figure assumed the host MCU could deep-sleep, which is incompatible with running a Thread border router. These numbers will be measured and refined during firmware bring-up.


Repository Layout

.
β”œβ”€β”€ README.md                       # This document
β”‚
β”œβ”€β”€ c6-hub/                         # ESP-IDF v6.0 firmware (ESP32-C6)
β”‚   β”œβ”€β”€ CMakeLists.txt
β”‚   β”œβ”€β”€ partitions.csv              # Single-app slot for 4 MB; switches to dual-OTA on 16 MB
β”‚   β”œβ”€β”€ sdkconfig.defaults
β”‚   β”œβ”€β”€ build.sh                    # Wraps idf.py
β”‚   β”œβ”€β”€ flash.sh                    # Wraps idf.py flash + monitor
β”‚   └── main/
β”‚       β”œβ”€β”€ CMakeLists.txt
β”‚       β”œβ”€β”€ main.c                  # Entry point β€” currently boot info + heartbeat
β”‚       β”œβ”€β”€ state_machine.c         # OFFGRID / CAMPSITE / TOWING / ARRIVED  (planned)
β”‚       β”œβ”€β”€ thread_otbr.c           # OpenThread Border Router  (planned)
β”‚       β”œβ”€β”€ matter_controller.c     # Matter device pairing + reads  (planned)
β”‚       β”œβ”€β”€ wifi_manager.c          # Wi-Fi STA + OTA  (planned)
β”‚       β”œβ”€β”€ ota_handler.c           # esp_https_ota driver  (planned)
β”‚       β”œβ”€β”€ victron_vedirect.c      # VE.Direct parser  (planned)
β”‚       β”œβ”€β”€ power_monitor.c         # INA219 + shore/car detect  (planned)
β”‚       β”œβ”€β”€ sensors.c               # DS18B20, water level, MPU6500  (planned)
β”‚       β”œβ”€β”€ ble_bms.c               # Power Queen BMS client  (planned)
β”‚       β”œβ”€β”€ ble_server.c            # Phone-app GATT server  (planned)
β”‚       β”œβ”€β”€ sms_handler.c           # SIM7600 AT commands  (planned)
β”‚       β”œβ”€β”€ gps.c                   # GPS-via-AT polling  (planned)
β”‚       β”œβ”€β”€ display_link.c          # T-Encoder UART protocol + buzzer  (planned)
β”‚       β”œβ”€β”€ alerts.c                # Threshold monitoring  (planned)
β”‚       β”œβ”€β”€ rules_engine.c          # Configurable automation  (planned)
β”‚       └── config.c                # NVS storage for settings  (planned)
β”‚
β”œβ”€β”€ t-encoder-display/              # LVGL UI for T-Encoder Pro  (planned)
β”‚   β”œβ”€β”€ main.cpp
β”‚   β”œβ”€β”€ gauges.cpp
β”‚   β”œβ”€β”€ level_screen.cpp
β”‚   β”œβ”€β”€ menu.cpp
β”‚   └── uart_protocol.cpp
β”‚
β”œβ”€β”€ docs/                           # Architecture & protocol specs
β”‚   β”œβ”€β”€ architecture.mermaid
β”‚   β”œβ”€β”€ state_machine.mermaid
β”‚   β”œβ”€β”€ wiring.mermaid
β”‚   β”œβ”€β”€ dataflow.mermaid
β”‚   β”œβ”€β”€ protocols/
β”‚   β”‚   β”œβ”€β”€ powerqueen_bms.md
β”‚   β”‚   └── victron_instant_readout.md
β”‚   └── superpowers/                # Specs and plans for major changes
β”‚       β”œβ”€β”€ specs/
β”‚       └── plans/
β”‚
└── tools/
    └── ble-probe/                  # Python reference (Pi-based) β€” reverse-engineers
        β”œβ”€β”€ read_battery.py         # the BLE protocols the firmware re-implements in C.
        β”œβ”€β”€ read_victron.py         # Not part of the runtime system.
        └── victron.env.example

Module source files inside c6-hub/main/ (other than main.c) and t-encoder-display/ are targets to be implemented β€” main.c is a hello-world that prints chip info; the rest will be built up module by module, each with its own spec under docs/superpowers/specs/.


Key Design Decisions

  1. Single ESP32-C6 SuperMini β€” One chip handles Thread (native 802.15.4), Wi-Fi 6, BLE 5.3, and the application logic. Replaces the earlier ESP32-S3 + XIAO nRF52840 RCP design; see docs/superpowers/specs/2026-04-25-c6-single-mcu-design.md for the rationale.

  2. IKEA Thread sensors over custom nodes β€” Off-the-shelf Matter-over-Thread devices eliminate custom firmware, provide multi-year battery life, and simplify deployment.

  3. SIM7600 over UART (AT mode + GPS-via-AT) β€” The C6 has no USB host. AT-mode polling at ~1 Hz is sufficient for the caravan use case (SMS commands, periodic GPS); avoids a second UART for raw NMEA streaming.

  4. T-Encoder Pro for display and audio β€” The display module includes its own ESP32-S3, AMOLED screen, rotary encoder, and a buzzer on its GPIO17. The C6 sends JSON over UART; the display drives its own UI and sounds its own buzzer. No discrete buzzer needed on the C6.

  5. Single Victron VE.Direct β€” MPPT only; IP65 charger data is redundant given shore power detection and INA219 monitoring.

  6. DS18B20 for outdoor temp β€” Wired sensor is more reliable than battery-powered Thread sensor for external mounting.

  7. Power Queen BMS via BLE β€” Deferred to software phase due to proprietary protocol; INA219 provides backup current measurement.

  8. Relay support pre-wired β€” GPIO 14 reserved for future relay control without implementing now.

  9. Automation rules in software β€” All thresholds and behaviors configurable in NVS, changeable via phone app or Wi-Fi.

  10. Wi-Fi kept active β€” Used for OTA updates and home-network connectivity when parked. Drops to backhaul-only or disabled if SRAM headroom becomes a problem.


Next Steps

  1. Flash XIAO nRF52840 with OpenThread RCP firmware β€” obsolete after C6 pivot.
  2. Bring up c6-hub hello-world firmware on the 4 MB ESP32-C6FH4 β€” confirm USB-Serial-JTAG flash + console + IEEE 802.15.4 MAC visible. βœ“ Done 2026-04-25.
  3. Build VE.Direct cable with TXS0102 level shifter.
  4. Wire detection circuits (shore power, car connection).
  5. Develop ESP32-C6 firmware modules β€” each with its own spec/plan under docs/superpowers/. Suggested order: state_machine β†’ power_monitor β†’ sensors β†’ display_link β†’ ble_bms β†’ thread_otbr β†’ matter_controller β†’ wifi_manager β†’ sms_handler β†’ ota_handler β†’ alerts/rules.
  6. Pair IKEA sensors to the Thread network (after Matter controller works).
  7. Develop T-Encoder Pro UI (LVGL gauges, menus, buzzer patterns).
  8. Port Power Queen BLE protocol to C (spec in docs/protocols/powerqueen_bms.md).
  9. Migrate to 16 MB SuperMini when it arrives β€” switch partitions.csv to dual-OTA layout.
  10. Test and iterate.

References


Document version: 2.0 β€” single-MCU ESP32-C6 architecture
Last updated: April 2026

About

BLE readers for caravan batteries: PowerQueen LiFePO4 BMS + Victron Instant Readout (SmartSolar MPPT, Blue Smart Charger)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages