Systems Engineering

IoT & Embedded
Systems

From a single sensor reading to a city-wide intelligent network — how billions of tiny devices reshape the physical world.

Prerequisites: Basic programming + Curiosity about connected devices. That's it.
10
Chapters
10+
Simulations
0
Assumed Knowledge

Chapter 0: The IoT Landscape

There are over 15 billion IoT devices active today. Your smart thermostat talks to the cloud every 30 seconds. A tractor in Iowa reports soil moisture to a farmer's phone. Traffic lights in Barcelona optimize flow using real-time data from thousands of buried sensors. A patient's insulin pump adjusts dosage based on continuous glucose readings.

This isn't science fiction. It's Tuesday.

The Internet of Things (IoT) is a simple idea with enormous consequences: take a physical thing, give it a sensor, connect it to the internet, and let software make it smarter. A thermostat becomes a climate optimization system. A light bulb becomes a security system. A cow becomes a health-monitored asset.

IoT in one sentence: An embedded system + connectivity + cloud intelligence = a device that can sense, communicate, and act on the physical world without human intervention.

The evolution happened in three waves:

EraNameWhat ChangedExample
1990s-2005M2M (Machine-to-Machine)Point-to-point connections, proprietary protocolsVending machine reports stock via GSM
2005-2018IoTIP-based networking, cloud platforms, open standardsSmart home with WiFi sensors + AWS backend
2018-presentAIoT (AI + IoT)Edge ML, predictive analytics, autonomous decisionsFactory robot predicts own bearing failure

Each domain has its own device types, protocols, cloud services, and constraints. A heart monitor has very different requirements than a smart streetlight. Let's explore five major IoT domains.

IoT Domain Explorer

Click a domain to see its device types, protocols, and cloud services. Each domain has unique constraints.

Notice the pattern: every domain has the same four ingredients — sensors that perceive, a network that transports, a cloud that processes, and an application that acts. The specifics change (LoRa for agriculture, BLE for health wearables, 5G for industrial robots) but the architecture is universal.

The unifying insight: IoT is not one technology. It's an architecture pattern. The same four-layer stack (sense → connect → process → act) applies whether you're monitoring a greenhouse or a nuclear reactor. Only the component choices change.
What distinguishes AIoT from traditional IoT?

Chapter 1: IoT Architecture Stack

Every IoT system, from a $5 soil sensor to a billion-dollar smart grid, is built from the same four layers. Understanding these layers is the skeleton key to designing any IoT solution.

The four-layer IoT architecture:

Layer 1: Perception
Sensors + actuators. The physical interface. Measures temperature, pressure, motion. Controls valves, motors, LEDs.
Layer 2: Network
Connectivity. Moves data from device to cloud. WiFi, BLE, LoRaWAN, Cellular, Zigbee, Thread.
Layer 3: Platform
Cloud processing. Ingests, stores, analyzes, routes. Azure IoT Hub, AWS IoT Core, Google Cloud IoT.
Layer 4: Application
User-facing. Dashboards, alerts, automation rules, mobile apps, APIs for third-party integrations.

Let's trace a concrete path through all four layers. Imagine a greenhouse monitoring system:

LayerComponentRoleData Shape
PerceptionBME280 sensorMeasures temp, humidity, pressure3 floats, 12 bytes
PerceptionESP32 MCUReads sensor via I2C, runs firmwareJSON payload ~64 bytes
NetworkWiFi (802.11n)Sends MQTT packet to broker~128 bytes with headers
PlatformAzure IoT HubReceives, authenticates, routesMessage enters routing pipeline
PlatformStream AnalyticsReal-time aggregation + alertingWindowed averages, threshold triggers
PlatformCosmos DBTime-series storageJSON documents, partitioned by device
ApplicationPower BI dashboardVisualization for greenhouse operatorCharts, maps, alert panels
ApplicationAzure FunctionsTriggers irrigation if humidity < 40%HTTP call to actuator endpoint
The actual MQTT payload from that BME280 path:
json
{
  "deviceId": "greenhouse-01",
  "timestamp": "2026-05-16T10:30:00Z",
  "temperature": 24.6,
  "humidity": 38.2,
  "pressure": 1013.25
}

At each layer, you make choices. Those choices cascade. Picking LoRaWAN at Layer 2 means your payload is limited to 51-222 bytes — you can't send raw images. Picking BLE means your range is ~100m — you need a gateway for anything larger than a room.

Architecture Builder

