2  Sensor Applications

Real-World IoT Implementation Examples

sensing
applications
smart-home
automation
Author

IoT Textbook

Published

March 22, 2026

Keywords

smart home, environmental monitoring, servo control, relay switching, MQTT, automation

In 60 Seconds

This chapter demonstrates three complete IoT sensor-to-action applications: a smart home environmental monitor using MQTT to control HVAC based on temperature, humidity, and light readings; automated blinds that use a light sensor to drive a servo motor through proportional control; and a temperature-controlled relay fan with hysteresis (different ON/OFF thresholds) to prevent rapid switching that damages relays. Each example shows the full pipeline from sensor reading to real-world actuation.

Key Concepts
  • Sensor Application Domain: a category of real-world use case where IoT sensors are deployed, such as smart home, industrial monitoring, precision agriculture, healthcare, or environmental sensing
  • Data Pipeline: the end-to-end flow of sensor data from physical measurement through collection, transmission, storage, processing, and visualisation to decision-making
  • Threshold Alert: a simple application logic pattern that triggers a notification or actuator action when a sensor reading exceeds or falls below a defined boundary value
  • Anomaly Detection: the process of identifying sensor readings that deviate significantly from expected patterns, indicating equipment fault, intrusion, or unusual environmental conditions
  • Digital Twin: a virtual model of a physical asset that is continuously updated with live sensor data to simulate, monitor, and optimise the real system
  • Edge Processing: running data analysis and decision logic close to the sensor (on a gateway or MCU) rather than in the cloud, reducing latency and bandwidth requirements
  • Application Layer Protocol: a communication standard (MQTT, CoAP, HTTP, AMQP) used to transmit sensor data between IoT devices and cloud or edge platforms

2.1 Learning Objectives

By the end of this chapter, you will be able to:

  • Build a complete smart home environmental monitoring system with MQTT integration
  • Implement sensor-actuator feedback loops for automated control
  • Design temperature-controlled relay switching with hysteresis to prevent rapid cycling
  • Select appropriate sensors for common IoT applications
  • Apply real-world control logic patterns to sensor-driven automation

This chapter shows how sensors and actuators work together in complete projects, like a smart thermostat that reads the temperature and automatically turns a fan on or off. These are the kinds of projects that make IoT tangible – instead of just reading numbers from a sensor, you build systems that sense the environment and take action in response, just like a real commercial smart home device.

2.2 Introduction

This chapter brings together sensor interfacing, data processing, and actuation into complete, practical IoT applications. Each example demonstrates the full sensor-to-action pipeline, from reading physical measurements to triggering real-world responses.

2.3 Smart Home Environmental Monitoring

25 min | Intermediate | P06.C09.U05a

A complete environmental monitoring system combining multiple sensors with cloud connectivity and automated responses.

// Complete environmental monitoring system
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <Wire.h>
#include <BH1750.h>

// Sensors
DHT dht(4, DHT22);
BH1750 lightMeter;

// Wi-Fi and MQTT
WiFiClient espClient;
PubSubClient mqtt(espClient);

// Thresholds
#define TEMP_HIGH 28.0
#define TEMP_LOW 18.0
#define HUMIDITY_HIGH 70.0
#define LIGHT_THRESHOLD 200.0

void setup() {
  Serial.begin(115200);

  // Initialize sensors
  dht.begin();
  Wire.begin();
  lightMeter.begin();

  // Connect to Wi-Fi
  connectWiFi();

  // Connect to MQTT
  mqtt.setServer("mqtt.example.com", 1883);
  connectMQTT();
}

void loop() {
  if (!mqtt.connected()) {
    connectMQTT();
  }
  mqtt.loop();

  // Read sensors
  float temp = dht.readTemperature();
  float humidity = dht.readHumidity();
  float light = lightMeter.readLightLevel();

  // Check conditions and take actions
  if (temp > TEMP_HIGH) {
    Serial.println("Temperature too high! Turning on AC");
    mqtt.publish("home/ac", "ON");
  } else if (temp < TEMP_LOW) {
    Serial.println("Temperature too low! Turning on heater");
    mqtt.publish("home/heater", "ON");
  }

  if (humidity > HUMIDITY_HIGH) {
    Serial.println("Humidity too high! Turning on dehumidifier");
    mqtt.publish("home/dehumidifier", "ON");
  }

  if (light < LIGHT_THRESHOLD) {
    Serial.println("Dark! Turning on lights");
    mqtt.publish("home/lights", "ON");
  } else {
    mqtt.publish("home/lights", "OFF");
  }

  // Publish sensor data
  String payload = "{\"temp\":" + String(temp) +
                   ",\"humidity\":" + String(humidity) +
                   ",\"light\":" + String(light) + "}";
  mqtt.publish("home/sensors", payload.c_str());

  delay(60000);  // 1 minute
}

