Wireless battery monitoring for a trail camera that doesn't expose battery info anywhere accessible.
I have a trail camera (embedded Linux) that I wanted to monitor remotely. Problem: there's no way to check the battery level without physically going there.
First attempt was to find it through the UART interface - found the pins, connected at 115200 baud, got boot logs and system output, but no battery info anywhere.
So I extracted the firmware and analyzed it with Ghidra looking for battery-related functions. Found that battery monitoring exists internally but it's not exposed to any external interface. Would need to modify the kernel to access it, which seemed like way more trouble than it's worth.
Just measure the voltage directly and send it via LoRa.
- ESP32 with LoRa (Heltec board)
- Voltage divider connected to the battery
- Reads voltage through ADC, converts to percentage, transmits
- Long range (the camera is far from my house)
- Low power (important for battery operation)
- Simple protocol
- ESP32 wakes up from deep sleep
- Takes 30 ADC readings and averages them (noise reduction)
- Converts the reading to battery percentage
- Sends via LoRa: "The Battery is XX%"
- Goes back to deep sleep for 10 minutes
- Repeat
Power consumption is minimal - deep sleep draws ~10µA, and it's only active for a few seconds every 10 minutes.
I figured out these thresholds by watching when the camera would shut down and when it would turn back on:
767+ → 100% (full charge)
715 → 80%
652 → 50%
615 → 25%
505 → 10% (critical)
<505 → 0% (shutdown imminent)The camera actually shuts down around ADC reading 409 and won't turn back on until it charges to about 557.
src/battery_monitor.ino- ESP32 code
You need:
- HC801a Camera
- Heltec ESP32 LoRa board
- Arduino IDE with Heltec support
- A LoRa receiver to get the data
Clone this, open the .ino file, upload to the board. Don't forget to connect the voltage divider to your battery and make sure it doesn't exceed 3.3V at the ADC pin.
Main things you might want to change in the code:
RF_FREQUENCY- LoRa frequency (915 MHz by default)ADC_PIN- which pin you're using (GPIO1 default)- Sleep interval - currently 10 minutes in
esp_sleep_enable_timer_wakeup()
- UART debugging and protocol analysis
- ESP32 deep sleep modes
- LoRa configuration
- That sometimes the simple solution (just measure voltage) is better than the "proper" one (modify the kernel)
Protocol to protect against replay attacks for receiver.