The Problem: A team prototypes a soil moisture sensor in MicroPython on an ESP32. It works beautifully in the lab. They deploy 200 units to farmers. Within 2 weeks, 80% of batteries are dead, and customers are furious.
Why it failed:
Lab testing (USB-powered, infinite energy): - Boot: 3 seconds - Read sensor + transmit: 2 seconds - Total: 5 seconds every 15 minutes - Power source: USB (doesn’t matter)
Field reality (battery-powered, 2000 mAh):
MicroPython performance on ESP32: - Boot: 3.5 seconds @ 80 mA = 280 mAs = 0.078 mAh - Sensor read: 1.2 seconds @ 75 mA = 90 mAs = 0.025 mAh - LoRa transmit: 0.8 seconds @ 120 mA = 96 mAs = 0.027 mAh - Total per cycle: 466 mAs = 0.13 mAh
Deep sleep: 10 µA × 894 seconds = 8.9 mAs = 0.0025 mAh
Per 15-minute cycle: 0.13 + 0.0025 = 0.1325 mAh
Cycles per day: 96 (every 15 minutes)
Daily energy: 96 × 0.1325 = 12.72 mAh/day
Battery life: 2000 / 12.72 = 157 days (not great, but acceptable)
What actually happened:
The team didn’t realize MicroPython’s garbage collector runs periodically, causing unpredictable delays and power spikes. During transmission, GC triggered, extending wake time from 5 seconds to 15-20 seconds:
- Extended wake time: 15 s @ 80 mA = 1200 mAs = 0.33 mAh
- Daily energy: 96 × 0.33 = 31.7 mAh/day
- Battery life: 63 days (vs promised 157 days)
In cold weather (5°C), LiPo capacity drops 30%: - Effective capacity: 2000 × 0.7 = 1400 mAh - Battery life: 44 days
In freezing weather (-5°C), LiPo capacity drops 50% and batteries stop charging: - Effective capacity: 2000 × 0.5 = 1000 mAh - Battery life: 31 days → then dead forever
The fix (rewrite in C):
C firmware with tight deep sleep control: - Boot: 0.8 s @ 70 mA = 56 mAs = 0.016 mAh - Sensor read: 0.3 s @ 65 mA = 19.5 mAs = 0.0054 mAh - LoRa transmit: 0.6 s @ 120 mA = 72 mAs = 0.02 mAh - Total per cycle: 0.041 mAh (3.2x better than MicroPython)
This chapter covers prototyping languages, explaining the core concepts, practical design decisions, and common pitfalls that IoT practitioners need to build effective, reliable connected systems.
New battery life: 2000 / (96 × 0.041) = 508 days = 1.4 years ✅
Even in cold weather (-5°C): 1000 / (96 × 0.041) = 254 days (acceptable)
Lesson: MicroPython is wonderful for prototyping (2-day development vs 2-week in C). But for battery-powered production devices, the 3-5x energy overhead is unacceptable. Prototype in Python, deploy in C.