Select one component at each layer to build a complete IoT path. Watch the assembled pipeline and see constraints.

Design principle: Start from the constraints, not the features. Battery life, range, payload size, latency requirement, cost per unit — these FORCE your layer choices. A $2 budget eliminates cellular. A 10-year battery life eliminates WiFi. A 50ms latency requirement eliminates LoRaWAN.
You need to monitor 500 cattle across 10,000 acres with GPS collars that last 5 years on battery. Which network layer is most appropriate?

Chapter 2: Sensors & Edge Processing

A sensor converts a physical quantity into an electrical signal. That signal gets digitized by an ADC (Analog-to-Digital Converter), processed by a microcontroller, and packaged for transmission. Every IoT system starts here — at the physical interface between the digital and analog worlds.

Sensor categories by what they measure:

CategorySensorsOutputInterfacePower
EnvironmentalBME280, SHT40, BMP390Temp, humidity, pressureI2C / SPI~3.6 μA
MotionMPU6050, LSM6DSO, BMI270Accel (g), gyro (dps)I2C / SPI~0.5 mA
Locationu-blox NEO-M9N, DW3000 (UWB)Lat/lon/alt or distanceUART / SPI~25 mA (GPS)
ChemicalSCD41 (CO2), pH probe, MQ-seriesppm, pH, resistance ratioI2C / Analog~20 mA (active)
OpticalOPT3001 (lux), MAX30102 (SpO2)Light intensity, heart rateI2C~0.4 mA

But here's the critical insight: you almost never want to send raw sensor data to the cloud.

The bandwidth problem: 100 sensors × 10 readings/sec × 32 bytes/reading = 32,000 bytes/sec = 32 KB/s raw. Over a day, that's 2.76 GB. Over cellular, that costs ~$30/day. Over LoRa, it's physically impossible (max ~300 bytes/sec).

The solution is edge processing — compute at the device or gateway level before transmitting. This is where the "intelligence" in AIoT lives.

Edge processing strategies:

StrategyWhat It DoesBandwidth Reduction
AggregationSend min/max/mean per minute instead of raw600×
Delta encodingOnly send when value changes by > threshold10-100×
Edge inferenceRun ML model locally, send only anomalies1000×+
CompressionLZ4 or delta + Huffman on time series3-8×

Worked example — let's calculate the edge vs cloud tradeoff:

Raw: 100 sensors × 10 Hz × 32 B = 32,000 B/s = 32 KB/s
Edge (1-min aggregation, 3 stats): 100 × (1/60) × 3 × 32 B = 160 B/s
Reduction factor: 32,000 / 160 = 200×

If we also apply delta encoding (only report if temp changed by >0.5°C), we might only send 1 in 3 intervals:

Final: 160 / 3 ≈ 53 B/s → 600× reduction from raw
Edge vs Cloud decision framework:
Choose edge when: low latency required (<100ms), bandwidth is expensive/limited, privacy-sensitive data (video, health), deterministic response needed.
Choose cloud when: complex ML models (>50MB), cross-device correlation needed, historical analysis, visualization dashboards, firmware updates.
Edge vs Cloud Data Calculator

Adjust sensor count and sampling rate. See raw bandwidth vs edge-processed bandwidth. The green zone shows what fits in LoRa; yellow in WiFi; red exceeds typical cellular budgets.

Sensors 100
Sample Rate (Hz) 10
python
# Edge aggregation on ESP32 (MicroPython)
import time
from machine import I2C, Pin
from bme280 import BME280

i2c = I2C(0, scl=Pin(22), sda=Pin(21))
sensor = BME280(i2c=i2c)

class EdgeAggregator:
    def __init__(self, window_sec=60, threshold=0.5):
        self.window = window_sec
        self.threshold = threshold
        self.buffer = []
        self.last_sent = None

    def add_reading(self, temp, hum, pres):
        self.buffer.append((temp, hum, pres))

    def should_send(self):
        if not self.buffer:
            return False
        avg_t = sum(r[0] for r in self.buffer) / len(self.buffer)
        if self.last_sent is None:
            return True
        return abs(avg_t - self.last_sent) > self.threshold

    def get_aggregate(self):
        """Returns {min, max, mean} for each channel."""
        temps = [r[0] for r in self.buffer]
        result = {
            "temp_min": min(temps),
            "temp_max": max(temps),
            "temp_mean": sum(temps) / len(temps),
        }
        self.last_sent = result["temp_mean"]
        self.buffer = []
        return result