void connectWiFi() {
  WiFi.begin("SSID", "password");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWi-Fi connected");
}

void connectMQTT() {
  while (!mqtt.connected()) {
    if (mqtt.connect("ESP32_Home_Sensor")) {
      Serial.println("MQTT connected");
    } else {
      delay(5000);
    }
  }
}

This HVAC control system uses simple threshold logic with potential rapid switching issues. Consider a room at 27.9°C approaching the TEMP_HIGH = 28.0°C threshold. DHT22 accuracy: ±0.5°C. Measurement noise: ±0.2°C typical. The AC turns ON at 28.0°C, cools to 27.9°C, turns OFF, temperature drifts to 28.1°C, AC turns ON again – cycling every 2-3 minutes.

Better approach: hysteresis with separate thresholds: - Turn AC ON when \(T > 28.0°C\) - Turn AC OFF when \(T < 27.0°C\)

Hysteresis band: ΔT = 28.0 - 27.0 = 1.0°C. With typical cooling rate 0.5°C/min and natural warming rate 0.5°C/min, the full cycle time is t_cycle = (2 × ΔT) / rate = (2 × 1.0°C) / (0.5°C/min) = 4 min/cycle.

This means 15 cycles/hour (60 min ÷ 4 min). A 1°C hysteresis band reduces AC cycles from ~30/hour (no hysteresis) to 15/hour, extending compressor life by 50% and reducing energy consumption by 8-12% through fewer startup transients.

Interactive Hysteresis Calculator:

2.4 Sensor-Controlled Servo Motor

20 min | Intermediate | P06.C09.U05b

Servo Motors in IoT: Servo motors provide precise angular positioning, making them ideal for automated control systems. Combined with sensors, they create feedback-controlled actuators.

Specifications (SG90 Servo):

  • Rotation Range: 0 to 180 degrees
  • Control: PWM signal (1000-2000 µs pulse width)
  • Torque: 1.8 kg·cm at 5V
  • Speed: 0.1 s/60 degrees at 5V
  • Power: 5V, 100-250 mA (moving), 10 mA (idle)

2.4.1 Application Example: Automated Blinds Control

#include <ESP32Servo.h>

#define SERVO_PIN 18
#define LDR_PIN 34

Servo blindsServo;

void setup() {
  Serial.begin(115200);

  // Attach servo
  blindsServo.attach(SERVO_PIN, 1000, 2000);  // min, max pulse width

  // Configure ADC
  analogReadResolution(12);
  analogSetAttenuation(ADC_11db);

  Serial.println("Automated Blinds Control");
}

void loop() {
  // Read light sensor
  int lightLevel = analogRead(LDR_PIN);
  float lightPercent = (lightLevel / 4095.0) * 100;

  // Map light level to servo angle
  // High light = close blinds (180 degrees)
  // Low light = open blinds (0 degrees)
  int servoAngle = map(lightLevel, 0, 4095, 0, 180);

  // Move servo
  blindsServo.write(servoAngle);

  // Display status
  Serial.print("Light: ");
  Serial.print(lightPercent, 1);
  Serial.print("% | Servo Angle: ");
  Serial.print(servoAngle);
  Serial.print(" deg | Blinds: ");

  if (servoAngle < 45) {
    Serial.println("Fully Open");
  } else if (servoAngle < 135) {
    Serial.println("Partially Open");
  } else {
    Serial.println("Fully Closed");
  }

  delay(1000);
}
Learning Points

