542 Hands-On Sensor Labs
Learning Objectives
After completing this chapter, you will be able to:
- Set up and read from common IoT sensors
- Wire sensors correctly to ESP32/Arduino
- Write code to acquire and process sensor data
- Troubleshoot common sensor connection issues
542.1 Prerequisites
- Common IoT Sensors: Sensor types and specifications
- Reading Datasheets: Understanding connections
542.2 Interactive Labs: Hands-On Sensor Practice
These labs use the Wokwi simulator for safe experimentation without needing physical hardware.
542.3 Lab 1: Read Environmental Data (DHT22)
Objective: Read temperature and humidity from a DHT22 sensor.
Hardware Setup: - ESP32 DevKit - DHT22 sensor - 10kohm pull-up resistor (data line to VCC)
Wiring: | DHT22 Pin | ESP32 Pin | |ββββ|ββββ| | VCC (1) | 3.3V | | Data (2) | GPIO4 | | NC (3) | - | | GND (4) | GND |
Code:
#include "DHT.h"
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(115200);
dht.begin();
Serial.println("DHT22 Sensor Test");
}
void loop() {
delay(2000); // DHT22 needs 2 seconds between readings
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print(" C, Humidity: ");
Serial.print(humidity);
Serial.println(" %");
}Try It: Modify the code to calculate heat index using the dht.computeHeatIndex() function.
542.4 Lab 2: Light-Activated System (LDR)
Objective: Build a light sensor that triggers an LED when it gets dark.
Hardware Setup: - ESP32 DevKit - LDR (photoresistor) - 10kohm resistor (voltage divider) - LED + 220ohm resistor
Wiring:
3.3V ---[LDR]---+---[10k]--- GND
|
GPIO34 (Analog input)
GPIO2 ---[220R]---[LED]--- GND
Code:
#define LDR_PIN 34
#define LED_PIN 2
#define DARK_THRESHOLD 1000 // Adjust based on your environment
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
int lightLevel = analogRead(LDR_PIN);
Serial.print("Light level: ");
Serial.println(lightLevel);
if (lightLevel < DARK_THRESHOLD) {
digitalWrite(LED_PIN, HIGH); // Turn on LED when dark
Serial.println("Dark - LED ON");
} else {
digitalWrite(LED_PIN, LOW); // Turn off LED when light
Serial.println("Light - LED OFF");
}
delay(500);
}542.5 Lab 3: Ultrasonic Distance Measurement (HC-SR04)
Objective: Measure distance using ultrasonic sensor.
Hardware Setup: - ESP32 DevKit - HC-SR04 ultrasonic sensor - Voltage divider for ECHO pin (5V to 3.3V)
Wiring: | HC-SR04 Pin | ESP32 Pin | Notes | |ββββ-|ββββ|ββ-| | VCC | 5V | Needs 5V power | | TRIG | GPIO5 | Trigger pulse | | ECHO | GPIO18 | Via voltage divider! | | GND | GND | |
Voltage Divider for ECHO:
ECHO ---[10k]---+---[20k]--- GND
|
GPIO18
Code:
#define TRIG_PIN 5
#define ECHO_PIN 18
void setup() {
Serial.begin(115200);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
}
float measureDistance() {
// Send trigger pulse
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Measure echo duration
long duration = pulseIn(ECHO_PIN, HIGH, 30000); // 30ms timeout
// Calculate distance (speed of sound = 343 m/s)
// distance = (duration * 0.0343) / 2
float distance = (duration * 0.0343) / 2;
return distance;
}
void loop() {
float distance = measureDistance();
if (distance > 0) {
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
} else {
Serial.println("Out of range or no echo");
}
delay(100);
}542.6 Lab 4: ESP32 Temperature Monitoring with DHT22
Objective: Create a complete temperature monitoring system with data validation.
Features: - Read temperature and humidity - Validate readings (check for NaN, range errors) - Apply moving average filter - Display on Serial and (optionally) OLED
Code:
#include "DHT.h"
#define DHTPIN 4
#define DHTTYPE DHT22
#define FILTER_SIZE 5
DHT dht(DHTPIN, DHTTYPE);
float tempReadings[FILTER_SIZE];
float humReadings[FILTER_SIZE];
int readIndex = 0;
void setup() {
Serial.begin(115200);
dht.begin();
// Initialize filter arrays
for (int i = 0; i < FILTER_SIZE; i++) {
tempReadings[i] = 0;
humReadings[i] = 0;
}
Serial.println("Temperature Monitor Started");
delay(2000); // DHT22 warm-up
}
bool validateReading(float temp, float hum) {
// Check for NaN
if (isnan(temp) || isnan(hum)) return false;
// Check for reasonable range
if (temp < -40 || temp > 80) return false;
if (hum < 0 || hum > 100) return false;
return true;
}
float getFilteredValue(float readings[], int size) {
float sum = 0;
for (int i = 0; i < size; i++) {
sum += readings[i];
}
return sum / size;
}
void loop() {
delay(2000); // DHT22 requires 2s between readings
float temp = dht.readTemperature();
float hum = dht.readHumidity();
if (!validateReading(temp, hum)) {
Serial.println("Invalid reading - skipping");
return;
}
// Add to filter buffer
tempReadings[readIndex] = temp;
humReadings[readIndex] = hum;
readIndex = (readIndex + 1) % FILTER_SIZE;
// Get filtered values
float filteredTemp = getFilteredValue(tempReadings, FILTER_SIZE);
float filteredHum = getFilteredValue(humReadings, FILTER_SIZE);
// Output
Serial.print("Raw: ");
Serial.print(temp);
Serial.print("C, ");
Serial.print(hum);
Serial.print("% | Filtered: ");
Serial.print(filteredTemp);
Serial.print("C, ");
Serial.print(filteredHum);
Serial.println("%");
}542.7 Troubleshooting Common Issues
| Problem | Likely Cause | Solution |
|---|---|---|
| NaN readings | Wiring issue, no pull-up | Check connections, add pull-up resistor |
| Constant zero | Wrong pin number | Verify pin definitions match wiring |
| Random spikes | No filtering, noise | Add moving average or median filter |
| I2C not detected | Wrong address, no pull-ups | Scan with I2C scanner, add 4.7k pull-ups |
| Slow response | Reading too fast | Respect minimum sampling interval |
| 5V sensor on 3.3V MCU | Voltage mismatch | Add level shifter or voltage divider |
542.8 Summary
Key hands-on takeaways:
- Always check wiring first - Most issues are connection problems
- Use pull-up resistors - Required for I2C and 1-Wire
- Validate readings - Check for NaN and out-of-range values
- Apply filtering - Reduce noise for stable readings
- Respect timing - Donβt read faster than sensor allows
542.9 Whatβs Next
Now that you have hands-on experience:
- To select sensors: Selection Guide - Tools for choosing
- To avoid mistakes: Common Mistakes - Top 10 pitfalls
- To go deeper: Advanced Topics - Noise, fusion, optimization