The LoRaWAN Battery Node is a low-power IoT sensor built around the TTGO T-Beam (ESP32 + SX1262 LoRa + AXP2101 PMU) that collects battery status data from an Intact Battery Guard BLE sensor and transmits it over LoRaWAN to The Things Network (TTN). It demonstrates battery monitoring, LoRaWAN communication, and deep-sleep power optimization.
This project is suitable for IoT developers and enthusiasts who want a fully integrated battery monitoring node with long-range wireless connectivity.
- TTGO T-Beam SX1262 with AXP2101 PMU
- Intact Battery Guard BLE sensor
- Battery or other power source for the T-Beam
- USB cable for programming
- Optional: LoRa antenna (external)
- PlatformIO (recommended) or Arduino IDE
- RadioLib for LoRa/SX1262
- LilyGo-LoRa-Series library (includes U8g2 and other dependencies)
- BLE library compatible with ESP32
- TTN account for device registration and LoRaWAN network access
PlatformIO is recommended for building, dependency management, and upload.
-
Install PlatformIO:
- Install VSCode: https://code.visualstudio.com/
- Install the PlatformIO extension.
-
Open the Project:
- Open the folder containing
platformio.iniin VSCode.
- Open the folder containing
-
Configure
platformio.ini: Example configuration for TTGO T-Beam with SX1262:[env:tbeam_sx1262] platform = espressif32 board = ttgo-lora32-v2 framework = arduino monitor_speed = 115200 lib_extra_dirs = lib/U8g2, lib/RadioLib, lib/XPowersLib build_flags = -DCORE_DEBUG_LEVEL=5 -DDEEP_SLEEP_ENABLED -DT_BEAM_SX1262
Notes:
lib_extra_dirspoints to submodules or local libraries.build_flagsinclude debug output and deep sleep optimizations.
-
Build & Upload:
- Connect the T-Beam via USB.
- Build with
PlatformIO: Build. - Upload using
PlatformIO: Upload.
-
Monitor Serial Output:
- Use
PlatformIO: Monitorat 115200 baud. - Debug messages include RSSI, SNR, LoRaWAN join attempts, and sensor readings.
- Use
Before uploading the firmware, you must provide your LoRaWAN OTAA keys in a file named keys.h. This file is not included in the repository for security reasons.
In the root of the project (or as specified in the code), create a new file called keys.h (see keys.h.tmp file) with the following contents:
#pragma once
#define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000
// the Device EUI & two keys can be generated on the TTN console
#ifndef RADIOLIB_LORAWAN_DEV_EUI
#define RADIOLIB_LORAWAN_DEV_EUI 0x0000000000000000
#endif
#ifndef RADIOLIB_LORAWAN_APP_KEY
#define RADIOLIB_LORAWAN_APP_KEY 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
#endif
#ifndef RADIOLIB_LORAWAN_NWK_KEY // Put your Nwk Key here
#define RADIOLIB_LORAWAN_NWK_KEY 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
#endifReplace RADIOLIB_LORAWAN_DEV_EUI, RADIOLIB_LORAWAN_APP_KEY, and RADIOLIB_LORAWAN_NWK_KEY with the values from The Things Network (TTN) console. Use the exact format provided by TTN (typically 16-character hexadecimal strings, e.g., "7864902458302"). Do not swap byte order—the code expects the standard TTN format.
To avoid accidentally committing your keys, ensure your .gitignore file contains the line:
keys.h
This will prevent keys.h from being tracked by git.
- TTN Frequency Plan: Set your region (e.g., EU868) in the code and TTN console to match.
- BLE Settings: Update the BLE address or device name in the code to match your Intact Battery Guard sensor.
- Deep Sleep: Adjust
DEEP_SLEEP_ENABLEDand the sleep duration in the code as needed for your use case.
- Power on the T-Beam.
- The device scans for the Intact Battery Guard BLE sensor and retrieves battery data.
- Data is encoded and transmitted via LoRaWAN to TTN.
- Monitor uplinks in the TTN console or integrate via MQTT to your backend.
- Optionally integrate with Home Assistant for real-time monitoring.
Example MQTT sensors for Home Assistant:
sensor:
- platform: mqtt
name: "Battery Voltage"
state_topic: "ttn/<application_id>/devices/<device_id>/up"
value_template: "{{ value_json.uplink_message.decoded_payload.battery_voltage }}"
unit_of_measurement: "V"
- platform: mqtt
name: "Battery Level"
state_topic: "ttn/<application_id>/devices/<device_id>/up"
value_template: "{{ value_json.uplink_message.decoded_payload.battery_level }}"
unit_of_measurement: "%"Replace <application_id> and <device_id> with your TTN identifiers. Adjust the paths based on your payload.
- RSSI around
-112 dBmcan indicate weak or no LoRaWAN gateway coverage. - Join failures (
-1116) may result from incorrect keys, frequency plan, or lack of gateway. - RX/TX loopback tests can be performed with RadioLib SX1262 minimal examples.
- Serial debug output helps identify whether the SX1262 module initializes correctly and receives downlinks.
Recommended approach: use submodules for consistent library versions:
- LilyGo-LoRa-Series → contains U8g2 and other LilyGo libraries.
- RadioLib
- XPowersLib
Submodules allow PlatformIO to build without manually copying libraries into lib/.
MIT License. See LICENSE file.
This setup provides a ready-to-build LoRaWAN battery node for testing, debugging, and integration with TTN or Home Assistant.