Observe:

  • Sensor-Actuator Feedback Loop: Light sensor to decision logic to servo control
  • PWM Servo Control: Pulse width (1000-2000 µs) determines angle (0-180 degrees)
  • Map Function: Converts sensor range to actuator range
  • Proportional Control: Servo angle proportional to light level
  • Real-time Response: System continuously adjusts to changing conditions

Interactive Servo Mapping Calculator:

Control Logic:

High Light (bright)  -> Angle 180 deg -> Blinds CLOSED (shade interior)
Medium Light         -> Angle 90 deg  -> Blinds HALF (moderate light)
Low Light (dark)     -> Angle 0 deg   -> Blinds OPEN (maximize daylight)

Real-World Applications:

  • Automated Blinds/Curtains: Adjust based on time of day and sunlight
  • Solar Panel Tracking: Follow sun position for maximum efficiency
  • Smart Vents: Open/close based on temperature readings
  • Robotic Arms: Position based on distance sensor feedback
  • Camera Pan/Tilt: Track objects detected by motion sensors

Experiment:

  • Add hysteresis: only move servo if light changes by >10%
  • Implement smooth transitions instead of immediate movements
  • Add manual override with buttons
  • Create schedules: fully open in morning, close at noon
  • Use temperature sensor to control ventilation servo

2.5 Temperature-Controlled Relay Switching

20 min | Intermediate | P06.C09.U05c

Relays in IoT: Relays are electrically operated switches that allow low-power microcontrollers to control high-power AC/DC devices safely. Essential for home automation and industrial control.

Relay Specifications:

  • Control: 3.3V or 5V DC signal
  • Switch: 10A @ 250VAC or 10A @ 30VDC (typical)
  • Isolation: Optical/electrical isolation between control and load
  • Types: SPST, SPDT, DPDT
  • Response Time: 10-15ms

2.5.1 Application Example: Temperature-Controlled Fan

#include <DHT.h>

#define DHT_PIN 4
#define RELAY_PIN 13

#define TEMP_THRESHOLD_ON 28.0   // Turn fan ON above 28C
#define TEMP_THRESHOLD_OFF 26.0  // Turn fan OFF below 26C (hysteresis)

DHT dht(DHT_PIN, DHT22);
bool fanState = false;

void setup() {
  Serial.begin(115200);

  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);  // Fan initially OFF

  dht.begin();

  Serial.println("Temperature-Controlled Fan System");
}

void loop() {
  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();

  if (isnan(temperature) || isnan(humidity)) {
    Serial.println("Failed to read from DHT sensor!");
    delay(2000);
    return;
  }

  // Control logic with hysteresis to prevent rapid switching
  if (!fanState && temperature > TEMP_THRESHOLD_ON) {
    // Turn fan ON
    fanState = true;
    digitalWrite(RELAY_PIN, HIGH);
    Serial.println("Temperature HIGH - Fan turned ON");
  }
  else if (fanState && temperature < TEMP_THRESHOLD_OFF) {
    // Turn fan OFF
    fanState = false;
    digitalWrite(RELAY_PIN, LOW);
    Serial.println("Temperature OK - Fan turned OFF");
  }

  // Display status
  Serial.print("Temp: ");
  Serial.print(temperature, 1);
  Serial.print("C | Humidity: ");
  Serial.print(humidity, 1);
  Serial.print("% | Fan: ");
  Serial.println(fanState ? "ON" : "OFF");

  delay(2000);
}
Learning Points

Observe:

  • Hysteresis Control: Different ON/OFF thresholds (28C ON, 26C OFF) prevent rapid switching
  • Relay Switching: GPIO pin controls relay coil, relay contacts switch high-power load
  • Electrical Isolation: Relay physically separates low-voltage control from high-voltage load
  • State Management: Boolean flag tracks fan state between loop iterations
  • Safety: Microcontroller never directly touches high-voltage circuits

Hysteresis Explanation:

Temperature Rising: 24C -> 26C -> 28C -> [FAN TURNS ON]
Temperature Falling: 30C -> 28C -> 26C -> [FAN TURNS OFF]

Without Hysteresis (bad):
27.9C -> OFF, 28.1C -> ON, 27.9C -> OFF... (rapid switching damages relay!)

With Hysteresis (good):
Temperature must fall to 26C before turning off again

