← Embedded Track
Embedded Systems & IoT · Course 03

ESP32 &
Internet of Things

Move from local electronics to connected devices. Learners build Wi-Fi projects, MQTT clients, HTTP dashboards, Bluetooth controls, data logging, alerts, and a complete smart room monitor.

Start Course 03 ← Course 02 Course 04 →
10Modules
ESP32Wi-Fi + Bluetooth
MQTT / HTTPIoT networking
CapstoneSmart room monitor
Course Progress
0%
Module 01

Meet the ESP32

The ESP32 is where beginner electronics becomes IoT. It has GPIO like Arduino, but also Wi-Fi, Bluetooth, more processing power, and enough memory to run connected device projects.

🎯 Course Outcome

By the end of this course, learners build a connected smart room monitor that reads temperature, humidity, light, and motion, publishes sensor readings over MQTT, serves a local dashboard, and can trigger alerts through an HTTP webhook.

Arduino IDEESP32 DevKitDHT sensorPIR motionMQTT broker

Microcontroller side

The ESP32 can read pins, control LEDs, handle buttons, read sensors, and run fast loops just like an Arduino-style board.

Network side

It can join Wi-Fi, serve a web page, send HTTP requests, publish MQTT messages, and act like a tiny connected product.

🧰 Recommended Hardware
ItemUse
ESP32 DevKit boardMain controller for the course.
Micro USB or USB-C cablePower and programming connection. Make sure it supports data, not just charging.
Breadboard + jumper wiresPrototyping sensor and LED circuits.
DHT22 or DHT11Temperature and humidity readings.
PIR motion sensorRoom movement detection for the capstone.
LEDs + 220Ω/330Ω resistorsVisible status indicators.
⚠️
Voltage ruleThe ESP32 is a 3.3V logic board. Some dev boards provide a 5V/VIN pin from USB, but GPIO signal pins should not receive 5V.
🧠 Quick Check
What makes the ESP32 especially useful for IoT compared to a basic Arduino Uno?
Module 02

Setup & First Upload

Install ESP32 board support, select the right board and port, then upload a first sketch to prove the toolchain works before adding hardware complexity.

🛠️ Setup Flow
  1. Install Arduino IDE.
  2. Add the ESP32 board package through Boards Manager.
  3. Connect the ESP32 with a data-capable USB cable.
  4. Select a matching ESP32 Dev Module board.
  5. Select the serial port that appears after plugging in the board.
  6. Upload a simple Blink sketch.
const int ledPin = 2; // many ESP32 boards have onboard LED on GPIO 2

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  digitalWrite(ledPin, HIGH);
  delay(500);
  digitalWrite(ledPin, LOW);
  delay(500);
}
🔎
Boot button noteSome ESP32 boards require holding BOOT while upload begins. If upload gets stuck at connecting, press and hold BOOT until writing starts.
🧪 Lab: First Upload Proof

Upload Blink, change the delay from 500ms to 100ms, upload again, and confirm the device changes behavior. This proves the board, cable, driver, IDE, and upload process are working.

🧠 Quick Check
If the ESP32 appears powered but uploads fail, what should you check first?
Module 03

GPIO on the ESP32

The ESP32 has many pins, but not every pin is safe for every purpose. Learners practice LEDs, buttons, pull-ups, and safe pin selection.

📌 Pin Selection Rules
  • Use common safe GPIO pins such as 2, 4, 5, 18, 19, 21, 22, 23, 25, 26, 27, 32, and 33 for beginner projects.
  • Avoid changing boot-strapping pins until you understand their startup behavior.
  • Remember that input-only pins exist on some ESP32 boards.
  • Keep all signal wiring at 3.3V logic.
const int buttonPin = 27;
const int ledPin = 2;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  bool pressed = digitalRead(buttonPin) == LOW;
  digitalWrite(ledPin, pressed ? HIGH : LOW);
}
🧪 Lab: Status Button
  1. Wire a button from GPIO 27 to GND.
  2. Use INPUT_PULLUP.
  3. Light the onboard LED while the button is pressed.
  4. Print the state to Serial for debugging.