You have 200 temperature sensors sampling at 5 Hz (32 bytes per reading). With 1-minute edge aggregation (sending min/max/mean), what's the approximate bandwidth reduction?

Chapter 3: Connectivity & MQTT

Your sensor has a reading. Now it needs to get that reading to the cloud. The choice of connectivity technology is the most consequential architectural decision in IoT — it determines battery life, range, cost, and what data you can realistically transmit.

TechnologyRangeBandwidthPowerCost/deviceBest For
WiFi (802.11)~50m indoor10-100 MbpsHigh (~100mA)$2-5Home, building, AC-powered
BLE (Bluetooth 5)~100m2 MbpsLow (~10μA sleep)$1-3Wearables, beacons, health
LoRaWAN2-15 km0.3-50 kbpsUltra-low$5-10Agriculture, utilities, tracking
Cellular (4G/5G)Nationwide10-1000 MbpsHigh$10-30 + planVehicles, cameras, high-value assets
Zigbee/Thread~100m (mesh)250 kbpsLow$2-5Smart home, lighting, HVAC
NB-IoTNationwide~100 kbpsLow$5-15 + planMeters, trackers, infrequent data

Once you've chosen how to connect, you need a protocol to structure the conversation. For IoT, that protocol is almost always MQTT (Message Queuing Telemetry Transport).

Why MQTT dominates IoT: It was designed in 1999 for oil pipeline monitoring over satellite links — unreliable networks, limited bandwidth, constrained devices. Every IoT platform (Azure, AWS, Google Cloud) uses MQTT as the primary device protocol.

MQTT uses a publish/subscribe model. This is fundamentally different from HTTP's request/response:

ConceptWhat It MeansExample
BrokerCentral server that routes all messagesAzure IoT Hub, Mosquitto, HiveMQ
PublisherDevice that sends dataTemperature sensor publishes readings
SubscriberClient that receives data it cares aboutDashboard subscribes to all farm sensors
TopicHierarchical address for messagesfarm/field1/moisture
QoSDelivery guarantee level0, 1, or 2 (see below)

MQTT Topics are hierarchical strings separated by /. They support wildcards:

mqtt topics
# Specific sensor
farm/field1/moisture

# All sensors in field1 (+ = single level wildcard)
farm/field1/+

# All sensors in all fields (# = multi-level wildcard)
farm/#

# Real-world Azure IoT Hub topic format
devices/{device-id}/messages/events/

QoS Levels — the trade-off between reliability and overhead:

QoSNameGuaranteePacketsUse Case
0At most onceFire-and-forget, may be lost1 (PUBLISH)Frequent telemetry (temp every 5s)
1At least onceDelivered, may duplicate2 (PUBLISH + PUBACK)Important events (door opened)
2Exactly onceDelivered exactly once4 (handshake)Critical commands (medication dose)
MQTT packet format (CONNECT): Fixed header (1 byte type + flags, 1-4 bytes remaining length) + Variable header (protocol name, version, connect flags, keep-alive) + Payload (client ID, will topic, username, password). A minimal CONNECT is ~20 bytes. Compare to an HTTP request header at ~400+ bytes.
MQTT Message Flow

Click "Publish" to send a message. Watch it route through the broker to all matching subscribers. Change QoS to see the acknowledgment handshake.

python
# MQTT publish with Paho client (the standard Python MQTT library)
import paho.mqtt.client as mqtt
import json, time

def on_connect(client, userdata, flags, rc):
    print(f"Connected with result code {rc}")
    client.subscribe("farm/+/moisture", qos=1)

def on_message(client, userdata, msg):
    data = json.loads(msg.payload)
    print(f"{msg.topic}: moisture={data['value']}%")

client = mqtt.Client(client_id="gateway-01")
client.tls_set()  # Enable TLS encryption
client.username_pw_set("user", "password")
client.on_connect = on_connect
client.on_message = on_message

client.connect("your-hub.azure-devices.net", 8883)
client.loop_start()

# Publish sensor data
payload = json.dumps({"value": 42.5, "unit": "%"})
client.publish("farm/field1/moisture", payload, qos=1)
A hospital needs to send medication dosage commands to an infusion pump. Which MQTT QoS level should they use?

Chapter 4: Azure IoT Architecture

Your sensor published a message. It left the device over WiFi, became an MQTT packet, and hit the cloud. Now what? The cloud platform is where raw telemetry becomes actionable intelligence. We'll use Azure IoT as our reference architecture — the concepts map directly to AWS IoT Core and Google Cloud IoT.

