The Garden Sensor Noise Filter
Change the slider level and observe the 5x5 LED display.
- Web browser (Chrome, Edge, Firefox)
- Internet connection
- MakeCode (micro:bit) online editor
🔧 Build Your Rolling Sensor Filter
const int SOIL_PIN = A0;
const int NUM_READINGS = 3;
int readings[NUM_READINGS] = {500, 500, 500};
int readIndex = 0;
long total = 1500;
int filteredAverage = 500;
void setup() {
Serial.begin(9600);
Serial.println("Raw,Filtered");
}
void loop() {
int rawVal = analogRead(SOIL_PIN);
// Rolling Window Moving Average
total = total - readings[readIndex];
readings[readIndex] = rawVal;
total = total + readings[readIndex];
readIndex = (readIndex + 1) % NUM_READINGS;
filteredAverage = total / NUM_READINGS;
Serial.print(rawVal);
Serial.print(",");
Serial.println(filteredAverage);
delay(300);
}
The rolling average algorithm attenuates sudden transient spikes while preserving true analog trends.
⚗️ Test your model
| Test Condition / Action | Expected Result |
|---|---|
| Transient Electrical Spike (900 raw) | Filtered output only rises mildly to 630; prevents false alarm |
| Sustained Dry Soil Transition | Filtered output smoothly matches true dry condition over 3 samples |
| Noise-free Steady Input | Filtered output tracks raw input perfectly without offset |
Increase filter size from 3 samples to 7 samples and compare noise reduction versus response lag!
📖 Our Story & Concepts
Analog sensors in agricultural fields, irrigation pumps, and factories suffer from environmental electrical noise: motor start-ups induce inductive voltage spikes, and loose wires generate transient artifacts. If an irrigation system shut off whenever a 10ms spike occurred, crops would wither.
Digital signal processing (DSP) filters out noise mathematically. A Simple Moving Average (SMA) acts as a low-pass filter, smoothing out rapid high-frequency noise while letting the genuine, slow physical process shine through cleanly.
</> Full Annotated Code Walkthrough
// Complete Circular Buffer Filter with Threshold Pump Control
const int SOIL_PIN = A0;
const int PUMP_PIN = 7;
const int WINDOW_SIZE = 5;
int buffer[WINDOW_SIZE];
int bufIndex = 0;
long runningSum = 0;
void setup() {
pinMode(PUMP_PIN, OUTPUT);
Serial.begin(115200);
for (int i = 0; i < WINDOW_SIZE; i++) {
buffer[i] = analogRead(SOIL_PIN);
runningSum += buffer[i];
}
}
void loop() {
int rawVal = analogRead(SOIL_PIN);
runningSum -= buffer[bufIndex];
buffer[bufIndex] = rawVal;
runningSum += buffer[bufIndex];
bufIndex = (bufIndex + 1) % WINDOW_SIZE;
int smoothed = runningSum / WINDOW_SIZE;
// Actuator triggers strictly on filtered data
if (smoothed < 350) {
digitalWrite(PUMP_PIN, HIGH);
} else {
digitalWrite(PUMP_PIN, LOW);
}
Serial.print("Raw:"); Serial.print(rawVal);
Serial.print(",Filtered:"); Serial.println(smoothed);
delay(200);
}
The rolling average algorithm attenuates sudden transient spikes while preserving true analog trends.
▷ Expected Results & Troubleshooting
| Test Condition / Action | Expected Result |
|---|---|
| Transient Electrical Spike (900 raw) | Filtered output only rises mildly to 630; prevents false alarm |
| Sustained Dry Soil Transition | Filtered output smoothly matches true dry condition over 3 samples |
| Noise-free Steady Input | Filtered output tracks raw input perfectly without offset |
⚑ Extension Challenges & Blueprints
- Level 1: Add a median filter that rejects the absolute highest and lowest outlier in every sample window.
- Level 2: Display both raw and smoothed signals on an I2C OLED display screen.
- Level 3: Implement an exponential moving average (EMA) using floating-point alpha weighting.