Real-World Applications:

  • HVAC Control: Heating/cooling systems with thermostats
  • Irrigation Systems: Pump control based on soil moisture
  • Lighting Control: Turn on/off high-wattage lights
  • Industrial Automation: Motor control, conveyor systems
  • Safety Systems: Emergency shutoffs, fire suppression
  • Appliance Automation: Coffee makers, heaters, refrigerators

Safety Considerations:

  • Never work on AC circuits while powered
  • Use proper gauge wire for current load
  • Ensure relay rating exceeds load requirements
  • Add flyback diodes for inductive loads (motors, solenoids)

Experiment:

  • Add multiple temperature zones with different thresholds
  • Implement time delays: keep fan on for minimum 5 minutes
  • Add manual override button
  • Log switching events to detect relay wear
  • Implement “smart” scheduling: different thresholds for day/night

2.6 Sensor Selection Guide

15 min | Intermediate | P06.C09.U04

2.6.1 Comparison of Common Temperature Sensors

Sensor Range Accuracy Iface Power Cost Tier Primary Use
DHT22 -40 to 80°C ±0.5°C 1-Wire 1.5 mA Low General indoor sensing
DS18B20 -55 to 125°C ±0.5°C 1-Wire 1.5 mA Low Multipoint or waterproof probes
LM35 -55 to 150°C ±0.5°C Analog 60 µA Low Simple low-power analog input
BME280 -40 to 85°C ±1°C I2C/SPI 3.6 µA Mid Combined environmental sensing
TMP117 -55 to 125°C ±0.1°C I2C 3.5 µA High Precision temperature control

2.6.2 Sensor Interface Decision Tree

Decision tree for sensor interface protocol selection starting with multiple versus single sensor question: multiple sensors branch asks if high speed above 1 MHz is needed, leading to SPI (up to 80 MHz, 4+ pins for MOSI MISO CLK CS, best for displays SD cards ADCs) or I2C (100-400 kHz, 2 pins SDA SCL, best for sensors EEPROM RTC); single sensor branch asks digital or analog output, leading to 1-Wire/UART (1-2 pins, simple protocol, best for DS18B20 DHT22) or Analog ADC (1 analog input, needs ADC conversion, best for LDR thermistor potentiometer).
Figure 2.1: Sensor Interface Protocol Selection: Decision Tree for I2C, SPI, or Analog

2.7 Practice Exercises

Objective: Build a multi-sensor system using I2C bus and resolve address conflicts.

Scenario: Connect BMP280 (pressure, 0x76), BH1750 (light, 0x23), and two MPU6050 IMUs (both default to 0x68) to an ESP32.

Tasks:

  1. I2C Address Scanning: Write code to scan I2C bus and detect all connected devices
  2. Address Conflict Resolution: MPU6050 has AD0 pin for address selection (0x68 or 0x69). Modify hardware to use different addresses
  3. Read All Sensors: Implement code to read from all 4 sensors in a single loop
  4. Timing Analysis: Measure read time at 100kHz vs 400kHz I2C speed
  5. Error Handling: Implement timeout and disconnection detection

Implementation Starter:

#include <Wire.h>

void scanI2C() {
    Serial.println("Scanning I2C bus...");
    for(byte addr = 1; addr < 127; addr++) {
        Wire.beginTransmission(addr);
        if (Wire.endTransmission() == 0) {
            Serial.printf("Found device at 0x%02X\n", addr);
        }
    }
}

// Exercise: Add code to read from all 4 sensors
// Exercise: Add error handling for sensor failures

Objective: Minimize power consumption for battery-powered sensor node.

Scenario: Battery-powered weather station (ESP32 + BME280 + BH1750) transmitting via LoRa every 15 minutes. Battery: 2000 mAh. Target lifetime: 1 year.

Tasks:

  1. Power Budget Analysis: Calculate current consumption for each component
  2. Lifetime Calculation: With sensors always on and ESP32 waking every 15 minutes, calculate battery lifetime
  3. Sensor Power Management: Implement code to power sensors on/off using GPIO-controlled MOSFET
  4. Buffering Strategy: Buffer 8 readings and transmit every 2 hours. Calculate power savings
  5. Adaptive Sampling: If temperature changes < 0.5C in 1 hour, reduce sampling to 30 minutes