The core Azure IoT services form a pipeline:

IoT Hub
Device registry, message ingestion, bidirectional communication, device twins. The front door.
Stream Analytics
Real-time SQL queries over streaming data. Windowed aggregations, anomaly detection, pattern matching.
Cosmos DB / ADX
Storage. Cosmos for low-latency key-value, Azure Data Explorer for time-series analytics.
Azure Functions
Serverless compute. Triggered by events (threshold exceeded, new device, schedule).
Power BI / Grafana
Dashboards. Real-time visualization with drill-down and alerting.

IoT Hub is the most critical component. It handles:

FeatureWhat It DoesWhy It Matters
Device RegistryStores identity + auth for each deviceYou know exactly which devices are authorized
Message RoutingRoutes messages to different endpoints by contentTemperature alerts go to Functions; all data goes to storage
Device TwinsJSON document per device: desired state + reported stateConfigure devices remotely without custom protocol
Direct MethodsSynchronous RPC calls to devices"Reboot now" or "take a photo" with response
DPS (Provisioning)Zero-touch enrollment of new devicesShip 10,000 devices; they self-register on first boot
Device Twin — the killer feature: A Device Twin is a JSON document that lives in the cloud and syncs with the device. It has two sections: desired (what the cloud wants) and reported (what the device says its state is). Change desired.temperature_threshold to 30, and the device automatically receives the update and adjusts.
json
// Device Twin for greenhouse-01
{
  "deviceId": "greenhouse-01",
  "properties": {
    "desired": {
      "telemetryInterval": 60,
      "temperatureThreshold": 30,
      "firmwareVersion": "2.1.0"
    },
    "reported": {
      "telemetryInterval": 60,
      "temperatureThreshold": 30,
      "firmwareVersion": "2.0.3",
      "battery": 78,
      "lastBoot": "2026-05-16T08:00:00Z"
    }
  }
}

Notice: the desired firmware is 2.1.0 but reported is 2.0.3. The device sees this mismatch and initiates an OTA update. No human intervention required.

Stream Analytics query — detect temperature spikes in real-time:

sql
-- Alert when any device exceeds threshold for 5 minutes
SELECT
    deviceId,
    AVG(temperature) AS avg_temp,
    MAX(temperature) AS max_temp,
    System.Timestamp() AS window_end
INTO
    alertOutput
FROM
    iothub TIMESTAMP BY EventEnqueuedUtcTime
GROUP BY
    deviceId,
    TumblingWindow(minute, 5)
HAVING
    AVG(temperature) > 30
Azure IoT Pipeline

Watch telemetry flow from device through IoT Hub to analytics. Click "Send Alert" to trigger a threshold breach and see the alert path activate.

python
# Register device and send telemetry with Azure IoT SDK
from azure.iot.device import IoTHubDeviceClient, Message
import json

# Connection string from Azure Portal > IoT Hub > Device
conn_str = "HostName=myhub.azure-devices.net;DeviceId=greenhouse-01;SharedAccessKey=..."

client = IoTHubDeviceClient.create_from_connection_string(conn_str)
client.connect()

# Send telemetry
payload = json.dumps({
    "temperature": 24.6,
    "humidity": 38.2
})
msg = Message(payload)
msg.content_type = "application/json"
msg.content_encoding = "utf-8"
msg.custom_properties["alert"] = "false"

client.send_message(msg)
print("Telemetry sent")

# Listen for Device Twin updates (desired properties)
def twin_patch_handler(patch):
    print(f"Received twin patch: {patch}")
    if "telemetryInterval" in patch:
        # Adjust our sending rate
        global INTERVAL
        INTERVAL = patch["telemetryInterval"]

client.on_twin_desired_properties_patch_received = twin_patch_handler
You want to remotely change the sampling rate of 1,000 deployed sensors without sending individual commands to each. Which Azure IoT feature achieves this?

Chapter 5: Device Programming

You've designed the architecture. Now you need to actually write the firmware that runs on the microcontroller. This is embedded programming — writing software for devices with 256KB of RAM, no operating system (or a minimal RTOS), and the need to run for years on a coin cell battery.

Framework choices for IoT device programming:

FrameworkLanguageTarget MCUsComplexityBest For
ArduinoC++ (simplified)AVR, ESP32, nRF52LowPrototyping, hobby, education
ESP-IDFCESP32 familyMedium-HighProduction ESP32 products
Zephyr RTOSC500+ boardsHighCommercial products, multi-vendor
Mbed OSC++ARM Cortex-MMediumARM ecosystem products
MicroPythonPythonESP32, RP2040LowRapid prototyping, scripts

