Releases: Techposts/TankSync
TankSync Transmitter 3.0.0 — new ESP-NOW "Lite" variant
Introduces the Lite transmitter: the same TankSync experience without the LoRa module, using the ESP32-C3's built-in radio for same-building range.
What's new
- ESP-NOW "Lite" transport variant via a build-time
transport_iface(-DTRANSPORT=lora|espnow). One source tree, two binaries — no module on the Lite board. - Full parity with LoRa. Lite keeps auto-pair, config push, remote OTA, and an identical
tx_data_t, so the dashboard / Home Assistant / PWA see no difference beyond range. - Pairs to the universal hub (rx-v3.0.0+); the hub auto-detects transport at pair time.
Downloads
tanksync-transmitter-tx-v3.0.0.bin— Transmitter, LoRa (RYLR998 module)tanksync-transmitter-lite-tx-v3.0.0.bin— Transmitter, Lite / ESP-NOW (built-in radio, no module)
Verified on hardware
- ESP-NOW transmitter validated end-to-end against ESP32 DevKit and ESP32-S3 hubs; mixed fleet confirmed.
Requires
- A hub on rx-v3.0.0 or newer for ESP-NOW pairing.
Who should install
- LoRa users: optional. New Lite SKU: flash the
-litebinary.
Full Changelog: tx-v2.0.15...tx-v3.0.0
TankSync Hub 3.0.0 — universal LoRa + ESP-NOW hub, redesigned display
The hub now serves LoRa and the new ESP-NOW "Lite" transmitters at the same time, and ships a fully redesigned OLED + LED experience. Recommended for every hub; required to pair the new Lite transmitters.
What's new
- Universal hub. A concurrent ESP-NOW receive path runs alongside LoRa and fills the same registry — one hub handles a mixed LoRa + Lite fleet. Transport is auto-detected at pairing; there is no selector to set.
- Redesigned OLED. Per-tank layout: name + signal bars, a cylinder with wavy water and level ticks, droplet + litres, and battery + last-update. Cloud-optional fix — no more stuck "NOT LINKED" when running without the cloud.
- WS2812 LED ring. Boot animation, gauge that follows the OLED's current tank (8- and 24-LED modes), live strip-mode switching, and a WiFi LED that turns green when connected.
- ESP32-S3 SuperMini pin-map updates for the S3 hub build.
Downloads
tanksync-receiver-rx-v3.0.0.bin— Hub, ESP32 DevKittanksync-receiver-s3-rx-v3.0.0.bin— Hub, ESP32-S3 SuperMini
Verified on hardware
- ESP-NOW validated end-to-end on ESP32 DevKit and ESP32-S3 hubs; mixed LoRa + Lite fleet confirmed. OLED + LED redesign validated on S3.
Who should install
- All hubs (optional but recommended). Required if you are pairing ESP-NOW "Lite" transmitters.
Full Changelog: rx-v2.8.6...rx-v3.0.0
rx-v2.8.6
rx-v2.8.6 — bidirectional sensor sync + on-device diagnostic console
This release pairs with tx-v2.0.15 and lights up two things I've wanted on the hub for a while: the receiver now understands which sensor each transmitter is actually running, and there's a built-in diagnostic console you can pull straight from the device — no laptop-on-balcony required.
What's new
Per-transmitter sensor selector
Each tank's edit sheet now has a Sensor dropdown (Ultrasonic AJ-SR04M / mmWave HLK-LD2413). The receiver tracks two fields per TX:
sensor_kind— what the hub wants the TX to useactive_sensor— what the TX is actually running, reported back inside each TANK packet
When you save a change from the hub or the PWA, the value gets queued as a remote-config update, sent over LoRa via the existing SET: downlink (now with a :SENSOR= clause), ACKed by the TX, and the next TANK frame closes the loop with active_sensor matching sensor_kind. Mixed-firmware fleets keep working — older TXs that don't yet emit the field parse fine with active_sensor="".
If you change the sensor on the TX directly (via its AP web UI), the hub also learns from it. When the registry sees an active_sensor that diverges from its sensor_kind and no SET is in flight, it auto-syncs the registry to TX-truth. So edits from either side converge.
Diagnostic console
Boot-time logging is now captured into a 4 KB ring buffer inside the receiver and exposed at GET /api/logs. Paired with the diagnostic-mode toggle on the TX firmware, you can pull a live log tail from either device to a terminal:
curl http://<hub-ip>/api/logs # whole tail
curl http://<hub-ip>/api/log_clear # wipe + start freshNo serial cable, no rooftop, no opening the case. The previous LoRa-OTA debug story relied on plugging into the TX — now you can diagnose from anywhere on the LAN.
MQTT bridge for the new field
Cloud telemetry now exposes:
tank_<addr>/sensor_kind(retained) — hub's desired sensor for this TXtank_<addr>/active_sensor(retained) — what the TX is currently runningcmd/set_confignow accepts asensor_kindfield for remote control from the PWA
What changed (file-level)
components/transmitter_registry/— addedsensor_kind+active_sensorfields, bidirectional auto-sync when TX-truth diverges from registry intent,registry_set_sensor_kind()APIcomponents/lora_rylr998/— TANK parser extracts the 11th positional field (active_sensor); backwards-compat with older TXs that omit itcomponents/web_server/— Edit Tank sheet adds the Sensor dropdown (full-width row),/api/transmittersreturns both fields,/api/logs+/api/log_clearadded, max URI handlers bumped to 12 so the new endpoints actually registercomponents/mqtt_client/— publishes both fields as retained topics, acceptssensor_kindoncmd/set_configcomponents/log_buffer/— new component: 4 KB ring buffer wired up viaesp_log_set_vprintf()main/main.c— SET-frame builder appends:SENSOR=...when a sensor change is queued;log_buffer_init()runs first thing inapp_main
OTA + upgrade notes
Standard OTA from any rx-v2.7.x+ build via the Settings → System → Check for updates flow on the hub web UI. The cloud-side OTA proxy and PWA OTA panel both already understand the new version. No manual steps required after upgrade — the new fields default to empty ("") on existing transmitters and populate as soon as each TX reports its active_sensor on the next wake.
If you're also flashing tx-v2.0.15 transmitters: the pair works end-to-end on the bench (Normal Water Tank, addr 2, on my own deployment). For mixed fleets with older TX firmware, the hub gracefully treats them as active_sensor="" and skips sensor-change downlinks until you upgrade them.
Why rx-v2.8.6 instead of rx-v2.8.5?
rx-v2.8.5 already shipped earlier this week as the version-stamping bugfix release (single-VERSION-file pattern). The sensor-sync work outgrew that scope, so it gets its own tag to keep release-history clean. Both 2.8.5 and 2.8.6 are OTA-compatible with any tx-v2.0.x transmitter.
Hardware compatibility
No hardware changes. Works on existing TankSync REV 2.2 PCBs and breadboards. The HLK-LD2413 driver lives on the TX firmware side, not the RX — see the tx-v2.0.15 notes for sensor wiring.
— Ravi
tx-v2.0.13
tx-v2.0.13 — version stamping fixed (paired with rx-v2.8.5)
Companion release to rx-v2.8.5. Same single-VERSION-file pattern applied on the transmitter side.
What's fixed
esp_app_desc.versionnow reflects what was actually built. Like RX, the TX binary was stamping its version field from a hardcoded literal infirmware/Transmitter-IDF/CMakeLists.txt. Released TX binaries since tx-v2.0.11 all carried a stale version string in the binary (offset 0x30), even though the code itself was current. The PWA's Devices page, hub's web UI Firmware tab, MQTT-publishedtx_versionfield — all read the wrong value.- After this build the TX correctly self-reports
2.0.13.
Internal
- Single source of truth: edit
firmware/Transmitter-IDF/VERSION(one file). CMake reads it, setsPROJECT_VER, andconfigure_file()generatescomponents/tanksync_version/include/version_gen.hconsumed bymain/,components/wifi_ota/, andcomponents/lora_tx/. - Build provenance fingerprint preserved in
main/main.c(the magic constant + the unique typo log string incomponents/lora_tx/lora_tx.care unchanged). - No protocol changes — packet format identical to tx-v2.0.12.
Upgrade
- PWA: Settings → Firmware → expand each TX → "Update available · v2.0.13" → tap. Hub orchestrates the over-Wi-Fi OTA; TX wakes up and pulls the new binary.
- Browser flasher: tanksync.smartghar.org/firmware → Transmitter card → Install.
- Manual:
esptool.py --chip esp32c3 -b 460800 \ write_flash 0x10000 tanksync-transmitter-tx-v2.0.13.bin
Compatibility
- Hub firmware: any
rx-v2.7.xorrx-v2.8.xworks (no protocol bump). - PWA: any version (no UI dependency).
- HACS: any version (no entity-shape change).
Verification
After flashing, confirm the TX self-reports 2.0.13:
# Direct inspection of the .bin
xxd -s 0x30 -l 32 tanksync-transmitter-tx-v2.0.13.bin
# Should print: 2.0.13 followed by null padding
# Or check at runtime: hub web UI → Devices → TX row → version columnPaired with
- rx-v2.8.5 — see for the matching RX-side notes.
rx-v2.8.5
rx-v2.8.5 — version stamping fixed (single-VERSION-file pattern)
This is the first per-binary public Release of TankSync under the rx-v* / tx-v* / rxc3-v* tag scheme. See the Firmware Versions wiki page for release history + compatibility matrix.
Paired with: tx-v2.0.13 — same version-stamping fix on the transmitter side.
What's fixed
esp_app_desc.versionnow reflects what was actually built. Every release since rx-v2.7.13 shipped with the version string stuck at"2.7.13"becausefirmware/Receiver-ESP32-DevKit/CMakeLists.txthardcodedPROJECT_VER. The OLED, web UI footer, PWA Firmware page, MQTTfirmware_versionfield — all reported the wrong version even though the underlying code was current.- Bench-confirmed: the hub at
192.168.0.56was reportingv2.7.13while running rx-v2.8.4 features. After flashing this build it correctly reportsv2.8.5.
Internal
- Single source of truth: edit
firmware/Receiver-ESP32-DevKit/VERSION(one file). CMake reads it, setsPROJECT_VER, andconfigure_file()generatescomponents/tanksync_version/include/version_gen.hconsumed bymain/,components/web_server/,components/ota_manager/, andcomponents/wifi_manager/. - Build provenance fingerprint preserved in
main/main.c(planted earlier in the rx-v2.7.x line). - No protocol changes — fully backward-compatible with any
tx-v2.0.xfirmware.
Upgrade
- PWA: Settings → Firmware → "Check for updates" → Install.
- Browser flasher: tanksync.smartghar.org/firmware (one click, no toolchain).
- Manual:
esptool.py --chip esp32 -b 460800 \ write_flash 0x10000 tanksync-receiver-rx-v2.8.5.bin
Compatibility
- PWA ≥ 1.14.0 (already shipped)
- HACS ≥ 0.8.0 if using buzzer entities
- TX firmware: any
tx-v2.0.xworks
Verification
After flashing, confirm the binary self-reports 2.8.5:
# Direct inspection of the .bin
xxd -s 0x30 -l 32 tanksync-receiver-rx-v2.8.5.bin
# Should print: 2.8.5 followed by null padding
# Or check at runtime
curl http://<hub-ip>/api/system | grep version
# Should show: "version":"2.8.5"v2.2.0
What's new in v2.2.0
End-to-end TX power telemetry with two hardware variants and boot-time auto-detect — the system now tells you not just how much battery is left, but whether the panel is harvesting, how many mA are flowing, and how much power your TX is actually drawing.
Hardware variants (TX)
- Variant A — voltage divider only (legacy, simplest BOM): VBAT → 100k → ADC → 100k → GND on GPIO0.
- Variant B — INA219 over I²C: bidirectional shunt sensor in the battery+ lead. Bus voltage from register 0x02, signed shunt current from 0x01, power computed as V·I in software (no calibration register needed). Default I²C address 0x40 on GPIO1 (SDA) / GPIO2 (SCL).
Both variants run the same firmware binary. At boot the TX probes 0x40 — if found, INA219 mode; otherwise falls back to ADC. An NVS-stored override (pwr_mode_ovr = auto / voltage / ina219 / disabled) lets you force a specific mode via the TX's wifi-OTA web UI (5s button hold → connect to TankSync-<addr> AP → SETTINGS card has a Power Sensor dropdown).
LoRa packet format (forward-compatible)
TANK:<dist>:<bat_pct>:<bat_v>:<msg_id>:<fw_version>:<MODE>:<CURR>:<POW>
Where MODE is a single char (v / i / n), CURR is signed mA (positive = discharging, negative = charging), POW is signed mW. Older RXs ignore the new optional fields; older TXs send 5 fields and new RXs default to ?/0/0. Old/new mix works in any direction.
RX changes (DevKit + C3 SuperMini)
lora_rx_packet_tand the per-TXtx_data_tregistry extended withpower_mode,current_ma,power_mw,charging.GET /api/transmittersJSON exposes the new fields per TX.- MQTT publishes 4 new HA-style sub-topics per tank:
tanksync/<slug>/power_mode(string),.../current_ma(signed int),.../power_mw(signed int),.../charging(ON/OFF). Skipped for unknown mode (pre-v2.0.4 TX).
Hardware docs + BOM
hardware/wiring.md— canonical wiring reference for both RX targets and TX (Variant A + Variant B), with full power chain (panel → CN3791 MPPT → 18650 → MT3608 boost → 5V rail).hardware/BOM.csv— replaced TP4056 (linear, wrong for solar) with CN3791 MPPT charger for proper solar harvesting under variable Indian sun. Two SKU totals listed: Variant A and Variant B.
Firmware versions
| Component | Version |
|---|---|
| Transmitter (ESP32-C3 SuperMini) | 2.0.4 |
| Receiver — ESP32 DevKit | 2.2.0 |
| Receiver — ESP32-C3 SuperMini | 2.2.0 |
Backward compatibility
- New TX → old RX: works (extra fields ignored).
- Old TX → new RX: works (defaults populated).
- New RX → existing PWA / Home Assistant: power topics added cleanly alongside existing ones; old subscribers unaffected.
Firmware Binaries
| Binary | Board | Description |
|---|---|---|
| `tanksync-receiver-v2.2.0.bin` | ESP32 DevKit | Receiver firmware |
| `tanksync-receiver-c3-v2.2.0.bin` | ESP32-C3 SuperMini | Receiver firmware (C3 variant) |
| `tanksync-transmitter-v2.2.0.bin` | ESP32-C3 SuperMini | Transmitter firmware |
Flashing
```bash
Receiver (ESP32 DevKit)
esptool.py --chip esp32 -b 460800 write_flash 0x10000 tanksync-receiver-v2.2.0.bin
Receiver (ESP32-C3 SuperMini)
esptool.py --chip esp32c3 -b 460800 write_flash 0x10000 tanksync-receiver-c3-v2.2.0.bin
Transmitter (ESP32-C3 SuperMini)
esptool.py --chip esp32c3 -b 460800 write_flash 0x10000 tanksync-transmitter-v2.2.0.bin
```
Or use OTA update via the receiver's web UI.
Full Changelog: v2.1.0...v2.2.0
v2.1.0
Firmware Binaries
| Binary | Board | Description |
|---|---|---|
tanksync-receiver-v2.1.0.bin |
ESP32 DevKit | Receiver firmware |
tanksync-receiver-c3-v2.1.0.bin |
ESP32-C3 | Receiver firmware (C3 variant) |
tanksync-transmitter-v2.1.0.bin |
ESP32-C3 | Transmitter firmware |
Flashing
# Receiver (ESP32 DevKit)
esptool.py --chip esp32 -b 460800 write_flash 0x10000 tanksync-receiver-v2.1.0.bin
# Receiver (ESP32-C3)
esptool.py --chip esp32c3 -b 460800 write_flash 0x10000 tanksync-receiver-c3-v2.1.0.bin
# Transmitter (ESP32-C3)
esptool.py --chip esp32c3 -b 460800 write_flash 0x10000 tanksync-transmitter-v2.1.0.binOr use the OTA update via the receiver's web UI.
Full Changelog: v1.0...v2.1.0
v1.0 - Initial Stable Release
🎉 LoRa Water Tank Monitor v1.0
Initial stable release with pre-compiled firmware binaries for ESP32-C3.
📥 Pre-compiled Binaries
No compilation needed - just flash and go!
| Component | File | Size | Description |
|---|---|---|---|
| Transmitter | Transmitter_ESP32C3_v1.0.bin |
4.0 MB | Tank-side battery-powered unit |
| Receiver | Receiver_ESP32C3_v1.0.bin |
4.0 MB | Indoor USB-powered unit |
🚀 Quick Flash
# Transmitter
esptool.py --chip esp32c3 --port COM3 --baud 921600 write_flash 0x0 Transmitter_ESP32C3_v1.0.bin
# Receiver
esptool.py --chip esp32c3 --port COM3 --baud 921600 write_flash 0x0 Receiver_ESP32C3_v1.0.bin📖 Complete Guide: See FLASHING.md
✨ Key Features
Transmitter
- 🔋 Ultra low power: 50+ days battery life
- ☀️ Solar charging compatible
- 💧 Waterproof sensor (AJ-SR04M IP67)
- 📡 LoRa range: Up to 10+ km
- 🔄 Reliable ACK-based transmission
Receiver
- 🏗️ Modular code architecture
- 📺 OLED display with 4 screens
- 💡 Dual LED status indicators
- 🌐 Web dashboard with real-time updates
- 📊 MQTT/Home Assistant integration
- 📱 WiFi configuration via web interface
🎯 Board Support
- ✅ ESP32-C3 SuperMini (recommended)
- ✅ Generic ESP32-C3 Dev Module
⚠️ Other ESP32-C3 boards (should work)
⚙️ Default Configuration
Transmitter:
- LoRa: 865 MHz (India), Network ID: 6, Address: 1
- Sleep: 5 minutes between transmissions
- TX Power: 14 dBm
Receiver:
- LoRa: 865 MHz, Network ID: 6, Address: 2
- WiFi AP: "TankSync" (configure via web interface)
- MQTT: 192.168.0.163:1885 (configurable)
📚 Documentation
- Main README - Complete hardware and software guide
- FLASHING.md - Detailed flashing instructions
- Transmitter README - Transmitter-specific documentation
- Receiver README - Receiver-specific documentation
🐛 Known Issues
- Transmitter settings are hardcoded (requires recompilation to change)
- No OTA update support yet (planned for v2.0)
- Web interface has no authentication
🔮 Coming in upcoming versions
- OTA firmware updates
- Reset and reconfigure tank transmitter (provisioning mode)
- Web-based transmitter configuration via LoRa Commands
- User authentication
- Email/Telegram alerts
- Multiple tank support
- Progressive Web App for setup and dashboard for Mobile Devices (iOS & Android)
You can also suggest features or updates you need.
v1.0 - Arduino (Legacy)
Legacy Arduino Version
This is the original Arduino-based firmware for the LoRa Water Tank Monitor.
All future development uses ESP-IDF. See the main branch for the current ESP-IDF firmware + TankSync PWA.
Pre-compiled Binaries
Receiver_ESP32C3_v1.0.bin— Receiver firmware (ESP32-C3)Transmitter_ESP32C3_v1.0.bin— Transmitter firmware (ESP32-C3)
Flashing
esptool.py --chip esp32c3 write_flash 0x0 Receiver_ESP32C3_v1.0.bin
esptool.py --chip esp32c3 write_flash 0x0 Transmitter_ESP32C3_v1.0.bin