Implementation Starter:

#define SENSOR_POWER_PIN 13

void powerOnSensors() {
    digitalWrite(SENSOR_POWER_PIN, HIGH);
    delay(100);  // Sensor stabilization time
}

void powerOffSensors() {
    digitalWrite(SENSOR_POWER_PIN, LOW);
}

void loop() {
    powerOnSensors();
    // Read sensors
    float temp = bme.readTemperature();
    powerOffSensors();

    // Buffer and transmit logic
    esp_deep_sleep(15 * 60 * 1000000);  // 15 minutes
}

Objective: Build complete data pipeline with calibration, filtering, validation, and anomaly detection.

Scenario: Industrial temperature monitoring using 10 DS18B20 sensors. Sensors require calibration and readings must be validated before sending to cloud.

Tasks:

  1. Two-Point Calibration: Calibrate all 10 sensors using ice bath (0C) and boiling water (100C). Store calibration coefficients in EEPROM/SPIFFS
  2. Data Validation: Implement checks:
    • Range validation: Reject readings outside -40C to 125C
    • Rate-of-change: Flag readings changing > 5C/minute (sensor malfunction)
    • Cross-sensor validation: If one sensor differs > 10C from average of others, flag as outlier
  3. Median Filtering: Apply 5-sample median filter to each sensor to remove spikes
  4. Anomaly Detection: If 3 consecutive readings from same sensor fail validation, send maintenance alert
  5. Data Logging: Format validated data as JSON with timestamps, calibrated values, and quality flags

2.8 Knowledge Checks

    1. The sensor has a 2-degree measurement error
    1. To implement hysteresis, preventing rapid ON/OFF switching that damages the relay
    1. The fan needs 2 degrees to cool down
    1. To save energy by running the fan less often

Answer: B) To implement hysteresis, preventing rapid ON/OFF switching that damages the relay

Without hysteresis, at exactly 28C the fan would turn ON, cool the air slightly to 27.9C, turn OFF, temperature rises back to 28.1C, turn ON again – cycling every few seconds. This rapid switching wears out relay contacts, creates electrical noise, and wastes energy. The 2-degree gap ensures the fan stays ON until temperature drops significantly, producing stable operation.

    1. It reads data from the DHT22 sensor
    1. It provides a publish/subscribe messaging system that connects the ESP32 to cloud services and other devices
    1. It controls the servo motor position
    1. It supplies power to the sensors

Answer: B) It provides a publish/subscribe messaging system that connects the ESP32 to cloud services and other devices

MQTT (Message Queuing Telemetry Transport) is a lightweight messaging protocol ideal for IoT. The ESP32 publishes sensor data to topics like “home/sensors” and control commands to topics like “home/ac” or “home/lights”. Other devices subscribe to these topics and act accordingly. This decoupled architecture means the sensor node does not need to know about every device it controls.

Scenario: You’re deploying a complete smart home monitoring system with the following actuators and sensors operating simultaneously:

System Components:

  • ESP32 microcontroller: 80mA active, 10μA deep sleep
  • DHT22 sensor (temp/humidity): 2.5mA when reading (1 second every 5 minutes)
  • BH1750 light sensor: 0.12mA continuous
  • Relay (5V coil): 70mA when energized
  • AC unit (controlled by relay): Draws from wall AC, not our power supply
  • Two servo motors (SG90): 100mA idle each, 500mA peak stall each

Step 1: Calculate worst-case peak current

When do all components draw maximum power simultaneously? When both servos are moving (adjusting blinds) while the relay activates the AC unit:

  • ESP32: 80mA
  • DHT22: 2.5mA (brief, can overlap with servo movement)
  • BH1750: 0.12mA
  • Relay coil: 70mA
  • Servo 1 (peak): 500mA
  • Servo 2 (peak): 500mA
  • Peak total: 1,152.62mA ≈ 1.15A

Step 2: Apply safety margins

  • Transient spikes: Servos can draw 1.2x rated current on sudden direction changes: 500mA × 1.2 = 600mA each
  • Component tolerance: Power supply components age; derate by 20%
  • Peak with margins: (80 + 2.5 + 0.12 + 70 + 600 + 600) = 1,352.62mA ÷ 0.8 = 1.69A required