The fundamental embedded programming loop is deceptively simple:

1. Initialize
Configure GPIO, I2C, SPI, WiFi. One-time setup.
2. Read sensors
Poll or interrupt-driven. Convert ADC values to physical units.
3. Process
Edge aggregation, filtering, anomaly detection.
4. Transmit
MQTT publish over WiFi/LoRa/BLE.
5. Sleep
Deep sleep to save power. Wake on timer or interrupt.
↻ repeat
Power budget reality: An ESP32 draws ~240mA when WiFi is active. A 3000mAh battery would last 12.5 hours. But in deep sleep it draws ~10μA — the same battery lasts 34 YEARS. The key is: wake, measure, transmit, sleep. Minimize awake time.

WiFi Provisioning — how does a headless device (no screen, no keyboard) connect to your WiFi network for the first time?

MethodHow It WorksUX Quality
HardcodedSSID/password in firmwareTerrible (can't change network)
SmartConfigPhone broadcasts credentials via WiFi packet timingFragile (doesn't work on 5GHz)
BLE ProvisioningPhone connects via BLE, sends WiFi credentialsExcellent (industry standard)
AP ModeDevice creates hotspot, phone connects and configuresGood (no BLE hardware needed)

OTA (Over-The-Air) Updates — critical for any deployed fleet. You cannot physically visit 10,000 sensors to update firmware.

OTA architecture: Device checks for updates periodically (via Device Twin or HTTP endpoint). If new version available: download to OTA partition → verify SHA256 hash → set boot partition → reboot → self-test → if test fails, rollback to previous partition. Two-partition scheme ensures you never brick a device.
c
// ESP-IDF: Complete IoT device firmware skeleton
// Connects to WiFi, publishes BME280 data via MQTT to Azure IoT Hub

#include "esp_wifi.h"
#include "esp_event.h"
#include "mqtt_client.h"
#include "esp_sleep.h"
#include "driver/i2c.h"

#define SLEEP_DURATION_US  (60 * 1000000)  // 60 seconds
#define MQTT_BROKER        "mqtts://myhub.azure-devices.net:8883"
#define MQTT_TOPIC         "devices/sensor-01/messages/events/"

static esp_mqtt_client_handle_t mqtt_client;

void wifi_init(void) {
    esp_netif_init();
    esp_event_loop_create_default();
    esp_netif_create_default_wifi_sta();

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    esp_wifi_init(&cfg);

    wifi_config_t wifi_config = {
        .sta = { .ssid = "MyNetwork", .password = "MyPassword" }
    };
    esp_wifi_set_mode(WIFI_MODE_STA);
    esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
    esp_wifi_start();
    esp_wifi_connect();
}

void mqtt_publish_telemetry(float temp, float hum) {
    char payload[128];
    snprintf(payload, sizeof(payload),
        "{\"temperature\":%.1f,\"humidity\":%.1f}", temp, hum);

    esp_mqtt_client_publish(mqtt_client, MQTT_TOPIC,
        payload, 0, 1, 0);  // QoS 1
}

void app_main(void) {
    wifi_init();
    // ... wait for connection ...

    esp_mqtt_client_config_t mqtt_cfg = {
        .broker.address.uri = MQTT_BROKER,
        .credentials.authentication.certificate = device_cert,
    };
    mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
    esp_mqtt_client_start(mqtt_client);

    // Read sensor
    float temp = bme280_read_temperature();
    float hum = bme280_read_humidity();

    // Publish
    mqtt_publish_telemetry(temp, hum);

    // Deep sleep
    esp_deep_sleep(SLEEP_DURATION_US);
}
Device Lifecycle Simulator

Watch an ESP32's power states cycle: boot → WiFi connect → MQTT publish → deep sleep. The bar shows current draw at each phase. See how sleep dominates the duty cycle.

An ESP32 draws 240mA during WiFi transmission and 10μA in deep sleep. If it wakes for 2 seconds every 60 seconds, what's the average current?

Chapter 6: Smart Agriculture System [SHOWCASE]

Everything comes together now. We'll simulate a complete smart agriculture irrigation system end-to-end: soil moisture sensors in the field, LoRa radio to a gateway, MQTT to Azure IoT Hub, Stream Analytics for decision-making, and an irrigation valve that opens automatically when the soil is too dry.

The architecture:

Soil Sensor (capacitive)
Measures volumetric water content: 0% (bone dry) to 50% (saturated)
↓ LoRa (868 MHz, SF7, 5.4 kbps)
LoRa Gateway
Receives from up to 1000 end devices. Forwards via Ethernet/4G to cloud.
↓ MQTT over TLS (port 8883)
Azure IoT Hub
Authenticates device, routes message to Stream Analytics.
↓ Event routing
Stream Analytics
Rule: IF avg(moisture) < 25% for 10 min THEN trigger irrigation.
↓ Azure Function call
Irrigation Controller
Solenoid valve opens. Water flows for calculated duration.
Latency budget for this system: Sensor read (2ms) + LoRa TX (50ms) + Gateway processing (10ms) + Internet transit (80ms) + IoT Hub routing (50ms) + Analytics window (10 min) + Function execution (200ms) + Valve actuation (500ms) = ~10 minutes from dry soil to water flowing. For agriculture, this is fine — plants don't die in 10 minutes.
Full System Simulation

Adjust rain level (left slider) to change soil moisture. Watch the entire pipeline react: sensor reads → LoRa packet → cloud processing → irrigation decision. Toggle failures to see graceful degradation.

Rain Level 50%
Irrigation Threshold 25%

What happens when the gateway goes offline? The sensor node stores readings in flash memory (up to 72 hours of data at 1-minute intervals = 4,320 readings × 8 bytes = 34 KB). When the gateway comes back, the node replays stored data with timestamps. The cloud sees the gap and processes the backlog. This is store-and-forward — a critical IoT resilience pattern.

What happens when the cloud goes down? The gateway itself has a local rule engine: "if latest moisture < 20%, open valve." This is edge fallback — the system degrades gracefully from "smart" (cloud analytics with historical context) to "functional" (simple threshold at the gateway).

Design principle — graceful degradation: An IoT system should NEVER have a single point of failure that makes physical systems stop working. Cloud down? Gateway takes over. Gateway down? Device stores data. Device battery dying? Send one final "battery critical" message. Every layer has a fallback.
The gateway is offline for 2 hours. When it reconnects, what happens to the sensor data from that period?

Chapter 7: Security & Privacy

In October 2016, the Mirai botnet enslaved 600,000 IoT devices (cameras, routers, DVRs) and used them to launch the largest DDoS attack in history, taking down Twitter, Netflix, Reddit, and GitHub for hours. The devices were compromised because they used default passwords like "admin/admin" and had no mechanism for firmware updates.

IoT security is not optional. It's existential. A compromised insulin pump can kill a patient. A hijacked traffic controller can cause accidents. A breached smart lock lets burglars in.

Why IoT security is harder than web security: Devices are physically accessible (attackers can probe hardware), run for 10+ years without updates, have limited CPU/RAM for encryption, and often ship with development credentials. You're defending thousands of attack surfaces with the computational budget of a calculator.

The OWASP IoT Top 10 (2024) — the most critical IoT vulnerabilities:

#VulnerabilityReal AttackDefense
1Weak/hardcoded passwordsMirai botnet (default creds)Unique per-device credentials, no defaults
2Insecure network servicesOpen Telnet/SSH on camerasDisable unused ports, firewall
3Insecure ecosystem interfacesUnauthed cloud API exposes all devicesOAuth2, API keys, rate limiting
4Lack of secure update mechanismNo OTA = unpatched foreverSigned OTA with rollback
5Insecure/outdated componentsOpenSSL Heartbleed in camera firmwareSBOM tracking, auto-update deps
6Insufficient privacy protectionSmart speaker recordings leakedEdge processing, data minimization
7Insecure data transferUnencrypted MQTT sniffed on WiFiTLS 1.3, certificate pinning
8Lack of device managementNo way to revoke compromised deviceDevice registry with revocation
9Insecure default settingsUPnP enabled by default on routersSecure by default, opt-in features
10Lack of physical hardeningJTAG debug port left accessibleDisable debug, fuse eFuse bits

Defense layers for a secure IoT deployment:

LayerMechanismWhat It Prevents
TransportTLS 1.3 / mTLSEavesdropping, man-in-the-middle
IdentityX.509 certificates (per-device)Device impersonation
BootSecure Boot (signature verification)Firmware tampering
StorageEncrypted flash (AES-256)Physical extraction of secrets
UpdateSigned OTA with hash verificationMalicious firmware injection
RuntimeAttestation (TPM/secure enclave)Runtime code modification
NetworkNetwork segmentation (VLAN/firewall)Lateral movement after breach
mTLS (mutual TLS) explained: Normal TLS: the client verifies the server (your browser checks that google.com's certificate is valid). mTLS: BOTH sides verify each other. The device proves its identity to the cloud, AND the cloud proves its identity to the device. In Azure IoT Hub, each device has a unique X.509 certificate enrolled in the device registry. A stolen certificate can be individually revoked without affecting other devices.

Privacy — GDPR and IoT:

Under GDPR (and similar regulations worldwide), IoT data that can identify a person is personal data. A smart meter's consumption pattern reveals when you're home, when you sleep, what appliances you use. A fitness tracker knows your heart rate, location, and sleep quality.

Privacy by design principles for IoT:
1. Data minimization: Only collect what you need. Don't send GPS coordinates if you only need "is the device in zone A or B?"
2. Edge processing: Process video/audio on-device, send only metadata (person count, not face images).
3. Purpose limitation: Data collected for energy optimization cannot be sold to advertisers.
4. Retention limits: Auto-delete raw data after aggregation period (e.g., 30 days).
Attack & Defense Matrix

Select an attack type to see which defenses mitigate it. Green = effective defense, red = vulnerable, yellow = partial protection.

An attacker captures MQTT packets from a device and replays them later to trigger false irrigation. Which defense specifically prevents replay attacks?

Chapter 8: 5G & Future Applications

4G gave us fast phones. 5G gives us a programmable network fabric for machines. The difference isn't just speed — it's three fundamentally different service types designed for three different use cases, all running simultaneously on the same physical infrastructure.

The three 5G service categories:

CategoryFull NameKey MetricIoT Application
eMBBEnhanced Mobile Broadband20 Gbps peakAR/VR, 4K video analytics, digital twins
URLLCUltra-Reliable Low Latency<1ms, 99.999% reliableRemote surgery, autonomous vehicles, industrial robots
mMTCMassive Machine-Type Comms1 million devices/km²Smart city sensors, agriculture, meters
The revolution is network slicing: A hospital can lease a URLLC slice (guaranteed <1ms latency) for remote surgery, while the city runs an mMTC slice (1M devices/km²) for parking sensors, and a stadium uses an eMBB slice (20 Gbps) for AR overlays — all on the same tower, completely isolated from each other. It's like having three separate physical networks, but virtualized.

5G-enabled IoT applications that were impossible before:

ApplicationWhy 5G Enables ItPrevious Limitation
Remote surgeryURLLC: <1ms haptic feedback4G: 30-50ms = surgeon feels lag = dangerous
Autonomous vehiclesURLLC: V2X communication at 200km/hWiFi: range too short, 4G: latency too high for safety
Smart city (dense)mMTC: 1M sensors per km²4G: ~100K devices/cell = congestion collapse
Precision agriculturemMTC: thousands of sensors per fieldLoRa: works but limited to 300 bytes/message
Digital twinseMBB: real-time 3D model streaming4G: insufficient bandwidth for point clouds
Smart gridURLLC + mMTC: instant fault detection across millions of nodesDedicated fiber = $$$, 4G = too slow for fault isolation

Concrete example: smart city air quality network

Imagine deploying 10,000 air quality sensors (PM2.5, NO2, O3) across a city of 500 km². That's 20 sensors per km². Each reports every 5 minutes. With 5G mMTC:

10,000 devices × (1 message / 5 min) = 33 messages/sec
Each message: 64 bytes × 33 = 2.1 KB/s total network load
5G mMTC capacity: 1,000,000 devices/km² → we're using 0.002% of capacity

The real value isn't raw capacity — it's the connection density. 10,000 devices can all be simultaneously connected without channel contention, sleeping most of the time, waking only to send their 64-byte payload.

5G Slice Comparison

Click each 5G category to see its latency, bandwidth, and device density characteristics visualized. Compare how the same physical network serves radically different needs.

5G vs LoRaWAN for IoT — when to use which:
LoRaWAN wins when: ultra-low cost (<$5/device), 10-year battery, rural areas without 5G coverage, very small payloads (<200 bytes).
5G mMTC wins when: urban deployment with existing coverage, need more bandwidth (>1KB), firmware OTA over cellular, carrier-grade SLA required.
A hospital wants to offer remote robotic surgery where a surgeon in New York operates on a patient in rural Texas. Which 5G category is essential?

Chapter 9: Mastery & Connections

You now understand the complete IoT stack: from sensor physics to cloud architecture, from MQTT packets to 5G network slicing, from edge processing to security hardening. Let's consolidate with decision frameworks you can use in real system design.

Protocol Selection Matrix — the cheat sheet for every IoT architect:

RequirementWiFiBLELoRaWANCellularThread/Zigbee
Range > 1kmNoNoYes (15km)YesNo
Battery > 5yrNoMaybeYesNoYes
Payload > 1KBYesYesNo (222B max)YesLimited
Latency < 100msYesYesNo (seconds)YesYes
Cost < $3YesYesBorderlineNoYes
No infrastructureRouter neededPhone neededGatewayTower existsCoordinator

IoT Security Deployment Checklist:

Before shipping any IoT device:
□ Unique credentials per device (no shared secrets)
□ TLS 1.3 for all cloud communication
□ Secure Boot enabled (signed firmware only)
□ OTA update mechanism with rollback
□ Debug ports (JTAG/UART) disabled in production
□ Encrypted credential storage (eFuse or secure element)
□ Device can be remotely revoked/decommissioned
□ SBOM (Software Bill of Materials) documented
□ Penetration test completed
□ GDPR data processing agreement in place (if EU)

Power Budget Calculator — will your battery last?

Battery Life (hours) = Battery Capacity (mAh) / Average Current (mA)
Average Current = (Iactive × tactive + Isleep × tsleep) / (tactive + tsleep)

Example: ESP32 with 3000mAh battery, wakes 2s every 5 min:

Iavg = (240mA × 2s + 0.01mA × 298s) / 300s = 1.61 mA
Life = 3000 / 1.61 = 1,863 hours = 77 days

To reach 1 year: either sleep longer (wake every 30 min = 465 days) or use LoRa (TX at 40mA for 100ms = 2+ years).

U.S. IoT Security Legislation:

LawYearScopeKey Requirements
California SB-3272020All IoT sold in CAUnique passwords, security appropriate to device function
Oregon HB 23952020All IoT sold in ORMirrors CA SB-327 requirements
IoT Cybersecurity Act2020US federal procurementNIST compliance for government IoT purchases
NIST IR 82592020Guidelines (voluntary)Baseline capabilities: ID, config, data protection, update
EU Cyber Resilience Act2024All digital products in EUSecurity by design, 5-year update support, SBOM required
The trend is clear: IoT security is moving from "nice to have" to legally mandated. The EU Cyber Resilience Act (2024) requires ALL connected products to provide security updates for 5 years, disclose vulnerabilities within 24 hours, and include a Software Bill of Materials. Non-compliance: fines up to 15M EUR or 2.5% of global revenue.

Design Challenge: Design a city-wide air quality monitoring network for a city of 2 million people, 800 km².

Your design decisions:
Sensor: SPS30 (PM2.5/PM10) + SCD41 (CO2) + NO2 electrochemical = $45/node
Density: 1 sensor per 500m grid = 3,200 nodes
Connectivity: LoRaWAN (low cost, outdoor range 5km, 1 gateway covers 50 nodes)
Gateways: 3,200/50 = 64 gateways, connected via 4G backhaul
Cloud: Azure IoT Hub (Standard S1: $25/month for 400K messages/day = sufficient)
Analytics: Stream Analytics for real-time AQI calculation + alerting
Dashboard: Power BI embedded in city portal + citizen mobile app
Total cost: ~$200K hardware + $500/month cloud = $206K year 1
Power Budget & Battery Life Calculator

Adjust active current, sleep current, duty cycle, and battery capacity. See projected battery life in real-time.

Active Current (mA) 240
Wake Duration (sec) 2
Sleep Duration (min) 5
Battery (mAh) 3000

Connections:

Want to Learn More About...Go To
Real-time operating systems for embeddedRTOS & Scheduling (coming soon)
Machine learning at the edgeTransformers (attention for sequence data)
Sensor fusion algorithmsKalman Filter (optimal state estimation)
Decision-making under uncertaintyMDPs (Markov Decision Processes)
Reinforcement learning for controlRL Algorithms (policy optimization)
"The best IoT system is one that disappears." — Mark Weiser, 1991. The goal isn't to build impressive technology. It's to solve a physical-world problem so seamlessly that users forget the technology exists. The thermostat that just works. The field that waters itself. The city that breathes clean air. That's IoT done right.
You're designing a livestock tracker for 500 cattle across 10,000 acres. You need GPS position every 10 minutes, 5-year battery life, and $10/device budget. Which connectivity is best?