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 tradeoff: 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 840mA during network initialisation.
The goal? Design a system that can:
- Read analog sensor data accurately
- Transmit to cloud dashboard via 4G/LTE-M
- Operate for years on primary lithium batteries
- Handle harsh industrial environments
System Architecture
[4-20mA 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,000mAh each)
- Sensor: 4-20mA diesel fuel tank level sensor
The Power Consumption Breakdown
Here's where it gets interesting. The system operates in three distinct stages:
Stage 1: Modem Initialization (60 seconds)
- Average Current: 17.71mA
- Peak Current: 840mA (during network registration)
- Energy: 3.93 J
This is the power-hungry phase. The SIM7070 needs to:
- Power up the RF circuitry
- Search for cellular networks
- Register with the tower
- Establish 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-40ms current spikes that can exceed 300mA.
Stage 2: Sensor Read + Data Transmission (7.5 seconds)
- Average Current: 11.24mA
- Energy: 0.31 J
During this phase:
- Read 4-20mA sensor (fuel level)
- Read battery voltage
- Publish telemetry to ThingsBoard via MQTT
- Disable all peripherals
Stage 3: Deep Sleep (15 minutes)
Average Current: 1.05µA
Energy: 0.0035 J
This is where the magic happens. The STM32L0 enters shutdown mode:
All peripherals powered down
Only RTC remains active
Occasional 2-3mA spikes for RTC maintenance (negligible impact)
The Math Behind Battery Life
With 38,000mAh capacity, here's the battery life estimation:
Average Current Formula:
I_avg = (I_sleep × T_sleep + I_active × T_active) / (T_sleep + T_active)
Results:
The 4× increase in sleep time gives you a 3.4× improvement in battery life. This demonstrates the power of duty cycling in embedded systems.
Software Implementation Highlights
Low-Power Mode Configuration
// STM32L0 shutdown mode configuration
#include <STM32LowPower.h>
void setup() {
Serial.begin(9600);
LowPower.begin(); //Initiate low power mode
}
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 your wiring, HIGH disables modem regulator
delay(2000);
LowPower.shutdown(900000);
}
Efficient MQTT Publishing
The system uses MQTT over LTE for minimal protocol overhead:
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
float fuel_level_mm = (fuel_percent / 100.0) * 1000;
// Fault detection
bool fuel_sensor_fault = false;
if (adc1 < 3.6 || adc1 > 22.0) {
fuel_sensor_fault = true;
}
StaticJsonDocument<200> 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 system monitors for open/short circuits in the 4-20mA loop:
- < 3.8mA: Sensor fault (open circuit)
- > 20.5mA: Sensor fault (short circuit)
- 4-20mA: Normal operation
Real-World Considerations
Cellular Signal Strength
Poor signal = higher power consumption. The modem will retry connections and transmit at higher power levels, significantly reducing battery life.Sensor Current Impact
The 4-20mA sensor itself consumes power proportional to the measured value. A full tank (20mA) drains more power than an empty tank (4mA).Temperature Effects
Lithium batteries lose capacity in extreme cold. Consider temperature-compensated battery life calculations for outdoor installations.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.

Top comments (0)