Simulasi MQTT dengan Wokwi
Pada pertemuan kali ini akan membahas simulasi IoT menggunakan platform Wokwi untuk testing MQTT tanpa hardware fisik. Mahasiswa akan mempelajari cara menggunakan Wokwi simulator, membuat virtual ESP32 dengan sensor DHT22 dan LED, publish data sensor ke MQTT broker, subscribe command untuk kontrol LED, serta monitoring dengan MQTTX.
Alat dan Bahan
Simulator:
- Wokwi Online Platform (https://wokwi.com)
- Akun Wokwi (gratis, bisa login dengan Google/GitHub)
Software:
- Web Browser (Chrome, Firefox, Edge)
- MQTTX Desktop Client (https://mqttx.app/)
- Text Editor untuk mencatat konfigurasi
MQTT Broker:
- EMQX Public Broker (broker.emqx.io)
- Port: 1883 (non-SSL)
- Tidak perlu username/password
- Gratis untuk testing
Network:
- Koneksi Internet untuk akses Wokwi dan EMQX broker
- WiFi connection akan di-mock oleh Wokwi simulator
Bagian 1: Pengenalan Wokwi dan Setup Project
1.1 Apa itu Wokwi?
Wokwi adalah platform simulasi hardware IoT berbasis web yang memungkinkan kita mendesain, coding, dan testing rangkaian elektronik tanpa memerlukan hardware fisik.
Keuntungan menggunakan Wokwi: - Tidak perlu hardware fisik - semua simulasi di cloud - Real-time simulation - behavior seperti hardware asli - Support ESP32 - cocok untuk project IoT dengan WiFi/MQTT - Built-in code editor - coding langsung di browser - Serial Monitor - debugging output program - Visual circuit diagram - lihat rangkaian secara visual - Gratis untuk pembelajaran - tidak ada biaya - Collaborative - bisa share project dengan link
Workflow development dengan Wokwi:
1. Design circuit di Wokwi simulator
↓
2. Write code dan test dengan Serial Monitor
↓
3. Connect ke MQTT broker (EMQX)
↓
4. Monitor data dengan MQTTX
↓
5. Deploy ke hardware asli (optional)
1.2 Membuat Project Wokwi Pertama
Praktikum 1.1: Setup Project Wokwi
Langkah 1: Akses dan Login Wokwi
- Buka browser dan akses: https://wokwi.com
- Klik tombol "Sign In" di pojok kanan atas
- Pilih metode login:
- Sign in with Google (recommended untuk mahasiswa)
- Sign in with GitHub (jika punya akun GitHub)
- Ikuti proses autentikasi
- Setelah login, akan masuk ke halaman dashboard
Langkah 2: Buat Project Baru ESP32
- Di dashboard Wokwi, klik tombol "New Project"
- Akan muncul dialog "Create New Project"
- Scroll dan pilih template "ESP32"
- Klik template tersebut
- Tunggu 10-15 detik hingga editor loading
- Berikan nama project: klik "Untitled Project" → ganti jadi "MQTT LED DHT22"
Langkah 3: Mengenal Interface Wokwi
Setelah project terbuka, akan melihat interface dengan beberapa area:
┌─────────────────────────────────────────────────┐
│ [Play] [Stop] [Share] MQTT LED DHT22 │ ← Toolbar
├──────────────────┬──────────────────────────────┤
│ │ │
│ CODE EDITOR │ CIRCUIT DIAGRAM │
│ (main.py) │ (Visual ESP32) │
│ │ │
│ - Line numbers │ - ESP32 board │
│ - Syntax color │ - Components │
│ - Auto-complete │ - Wiring │
│ │ │
├──────────────────┴──────────────────────────────┤
│ SERIAL MONITOR │
│ (Output console) │
└─────────────────────────────────────────────────┘
Penjelasan area: - Toolbar (atas): Tombol Play/Stop untuk run simulasi, Share untuk bagikan project - Code Editor (kiri): Tempat menulis kode MicroPython - Circuit Diagram (kanan): Tampilan visual ESP32 dan komponen - Serial Monitor (bawah): Console output dari program
Langkah 4: File Structure Project
Wokwi otomatis membuat files:
Project Files:
├── main.py # File code MicroPython utama
├── diagram.json # Konfigurasi hardware dan wiring
└── wokwi.toml # Metadata project (optional)
Langkah 5: Test Run Pertama
Mari test bahwa simulator berfungsi dengan baik.
- Klik tab "main.py" di code editor (biasanya sudah terbuka)
- Hapus semua code yang ada (jika ada)
- Copy-paste code test ini:
# Test code untuk verifikasi Wokwi
import time
print("="*40)
print("Wokwi ESP32 Simulator - Test Run")
print("="*40)
print("MicroPython is running!")
print("Simulator: OK")
print("="*40)
counter = 0
while True:
counter += 1
print(f"Loop {counter} - Time: {time.time():.1f}s")
time.sleep(2)
- Klik tombol "Play" (segitiga hijau) di toolbar atas
- Tunggu 3-5 detik hingga simulator starting
- Lihat output di Serial Monitor (area bawah)
Output yang diharapkan:
========================================
Wokwi ESP32 Simulator - Test Run
========================================
MicroPython is running!
Simulator: OK
========================================
Loop 1 - Time: 0.0s
Loop 2 - Time: 2.0s
Loop 3 - Time: 4.0s
...
- Jika output muncul seperti di atas, simulator berhasil!
- Klik tombol "Stop" (kotak merah) untuk stop simulasi
Troubleshooting: - Jika tidak ada output: Pastikan Serial Monitor terbuka (klik tab "Serial" di bawah) - Jika error "Failed to start": Refresh browser dan coba lagi - Jika lambat: Tutup tab browser lain untuk free up memory
1.3 Arsitektur Sistem MQTT
Sebelum mulai praktikum, penting memahami alur komunikasi MQTT di project ini.
Diagram Arsitektur:
┌─────────────────────────────────────┐
│ WOKWI SIMULATOR (ESP32) │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ DHT22 │ │ LED │ │
│ │ Sensor │ │ Actuator│ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
│ ┌────▼─────────────────▼─────┐ │
│ │ MicroPython Program │ │
│ │ - Read sensor │ │
│ │ - MQTT publish │ │
│ │ - MQTT subscribe │ │
│ │ - Control LED │ │
│ └────────────┬───────────────┘ │
│ │ │
└────────────────┼────────────────────┘
│ WiFi (simulated)
│
▼
┌─────────────────────────────────────┐
│ EMQX BROKER (Cloud) │
│ broker.emqx.io:1883 │
│ │
│ Topics: │
│ ├─ sensor/dht22/temperature │
│ ├─ sensor/dht22/humidity │
│ └─ device/led/command │
│ │
└────────┬──────────────┬─────────────┘
│ │
▼ ▼
┌─────────────┐ ┌──────────────┐
│ MQTTX │ │ Dashboard │
│ (Monitor) │ │ (Optional) │
└─────────────┘ └──────────────┘
Alur Data:
1. PUBLISH (ESP32 → Broker):
2. SUBSCRIBE (Broker → ESP32):
Topics yang digunakan:
| Topic | Arah | Payload | Fungsi |
|---|---|---|---|
sensor/dht22/temperature |
ESP32 → Broker | {"temp": 25.5, "humidity": 60.2} |
Kirim data sensor |
sensor/dht22/humidity |
ESP32 → Broker | {"humidity": 60.2} |
Kirim humidity saja |
device/led/command |
Broker → ESP32 | {"action": "on"} |
Kontrol LED |
device/led/status |
ESP32 → Broker | {"status": "ON"} |
Status LED |
Bagian 2: Hardware Setup - Rangkaian di Wokwi
Pada bagian ini kita akan merangkai ESP32 dengan sensor DHT22 dan LED di Wokwi simulator.
2.1 Memahami Komponen
ESP32 DevKit V1
- Microcontroller dengan WiFi built-in
- 30 GPIO pins
- Support MicroPython
- Voltage: 3.3V logic
DHT22 Temperature & Humidity Sensor
- Sensor digital temperature dan humidity
- Range: -40°C to 80°C, 0-100% RH
- 3 pins: VCC, GND, DATA
- Protocol: One-wire digital signal
LED (Light Emitting Diode)
- Indikator visual output
- 2 pins: Anode (+, kaki panjang), Cathode (-, kaki pendek)
- Perlu resistor 220Ω-1kΩ untuk limit current
2.2 Diagram Wiring
Praktikum 2.1: Merangkai Komponen di Wokwi
Langkah 1: Buka Diagram Editor
- Di project Wokwi, lihat area Circuit Diagram (kanan)
- Seharusnya sudah ada ESP32 board di tengah canvas
- Jika belum ada, klik "+ Add part" → Search "ESP32" → Pilih "ESP32 DevKit V1"
Langkah 2: Tambahkan DHT22 Sensor
- Klik tombol "+" (Add part) di atas diagram
- Di search box, ketik: "DHT22"
- Klik komponen "DHT22" dari hasil pencarian
- DHT22 akan muncul di canvas
- Drag DHT22 ke posisi di sebelah kanan ESP32
Langkah 3: Tambahkan LED
- Klik tombol "+" lagi
- Search: "LED"
- Pilih "Red LED" (atau warna lain sesuai selera)
- Drag LED ke posisi di bawah ESP32
Langkah 4: Tambahkan Resistor
- Klik "+"
- Search: "Resistor"
- Pilih resistor, akan muncul dialog
- Atur nilai: 220 Ω (atau 330Ω, 1kΩ juga OK)
- Klik "OK"
- Posisikan resistor dekat LED
Langkah 5: Wiring DHT22 ke ESP32
Sekarang kita akan hubungkan pin DHT22 ke ESP32.
Cara membuat koneksi: 1. Hover mouse di atas pin yang mau dihubungkan 2. Pin akan berubah warna (highlight) 3. Klik dan drag dari pin tersebut 4. Lepas di pin tujuan 5. Wire (kabel) akan terbentuk otomatis
Koneksi DHT22:
| DHT22 Pin | ESP32 Pin | Keterangan |
|---|---|---|
| VCC (pin 1, kiri) | 3V3 | Power supply 3.3V |
| DATA (pin 2, tengah) | D15 (GPIO 15) | Data signal |
| GND (pin 3, kanan) | GND | Ground |
Langkah 6: Wiring LED dan Resistor ke ESP32
Koneksi LED:
| LED Pin | Tujuan | ESP32 Pin | Keterangan |
|---|---|---|---|
| Anode (+, kaki panjang) | → Resistor | - | Positif LED |
| Resistor | → | D2 (GPIO 2) | Output signal |
| Cathode (-, kaki pendek) | → | GND | Ground |
Langkah 7: Verifikasi Wiring
Setelah semua terhubung, diagram seharusnya terlihat seperti ini:
┌─────────────┐
│ DHT22 │
│ ┌─┬─┬─┐ │
└──┼─┼─┼──────┘
│ │ │
VCC │ │ └── GND
│ └──── DATA
│
┌──────┴───────────────┐
│ │
│ ESP32 │
│ DevKit V1 │
│ │
│ 3V3 D15 GND D2 │
└───┬───┬────┬────┬────┘
│ │ │ │
│ │ │ └────┐
│ │ │ │
│ │ │ ┌──▼──┐
│ │ │ │ Res │ 220Ω
│ │ │ └──┬──┘
│ │ │ │
│ │ │ ┌──▼──┐
│ │ │ │ LED │
│ │ │ └──┬──┘
│ │ │ │
│ │ └─────────┴── GND
Langkah 8: Lihat File diagram.json
Wokwi otomatis generate file JSON yang describe rangkaian.
- Klik tab "diagram.json" di code editor
- Akan melihat JSON seperti ini:
{
"version": 1,
"author": "Your Name",
"editor": "wokwi",
"parts": [
{
"type": "board-esp32-devkit-c-v4",
"id": "esp",
"top": 0,
"left": 0,
"attrs": { "env": "micropython-20231227-v1.22.0" }
},
{
"type": "wokwi-led",
"id": "led1",
"top": 217.2,
"left": 272.6,
"attrs": { "color": "red" }
},
{ "type": "wokwi-dht22", "id": "dht1", "top": -38.1, "left": 253.8, "attrs": {} },
{
"type": "wokwi-resistor",
"id": "r1",
"top": 234.35,
"left": 134.4,
"attrs": { "value": "220" }
}
],
"connections": [
[ "esp:TX", "$serialMonitor:RX", "", [] ],
[ "esp:RX", "$serialMonitor:TX", "", [] ],
[ "esp:3V3", "dht1:VCC", "red", [ "h0" ] ],
[ "dht1:SDA", "esp:15", "yellow", [ "v0" ] ],
[ "dht1:GND", "esp:GND.3", "black", [ "v0" ] ],
[ "led1:C", "r1:2", "green", [ "v0" ] ],
[ "r1:1", "esp:2", "green", [ "v0" ] ],
[ "led1:A", "esp:GND.3", "black", [ "v0" ] ]
],
"dependencies": {}
}
File ini bisa di-edit manual jika perlu, tapi lebih mudah pakai visual editor.
Langkah 9: Save Project
Wokwi auto-save, tapi bisa manual save juga: 1. Tekan Ctrl+S (Windows/Linux) atau Cmd+S (Mac) 2. Atau klik icon "Save" jika ada
Project sekarang sudah siap untuk coding!
Bagian 3: WiFi Connection dan MQTT Setup
3.1 Memahami WiFi di Wokwi
Wokwi simulator memiliki WiFi virtual yang bisa connect ke internet real. Ini memungkinkan ESP32 simulasi untuk: - Connect ke MQTT broker di cloud (EMQX) - Publish dan subscribe data real-time - Testing IoT application tanpa hardware
Penting: WiFi di Wokwi adalah mock/simulated, tapi koneksi network-nya real. Jadi bisa benar-benar komunikasi dengan broker MQTT eksternal.
3.2 Setup WiFi dan MQTT Library
Praktikum 3.1: Code Inisialisasi WiFi dan MQTT
Langkah 1: Import Libraries
Buka file main.py dan hapus semua isi sebelumnya, lalu mulai dengan import libraries:
# ============================================
# MQTT IoT Simulator - ESP32 with DHT22 & LED
# Platform: Wokwi Simulator
# ============================================
# Library imports
import network
import time
from umqtt.simple import MQTTClient
import json
from machine import Pin
import dht
print("\n" + "="*50)
print("MQTT IoT Simulator Starting...")
print("Platform: Wokwi ESP32")
print("="*50)
Penjelasan imports:
- network: Library untuk WiFi connection
- time: Untuk timing dan delay
- umqtt.simple: MQTT client library (built-in MicroPython)
- json: Untuk format data JSON
- machine.Pin: Untuk kontrol GPIO pins
- dht: Library untuk sensor DHT22
Langkah 2: Konfigurasi WiFi dan MQTT
Tambahkan konfigurasi di bawah imports:
# ============================================
# CONFIGURATION
# ============================================
# WiFi Configuration
# Note: Wokwi simulator akan mock WiFi connection
WIFI_SSID = "Wokwi-GUEST"
WIFI_PASSWORD = ""
# MQTT Broker Configuration
# Menggunakan EMQX public broker (gratis)
MQTT_BROKER = "broker.emqx.io"
MQTT_PORT = 1883
MQTT_CLIENT_ID = "wokwi-esp32-001" # Harus unique per device
# MQTT Topics
TOPIC_TEMPERATURE = "sensor/dht22/temperature"
TOPIC_HUMIDITY = "sensor/dht22/humidity"
TOPIC_LED_COMMAND = "device/led/command"
TOPIC_LED_STATUS = "device/led/status"
# Timing Configuration
PUBLISH_INTERVAL = 5 # Publish sensor data setiap 5 detik
print("[CONFIG] Configuration loaded")
print(f"[CONFIG] MQTT Broker: {MQTT_BROKER}:{MQTT_PORT}")
print(f"[CONFIG] Client ID: {MQTT_CLIENT_ID}")
print(f"[CONFIG] Publish interval: {PUBLISH_INTERVAL}s")
Penjelasan konfigurasi:
- WIFI_SSID & PASSWORD: Di Wokwi, gunakan "Wokwi-GUEST" (WiFi mock)
- MQTT_BROKER:
broker.emqx.ioadalah public broker gratis dari EMQX - MQTT_PORT: 1883 adalah port standar MQTT (non-SSL)
- MQTT_CLIENT_ID: ID unik untuk identify device ini. Harus berbeda untuk setiap device
- Topics: Naming convention menggunakan hierarki (sensor/device/measurement)
Best Practice untuk Topic Naming:
sensor/<device>/<measurement> # Untuk sensor data
device/<device>/<control> # Untuk control command
system/<device>/<status> # Untuk status system
Langkah 3: Hardware Pin Setup
Tambahkan setup untuk LED dan DHT22:
# ============================================
# HARDWARE SETUP
# ============================================
# LED setup - GPIO 2
led = Pin(2, Pin.OUT)
led.value(0) # Initial state: OFF
print("[HARDWARE] LED initialized on GPIO 2")
# DHT22 setup - GPIO 15
dht_sensor = dht.DHT22(Pin(15))
print("[HARDWARE] DHT22 sensor initialized on GPIO 15")
# State variables
led_state = False
last_publish_time = 0
Penjelasan:
- Pin(2, Pin.OUT): GPIO 2 sebagai output untuk LED
- led.value(0): Set LED OFF di awal (0 = LOW, 1 = HIGH)
- dht.DHT22(Pin(15)): Initialize DHT22 di GPIO 15
- State variables untuk tracking timing dan status
3.3 WiFi Connection Function
Praktikum 3.2: Implement WiFi Connection
Langkah 1: Fungsi Connect WiFi
Tambahkan fungsi untuk connect WiFi:
# ============================================
# WIFI CONNECTION
# ============================================
def connect_wifi():
"""Connect to WiFi - Optimized for Wokwi simulator"""
print("\n[WIFI] Initializing WiFi for Wokwi simulator...")
print(f"[WIFI] SSID: {WIFI_SSID}")
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# Wokwi: Sometimes need to disconnect first
try:
wlan.disconnect()
time.sleep(0.5)
except:
pass
# Connect
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
print("[WIFI] Connecting...")
# Wait for connection with Wokwi-specific status handling
max_wait = 20
while max_wait > 0:
status = wlan.status()
# Standard MicroPython status codes
if status == 3: # STAT_GOT_IP
print("[WIFI] ✓ Connected successfully!")
ifconfig = wlan.ifconfig()
print(f"[WIFI] IP Address: {ifconfig[0]}")
return True
# Wokwi-specific status codes (1000-1010 range)
# These are internal Wokwi states, not standard MicroPython
if status >= 1000 and status <= 1010:
# Still connecting in Wokwi
if max_wait % 5 == 0: # Print every 5 seconds
print(f"[WIFI] Wokwi connecting... ({max_wait}s remaining)")
# Error states
elif status < 0:
print(f"[WIFI] Connection failed with status: {status}")
break
max_wait -= 1
time.sleep(1)
# Wokwi quirk: Even if status != 3, network might work
print("[WIFI] ⚠ Connection status ambiguous in Wokwi")
print("[WIFI] Attempting to proceed - network may still work...")
return True # Proceed anyway for Wokwi testing
Penjelasan code:
1. network.WLAN(network.STA_IF): Create WiFi station interface
2. wlan.active(True): Activate WiFi
3. wlan.connect(): Mulai connection process
4. while max_wait > 0: Loop untuk wait connection (timeout 10 detik)
5. wlan.status(): Check status (3 = connected)
6. wlan.ifconfig(): Get IP address info
WiFi Status Codes:
- 0: STAT_IDLE (idle)
- 1: STAT_CONNECTING (sedang connect)
- 2: STAT_WRONG_PASSWORD (password salah)
- 3: STAT_GOT_IP (connected, dapat IP)
- -1: STAT_NO_AP_FOUND (SSID tidak ketemu)
- -2: STAT_CONNECT_FAIL (gagal connect)
3.4 MQTT Connection Function
Praktikum 3.3: Implement MQTT Connection
Langkah 1: Fungsi Connect MQTT
Tambahkan fungsi untuk connect ke MQTT broker:
# ============================================
# MQTT CONNECTION
# ============================================
def connect_mqtt():
"""
Connect ke MQTT broker dan setup subscriptions
"""
print("\n[MQTT] Connecting to MQTT broker...")
print(f"[MQTT] Broker: {MQTT_BROKER}:{MQTT_PORT}")
try:
# Create MQTT client instance
client = MQTTClient(
client_id=MQTT_CLIENT_ID,
server=MQTT_BROKER,
port=MQTT_PORT,
keepalive=60 # Send ping setiap 60 detik
)
# Set callback untuk handle incoming messages
client.set_callback(mqtt_callback)
# Connect ke broker
client.connect()
print("[MQTT] ✓ Connected to broker successfully!")
# Subscribe ke command topics
client.subscribe(TOPIC_LED_COMMAND)
print(f"[MQTT] ✓ Subscribed to: {TOPIC_LED_COMMAND}")
return client
except Exception as e:
print(f"[MQTT] ✗ Connection failed: {e}")
return None
Penjelasan:
- MQTTClient(): Create MQTT client instance
- client_id: Unique identifier untuk device
- keepalive=60: Ping interval untuk maintain connection
- set_callback(): Set function yang dipanggil saat terima message
- connect(): Establish connection ke broker
- subscribe(): Subscribe ke topic untuk receive messages
Langkah 2: Callback Function untuk Handle Messages
Tambahkan fungsi callback yang akan dipanggil saat ada message masuk:
def mqtt_callback(topic, msg):
"""
Callback function dipanggil saat menerima MQTT message
Args:
topic: Topic dari message (bytes)
msg: Payload message (bytes)
"""
global led_state
# Convert bytes ke string
topic_str = topic.decode()
msg_str = msg.decode()
print(f"\n[MQTT] Message received!")
print(f"[MQTT] Topic: {topic_str}")
print(f"[MQTT] Payload: {msg_str}")
# Handle LED command
if topic_str == TOPIC_LED_COMMAND:
try:
# Parse JSON payload
data = json.loads(msg_str)
action = data.get("action", "").lower()
if action == "on":
led.value(1) # Turn ON LED
led_state = True
print("[LED] ✓ Turned ON")
# Publish status update
publish_led_status(True)
elif action == "off":
led.value(0) # Turn OFF LED
led_state = False
print("[LED] ✓ Turned OFF")
# Publish status update
publish_led_status(False)
else:
print(f"[LED] ✗ Unknown action: {action}")
except Exception as e:
print(f"[LED] ✗ Error processing command: {e}")
Penjelasan callback:
1. Function dipanggil otomatis saat message diterima
2. topic dan msg dalam bentuk bytes, perlu decode ke string
3. Parse JSON untuk extract command
4. Control LED based on action ("on" atau "off")
5. Publish status update setelah action
Bagian 4: Sensor Reading dan MQTT Publish
4.1 Read Sensor DHT22
Praktikum 4.1: Fungsi Baca Sensor
Langkah 1: Fungsi Read DHT22
Tambahkan fungsi untuk baca sensor:
# ============================================
# SENSOR FUNCTIONS
# ============================================
def read_dht22():
"""
Baca temperature dan humidity dari sensor DHT22
Returns:
dict: {'temperature': float, 'humidity': float, 'success': bool}
"""
try:
# Trigger sensor measurement
dht_sensor.measure()
# Wait sebentar untuk measurement selesai
time.sleep(0.5)
# Read values
temperature = dht_sensor.temperature()
humidity = dht_sensor.humidity()
# Validation
if temperature is None or humidity is None:
print("[SENSOR] ✗ Failed to read sensor (None values)")
return None
# Format data
data = {
'temperature': round(temperature, 1),
'humidity': round(humidity, 1),
'success': True
}
print(f"[SENSOR] ✓ DHT22 read: Temp={data['temperature']}°C, Humidity={data['humidity']}%")
return data
except OSError as e:
print(f"[SENSOR] ✓ DHT22 read: Temp={data['temperature']}°C, Humidity={data['humidity']}%")
return data
except OSError as e:
print(f"[SENSOR] ✗ Sensor error: {e}")
return None
except Exception as e:
print(f"[SENSOR] ✗ Unexpected error: {e}")
return None
Penjelasan:
- dht_sensor.measure(): Trigger sensor untuk mulai measurement
- time.sleep(0.5): Wait 500ms untuk sensor selesai baca
- dht_sensor.temperature(): Get temperature value
- dht_sensor.humidity(): Get humidity value
- round(value, 1): Round ke 1 decimal untuk format yang rapi
- Error handling untuk handle sensor failure
Common DHT22 Errors:
- OSError: [Errno 110] ETIMEDOUT: Sensor tidak response (cek wiring)
- None values: Sensor belum ready atau rusak
- Reading too fast: Tunggu minimal 2 detik antar reading
4.2 MQTT Publish Functions
Praktikum 4.2: Implement Publish Functions
Langkah 1: Fungsi Publish Sensor Data
Tambahkan fungsi untuk publish data sensor:
# ============================================
# MQTT PUBLISH FUNCTIONS
# ============================================
def publish_sensor_data(client, sensor_data):
"""
Publish sensor data ke MQTT broker
Args:
client: MQTT client instance
sensor_data: Dict dengan temperature dan humidity
"""
if sensor_data is None or not sensor_data.get('success'):
print("[MQTT] ✗ Cannot publish - invalid sensor data")
return False
try:
# Prepare payload dengan timestamp
payload = {
'temperature': sensor_data['temperature'],
'humidity': sensor_data['humidity'],
'timestamp': time.time(),
'device_id': MQTT_CLIENT_ID
}
# Convert ke JSON string
payload_json = json.dumps(payload)
# Publish ke topic temperature
client.publish(TOPIC_TEMPERATURE, payload_json)
print(f"[MQTT] ✓ Published to {TOPIC_TEMPERATURE}")
print(f"[MQTT] Data: {payload_json}")
# Optional: Publish humidity ke topic terpisah
humidity_payload = {
'humidity': sensor_data['humidity'],
'timestamp': time.time(),
'device_id': MQTT_CLIENT_ID
}
client.publish(TOPIC_HUMIDITY, json.dumps(humidity_payload))
print(f"[MQTT] ✓ Published to {TOPIC_HUMIDITY}")
return True
except Exception as e:
print(f"[MQTT] ✗ Publish error: {e}")
return False
def publish_led_status(status):
"""
Publish LED status ke MQTT broker
Args:
status: Boolean (True=ON, False=OFF)
"""
try:
payload = {
'status': 'ON' if status else 'OFF',
'timestamp': time.time(),
'device_id': MQTT_CLIENT_ID
}
payload_json = json.dumps(payload)
mqtt_client.publish(TOPIC_LED_STATUS, payload_json)
print(f"[MQTT] ✓ Published LED status: {payload['status']}")
except Exception as e:
print(f"[MQTT] ✗ Failed to publish LED status: {e}")
Penjelasan: - Payload structure: Include data, timestamp, dan device_id untuk traceability - JSON format: Standard format untuk MQTT payload, mudah di-parse - Multiple topics: Temperature dan humidity bisa di-publish ke topic terpisah - Error handling: Catch exception untuk prevent program crash
Best Practice Payload Format:
Include timestamp membantu untuk: - Data synchronization - Troubleshooting delay - Historical data analysis
Bagian 5: Main Loop - Integration
5.1 Main Program Loop
Praktikum 5.1: Complete Main Program
Langkah 1: Fungsi Main dengan Loop
Tambahkan main function yang integrate semua components:
# ============================================
# MAIN PROGRAM
# ============================================
def main():
"""
Main program loop
"""
global mqtt_client, last_publish_time
print("\n" + "="*50)
print("Starting MQTT IoT Application")
print("="*50)
# Step 1: Connect WiFi
if not connect_wifi():
print("[ERROR] WiFi connection failed - stopping")
return
time.sleep(2) # Wait sebentar setelah WiFi connect
# Step 2: Connect MQTT
mqtt_client = connect_mqtt()
if mqtt_client is None:
print("[ERROR] MQTT connection failed - stopping")
return
print("\n" + "="*50)
print("System Ready!")
print("="*50)
print(f"[INFO] Publishing sensor data every {PUBLISH_INTERVAL} seconds")
print("[INFO] Listening for LED commands...")
print("[INFO] Press STOP button to exit")
print("="*50 + "\n")
# Initialize timing
last_publish_time = time.time()
loop_count = 0
# Main loop
while True:
try:
loop_count += 1
current_time = time.time()
# Check for incoming MQTT messages
# Note: check_msg() adalah non-blocking
mqtt_client.check_msg()
# Publish sensor data berdasarkan interval
if (current_time - last_publish_time) >= PUBLISH_INTERVAL:
print(f"\n--- Loop {loop_count} ---")
# Read sensor
sensor_data = read_dht22()
# Publish jika reading berhasil
if sensor_data and sensor_data.get('success'):
publish_sensor_data(mqtt_client, sensor_data)
else:
print("[WARNING] Skipping publish - sensor read failed")
# Update timing
last_publish_time = current_time
# Small delay untuk prevent CPU overload
time.sleep(0.1)
except KeyboardInterrupt:
print("\n[INFO] Program interrupted by user")
break
except Exception as e:
print(f"[ERROR] Main loop error: {e}")
print("[INFO] Attempting to reconnect...")
# Try reconnect MQTT
try:
mqtt_client = connect_mqtt()
if mqtt_client is None:
print("[ERROR] Reconnection failed - stopping")
break
except:
print("[ERROR] Reconnection failed - stopping")
break
time.sleep(5)
# Cleanup
print("\n[INFO] Cleaning up...")
try:
mqtt_client.disconnect()
print("[INFO] MQTT disconnected")
except:
pass
led.value(0) # Turn off LED
print("[INFO] LED turned off")
print("[INFO] Program ended")
print("="*50)
# ============================================
# ENTRY POINT
# ============================================
# Run main program
if __name__ == "__main__":
main()
Penjelasan Main Loop:
- Initialization Phase:
- Connect WiFi
- Connect MQTT broker
-
Setup timing variables
-
Main Loop:
check_msg(): Check incoming MQTT messages (non-blocking)- Timer-based publish: Publish sensor data setiap interval
-
Error handling: Catch exception dan attempt reconnect
-
Cleanup:
- Disconnect MQTT gracefully
- Turn off LED
- Print exit message
Langkah 2: Test Run Complete Code
- Pastikan semua code sudah di-copy ke main.py
- Verify wiring di diagram masih benar
- Klik tombol "Play" (▶)
- Tunggu 5-10 detik untuk initialization
- Monitor output di Serial Monitor
Expected Output:
==================================================
MQTT IoT Simulator Starting...
Platform: Wokwi ESP32
==================================================
[CONFIG] Configuration loaded
[CONFIG] MQTT Broker: broker.emqx.io:1883
[CONFIG] Client ID: wokwi-esp32-001
[CONFIG] Publish interval: 5s
[HARDWARE] LED initialized on GPIO 2
[HARDWARE] DHT22 sensor initialized on GPIO 15
[WIFI] Connecting to WiFi...
[WIFI] SSID: Wokwi-GUEST
[WIFI] ✓ Connected successfully!
[WIFI] IP Address: 192.168.1.100
[MQTT] Connecting to MQTT broker...
[MQTT] Broker: broker.emqx.io:1883
[MQTT] ✓ Connected to broker successfully!
[MQTT] ✓ Subscribed to: device/led/command
==================================================
System Ready!
==================================================
[INFO] Publishing sensor data every 5 seconds
[INFO] Listening for LED commands...
[INFO] Press STOP button to exit
==================================================
--- Loop 1 ---
[SENSOR] ✓ DHT22 read: Temp=24.5°C, Humidity=55.3%
[MQTT] ✓ Published to sensor/dht22/temperature
[MQTT] Data: {"temperature": 24.5, "humidity": 55.3, "timestamp": 123456, "device_id": "wokwi-esp32-001"}
[MQTT] ✓ Published to sensor/dht22/humidity
--- Loop 2 ---
[SENSOR] ✓ DHT22 read: Temp=24.6°C, Humidity=55.1%
[MQTT] ✓ Published to sensor/dht22/temperature
[MQTT] Data: {"temperature": 24.6, "humidity": 55.1, "timestamp": 123461, "device_id": "wokwi-esp32-001"}
[MQTT] ✓ Published to sensor/dht22/humidity
- Jika melihat output seperti di atas, simulator berhasil! ✓
Troubleshooting:
| Error | Penyebab | Solusi |
|---|---|---|
MQTT connection failed |
Broker tidak reachable | Check internet connection, try broker lain |
Sensor error: ETIMEDOUT |
DHT22 wiring salah | Verify wiring DATA ke GPIO 15 |
None values |
Sensor belum ready | Tambah delay setelah measure() |
Memory error |
Code terlalu besar | Simplify code, hapus print tidak perlu |
Bagian 6: Testing dengan MQTTX
Sekarang kita akan monitor dan control ESP32 menggunakan MQTTX desktop client.
6.1 Setup MQTTX
Praktikum 6.1: Install dan Configure MQTTX
Langkah 1: Download dan Install MQTTX
- Buka browser, akses: https://mqttx.app/
- Klik "Download"
- Pilih sesuai OS:
- Windows: Download installer
.exe - macOS: Download
.dmg - Linux: Download
.AppImageatau.deb - Install MQTTX:
- Windows: Double-click installer, follow wizard
- macOS: Drag ke Applications folder
- Linux:
chmod +xdan run, atausudo dpkg -i - Launch MQTTX
Langkah 2: Create New Connection ke EMQX Broker
Setelah MQTTX terbuka, akan melihat window dengan sidebar kiri.
- Klik tombol "+ New Connection" (pojok kiri atas)
- Form "New Connection" akan muncul di kanan
- Isi form dengan detail berikut:
Connection Settings:
| Field | Value | Keterangan |
|---|---|---|
| Name | EMQX Wokwi Test |
Nama connection (bebas) |
| Client ID | (sesuaikan ditampilan) |
Unique ID untuk MQTTX |
| Host | broker.emqx.io |
EMQX public broker |
| Port | 1883 |
MQTT port (non-SSL) |
| Username | (kosongkan) | Public broker tidak perlu auth |
| Password | (kosongkan) | Public broker tidak perlu auth |
| SSL/TLS | OFF |
Tidak pakai encryption |
| MQTT Version | 3.1.1 |
Version default |
- Setelah selesai isi, klik tombol "Connect" (pojok kanan atas)
- Status akan berubah jadi "Connected" dengan dot hijau
- Bottom panel akan show "Connection successful"
6.2 Subscribe ke Sensor Topics
Praktikum 6.2: Monitor Sensor Data dari ESP32
Langkah 1: Create Subscription untuk Temperature
- Di MQTTX window, pastikan connection EMQX Wokwi Test sudah selected (highlight)
- Klik tombol "+ New Subscription" (di area subscription)
- Dialog "Add Subscription" akan muncul
- Isi form:
| Field | Value |
|---|---|
| Topic | sensor/dht22/temperature |
| QoS | 1 |
| Color | Blue (optional, untuk visual) |
- Klik "Confirm"
- Subscription akan muncul di list dengan badge count "0"
Langkah 2: Create Subscription untuk Humidity
Repeat langkah di atas untuk humidity:
- Klik "+ New Subscription" lagi
- Isi form:
| Field | Value |
|---|---|
| Topic | sensor/dht22/humidity |
| QoS | 1 |
| Color | Green |
- Klik "Confirm"
Langkah 3: Create Subscription untuk LED Status
- Klik "+ New Subscription" lagi
- Isi:
| Field | Value |
|---|---|
| Topic | device/led/status |
| QoS | 1 |
| Color | Yellow |
- Klik "Confirm"
Langkah 4: Monitor Incoming Messages
Sekarang MQTTX sudah subscribe ke 3 topics. Mari verify data masuk:
- Pastikan Wokwi simulator masih running (jika belum, klik Play)
- Di MQTTX, lihat area "Messages" (tengah bawah)
- Setiap 5 detik, seharusnya melihat message baru muncul
Expected messages:
Topic: sensor/dht22/temperature
Time: 10:15:23
QoS: 1
Payload:
{
"temperature": 24.5,
"humidity": 55.3,
"timestamp": 1698765432,
"device_id": "wokwi-esp32-001"
}
Topic: sensor/dht22/humidity
Time: 10:15:23
QoS: 1
Payload:
{
"humidity": 55.3,
"timestamp": 1698765432,
"device_id": "wokwi-esp32-001"
}
- Badge count di subscription akan increment (1, 2, 3, ...)
- Klik message untuk see full detail di right panel
Langkah 5: Verify Data Flow
Untuk verify data real-time:
- Lihat Serial Monitor di Wokwi - seharusnya show publish logs
- Lihat MQTTX Messages - seharusnya receive data yang sama
- Compare timestamp - delay harusnya < 1 detik
Diagram data flow:
Wokwi ESP32 EMQX Broker MQTTX
| | |
|--- Publish temperature --->| |
| (every 5 seconds) | |
| |--- Forward message -->|
| | |
| |<--- Subscribed to ----|
6.3 Publish Command ke ESP32
Praktikum 6.3: Control LED dari MQTTX
Sekarang kita akan send command dari MQTTX ke ESP32 untuk control LED.
Langkah 1: Prepare Publish Panel
- Di MQTTX window (connection EMQX Wokwi Test selected)
- Lihat area "Publish" di bottom (below subscriptions)
- Ada form dengan fields: Topic, QoS, Payload
Langkah 2: Turn ON LED
- Di field "Topic", ketik:
device/led/command - Di dropdown "QoS", pilih:
1 - Di field "Payload", ketik JSON command:
- Klik tombol "Publish" (atau tekan Enter)
Langkah 3: Verify LED ON
Setelah publish:
- Di MQTTX: Message akan appear di sent messages (abu-abu)
- Di Wokwi Simulator:
- Lihat diagram - LED seharusnya menyala merah
- Lihat Serial Monitor - akan show log:
- Di MQTTX Messages: Akan receive message di topic
device/led/status:
Langkah 4: Turn OFF LED
Repeat untuk turn off:
- Topic:
device/led/command - Payload:
- Klik "Publish"
- Verify:
- LED di Wokwi mati
- Serial Monitor show "Turned OFF"
- MQTTX receive status "OFF"
Langkah 5: Test Multiple Commands
Test rapid toggle:
- Publish
{"action": "on"}- wait 2 detik - Publish
{"action": "off"}- wait 2 detik - Publish
{"action": "on"}- wait 2 detik - Publish
{"action": "off"}
Setiap command seharusnya: - ✓ Toggle LED state di Wokwi - ✓ Show log di Serial Monitor - ✓ Publish status update yang diterima MQTTX
Langkah 6: Test Invalid Command
Test error handling:
- Publish dengan payload invalid:
- Di Serial Monitor, seharusnya show:
- LED state tidak berubah
Command Summary:
| Command | Payload | Expected Result |
|---|---|---|
| Turn ON | {"action": "on"} |
LED menyala, status "ON" published |
| Turn OFF | {"action": "off"} |
LED mati, status "OFF" published |
| Invalid | {"action": "xyz"} |
Error message, no state change |
| Malformed | {invalid json} |
JSON parse error |
6.4 Advanced MQTTX Features
Praktikum 6.4: Monitoring dan Analysis
Langkah 1: View Message Statistics
- Di MQTTX, klik tab "Statistics" (jika ada)
- Atau lihat badge counts di subscriptions
- Akan show:
- Total messages received
- Messages per topic
- Message rate (msg/sec)
Langkah 2: Search dan Filter Messages
- Di area Messages, ada search box
- Ketik:
temperature- akan filter messages yang contain kata itu - Clear search untuk show all messages again
Langkah 3: Export Messages
Untuk save messages ke file:
- Right-click di message
- Pilih "Copy" atau "Export"
- Paste ke text editor
- Save sebagai reference
Langkah 4: Monitor Connection Quality
Indicator connection quality:
- Green dot: Connected, good
- Yellow dot: Connected, warning (high latency)
- Red dot: Disconnected
- Gray dot: Connecting
Jika connection unstable: - Check internet connection - Try restart MQTTX - Verify broker address