🧠 Quick Check
With INPUT_PULLUP, what does the button usually read when pressed?
Module 04

Wi-Fi Fundamentals

A connected device must join a network reliably. This module covers SSID, password, station mode, IP addresses, connection status, and basic troubleshooting.

🌐 Station Mode

Most beginner ESP32 projects use station mode, meaning the ESP32 joins an existing Wi-Fi network like a laptop or phone. Once connected, it receives an IP address and can communicate on the local network or internet.

#include <WiFi.h>

const char* ssid = "YOUR_WIFI_NAME";
const char* password = "YOUR_WIFI_PASSWORD";

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);

  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println();
  Serial.print("Connected. IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {}
🔐
Credential habitFor real projects, keep Wi-Fi credentials outside code you publish. Beginners can hard-code locally while learning, but public repositories should not contain private passwords.
🧠 Quick Check
What does the ESP32 need before other devices can open its local dashboard?
Module 05

Web Server Dashboard

The ESP32 can host a tiny web server. Learners create a browser dashboard that shows device state and controls an LED from any phone or laptop on the same network.

🖥️ Device as a Web Server

When the ESP32 runs a web server, it listens for browser requests. A phone opens the ESP32 IP address, the ESP32 sends HTML back, and button links can trigger GPIO actions.

#include <WiFi.h>
#include <WebServer.h>

const char* ssid = "YOUR_WIFI_NAME";
const char* password = "YOUR_WIFI_PASSWORD";
const int ledPin = 2;

WebServer server(80);
bool ledOn = false;

void handleHome() {
  String page = "<h1>ESP32 Dashboard</h1>";
  page += "<p>LED: " + String(ledOn ? "ON" : "OFF") + "</p>";
  page += "<a href='/toggle'>Toggle LED</a>";
  server.send(200, "text/html", page);
}

void handleToggle() {
  ledOn = !ledOn;
  digitalWrite(ledPin, ledOn ? HIGH : LOW);
  server.sendHeader("Location", "/");
  server.send(303);
}

void setup() {
  pinMode(ledPin, OUTPUT);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) delay(300);
  server.on("/", handleHome);
  server.on("/toggle", handleToggle);
  server.begin();
}

void loop() {
  server.handleClient();
}
🧪 Lab: Phone-Controlled LED

Connect the ESP32 to Wi-Fi, open the printed IP address on a phone, and toggle the LED from the dashboard.

🧠 Quick Check
Which line keeps the ESP32 web server responding to browser requests?
Module 06

Sensors & Data

An IoT device becomes useful when it collects real measurements. This module reads temperature, humidity, light, and motion, then formats clean data for dashboards and messages.

🌡️ Data Pipeline
  1. Read the sensor.
  2. Validate the reading.
  3. Store it in variables.
  4. Print it for debugging.
  5. Display or publish it.
#include "DHT.h"

#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

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

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

  if (isnan(tempC) || isnan(humidity)) {
    Serial.println("Sensor read failed");
    return;
  }

  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print("  Humidity: ");
  Serial.println(humidity);
  delay(2000);
}
🧠
Why validation mattersSensors sometimes fail or return invalid values. A professional device checks data before displaying, saving, or publishing it.
🧪 Lab: Room Readings

Read a DHT sensor, print values to Serial, then add the readings to the web dashboard from Module 05.

🧠 Quick Check
Why should sensor readings be checked before publishing?
Module 07

MQTT Messaging

MQTT is one of the most common IoT messaging patterns. Devices publish messages to topics, and dashboards or services subscribe to receive them.

Publisher

The ESP32 sends a message such as temperature data to a named topic.

Subscriber

A dashboard, server, or another device listens to the topic and reacts when a message arrives.

📨 Topic Design
TopicPurpose
home/room1/temperatureTemperature readings
home/room1/humidityHumidity readings
home/room1/motionMotion status
home/room1/statusDevice online/offline heartbeat
#include <WiFi.h>
#include <PubSubClient.h>

WiFiClient wifiClient;
PubSubClient mqtt(wifiClient);

