Capstone · #17 of 20
Firmware Architecture
Task Loop, State Machine, Error Budget
Why it matters
Good firmware architecture makes code maintainable, testable, and reliable. A clear state machine prevents bugs.
The idea
State Machine
The capstone has clear states:- INIT: Setup GPIO, I²C, Wi‑Fi
- READ_SENSOR: Read temperature/humidity
- CONNECT_WIFI: Establish Wi‑Fi connection
- TRANSMIT: Send data to server
- SLEEP: Enter deep sleep, wait for wake
<h3>Error Handling</h3>
Every operation can fail:
<ul>
<li><strong>Sensor read fails</strong> → retry (with limit), then sleep</li>
<li><strong>Wi‑Fi connect fails</strong> → retry (with limit), then sleep</li>
<li><strong>Transmit fails</strong> → retry (with limit), then sleep</li>
<li><strong>Error budget</strong>: Max retries before giving up</li>
</ul>
<h3>Task Loop</h3>
Main loop structure:
<ol>
<li>Restore state from RTC memory</li>
<li>Read sensor (with retries)</li>
<li>Connect Wi‑Fi (with timeout)</li>
<li>Transmit data (with retries)</li>
<li>Save state to RTC memory</li>
<li>Enter deep sleep</li>
</ol>
<h3>Power Optimization</h3>
Minimize active time:
<ul>
<li>Turn off Wi‑Fi when not needed</li>
<li>Use fast I²C speed (400kHz)</li>
<li>Batch operations (read all sensor data at once)</li>
<li>Enter sleep immediately after transmit</li>
</ul>
Demo
Firmware architecture is code structure, not visual. Review this before writing the capstone code.
Key takeaways
- Use a state machine to organize firmware logic
- Every operation can fail — implement error handling
- Error budget: max retries before giving up
- Minimize active time to save power
Going deeper
For production firmware, use an RTOS (Real-Time Operating System) like FreeRTOS for task scheduling. For simple projects, a state machine in the main loop is sufficient. Always implement watchdog timers to recover from hangs. Use structured logging (not just print statements) for debugging.
Math details
Timing budget (5-minute cycle):
Sensor read: ~100ms
Wi‑Fi connect: ~2s (first time), ~500ms (reconnect)
Transmit: ~200ms
Sleep entry: ~50ms
Total active: ~3s (worst case)
Error budget:
Max retries per operation: 3
Total max active time: ~10s (if all retries fail)
Still acceptable for 5-minute cycle
Power impact:
Normal cycle: 80mA × 3s = 240mAs
Error cycle: 80mA × 10s = 800mAs
Impact: ~3× power consumption (acceptable for rare errors)