The Noise Problem in Low-Cost IoT Sensors
If you have ever connected an MQ-135 or BME680 gas sensor to an Arduino or ESP32 and plotted the raw analog readings, you know the truth: **raw sensor data is terrible.** It jumps around due to high-frequency thermal noise, and drifts slowly over hours as ambient room humidity changes.
If you feed this raw data directly into a cloud database or trigger alarms based on simple threshold checks, your IoT system will be plagued by false positives.
Enter the Kalman Filter
Rudolf E. Kálmán published his famous recursive linear estimator in 1960. It was famously used by NASA on the Apollo navigation computers to take noisy radar and inertial measurements and predict the true spacecraft trajectory.
We can use the exact same algorithm on an ESP32 microcontroller to estimate true indoor air quality!
// The Two-Step Cycle The Kalman filter operates in a continuous two-step loop: 1. **Time Update (Predict)**: We project the current state estimate forward in time using our system model and add process noise covariance $Q$. 2. **Measurement Update (Correct)**: We take the noisy physical sensor reading, compute the Kalman Gain $K$, and correct our predicted state.
Why C++ on ESP32?
While Python has libraries like FilterPy, running Kalman filtering on the edge microcontroller itself (in C++) saves network bandwidth, reduces cloud compute costs, and allows sub-millisecond local alarm triggering. By using fixed-point arithmetic or hardware floating-point units (FPU) on the ESP32 ARM Cortex core, we achieve an execution footprint of under 2 milliseconds per sensor channel!