The Problem
Victron’s "Instant Readout" is great on a smartphone, but a dedicated wall-mounted display is often preferred in an RV or boat. While the official Victron GX Touch displays are beautiful, they require a GX-device (Cerbo) and a significant budget. I wanted a standalone, low-power display that I could mount in a cabinet and dim at night with a single tap.
The Build
The heart of the project is the ESP32 using the VictronBLE library.
Key Features:
- Flicker-Free UI: Implemented using a double-buffered Sprite strategy (via
TFT_eSPI). Only half the screen is updated in memory at a time to stay within RAM limits while maintaining 60fps-style smooth transitions. - Smart Data Filtering: To prevent "ghost" readings or corrupted BLE packets from showing wild values, I implemented a Plausibility Engine. It checks the delta between the last known good reading and the new packet (e.g., rejecting a 2% SOC jump in 1 second).
- Touch-to-Dim: Integrated the
XPT2046touchscreen to cycle the backlight through three brightness levels via PWM—essential for sleeping in an RV. - Color-Coded Status: Visual cues use Cyan for charging and Orange for discharging, making it readable from across the rig.
Technical Breakdown
- Hardware: ESP32-2432S028R (ILI9341 2.8" TFT).
- Connectivity: BLE (for data) and WiFi (for OTA updates).
- Backlight Control: PWM on GPIO 21.
- Validation: Custom
packetPlausible()function to filter out transient EMI noise often found in automotive environments.
The Code
The software is written in the Arduino IDE. It uses a custom callback structure to handle incoming BLE advertisements. When a packet is decrypted using the Shunt's 32-character key, the UI is updated instantly.
Lessons Learned
The biggest challenge was memory management. Running a full BLE stack alongside a high-resolution display driver on an ESP32 is tight. Moving to a "Half-Sprite" rendering method (updating the top and bottom 120 pixels separately) saved enough RAM to keep the Bluetooth connection stable without crashes.
rockfishon