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

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:

  1. Always check wiring first - Most issues are connection problems
  2. Use pull-up resistors - Required for I2C and 1-Wire
  3. Validate readings - Check for NaN and out-of-range values
  4. Apply filtering - Reduce noise for stable readings
  5. Respect timing - Don’t read faster than sensor allows

542.9 What’s Next

Now that you have hands-on experience:

Continue to Selection Guide ->