# Demo 43: How to apply Kalman Filter to ESP to make sensor measurement more accurate

1. Introduction
Kalman filtering is an algorithm that uses a series of measurements (including statistical noise and other inaccuracies) observed over time to make estimates of unknown variables more accurate than just use a single measurement.
Figure: Blue line is sensor data from ADC with noise and Brown line is sensor data after applying Kalman Filter
In order to understand more about the equations and calculations, please refer this.
In summary, the filter process includes 2 steps: Prediction and Correction.
- Prediction step: tries to predict the value based on system model with previous corrected value.
- Correction step: tries to correct the predicted value in prediction step by measurement value.

This post will make a simple demo of applying Kalman Filter to ESP to make sensor measurement from a LDR (Light Dependent Resistor) more accurate.
Figure: LDR sensor
Figure: ESP32 module
2. Hardware
ESP32 3.3V connect LDR Vcc
ESP32 GND connect LDR GND
ESP32 G34(ADC pin) connect LDR A0
3. Software
I developed the matrix version of Kalman filter.

It can be applied to Arduino, ESP8266/ESP32/MCUs.
There are 3 files that you need to include in your project (ESP8266/ESP32/MCUs):
- ArduiKalman.cpp
- ArduiKalman.h
- mat.h
where:
n: number of states
m: number of measurement values
xc[n]: correct state vector
xp[n]: predict state vector
A(n, n): System dynamics matrix
H(m, n): Measurement matrix
Q(n, n): Process noise covariance
R(m, m): Measurement noise covariance
P(n, n): Estimate error covariance

Predict step:
float *predict = m_kf.predict()

Correct step:
float *correct = m_kf.correct(measurement)

An example when n=4, m=2, and how to initialize the matrices.

A = 1.0f;
A = 1.0f;
A = 1.0f;
A = 1.0f;
H = 1.0f;
H = 1.0f;
Q = 0.01f;
Q = 0.01f;
Q = 0.01f;
Q = 0.01f;
R = 0.1f;
R = 0.1f;
P = 1.0f;
P = 1.0f;
P = 1.0f;
P = 1.0f;
xc = 0.01f;
xc = 0.01f;
xc = 0.01f;
xc = 0.01f;

```#include "ArduiKalman.h"

#define UPDATE_TIME  100
long current;

int stateNum = 1;
int measureNum = 1;

//init matrix for Kalman
float xc;        // correct state vector
float xp;        // predict state vector
float A;      // prediction error covariance
float Q;      // process noise covariance
float R;      // measurement error covariance
float H;      // Measurement model
float P;      // Post-prediction, pre-update

KalmanFilter m_kf;

void setup() {
Serial.begin(115200);
Serial.print(0);  // To freeze the lower limit
Serial.print(" ");
Serial.print(3.3);  // To freeze the upper limit
Serial.print(" ");

// put your setup code here, to run once:
m_kf.init(stateNum, measureNum, &A, &P, &Q, &H, &R, &xp, &xc);
m_kf.zeros();
A = 1.0f;
H = 1.0f;
Q = 0.01f;
R = 100.0f;
P = 1.0f;

}

void loop() {
// predict
float *predict = m_kf.predict();
// correct
float rand_noise = random(-100,100)/100.0;
float measurement[measureNum];
measurement = measured_value;
float *correct = m_kf.correct(measurement);
float estimated_value = correct;

//update plotter
if (millis() > current) {
Serial.print(measured_value);
Serial.print(",");
Serial.print(estimated_value);
Serial.println();

current = millis() + UPDATE_TIME;
}

}
```
4. Result

Figure: Blue line is sensor data from ADC with noise and Red line is sensor data after applying Kalman Filter