sensor interfacing, I2C, SPI, calibration, filtering, power management, IoT sensors
3.1 Learning Objectives
Compare I2C, SPI, and UART communication protocols and select the appropriate interface for a given sensor integration scenario
Implement data processing techniques including moving average, Kalman, and median filters to improve sensor measurement quality
Design power management strategies using deep sleep modes and transmission buffering to extend battery life in IoT sensor nodes
Build end-to-end sensor integration pipelines from physical interfacing through calibration, filtering, and cloud connectivity
In 60 Seconds
Sensor interfacing covers the complete pipeline from physical sensor to useful IoT data: communication protocols (I2C for multi-sensor buses, SPI for high-speed data), data processing (moving average for noise, Kalman filter for tracking, median filter for outliers), power management (deep sleep for months-long battery life, transmission buffering for 3x battery extension), real-world applications (MQTT-connected smart homes, hysteresis-controlled actuators), and hands-on calibration labs. Master these five topics and you can build production-quality IoT sensor systems.
3.2 Introduction
This section covers the complete sensor integration pipeline for IoT systems, from physical communication protocols to data processing and real-world applications. The content is organized into five focused chapters that build progressively from fundamentals to advanced techniques.
For Beginners: What is Sensor Interfacing?
Sensor interfacing is the art of connecting physical sensors to your microcontroller and making sense of the data they produce. Just like learning a new language, you need to understand how sensors “speak” (protocols like I2C and SPI), how to clean up their “accent” (filtering noise), and how to translate their words into useful information (calibration). This section teaches all these skills through practical examples.
For 400 kHz I2C with 200 pF bus capacitance: Use resistors within the calculated R_min to R_max range (typically 1kΩ to 1.8kΩ). For 100 kHz standard mode (t_rise = 1000 ns), the range widens and 4.7kΩ is commonly used.
Sammy the Sensor was showing the squad how sensors talk to microcontrollers.
“There are different ways we communicate!” Sammy explained. “It’s like how people use phones, email, and walkie-talkies!”
Max the Microcontroller demonstrated: “I2C is like a classroom roll call. I have two wires – SDA for data and SCL for the clock. I call out each sensor’s address: ‘Sensor at address 0x76, what’s the temperature?’ And they answer one by one. I can talk to up to 112 sensors on just two wires!”
“SPI is different,” added Lila the LED. “It’s like having a separate phone line for each sensor. Faster, but needs more wires. Four wires shared, plus one extra for each sensor. Use it when speed matters!”
Bella the Battery raised the most important topic: “But all this talking uses MY energy! That’s why we use DEEP SLEEP. It’s like Max taking a nap between readings. When he’s asleep, he uses only 10 microamps – that’s 15,000 times less than when he’s awake and chatting on Wi-Fi!”
“And we make our readings more accurate with FILTERS!” Sammy added. “A moving average is like asking 10 friends for the temperature and taking the average – smoother than one reading. A median filter is like ignoring the friend who always exaggerates – you take the middle answer instead!”
Max put it all together: “So the whole process is: Connect the sensor (I2C or SPI), clean up the signal (filters), save battery (deep sleep), and send the data (Wi-Fi or LoRa). That’s sensor interfacing in a nutshell!”
“And that,” said Bella with a yawn, “is why I can last for months instead of hours. Now if you’ll excuse me, it’s time for deep sleep mode… zzzzz…”
Decision Framework: Filter Selection for Different Noise Types
Choosing the right filter depends on the characteristics of your noise and signal. This decision framework helps you select between moving average, median, Kalman, and exponential moving average (EMA) filters.
Noise Characteristic
Recommended Filter
Window/Parameter
Why This Filter?
Gaussian (random, zero-mean)
Moving Average
N=10-50 samples
Averages out random variations, noise reduced by √N
Occasional spikes/outliers
Median
N=5-11 (odd)
Ignores extreme values, takes middle value
Smoothly varying signal
Kalman
Process/measurement noise tuned
Optimal state estimation, adapts to signal dynamics
Need fast response
EMA (α=0.2-0.5)
Alpha = 0.2-0.5
Recent samples weighted more, lower lag than MA
Periodic noise (50/60 Hz)
Notch filter or sample at integer multiple
Depends on frequency
Cancels specific frequency
Combination: random + spikes
Median → Moving Average
Median N=5, MA N=10
Median removes spikes first, then MA smooths random noise
Quick Selection Decision Tree:
START: You have noisy sensor data
|
├─ Do you see occasional extreme spikes (outliers)?
│ ├─ YES → How frequent?
│ │ ├─ <10% of readings → **MEDIAN FILTER** (N=5 to 11)
│ │ └─ >10% of readings → Your sensor may be faulty, check wiring
│ └─ NO → Continue to next question
|
├─ Is your signal constantly changing (motion, tracking)?
│ ├─ YES → Do you know the signal dynamics (velocity, acceleration)?
│ │ ├─ YES → **KALMAN FILTER** (optimal tracking)
│ │ └─ NO → **EMA** with α=0.2 (good general-purpose tracking)
│ └─ NO → Signal is slow-changing or static
|
├─ How fast does your signal change?
│ ├─ Very slow (>10 seconds per significant change)
│ │ └─ **MOVING AVERAGE** with large window (N=50-100)
│ ├─ Moderate (1-10 seconds per change)
│ │ └─ **MOVING AVERAGE** with medium window (N=10-20)
│ └─ Fast (<1 second per change)
│ └─ **EMA** with α=0.3 or **MOVING AVERAGE** with small window (N=5)
|
└─ Do you have periodic noise (50/60 Hz power line hum)?
├─ YES → Can you sample at integer multiple of noise frequency?
│ ├─ YES → Sample at 50Hz/60Hz and average N readings per cycle
│ └─ NO → Use notch filter (requires signal processing library)
└─ NO → Use filter from above based on signal dynamics
Example Scenarios with Specific Choices:
1. Temperature Sensor in HVAC System
Signal: Slow-changing (room temp changes over minutes)
Noise: Random, Gaussian, ±0.2°C
Choice: Moving Average, N=30
Reasoning: Temperature is slow, large window smooths noise without lag
Code:
float movingAvg(float newValue){staticfloat buffer[30]={0};staticint idx =0;staticint count =0;// Track how many samples collected buffer[idx]= newValue; idx =(idx +1)%30;if(count <30) count++;// Increment until buffer is fullfloat sum =0;for(int i =0; i < count; i++) sum += buffer[i];return sum /(float)count;// Divide by actual sample count}
Noise: Random vibrations, occasional spikes from bumps
Choice: Median filter (N=5) → EMA (α=0.2)
Reasoning: Median removes bump spikes, EMA tracks steps without excessive lag
Code:
float medianFilter(float newValue){staticfloat buffer[5]={0};staticint idx =0;staticint count =0;// Track how many samples collected buffer[idx]= newValue; idx =(idx +1)%5;if(count <5) count++;// Increment until buffer is fullfloat sorted[5]; memcpy(sorted, buffer, count *sizeof(float));// Simple bubble sort for small arrayfor(int i =0; i < count -1; i++)for(int j =0; j < count -1- i; j++)if(sorted[j]> sorted[j+1]){float temp = sorted[j]; sorted[j]= sorted[j+1]; sorted[j+1]= temp;}return sorted[count /2];// Middle value of filled portion}float emaFilter(float newValue){staticfloat ema =0;staticbool initialized =false;if(!initialized){ ema = newValue; initialized =true;} ema =0.2* newValue +0.8* ema;return ema;}// Usagefloat rawAccel = readAccelerometer();float median = medianFilter(rawAccel);float smoothed = emaFilter(median);
3. Soil Moisture for Irrigation
Signal: Very slow (hours to change significantly)
Noise: Random + occasional false readings from air pockets
Choice: Median (N=7) → Moving Average (N=60)
Reasoning: Median rejects air pocket outliers, large MA window smooths random noise
Result: One filtered reading per minute, stable over 1-hour window
4. Distance Sensor (Ultrasonic) for Robot Navigation
Signal: Moderate speed (robot moving 0.5 m/s)
Noise: Occasional bad echoes (returns 0 or max range)
Choice: Median (N=5) → EMA (α=0.3)
Reasoning: Median removes bad echoes, EMA provides fast response for collision avoidance
Tradeoff: Some lag acceptable, safety requires spike removal
Filter Performance Comparison Table:
Filter Type
Latency
Spike Rejection
Random Noise Reduction
Computational Cost
Moving Avg
N/2 samples
Poor
Excellent (√N)
Low (sum/divide)
Median
(N-1)/2 samples
Excellent
Poor
Medium (sorting)
EMA
~1/α samples
Poor
Good
Very Low (multiply/add)
Kalman
0-2 samples
Good
Excellent
High (matrix ops)
Key Parameters:
Moving Average Window Size (N):
N=5: Fast response, 2.2× noise reduction
N=10: Balanced, 3.2× noise reduction
N=50: Slow response, 7× noise reduction
N=100: Very smooth, 10× noise reduction
EMA Alpha (α) (equivalent MA window: N = 2/α − 1): - α=0.1: Very smooth, slow response (equivalent to MA with N≈19) - α=0.2: Balanced for tracking (equivalent to MA with N≈9) - α=0.5: Fast response, minimal smoothing (equivalent to MA with N≈3)
Show code
viewof ema_alpha = Inputs.range([0.01,0.99], {value:0.2,step:0.01,label:"EMA Alpha (α)"})viewof ma_window = Inputs.range([2,100], {value:10,step:1,label:"Moving Average Window (N)"})ema_equiv_n = (2/ ema_alpha) -1ma_equiv_alpha =2/ (ma_window +1)ema_noise_reduction =1/Math.sqrt(ema_alpha / (2- ema_alpha))ma_noise_red =Math.sqrt(ma_window)ema_latency =1/ ema_alphama_latency = ma_window /2html`<div style="background: linear-gradient(135deg, #16A085 0%, #2C3E50 100%); color: white; padding: 20px; border-radius: 8px; margin-top: 15px;"> <h4 style="margin-top: 0; color: white;">EMA vs Moving Average Comparison</h4> <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-top: 15px;"> <div style="background: rgba(255,255,255,0.1); padding: 12px; border-radius: 6px;"> <div style="font-size: 0.85em; opacity: 0.9;">EMA (α=${ema_alpha.toFixed(2)})</div> <div style="font-size: 0.9em; margin-top: 8px;">Equivalent MA window: <strong style="color: #E67E22;">N≈${ema_equiv_n.toFixed(0)}</strong></div> <div style="font-size: 0.9em;">Noise reduction: <strong style="color: #3498DB;">${ema_noise_reduction.toFixed(1)}×</strong></div> <div style="font-size: 0.9em;">Effective latency: <strong style="color: #E67E22;">${ema_latency.toFixed(1)} samples</strong></div> </div> <div style="background: rgba(255,255,255,0.1); padding: 12px; border-radius: 6px;"> <div style="font-size: 0.85em; opacity: 0.9;">Moving Average (N=${ma_window})</div> <div style="font-size: 0.9em; margin-top: 8px;">Equivalent EMA α: <strong style="color: #E67E22;">${ma_equiv_alpha.toFixed(3)}</strong></div> <div style="font-size: 0.9em;">Noise reduction: <strong style="color: #3498DB;">${ma_noise_red.toFixed(1)}×</strong></div> <div style="font-size: 0.9em;">Latency: <strong style="color: #E67E22;">${ma_latency.toFixed(1)} samples</strong></div> </div> </div> <div style="margin-top: 15px; padding: 12px; background: rgba(255,255,255,0.1); border-radius: 6px; font-size: 0.9em;"> <strong>Tradeoff:</strong> ${ema_alpha <0.15?"Low α gives excellent smoothing but slow response -- best for near-static signals like ambient temperature.": ema_alpha <0.35?"Moderate α balances smoothing and responsiveness -- good general-purpose choice for most IoT sensors.":"High α gives fast tracking but minimal noise reduction -- use for rapidly changing signals like accelerometers."} </div></div>`
Rule of Thumb: Start with Moving Average N=10 for slow sensors, Median N=5 followed by EMA α=0.2 for fast sensors. Tune based on observed performance.
🏷️ Label the Diagram
Code Challenge
3.8 Summary
Communication Protocols: I2C uses two shared wires (SDA, SCL) with unique addresses for multi-sensor buses, while SPI provides higher-speed full-duplex transfer at the cost of additional wiring per device
Digital Filtering Techniques: Moving average smooths random noise, median filters reject outlier spikes, and Kalman filters provide optimal state estimation for tracking applications – filter choice depends on the noise characteristics
Power Management: Deep sleep modes reduce microcontroller consumption to microamps, and transmission buffering extends battery life by 3x or more by batching data before wireless sends
Calibration for Accuracy: Two-point calibration corrects offset and gain errors, while multi-point calibration handles non-linear sensors – calibration data should be stored persistently in EEPROM
End-to-End Pipeline: Production-quality IoT sensor systems follow five stages – connect (choose protocol), condition (amplify and filter), process (calibrate and digitally filter), manage power (duty cycle), and communicate (MQTT, HTTP, LoRaWAN)