Step 3: Select power supply rating

Choose a 5V 2A regulated power supply (common size, provides 18% headroom above 1.69A).

Step 4: Calculate average power consumption

Most of the time, the system is idle: - Duty cycle: Servos move 10 seconds every 10 minutes (1.67% active) - Relay ON: 30% of the time when temperature exceeds threshold - DHT22 reading: 1 second every 300 seconds (0.33% active)

Average current = 80 + 0.12 + (2.5×0.0033) + (70×0.30) + (2×100×0.0167) ≈ 104mA typical

Battery life estimate (if using 10,000mAh USB power bank for backup): 10,000mAh ÷ 104mA = 96 hours (4 days) backup runtime

Key Insight: Peak current (1.15A) is 11x higher than average current (104mA). Designing for average would cause brownout resets when servos activate. Always design power supplies for worst-case peak, not average load.

Interactive Power Budget Calculator:

Key Takeaway

Building real-world IoT applications requires combining sensors, processing logic, and actuators into complete feedback loops. The three critical patterns demonstrated here – threshold-based control with hysteresis (relay), proportional control with mapping (servo), and multi-sensor monitoring with cloud connectivity (MQTT) – form the foundation for virtually all IoT automation systems, from smart homes to industrial processes.

Max the Microcontroller gathered the team for a home automation demo day. “Alright squad, let’s show how a smart home works!”

Sammy the Sensor went first. “I’m watching the temperature, humidity, AND light levels – all at the same time! Right now it’s 29 degrees… that’s too hot!”

“Leave it to me!” said Lila the LED, flashing red. “I just told the air conditioner to turn ON through our message system called MQTT. It’s like sending a text message that says ‘home/ac: ON’ and the AC gets the message instantly!”

“But what about the blinds?” asked Bella the Battery. “The sun is super bright!”

Sammy checked the light sensor. “The light level is really high – 90%! So the servo motor turns the blinds almost all the way closed. When it gets cloudy and light drops to 20%, the blinds open up again. It’s like the house has sunglasses that adjust automatically!”

Max explained the cleverest part: “And see the fan? It turns ON when temperature hits 28 degrees, but it doesn’t turn OFF until it drops to 26 degrees. That 2-degree gap is called hysteresis – it’s like how you don’t put your jacket back on until it’s actually cold, not just slightly cooler!”

“So the house basically takes care of itself?” Bella asked, impressed.

“Exactly!” Max beamed. “Sensors watch, I think, and actuators act. That’s the IoT magic – sense, decide, act, repeat!”

2.9 Summary

This chapter covered real-world sensor applications:

  • Smart Home Monitoring: Multi-sensor environmental monitoring with MQTT integration
  • Servo Control: Light-responsive automated blinds using PWM servo control
  • Relay Switching: Temperature-controlled fan with hysteresis to prevent rapid cycling
  • Sensor Selection: Comparison of common temperature sensors and interface selection
  • Practical Patterns: Sensor-actuator feedback loops, state management, safety isolation

2.10 Knowledge Check

Common Pitfalls

Instrumenting everything and storing raw sensor streams without a clear analytical goal wastes storage, bandwidth, and compute. Define the decision you need to make first, then instrument only what supports that decision.

Missing values, stuck readings, and out-of-range spikes propagate silently through pipelines and corrupt analytics. Implement data validation and anomaly flagging close to the sensor source.

Many sensor applications do not require sub-second response. Batching readings and transmitting periodically reduces energy use and network load. Reserve streaming for safety-critical or time-sensitive use cases.

Hard-coding sensor model assumptions (scale factors, units, pin assignments) into application logic makes it fragile when sensors are upgraded. Use abstraction layers and configuration files to separate hardware from application logic.

2.11 What’s Next

If you want to… Read this
Explore specific vertical application domains Smart Home and Building Automation
Learn about industrial IoT sensor applications Industrial IoT Sensing
Understand the data platforms that receive sensor data IoT Reference Architectures
See how edge processing fits into sensor applications Edge and Fog Computing

The next chapter provides a hands-on Sensor Calibration Lab using the Wokwi simulator, where you will implement two-point calibration, signal conditioning, and EEPROM storage.