18  Hands-On Labs Hub

Practical IoT Learning Through Guided Experiments

18.1 Hands-On Labs Hub

TipLearning by Doing

This hub provides structured laboratory exercises that take you from theory to practice. Each lab includes clear objectives, required materials, step-by-step instructions, and validation checkpoints.


18.2 Lab Difficulty Levels

Level Duration Prerequisites Suitable For
Beginner 30-60 min Basic programming New to IoT
Intermediate 1-2 hours Completed beginner labs Building skills
Advanced 2-4 hours Strong foundation Project preparation

18.3 Networking & Protocols Labs

18.3.1 Lab 1: Your First MQTT Message (Beginner)

Duration: 45 minutes | Difficulty: Beginner

Learning Objectives:

  • Understand publish/subscribe messaging pattern
  • Connect to an MQTT broker
  • Send and receive messages programmatically
  • Observe message flow in real-time

Materials Needed:

  • Computer with Python 3.8+
  • Internet connection
  • Text editor or IDE

Prerequisites: Basic Python knowledge

18.3.1.1 Step 1: Environment Setup (10 min)

# Install the MQTT client library
pip install paho-mqtt

# Verify installation
python -c "import paho.mqtt.client as mqtt; print('MQTT library ready!')"

18.3.1.2 Step 2: Connect to Public Broker (10 min)

Create a file called mqtt_subscriber.py:

import paho.mqtt.client as mqtt

# Callback when connected
def on_connect(client, userdata, flags, rc):
    print(f"Connected with result code {rc}")
    # Subscribe to a test topic
    client.subscribe("iotclass/lab1/temperature")

# Callback when message received
def on_message(client, userdata, msg):
    print(f"Received: {msg.topic} -> {msg.payload.decode()}")

# Create client and set callbacks
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

# Connect to public broker (test.mosquitto.org)
client.connect("test.mosquitto.org", 1883, 60)

# Start listening
print("Waiting for messages... Press Ctrl+C to stop")
client.loop_forever()
WarningCheckpoint 1

Run the subscriber: python mqtt_subscriber.py

You should see: “Connected with result code 0”

If you see a different code, check your internet connection.

18.3.1.3 Step 3: Publish Messages (15 min)

Create a file called mqtt_publisher.py:

import paho.mqtt.client as mqtt
import time
import random

client = mqtt.Client()
client.connect("test.mosquitto.org", 1883, 60)

# Simulate temperature readings
for i in range(5):
    temperature = round(20 + random.uniform(-5, 10), 1)
    message = f"{temperature}C"

    client.publish("iotclass/lab1/temperature", message)
    print(f"Published: {message}")
    time.sleep(2)

client.disconnect()
print("Done!")
WarningCheckpoint 2

With subscriber running in one terminal, run publisher in another:

python mqtt_publisher.py

You should see messages appear in the subscriber terminal.

18.3.1.4 Step 4: Experiment (10 min)

Try these modifications:

  1. Change the topic: Use iotclass/lab1/yourname/temperature
  2. Add QoS: Modify publish to use qos=1 for guaranteed delivery
  3. JSON payload: Send {"temp": 25.5, "unit": "C"} instead of plain text

18.3.1.5 Lab Validation

TipSuccess Criteria

You have completed this lab when you can:

18.3.1.6 What’s Next?


18.3.2 Lab 2: Sensor Data Pipeline (Intermediate)

Duration: 90 minutes | Difficulty: Intermediate

Learning Objectives:

  • Build end-to-end data pipeline: Sensor -> MQTT -> Database -> Dashboard
  • Store time-series data in InfluxDB
  • Create real-time visualizations with Grafana
  • Understand data flow in IoT architectures

Materials Needed:

  • Docker installed on your computer
  • Completed Lab 1
  • 2GB free disk space

Prerequisites: Lab 1, basic Docker knowledge helpful

18.3.2.1 Step 1: Start Infrastructure (15 min)

Create docker-compose.yml:

version: '3'
services:
  mosquitto:
    image: eclipse-mosquitto:2
    ports:
      - "1883:1883"
    volumes:
      - ./mosquitto.conf:/mosquitto/config/mosquitto.conf

  influxdb:
    image: influxdb:2.7
    ports:
      - "8086:8086"
    environment:
      - DOCKER_INFLUXDB_INIT_MODE=setup
      - DOCKER_INFLUXDB_INIT_USERNAME=admin
      - DOCKER_INFLUXDB_INIT_PASSWORD=adminpassword
      - DOCKER_INFLUXDB_INIT_ORG=iotclass
      - DOCKER_INFLUXDB_INIT_BUCKET=sensors

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    depends_on:
      - influxdb

