IoT Tutorial: Learn Internet of Things from Scratch (2026)
The Internet of Things (IoT) connects physical devices to the digital world, enabling sensing, actuation, and data-driven automation. Having built IoT systems spanning smart agriculture, industrial monitoring, and home automation, I have navigated the unique challenges of constrained devices, unreliable networks, and real-time processing. This tutorial covers the IoT stack from sensors and microcontrollers to cloud platforms and data analytics.
We will explore communication protocols (MQTT, CoAP, LoRaWAN), edge vs cloud processing, device management, security considerations, and the architectural patterns that make IoT systems reliable and scalable. Practical examples use ESP32 microcontrollers and AWS IoT Core.
IoT Architecture: Devices, Gateways, and Cloud
A typical IoT architecture has three tiers: devices (sensors and actuators with microcontrollers), gateways (aggregating device data and providing local processing), and the cloud (storage, analytics, and application logic). Devices are often resource-constrained — limited memory, battery power, and processing — running real-time operating systems (FreeRTOS, Zephyr) or bare-metal firmware. Gateways bridge different protocols (Zigbee to Wi-Fi) and perform edge computing (filtering, aggregation, ML inference). The cloud provides long-term storage, dashboards, and integration with enterprise systems.
# ESP32 sketch: reading a temperature sensor and publishing to MQTT
#include
#include
#include
#define DHTPIN 4
#define DHTTYPE DHT11
WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(DHTPIN, DHTTYPE);
void setup() {
WiFi.begin("SSID", "PASSWORD");
while (WiFi.status() != WL_CONNECTED) delay(500);
client.setServer("mqtt.example.com", 1883);
dht.begin();
}
void loop() {
if (!client.connected()) client.connect("esp32-sensor");
float temp = dht.readTemperature();
float hum = dht.readHumidity();
char payload[64];
snprintf(payload, 64, "{\"temp\":%.1f,\"hum\":%.1f}", temp, hum);
client.publish("sensors/temperature", payload);
delay(60000);
}
IoT Communication Protocols: MQTT and CoAP
MQTT (Message Queuing Telemetry Transport) is a publish-subscribe protocol designed for constrained devices and unreliable networks. It uses a broker to route messages by topic, supports three quality-of-service levels (0: at most once, 1: at least once, 2: exactly once), and has minimal overhead (2-byte header). CoAP (Constrained Application Protocol) is an HTTP-like protocol over UDP with built-in discovery and resource observation. Both support TLS/DTLS for security. MQTT dominates cloud-connected IoT, while CoAP is common in constrained mesh networks.
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
print(f"Connected with result {rc}")
client.subscribe("sensors/#")
def on_message(client, userdata, msg):
print(f"{msg.topic}: {msg.payload.decode()}")
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("mqtt.example.com", 1883, 60)
client.loop_forever()
Edge Computing vs Cloud Processing
Edge computing processes data near the source rather than sending everything to the cloud. This reduces latency (critical for real-time control), saves bandwidth (transmitting only insights, not raw data), and works offline. Edge devices run lightweight ML models (TensorFlow Lite) for tasks like anomaly detection or object recognition. Cloud processing handles complex analytics across many devices, model training, long-term storage, and dashboards. The split depends on latency requirements, bandwidth cost, and device capabilities.
# Edge inference with TensorFlow Lite on Raspberry Pi
import tflite_runtime.interpreter as tflite
import numpy as np
from sensor import read_accelerometer
interpreter = tflite.Interpreter(model_path="anomaly_model.tflite")
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
while True:
data = read_accelerometer()
input_data = np.array([data], dtype=np.float32)
interpreter.set_tensor(input_details[0]['index'], input_data)
interpreter.invoke()
score = interpreter.get_tensor(output_details[0]['index'])[0][0]
if score > 0.9:
publish_alert("Anomaly detected", data)
else:
publish_summary(np.mean(data, axis=0))
time.sleep(1)
LoRaWAN for Long-Range Low-Power Communication
LoRaWAN (Long Range Wide Area Network) enables IoT devices to communicate over kilometers with minimal power consumption. LoRa modulation uses chirp spread spectrum to achieve long range at low data rates (0.3-50 kbps). The network uses a star-of-stars topology: end devices communicate with gateways, which forward packets to a network server. Classes define receive window behavior — Class A (lowest power, two receive windows after each uplink), Class B (scheduled receive slots), Class C (continuously listening). Duty cycle regulations limit time-on-air per frequency band.
# LoRaWAN device configuration (Arduino-compatible)
from network import LoRa
import socket
import time
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
def join_network():
app_eui = binascii.unhexlify('0000000000000000')
app_key = binascii.unhexlify('...')
lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0)
while not lora.has_joined():
time.sleep(2.5)
print("Joined LoRaWAN network")
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
while True:
moisture = read_soil_moisture()
s.send(bytes([moisture]))
time.sleep(3600)
IoT Security: Device Identity and Secure Boot
Securing IoT devices is challenging due to physical access, resource constraints, and scale. Each device needs a unique identity — typically an X.509 certificate or hardware-backed unique ID (e.g., ESP32's efuse MAC). Secure boot verifies firmware signatures before execution, preventing malicious code from running. Over-the-air (OTA) updates must verify signatures and use encrypted channels. On the cloud side, AWS IoT Core uses device certificates and IAM policies to control access. TLS mutual authentication ensures both the device and cloud verify each other's identity.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:Connect",
"Resource": "arn:aws:iot:us-east-1:123456:client/${iot:ClientId}"
},
{
"Effect": "Allow",
"Action": "iot:Publish",
"Resource": [
"arn:aws:iot:us-east-1:123456:topic/sensors/${iot:ClientId}/temperature",
"arn:aws:iot:us-east-1:123456:topic/sensors/${iot:ClientId}/humidity"
]
}
]
}
Digital Twins and Device Shadow
A digital twin is a virtual representation of a physical device that mirrors its state in the cloud. AWS IoT Device Shadow stores reported and desired states — the device reports its actual state (e.g., temperature=22.5, led=on), and applications set desired state (e.g., led=off). The device synchronizes by retrieving delta (difference between desired and reported). This pattern handles intermittent connectivity: applications interact with the shadow regardless of whether the device is online. Digital twins extend this with richer models including geometry, simulation, and lifecycle.
{
"state": {
"reported": {
"temperature": 22.5,
"humidity": 60,
"led": "on",
"battery": 85
},
"desired": {
"led": "off"
}
}
}
# Device requests delta
GET /things/my-sensor/shadow
# Response includes delta
{
"state": {
"desired": {"led": "off"},
"delta": {"led": "off"}
}
}
Frequently Asked Questions
What are the biggest challenges in IoT development?
Power management (devices must last months on batteries), connectivity reliability (recovering from network drops gracefully), security at scale (managing device credentials and updates for thousands of devices), and interoperability between protocols and vendors.
How do you choose between Wi-Fi, BLE, and LoRaWAN?
Wi-Fi for high-bandwidth indoor applications with available power. BLE for short-range, low-power devices with frequent smartphone interaction. LoRaWAN for long-range (km+), low-data-rate, battery-powered outdoor sensors with infrequent transmissions.
What is the difference between MQTT and HTTP for IoT?
MQTT is push-based (server receives data when published), has lower overhead (2-byte header), supports QoS levels, and maintains persistent connections. HTTP is pull-based (server must be polled), has higher overhead, and is stateless. MQTT is generally preferred for constrained IoT devices.
How do you handle firmware updates for devices in the field?
Over-the-air (OTA) updates use a staged approach: download to a secondary partition, verify signature, swap partitions. Delta updates minimize transfer size. Rollback mechanisms revert on failure. Fleet management services (AWS IoT Device Management, Azure IoT Hub) orchestrate campaigns across thousands of devices.
Originally published on Ayodhyyya. Last updated June 1, 2026.