Building a Multi-Year Battery Life IoT Data Logger: A Deep Dive into Ultra-Low-Power Design
Source: Dev.to
Introduction
Ever wondered how industrial IoT devices achieve multi‑year battery life while transmitting data over cellular networks? In this article, I’ll walk you through a real‑world implementation of an ultra‑low‑power industrial data logger that monitors diesel fuel levels remotely and achieves an impressive 3–11 year battery life.
We’ll be using the EC‑M12‑BC‑C6‑C‑A – a battery‑powered device with an STM32L0 series microcontroller and a SIM7070 LTE modem – a common setup in industrial monitoring applications.
The Challenge
Remote monitoring systems face a critical trade‑off: you need frequent data updates for real‑time insights, but each transmission cycle drains your battery. Cellular modems are particularly power‑hungry, with peak currents reaching 840 mA during network initialisation.
Goal: design a system that can
- Read analog sensor data accurately
- Transmit to a cloud dashboard via 4G/LTE‑M
- Operate for years on primary lithium batteries
- Withstand harsh industrial environments
System Architecture
[4‑20 mA Fuel Sensor] → [STM32L0 MCU] → [SIM7070 Modem] → [4G Network] → [ThingsBoard Dashboard]
Hardware Components
- MCU: STM32L0
- Cellular: SIM7070 NB‑IoT/LTE‑M modem
- Power: 2 × ER34615H lithium batteries (19 000 mAh each)
- Sensor: 4‑20 mA diesel fuel tank level sensor
Power‑Consumption Breakdown
The system operates in three distinct stages:
Stage 1 – Modem Initialization (≈ 60 s)
| Parameter | Value |
|---|---|
| Average current | 17.71 mA |
| Peak current | 840 mA (during network registration) |
| Energy | 3.93 J |
The SIM7070 must power up the RF circuitry, search for cellular networks, register with the tower, and establish a GPRS/LTE connection.
Key design decision: a 1000 µF tantalum capacitor placed near the modem acts as a local energy reservoir, smoothing out the 30‑40 ms current spikes that can exceed 300 mA.
Stage 2 – Sensor Read + Data Transmission (≈ 7.5 s)
- Average current: 11.24 mA
- Energy: 0.31 J
During this phase the firmware:
- Reads the 4‑20 mA fuel sensor
- Reads battery voltage
- Publishes telemetry to ThingsBoard via MQTT
- Disables all unnecessary peripherals
Stage 3 – Deep Sleep (≈ 15 min)
- Average current: 1.05 µA
- Energy: 0.0035 J
The STM32L0 enters shutdown mode:
- All peripherals powered down
- Only the RTC remains active
- Occasional 2‑3 mA spikes for RTC maintenance (negligible impact)
The Math Behind Battery Life
With a total capacity of 38 000 mAh, the average current can be estimated with:
I_avg = (I_sleep × T_sleep + I_active × T_active) / (T_sleep + T_active)
The resulting current‑usage graph:
Increasing the sleep interval by a factor of 4 yields a 3.4× improvement in battery life, illustrating the power of duty‑cycling in embedded systems.
Software Implementation Highlights
Low‑Power Mode Configuration
// STM32L0 shutdown mode configuration
#include
void setup() {
Serial.begin(9600);
LowPower.begin(); // Initiate low‑power library
}
void loop() {
Serial.println("Entering low power mode...");
SPI.end(); delay(1000);
Wire2.end(); delay(1000);
digitalWrite(BOOST_EN, LOW); delay(1000);
// === Fully cut power to GSM ===
digitalWrite(GSM_POWER, HIGH); // Depending on wiring, HIGH disables modem regulator
delay(2000);
LowPower.shutdown(900000); // Sleep for 15 min (900 000 ms)
}
Efficient MQTT Publishing
void publishTelemetry() {
int16_t adc0, adc1, adc2, adc3;
adc1 = ads1.readADC_SingleEnded(1) * mA_Factor;
adc2 = ads1.readADC_SingleEnded(2);
float voltage2 = adc2 * 0.125 / 1000.0 / VOLTAGE_DIVIDER_RATIO;
Serial.print("AIN1: "); Serial.print(adc0); Serial.println(" ");
Serial.print("AIN2: "); Serial.print(adc1); Serial.println(" ");
Serial.print("Voltage: "); Serial.print(voltage2); Serial.println(" ");
float fuel_percent = (adc1 - 4.0) * 100.0 / 16.0;
fuel_percent = constrain(fuel_percent, 0, 100);
// Fuel height (mm)
float fuel_level_mm = (fuel_percent / 100.0) * 1000;
// Fault detection
bool fuel_sensor_fault = false;
if (adc1 22.0) {
fuel_sensor_fault = true;
}
StaticJsonDocument doc;
doc["fuel_level_percent"] = fuel_percent;
doc["fuel_level_mm"] = fuel_level_mm;
doc["battery_voltage"] = voltage2;
doc["fuel_sensor_fault"] = fuel_sensor_fault;
String jsonStr;
serializeJson(doc, jsonStr);
mqtt.publish("v1/devices/me/telemetry", jsonStr.c_str());
Serial.print("Published: ");
Serial.println(jsonStr);
}
Sensor Fault Detection
The firmware monitors the 4‑20 mA loop for open/short circuits:
- ** 20.5 mA** → sensor fault (short circuit)
- 4 – 20 mA → normal operation
Real‑World Considerations
Cellular Signal Strength
Poor signal forces the modem to retry connections and transmit at higher power levels, dramatically reducing battery life.
Sensor Current Impact
The 4‑20 mA sensor itself consumes power proportional to the measured value. A full tank (≈ 20 mA) draws more current than an empty tank (≈ 4 mA).
Temperature Effects
Lithium batteries lose capacity in extreme cold; plan for derating the usable capacity when operating in harsh climates.
By carefully managing each stage of operation, selecting appropriate hardware, and leveraging aggressive duty‑cycling, the EC‑M12‑BC‑C6‑C‑A data logger can reliably monitor diesel fuel levels for up to a decade on a single battery pair.
Network Protocol Choice
NB‑IoT and LTE‑M are specifically designed for IoT applications with lower power consumption than standard LTE. Choose wisely based on your region’s network availability.
Lessons Learned
- Duty cycling is king: The difference between 15‑minute and 1‑hour intervals is massive (3.36 vs 11.4 years).
- Modem initialization dominates: Even though it’s only 1 minute per cycle, it consumes ≈ 85 % of the total energy per transmission.
- Hardware matters: The STM32L0’s 1.05 µA shutdown current makes multi‑year operation possible. A standard MCU would drain batteries in months.
Future Improvements
- Implement adaptive transmission intervals based on fuel‑level change rate.
- Implement predictive‑maintenance alerts based on battery‑voltage trends.
Conclusion
Building ultra‑low‑power IoT devices requires careful consideration of every milliamp‑hour. By combining:
- Efficient duty cycling
- Ultra‑low‑power MCU sleep modes
- Optimized cellular communication
- Smart peripheral management
we achieved a system that can monitor remote industrial assets for over 3 years on battery power alone, with the potential to extend that to 11 + years with less frequent updates.
The complete source code and detailed setup instructions are available on GitHub.
Check the product (EC‑M12‑BC‑C6‑C‑A) documentation.