Create mosquitto.conf:

listener 1883
allow_anonymous true

Start the stack:

docker-compose up -d
WarningCheckpoint 1

Verify all services are running:

docker-compose ps

All three services should show “Up” status.

18.3.2.2 Step 2: Bridge MQTT to InfluxDB (20 min)

Create mqtt_to_influx.py:

import paho.mqtt.client as mqtt
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS
import json

# InfluxDB connection
influx_client = InfluxDBClient(
    url="http://localhost:8086",
    token="your-token-here",  # Get from InfluxDB UI
    org="iotclass"
)
write_api = influx_client.write_api(write_options=SYNCHRONOUS)

def on_message(client, userdata, msg):
    try:
        # Parse JSON payload
        data = json.loads(msg.payload.decode())

        # Create InfluxDB point
        point = Point("sensor_reading") \
            .tag("sensor", msg.topic.split("/")[-1]) \
            .field("temperature", float(data.get("temp", 0))) \
            .field("humidity", float(data.get("humidity", 0)))

        # Write to InfluxDB
        write_api.write(bucket="sensors", record=point)
        print(f"Stored: {data}")

    except Exception as e:
        print(f"Error: {e}")

# MQTT setup
mqtt_client = mqtt.Client()
mqtt_client.on_message = on_message
mqtt_client.connect("localhost", 1883)
mqtt_client.subscribe("sensors/#")

print("Bridge running... Press Ctrl+C to stop")
mqtt_client.loop_forever()

18.3.2.3 Step 3: Simulate Sensors (15 min)

Create sensor_simulator.py:

import paho.mqtt.client as mqtt
import json
import time
import random

client = mqtt.Client()
client.connect("localhost", 1883)

sensors = ["living_room", "bedroom", "kitchen"]

while True:
    for sensor in sensors:
        data = {
            "temp": round(20 + random.gauss(0, 2), 1),
            "humidity": round(50 + random.gauss(0, 5), 1)
        }
        client.publish(f"sensors/{sensor}", json.dumps(data))
        print(f"{sensor}: {data}")

    time.sleep(5)

18.3.2.4 Step 4: Configure Grafana Dashboard (30 min)

  1. Open Grafana: http://localhost:3000 (admin/admin)
  2. Add InfluxDB data source (Configuration -> Data Sources)
  3. Create new dashboard with time-series panel
  4. Query: from(bucket:"sensors") |> range(start: -1h) |> filter(fn: (r) => r._measurement == "sensor_reading")
WarningCheckpoint 2

Your Grafana dashboard should show real-time temperature and humidity readings updating every 5 seconds.

18.3.2.5 Lab Validation

TipSuccess Criteria

18.3.3 Lab 3: LoRaWAN Network Simulation (Advanced)

Duration: 2-3 hours | Difficulty: Advanced

Learning Objectives:

  • Understand LoRaWAN network architecture
  • Configure spreading factors and their impact
  • Analyze airtime and duty cycle constraints
  • Simulate multi-gateway deployments

Materials Needed:

Full lab content continues…


18.4 Sensing & Actuation Labs

18.4.1 Lab 4: Sensor Calibration Workshop (Beginner)

Build practical sensor calibration skills with temperature and humidity sensors.

Coming soon - uses Sensor Calibration Tool

18.4.2 Lab 5: PID Controller Tuning (Intermediate)

Tune a PID controller for motor speed control using the Ziegler-Nichols method.

Coming soon - uses PID Tuner Simulator


18.5 Security Labs

18.5.1 Lab 6: TLS Certificate Setup (Intermediate)

Configure TLS for secure MQTT communications.

Coming soon - uses Zero Trust Simulator

18.5.2 Lab 7: IoT Penetration Testing Basics (Advanced)

Learn ethical security testing techniques for IoT devices.

Coming soon


18.6 Architecture Labs

18.6.1 Lab 8: Edge vs Cloud Decision Workshop (Intermediate)

Design and evaluate edge computing architectures.

Coming soon - uses Edge Cloud Decision Tool


18.7 Lab Equipment Recommendations

For physical labs (optional but recommended):

Component Purpose Approx. Cost
ESP32 DevKit Wi-Fi + BLE microcontroller $8-15
DHT22 Sensor Temperature + humidity $5-10
LoRa Module (SX1276) Long-range communication $10-20
Breadboard + Wires Prototyping $5-10
USB Power Bank Portable power $15-25