IOT 101 - Minimizing Wifi Battery Consumption in IOT projects
In the early development stages of PetDrifts, we faced significant challenges with our MVP, which included a custom PCB equipped with an ESP32 C3 mini, sensor, and a Li-ion battery. One of the major issues was the rapid draining of the battery, a critical problem in our IoT device design
ESP32 based circuit was consuming significant power. The code was simply collecting data from sensors and sending it over network every 5 minutes. We were using a small battery (~250mAh) and esp32 c3. This circuit contains, mcu (built-in ADC) with pcb antenna, accelerations sensor, and some battery charging and regulating components. The firmware was collecting data in normal operation and sending it over network using HTTP POST call every n minutes (configurable and tried 5 to 15 minutes).
This IoT design was consuming battery so fast, that the battery was hardly lasting a day. To see what would be my usual battery battery runtime, I was using this online tool
Finding the Battery Killer in my IoT project
To find what was killing the battery so soon, I measured real-time current drawn by the circuit which was equal to an average esp32 current drawn (around ~35 mA, no surprise), but every 15 minutes I could clearly see a spikes ~190 mA during network activity (API call).
To get a better insight on battery consumption, I got Nordic's power profiler kit. This is one of the best IoT tool I got so far. I could clearly saw the power consumption graphs and spikes during network operations.
No surprise, this was matching to esp's datasheet:
Now, I have few options to reduce this power consumption:
1. Use less frequent network calls
2. Lower the transmission power of module (compromise with range of device )
3. Optimize the network calls (explaining this further)
How We Optimize Our Network Calls
We were using REST APIs to send the data. On asking myself, could this be a problem. Oh yes! REST works with TCP which consumes network for its own benefit.
REST Under the Hood
REST APIs operate over HTTP, which in turn uses the TCP protocol. TCP is great for reliable data transfer, but reliability comes at the cost of additional overhead due to the three-way handshake process. Every REST call requires this handshake process before any data is exchanged, leading to potential delays in high-frequency or low-latency applications.
TCP's Three-Way Handshake:
- Client Sends a SYN (Synchronize) Packet
- Server Responds with SYN-ACK (Synchronize-Acknowledge)
- Client Sends an ACK (Acknowledge) Packet
Solution #1: Switching to UDP
Using UDP sockets in the firmware instead of TCP. This will save three extra call spent on TCP each time device send data to your server. However you will need to adjust your server to receive UDP data. UDP is less reliable than TCP, to ensure reliability you can add a mechanism like sync flags or retries. If reliable data transfer is must, then use Solution #2.
An example of simple UDP socket in micropython:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('server_ip_address', 12345) #Add your server address
# Send data
message = 'Sensor data here 0x111'
sock.sendto(message.encode(), server_address)
# Close the socket
sock.close()
Solution #2: Switching to MQTT (for reliability)
For the data I was sending, UDP was sufficient but to ensure better data delivery you can also use MQTT, this is a great alternative to REST. Under the hood, MQTT use persistent connection and one handshake per session to reduce power consumption.
You may need to add a MQTT broker as an additional component to your IoT architecture, if you decide to use MQTT.
We used both approaches for our MVP and observed a good improvement on battery saving. This wasn't enough to provide long lasting battery life (weeks of battery life in one charge) like other dog activity trackers in the market were providing. We switched to Bluetooth based MCUs to get months of battery life from our device!
Other resources to reduce power consumption on esp32:
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/low-power-mode/low-power-mode-wifi.html
https://github.com/espressif/esp-idf/blob/master/examples/wifi/power_save/README.md
Got more questions/curiosity about IoT:
connect with me:LinkedIn
My free newsletter for startup stories: founderpedia