Skip to content

Releases: Techposts/TankSync

TankSync Transmitter 3.0.0 — new ESP-NOW "Lite" variant

04 Jun 10:27

Choose a tag to compare

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 -lite binary.

Full Changelog: tx-v2.0.15...tx-v3.0.0

TankSync Hub 3.0.0 — universal LoRa + ESP-NOW hub, redesigned display

04 Jun 10:27

Choose a tag to compare

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 DevKit
  • tanksync-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

27 May 15:17

Choose a tag to compare

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 use
  • active_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 fresh

No 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 TX
  • tank_<addr>/active_sensor (retained) — what the TX is currently running
  • cmd/set_config now accepts a sensor_kind field for remote control from the PWA

What changed (file-level)

  • components/transmitter_registry/ — added sensor_kind + active_sensor fields, bidirectional auto-sync when TX-truth diverges from registry intent, registry_set_sensor_kind() API
  • components/lora_rylr998/ — TANK parser extracts the 11th positional field (active_sensor); backwards-compat with older TXs that omit it
  • components/web_server/ — Edit Tank sheet adds the Sensor dropdown (full-width row), /api/transmitters returns both fields, /api/logs + /api/log_clear added, max URI handlers bumped to 12 so the new endpoints actually register
  • components/mqtt_client/ — publishes both fields as retained topics, accepts sensor_kind on cmd/set_config
  • components/log_buffer/ — new component: 4 KB ring buffer wired up via esp_log_set_vprintf()
  • main/main.c — SET-frame builder appends :SENSOR=... when a sensor change is queued; log_buffer_init() runs first thing in app_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

23 May 19:10

Choose a tag to compare

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.version now reflects what was actually built. Like RX, the TX binary was stamping its version field from a hardcoded literal in firmware/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-published tx_version field — 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, sets PROJECT_VER, and configure_file() generates components/tanksync_version/include/version_gen.h consumed by main/, components/wifi_ota/, and components/lora_tx/.
  • Build provenance fingerprint preserved in main/main.c (the magic constant + the unique typo log string in components/lora_tx/lora_tx.c are 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.x or rx-v2.8.x works (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 column

Paired with

  • rx-v2.8.5 — see for the matching RX-side notes.

rx-v2.8.5

23 May 19:00

Choose a tag to compare

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.version now reflects what was actually built. Every release since rx-v2.7.13 shipped with the version string stuck at "2.7.13" because firmware/Receiver-ESP32-DevKit/CMakeLists.txt hardcoded PROJECT_VER. The OLED, web UI footer, PWA Firmware page, MQTT firmware_version field — all reported the wrong version even though the underlying code was current.
  • Bench-confirmed: the hub at 192.168.0.56 was reporting v2.7.13 while running rx-v2.8.4 features. After flashing this build it correctly reports v2.8.5.

Internal

  • Single source of truth: edit firmware/Receiver-ESP32-DevKit/VERSION (one file). CMake reads it, sets PROJECT_VER, and configure_file() generates components/tanksync_version/include/version_gen.h consumed by main/, components/web_server/, components/ota_manager/, and components/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.x firmware.

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.x works

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

27 Apr 10:55

Choose a tag to compare

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_t and the per-TX tx_data_t registry extended with power_mode, current_ma, power_mw, charging.
  • GET /api/transmitters JSON 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

16 Apr 06:10

Choose a tag to compare

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.bin

Or use the OTA update via the receiver's web UI.

Full Changelog: v1.0...v2.1.0

v1.0 - Initial Stable Release

03 Jan 16:24

Choose a tag to compare

🎉 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

🐛 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)

16 Apr 05:47

Choose a tag to compare

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