void publishReading(float tempC) {
  char payload[16];
  dtostrf(tempC, 4, 1, payload);
  mqtt.publish("home/room1/temperature", payload);
}
⚠️
Reliability ruleMQTT publishing only works when Wi-Fi is connected and the broker connection is alive. Real code should reconnect when either one drops.
🧪 Lab: Publish Sensor Data

Run a local MQTT broker, connect the ESP32, publish temperature readings every few seconds, and view messages from a desktop MQTT client.

🧠 Quick Check
In MQTT, what does a device publish to?
Module 08

HTTP APIs & Webhooks

HTTP lets the ESP32 talk to web services. Learners send data to an API endpoint and trigger a webhook-style alert when a sensor crosses a threshold.

🔗 MQTT vs HTTP
ProtocolBest For
MQTTContinuous small messages between devices and dashboards.
HTTPCalling web APIs, sending form-like data, triggering webhook endpoints.
#include <HTTPClient.h>

void sendWebhook(String message) {
  HTTPClient http;
  http.begin("https://example.com/webhook");
  http.addHeader("Content-Type", "application/json");

  String body = "{\"message\":\"" + message + "\"}";
  int code = http.POST(body);

  Serial.print("HTTP status: ");
  Serial.println(code);
  http.end();
}
🔐
Security habitAPI keys and webhook URLs should be treated like passwords. Do not publish private keys in public code repositories.
🧪 Lab: Motion Alert

When the PIR sensor detects motion, send a webhook message. Add cooldown logic so the ESP32 does not spam repeated alerts.

🧠 Quick Check
Why add cooldown logic to alerts?
Module 09

Bluetooth & Power

Not every connected device needs Wi-Fi all the time. This module introduces Bluetooth use cases and power-aware design for battery-powered projects.

Bluetooth use cases

Local phone control, setup mode, short-range device configuration, and simple nearby interactions.

Power awareness

Reduce radio time, avoid unnecessary delays, dim indicators, and use deep sleep for periodic sensor projects.

🔋 Power Design Questions
  • Does the device need to be always-on?
  • Can it wake, read, publish, then sleep?
  • How often does the sensor actually need to report?
  • Are LEDs wasting power?
  • Is Wi-Fi required, or is Bluetooth enough?
#define SECONDS_TO_SLEEP 60

void setup() {
  Serial.begin(115200);
  Serial.println("Read sensor, publish data, then sleep...");

  esp_sleep_enable_timer_wakeup(SECONDS_TO_SLEEP * 1000000ULL);
  esp_deep_sleep_start();
}

void loop() {}
🧪 Lab: Sleep Cycle Concept

Build a sketch that wakes, prints a sensor reading, waits briefly, and enters deep sleep. Discuss how this changes battery life compared to always-on Wi-Fi.

🧠 Quick Check
What is the main reason to use deep sleep?
Module 10

Capstone: Smart Room Monitor

Learners combine everything from the course into one product-style build: sensing, dashboard, MQTT publishing, motion alerts, status LED, and deployment notes.

🏁 Final Build Requirements
  1. Read temperature and humidity from a DHT sensor.
  2. Read motion from a PIR sensor.
  3. Show current readings on a local ESP32 web dashboard.
  4. Publish readings to MQTT topics every fixed interval.
  5. Send an HTTP webhook alert when motion is detected.
  6. Use a status LED pattern for booting, connected, error, and alert states.
  7. Document wiring, setup steps, screenshots, and troubleshooting notes.
🧱 Suggested Architecture
ESP32
├── inputs
│   ├── DHT22 temperature/humidity
│   └── PIR motion sensor
├── outputs
│   └── status LED
├── local dashboard
│   └── WebServer on port 80
├── MQTT publisher
│   ├── home/room1/temperature
│   ├── home/room1/humidity
│   └── home/room1/motion
└── HTTP alert
    └── webhook on motion event
📦 Ship-It Checklist
  • README with parts list and wiring table.
  • Screenshot of local dashboard.
  • Photo of the breadboard build.
  • Short demo video or GIF.
  • Known issues and future improvements.
  • Clean code with credentials removed.
🧠 Final Check
What separates a course project from a portfolio project?