LAPORAN PRAKTIKUM MINGGU KE-3: IMPLEMENTASI ESP32 ENVIRONMENTAL MONITORING WEB SERVER DAN SISTEM KONTROL KIPAS OTOMATIS BERBASIS PROTOKOL MQTT
Disusun Oleh:
| Muhammad Naufal Aziz | (24051204001) |
| Muhammad Rifqi Al Hafidh | (24051204009) |
| Ig. Krisna Wijaya Prihandono | (24051204032) |
| Ahmad Syihan Arijuddin | (24051204035) |
1.1 Latar Belakang
Perkembangan teknologi Internet of Things (IoT) pada arsitektur sistem tertanam (embedded systems) telah menggeser paradigma pemantauan perangkat keras dari sekadar komunikasi serial lokal menuju sistem pemantauan dan pengendalian terdistribusi nirkabel. Mikrokontroler modern seperti ESP32 yang memiliki antarmuka Wi-Fi terintegrasi dan konektivitas ganda menawarkan fleksibilitas tinggi dalam memproses data sensorik sekaligus melayani antarmuka pengguna secara real-time.
Dalam praktikum minggu ketiga ini, Kelompok 1 merancang dua arsitektur sistem IoT terintegrasi. Proyek pertama berfokus pada pembentukan embedded HTTP web server lokal pada ESP32 untuk memantauan parameter suhu dan kelembapan dari sensor DHT11 serta pembacaan nilai Analog-to-Digital Converter (ADC) 12-bit pada GPIO 34. Data tersebut visualisasikan secara dinamis melalui antarmuka grafik HTML/CSS di browser serta ditampilkan pada layar LCD I2C 16x2. Proyek kedua mengimplementasikan otomatisasi aktuator Relay dan LED indikator kipas berbasis sensor suhu DHT22 yang terhubung dengan protokol Message Queuing Telemetry Transport (MQTT) melalui broker publik emqx.io. Sistem ini mendukung pemantauan terpusat serta mekanisme kendali paksa jarak jauh (manual override) menggunakan MQTTX client.
1.2 Rumusan Masalah
Berdasarkan latar belakang di atas, rumusan masalah dalam praktikum ini adalah sebagai berikut:
1. Bagaimana merancang dan mengonfigurasi embedded HTTP Web Server pada ESP32 untuk menyajikan dashboard pemantauan suhu, kelembapan, dan persentase ADC secara dinamis?
2. Bagaimana mengintegrasikan layar LCD I2C 16x2 untuk menampilkan IP address jaringan Wi-Fi dan telemetry sensor secara lokal?
3. Bagaimana mengimplementasikan komunikasi dua arah berbasis protokol MQTT untuk kontrol Relay/LED otomatis berdasarkan ambang batas suhu dan eksekusi perintah manual override dari MQTTX?
1.3 Tujuan Laporan
Tujuan dari penyusunan laporan praktikum ini adalah:
1. Memahami mekanisme inisialisasi jaringan Wi-Fi, pemrosesan sensor DHT11, pembacaan ADC 12-bit (0–4095), dan pelayanan request HTTP 200 OK pada ESP32 Web Server.
2. Menguasai pembuatan antarmuka web interaktif menggunakan HTML5 dan CSS conic-gradient yang dikirimkan langsung dari memori ESP32.
3. Menganalisis alur Publish dan Subscribe pada protokol MQTT menggunakan library umqtt.simple di MicroPython untuk otomatisasi aktuator dan interupsi kendali jarak jauh.
1.4 Manfaat Penulisan
Penulisan laporan ini memberikan manfaat teoritis dan praktis bagi mahasiswa dalam memahami arsitektur web tersemat, protokol komunikasi IoT ringan, serta logika kendali berbasis ambang batas (thresholding) pada sistem kendali otomatisasi lingkungan.
2.1 Dasar Teori
a. Mikrokontroler ESP32 dan Web Server Tersemat
ESP32 merupakan sistem mikrokontroler System-on-Chip (SoC) yang dilengkapi dengan modul Wi-Fi 802.11 b/g/n dan Bluetooth. Dengan memanfaatkan library WiFi.h dan WiFiServer pada port 80, ESP32 dapat bertindak sebagai HTTP Server independen. Ketika browser client mengakses IP address ESP32, mikrokontroler membaca HTTP Request Header dan merespon dengan dokumen HTML/CSS beserta header 'Refresh: 3' untuk pembaruan data secara otomatis setiap 3 detik.
b. Sensor Lingkungan Seri DHT
Sensor seri DHT (DHT11 dan DHT22) mengukur suhu dan kelembapan udara menggunakan sinyal digital tunggal (1-Wire protocol). DHT11 memiliki rentang pengukuran suhu 0–50°C (akurasi ±2°C) dan kelembapan 20–90% (akurasi ±5%), sedangkan DHT22 memiliki tingkat presisi yang lebih tinggi. Pembacaan dilakukan menggunakan fungsi dht.readTemperature() dan dht.readHumidity() dengan jeda minimal siklus pembacaan sekitar 2 detik.
c. Konversi Analog ke Digital (ADC) ESP3
ESP32 memiliki unit ADC terintegrasi dengan resolusi hingga 12-bit, yang menghasilkan nilai kuantisasi digital dari 0 hingga 4095 untuk rentang tegangan analog 0–3.3V. Pada proyek ini, pembacaan GPIO 34 dipetakan ke skala persentase 0–100% menggunakan fungsi map(adcValue, 0, 4095, 0, 100).
d. Protokol MQTT dan Arsitektur Publish-Subscribe
MQTT adalah protokol komunikasi M2M (Machine-to-Machine) yang sangat ringan berbasis TCP/IP. Komunikasi dipublikasikan oleh Publisher ke Broker publik (seperti broker.emqx.io port 1883) melalui topik tertentu, dan disalurkan ke Subscriber yang terhubung. Mekanisme callback pada library umqtt.simple memungkinkan ESP32 menerima pesan interupsi kontrol secara real-time tanpa melakukan polling yang membebani prosessor.
e. Antarmuka Display LCD I2C dan Aktuator Relay
LCD 16x2 dengan modul konverter I2C (PC8574) memungkinkan penghematan pin mikrokontroler dengan hanya menggunakan 2 saluran komunikasi (SDA dan SCL). Modul Relay berfungsi sebagai sakelar diferensial yang mengisolasi rangkaian kontrol ESP32 tegangan rendah dengan beban daya aktuator (seperti kipas atau LED indikator daya).
2.2 Komponen
Berikut adalah daftar perangkat keras dan perangkat lunak yang digunakan dalam simulasi dan implementasi Proyek Minggu Ke-3:
Komponen / Software | Spesifikasi / Pinout | Fungsi dalam Sistem |
|---|---|---|
ESP32 DevKit | SoC Dual-Core Wi-Fi/BT | Mikrokontroler utama pemroses data & web server |
Sensor DHT11 / DHT22 | GPIO 4 (1-Wire Data) | Mengukur parameter suhu dan kelembapan udara |
LCD I2C 16x2 | Alamat 0x27 / GPIO 21, 22 | Menampilkan status IP Wi-Fi & data telemetry lokal |
Pin ADC Analog | GPIO 34 (Resolusi 12-Bit) | Membaca input analog (0-4095) & konversi % |
Modul Relay 5V | GPIO 5 (Signal Input) | Sakelar pengontrol daya indikator kipas |
LED Indikator Kipas | Anoda via Relay, Katoda GND | Simulasi visual fisik untuk status operasional kipas |
Wi-Fi Network | SSID 'iwak tempe' / Wokwi-GUEST | Media transmisi data lokal dan koneksi internet |
MQTT Broker | broker.emqx.io (Port 1883) | Broker perantara pengiriman telemetry & perintah |
MQTTX Client Application | Publisher/Subscriber App | Pusat kendali & pemantauan pesan MQTT jarak jauh |
Arduino IDE / MicroPython | C++ / MicroPython Engine | Lingkungan pengembangan kode program tersemat |
3.1 Penjelasan simulasi
A. Proyek 1: ESP32 Environmental Monitoring Web Server & Display LCD
Pada Proyek 1, ESP32 dikonfigurasi sebagai Web Server lokal untuk menyajikan dashboard pemantauan lingkungan. Arsitektur sirkuit dan alur kerja sistem dijelaskan sebagai berikut:
a. Skema Rangkaian: 1. Konfigurasi Wiring Hardware:
Sensor DHT11 dihubungkan ke GPIO 4, input analog ADC dihubungkan ke GPIO 34, dan modul LCD I2C 16x2 dihubungkan ke bus I2C ESP32 (SDA/SCL) dengan alamat I2C 0x27.
b. Proses Inisialisasi: 2. Alur Inisialisasi setup():
Saat ESP32 pertama kali dinyalakan, komunikasi Serial diatur pada baud rate 115200, sensor DHT11 diaktifkan, dan LCD menampilkan pesan 'Connecting WiFi'. ESP32 mencoba terhubung ke jaringan Wi-Fi dengan SSID 'iwak tempe' dan password '12345678'. Setelah status koneksi menjadi WL_CONNECTED, IP address lokal ESP32 ditampilkan pada Serial Monitor serta layar LCD selama 3 detik sebelum Web Server dimulai pada port 80.
c. Pemrosesan Data & Web Dashboard: 3. Pelayanan Request HTTP & Pembaruan LCD:
Pada fungsi loop(), ESP32 membaca nilai suhu (°C), kelembapan (%), dan kuantisasi ADC (0–4095) yang dipetakan ke persentase (0–100%). Baris pertama LCD menampilkan suhu dan baris kedua menampilkan kelembapan. Jika pembacaan DHT11 gagal, LCD secara otomatis menampilkan status error sensor dan nilai ADC mentah. Ketika browser client mengakses IP ESP32, server merespon dengan dokumen HTML/CSS lengkap yang memuat 3 kartu grafik visual melingkar (conic-gradient) untuk Suhu, Kelembapan, dan ADC, serta melakukan auto-refresh setiap 3 detik.
B. Proyek 2: Simulasi IoT Kontrol Kipas Otomatis & MQTT dengan DHT
Proyek 2 mengimplementasikan otomatisasi pendingin ruangan (kipas/LED) berbasis ambang batas suhu dan integrasi protokol MQTT terpusat berbasis MicroPython. Rincian pelaksanaan simulasi adalah sebagai berikut:
a. Skema Rangkaian Wokwi: 1. Konfigurasi Wiring Hardware:
Sensor DHT22 dihubungkan ke GPIO 4, Modul Relay dihubungkan ke GPIO 5, Anoda LED indikator kipas dihubungkan ke terminal Normal Open (NO) Relay dan Katoda ke GND via resistor, serta LCD I2C dihubungkan ke GPIO 21 (SDA) dan GPIO 22 (SCL).
b. Pengaturan Jaringan MQTT: 2. Konfigurasi Broker MQTT & Topik Pesan:
ESP32 terhubung ke Wi-Fi 'Wokwi-GUEST' dan terhubung ke MQTT Broker 'broker.emqx.io' (Port 1883) dengan Client ID b'esp32_wokwi_sim'. Topik publikasi telemetry diatur pada 'wokwi/esp32/data_lengkap' dan topik langganan perintah diatur pada 'wokwi/esp32/perintah_kipas'.
c. Skenario Pengujian Sistem: 3. Skenario Pengujian Mode Otomatis & Override:
1) Mode Otomatis: - Mode Otomatis (AUTO):
Ketika suhu udara dari DHT22 melebihi ambang batas 30°C, ESP32 mengaktifkan Relay (nilai 1) sehingga LED menyala, LCD menampilkan status 'ON (AUTO)', dan pesan dikirim ke MQTT Broker. Jika suhu <= 30°C, Relay mati dan status menjadi 'OFF(AUTO)'.
2) Interupsi Jarak Jauh: - Mode Manual Override (Interupsi MQTT):
Melalui aplikasi MQTTX, pengguna dapat mengabaikan kontrol otomatis dengan mengirimkan string pesan pada topik perintah. Pesan 'FORCE_ON' memaksa Relay dan LED menyala dengan status 'ON (FRCE)', pesan 'FORCE_OFF' mematikan Relay dengan status 'OFF(FRCE)', dan pesan 'AUTO' mengembalikan sistem ke kontrol ambang batas otomatis.
3.2 Program
Berikut adalah seluruh kode sumber (source code) resmi yang digunakan dalam praktikum minggu ketiga:
A. Source Code Proyek 1: ESP32 Environmental Monitoring Web Server (Arduino C++)
#include <WiFi.h>
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// =====================================================
// INFORMASI WI-FI
// =====================================================
const char* ssid = "iwak tempe";
const char* password = "12345678";
// =====================================================
// KONFIGURASI DHT11
// =====================================================
#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
// =====================================================
// KONFIGURASI ADC
// =====================================================
// Pin ADC ESP32
#define ADC_PIN 34
// ESP32 memiliki ADC 12-bit
// Nilai ADC = 0 - 4095
const int ADC_MAX = 4095;
// =====================================================
// KONFIGURASI LCD I2C
// =====================================================
LiquidCrystal_I2C lcd(0x27, 16, 2);
// =====================================================
// WEB SERVER
// =====================================================
WiFiServer server(80);
// =====================================================
// SETUP
// =====================================================
void setup() {
Serial.begin(115200);
// -----------------------------
// Inisialisasi sensor
// -----------------------------
dht.begin();
// Konfigurasi ADC
pinMode(ADC_PIN, INPUT);
analogReadResolution(12);
// -----------------------------
// Inisialisasi LCD
// -----------------------------
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Connecting WiFi");
// -----------------------------
// Menghubungkan WiFi
// -----------------------------
Serial.print("Menghubungkan ke ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWi-Fi Terhubung!");
Serial.print("Alamat IP: ");
Serial.println(WiFi.localIP());
// -----------------------------
// Tampilkan IP pada LCD
// -----------------------------
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("IP ESP32:");
lcd.setCursor(0, 1);
lcd.print(WiFi.localIP());
delay(3000);
// -----------------------------
// Jalankan Web Server
// -----------------------------
server.begin();
Serial.println("Web Server dimulai!");
}
// =====================================================
// LOOP
// =====================================================
void loop() {
// ===================================================
// MEMBACA SENSOR DHT11
// ===================================================
float humidity = dht.readHumidity();
float tempC = dht.readTemperature();
// ===================================================
// MEMBACA ADC
// ===================================================
int adcValue = analogRead(ADC_PIN);
// Konversi ADC ke persentase
int adcPercent = map(adcValue, 0, ADC_MAX, 0, 100);
// ===================================================
// SERIAL MONITOR
// ===================================================
Serial.println("============================");
if (!isnan(humidity) && !isnan(tempC)) {
Serial.print("Suhu : ");
Serial.print(tempC);
Serial.println(" C");
Serial.print("Kelembapan : ");
Serial.print(humidity);
Serial.println(" %");
} else {
Serial.println("DHT11 gagal dibaca!");
}
Serial.print("ADC : ");
Serial.println(adcValue);
Serial.print("ADC (%) : ");
Serial.print(adcPercent);
Serial.println(" %");
// ===================================================
// UPDATE LCD
// ===================================================
if (!isnan(humidity) && !isnan(tempC)) {
lcd.setCursor(0, 0);
lcd.print("Suhu:");
lcd.print(tempC, 1);
lcd.print((char)223);
lcd.print("C ");
lcd.setCursor(0, 1);
lcd.print("Hum:");
lcd.print(humidity, 1);
lcd.print("% ");
} else {
lcd.setCursor(0, 0);
lcd.print("Err Sensor DHT ");
lcd.setCursor(0, 1);
lcd.print("ADC:");
lcd.print(adcValue);
lcd.print(" ");
}
// ===================================================
// WEB SERVER
// ===================================================
WiFiClient client = server.available();
if (client) {
String requestHeader = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
requestHeader += c;
// HTTP request selesai
if (c == '\n') {
if (requestHeader.endsWith("\r\n\r\n")) {
// =================================================
// HTTP RESPONSE HEADER
// =================================================
client.println("HTTP/1.1 200 OK");
client.println(
"Content-Type: text/html; charset=utf-8"
);
client.println("Connection: close");
// Refresh setiap 3 detik
client.println("Refresh: 3");
client.println();
// =================================================
// HTML
// =================================================
client.println("<!DOCTYPE html>");
client.println("<html>");
client.println("<head>");
client.println(
"<meta name=\"viewport\" "
"content=\"width=device-width, initial-scale=1\">"
);
client.println(
"<title>ESP32 Environmental Monitor</title>"
);
// =================================================
// CSS
// =================================================
client.println("<style>");
client.println(
"* { box-sizing: border-box; }"
);
client.println(
"body {"
" margin: 0;"
" min-height: 100vh;"
" font-family: Arial, sans-serif;"
" background: linear-gradient(135deg, #0f172a, #1e293b);"
" color: white;"
" padding: 30px 15px;"
"}"
);
client.println(
".container {"
" max-width: 900px;"
" margin: auto;"
"}"
);
client.println(
".header {"
" text-align: center;"
" margin-bottom: 30px;"
"}"
);
client.println(
".header h1 {"
" margin: 0;"
" font-size: 30px;"
"}"
);
client.println(
".header p {"
" color: #94a3b8;"
" margin-top: 8px;"
"}"
);
// Grid kartu
client.println(
".dashboard {"
" display: grid;"
" grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));"
" gap: 20px;"
"}"
);
// Card
client.println(
".card {"
" background: rgba(255,255,255,0.08);"
" border: 1px solid rgba(255,255,255,0.1);"
" border-radius: 20px;"
" padding: 25px;"
" text-align: center;"
" backdrop-filter: blur(10px);"
" box-shadow: 0 10px 30px rgba(0,0,0,0.25);"
"}"
);
client.println(
".card h2 {"
" font-size: 18px;"
" margin-bottom: 20px;"
" color: #cbd5e1;"
"}"
);
// Lingkaran
client.println(
".circle {"
" width: 170px;"
" height: 170px;"
" border-radius: 50%;"
" margin: auto;"
" display: flex;"
" align-items: center;"
" justify-content: center;"
" position: relative;"
"}"
);
// Lingkaran bagian dalam
client.println(
".circle::after {"
" content: '';"
" position: absolute;"
" width: 130px;"
" height: 130px;"
" border-radius: 50%;"
" background: #172033;"
"}"
);
client.println(
".value {"
" position: relative;"
" z-index: 2;"
" font-size: 28px;"
" font-weight: bold;"
"}"
);
client.println(
".unit {"
" font-size: 14px;"
" color: #94a3b8;"
" margin-top: 5px;"
"}"
);
// Suhu
client.println(
".temp-circle {"
" background: conic-gradient("
"#ef4444 "
+ String((tempC / 50.0) * 360.0)
+ "deg, #334155 0deg);"
"}"
);
// Kelembapan
client.println(
".hum-circle {"
" background: conic-gradient("
"#38bdf8 "
+ String((humidity / 100.0) * 360.0)
+ "deg, #334155 0deg);"
"}"
);
// ADC
client.println(
".adc-circle {"
" background: conic-gradient("
"#a78bfa "
+ String((adcValue / 4095.0) * 360.0)
+ "deg, #334155 0deg);"
"}"
);
// Status
client.println(
".status {"
" margin-top: 30px;"
" padding: 15px;"
" background: rgba(34,197,94,0.12);"
" border: 1px solid rgba(34,197,94,0.3);"
" border-radius: 12px;"
" color: #86efac;"
"}"
);
client.println(
".footer {"
" text-align: center;"
" margin-top: 30px;"
" color: #64748b;"
" font-size: 13px;"
"}"
);
client.println("</style>");
client.println("</head>");
// =================================================
// BODY
// =================================================
client.println("<body>");
client.println("<div class=\"container\">");
// Header
client.println("<div class=\"header\">");
client.println(
"<h1>ESP32 Environmental Monitor</h1>"
);
client.println(
"<p>Monitoring Suhu, Kelembapan & ADC</p>"
);
client.println("</div>");
// =================================================
// DASHBOARD
// =================================================
client.println("<div class=\"dashboard\">");
// -------------------------------------------------
// SUHU
// -------------------------------------------------
client.println("<div class=\"card\">");
client.println("<h2>🌡️ SUHU</h2>");
client.println("<div class=\"circle temp-circle\">");
client.println(
"<div class=\"value\">"
+ String(tempC, 1)
+ "<div class=\"unit\">°C</div>"
"</div>"
);
client.println("</div>");
client.println("</div>");
// -------------------------------------------------
// KELEMBAPAN
// -------------------------------------------------
client.println("<div class=\"card\">");
client.println("<h2>💧 KELEMBAPAN</h2>");
client.println("<div class=\"circle hum-circle\">");
client.println(
"<div class=\"value\">"
+ String(humidity, 1)
+ "<div class=\"unit\">%</div>"
"</div>"
);
client.println("</div>");
client.println("</div>");
// -------------------------------------------------
// ADC
// -------------------------------------------------
client.println("<div class=\"card\">");
client.println("<h2>📊 NILAI ADC</h2>");
client.println("<div class=\"circle adc-circle\">");
client.println(
"<div class=\"value\">"
+ String(adcValue)
+ "<div class=\"unit\">/ 4095</div>"
"</div>"
);
client.println("</div>");
client.println(
"<p style=\"color:#94a3b8; margin-top:15px;\">"
+ String(adcPercent)
+ "% dari maksimum"
"</p>"
);
client.println("</div>");
client.println("</div>");
// =================================================
// STATUS
// =================================================
client.println("<div class=\"status\">");
client.println("● ESP32 Online | Wi-Fi Terhubung");
client.println("</div>");
// =================================================
// FOOTER
// =================================================
client.println(
"<div class=\"footer\">"
"ESP32 IoT Monitoring System"
"</div>"
);
client.println("</div>");
client.println("</body>");
client.println("</html>");
break;
}
}
}
}
client.stop();
}
// DHT11 sebaiknya tidak dibaca terlalu cepat
delay(2000);
}B. Source Code Proyek 2: Kontrol Kipas Otomatis & MQTT (MicroPython)
1. Library LCD I2C (machine_i2c_lcd.py):
import time
class I2cLcd:
LCD_CLEARDISPLAY = 0x01
LCD_RETURNHOME = 0x02
LCD_ENTRYMODESET = 0x04
LCD_DISPLAYCONTROL = 0x08
LCD_CURSORSHIFT = 0x10
LCD_FUNCTIONSET = 0x20
LCD_SETDDRAMADDR = 0x80
LCD_DISPLAYON = 0x04
LCD_CURSOROFF = 0x00
LCD_BLINKOFF = 0x00
LCD_4BITMODE = 0x00
LCD_2LINE = 0x08
LCD_5x8DOTS = 0x00
def __init__(self, i2c, i2c_addr, num_lines, num_columns):
self.i2c = i2c
self.i2c_addr = i2c_addr
self.num_lines = num_lines
self.num_columns = num_columns
self.backlight = 0x08
time.sleep_ms(20)
self.hal_write_init_nibble(0x30)
time.sleep_ms(5)
self.hal_write_init_nibble(0x30)
time.sleep_ms(1)
self.hal_write_init_nibble(0x30)
time.sleep_ms(1)
self.hal_write_init_nibble(0x20)
time.sleep_ms(1)
self.hal_write_command(self.LCD_FUNCTIONSET | self.LCD_4BITMODE | self.LCD_2LINE | self.LCD_5x8DOTS)
self.hal_write_command(self.LCD_DISPLAYCONTROL | self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF)
self.clear()
def hal_write_init_nibble(self, nibble):
byte = (nibble & 0xF0) | self.backlight
self.i2c.writeto(self.i2c_addr, bytearray([byte | 0x04]))
self.i2c.writeto(self.i2c_addr, bytearray([byte]))
def hal_write_command(self, cmd):
byte = (cmd & 0xF0) | self.backlight
self.i2c.writeto(self.i2c_addr, bytearray([byte | 0x04]))
self.i2c.writeto(self.i2c_addr, bytearray([byte]))
byte = ((cmd << 4) & 0xF0) | self.backlight
self.i2c.writeto(self.i2c_addr, bytearray([byte | 0x04]))
self.i2c.writeto(self.i2c_addr, bytearray([byte]))
if cmd <= 3:
time.sleep_ms(5)
def hal_write_data(self, data):
byte = (data & 0xF0) | self.backlight | 0x01
self.i2c.writeto(self.i2c_addr, bytearray([byte | 0x04]))
self.i2c.writeto(self.i2c_addr, bytearray([byte]))
byte = ((data << 4) & 0xF0) | self.backlight | 0x01
self.i2c.writeto(self.i2c_addr, bytearray([byte | 0x04]))
self.i2c.writeto(self.i2c_addr, bytearray([byte]))
def clear(self):
self.hal_write_command(self.LCD_CLEARDISPLAY)
def move_to(self, cursor_x, cursor_y):
addr = cursor_x & 0x3F
if cursor_y == 1:
addr += 0x40
self.hal_write_command(self.LCD_SETDDRAMADDR | addr)
def putstr(self, string):
for char in string:
self.hal_write_data(ord(char))2. Program Utama MQTT & Control Logic (main.py):
import machine
import dht
import time
import network
from machine import I2C, Pin
from machine_i2c_lcd import I2cLcd
from umqtt.simple import MQTTClient
# Konfigurasi Jaringan & MQTT Broker
WIFI_SSID = 'Wokwi-GUEST'
WIFI_PASSWORD = ''
MQTT_BROKER = 'broker.emqx.io'
MQTT_CLIENT_ID = b'esp32_wokwi_sim'
TOPIC_DATA = b'wokwi/esp32/data_lengkap'
TOPIC_PERINTAH = b'wokwi/esp32/perintah_kipas'
mode_sistem = "AUTO"
status_paksa = 0
# Inisialisasi Perangkat
sensor_dht = dht.DHT22(Pin(4))
relay = Pin(5, Pin.OUT)
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16)
# Callback MQTT Menerima Perintah
def pesan_diterima(topic, msg):
global mode_sistem, status_paksa
pesan = msg.decode('utf-8')
print("Menerima Perintah: {}".format(pesan))
if pesan == "FORCE_ON":
mode_sistem = "MANUAL"
status_paksa = 1
elif pesan == "FORCE_OFF":
mode_sistem = "MANUAL"
status_paksa = 0
elif pesan == "AUTO":
mode_sistem = "AUTO"
def connect_wifi():
lcd.clear()
lcd.putstr("Koneksi WiFi...")
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect(WIFI_SSID, WIFI_PASSWORD)
while not sta_if.isconnected():
time.sleep(0.5)
lcd.clear()
lcd.putstr("WiFi Terhubung!")
time.sleep(1)
connect_wifi()
client = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER)
client.set_callback(pesan_diterima)
client.connect()
client.subscribe(TOPIC_PERINTAH)
lcd.clear()
waktu_terakhir = 0
interval_publish = 2000
suhu = 0.0
kelembapan = 0.0
status_kipas = "OFF(AUTO)"
while True:
try:
client.check_msg()
except:
pass
waktu_sekarang = time.ticks_ms()
if time.ticks_diff(waktu_sekarang, waktu_terakhir) >= interval_publish:
waktu_terakhir = waktu_sekarang
# 1. Baca Sensor
try:
sensor_dht.measure()
suhu = sensor_dht.temperature()
kelembapan = sensor_dht.humidity()
except OSError:
print("Gagal membaca sensor, memakai data terakhir.")
# 2. Logika Override
if mode_sistem == "AUTO":
if suhu > 30:
relay.value(1)
status_kipas = "ON (AUTO)"
else:
relay.value(0)
status_kipas = "OFF(AUTO)"
elif mode_sistem == "MANUAL":
relay.value(status_paksa)
status_kipas = "ON (FRCE)" if status_paksa == 1 else "OFF(FRCE)"
# 3. Format Data Telemetry
teks_suhu_lembap = "S:{:.1f}C L:{:.0f}%".format(suhu, kelembapan)
teks_kipas = "Kipas: {}".format(status_kipas)
payload_gabungan = "{} | {}".format(teks_suhu_lembap, teks_kipas)
# Tampilkan pada LCD & Console
lcd.move_to(0, 0)
lcd.putstr(teks_suhu_lembap + " " * (16 - len(teks_suhu_lembap)))
lcd.move_to(0, 1)
lcd.putstr(teks_kipas + " " * (16 - len(teks_kipas)))
print(payload_gabungan)
# 4. Kirim Data ke MQTT Broker
try:
client.publish(TOPIC_DATA, payload_gabungan.encode())
except Exception as e:
print("Gagal Publish ke MQTT:", e)
time.sleep_ms(10)4.1 Kesimpulan
Berdasarkan hasil perancangan, pengujian, dan analisis simulasi pada praktikum minggu ketiga, diperoleh kesimpulan sebagai berikut:
1. ESP32 berhasil dikonfigurasi sebagai embedded HTTP Web Server lokal yang mampu melayani request HTML/CSS interaktif untuk menampilkan pemantauan suhu, kelembapan, dan persentase kuantisasi ADC 12-bit secara real-time dengan fitur auto-refresh setiap 3 detik.
2. Integrasi modul display LCD I2C 16x2 terbukti efektif dalam menyajikan alamat IP jaringan Wi-Fi saat inisialisasi serta menampilkan telemetry data sensorik secara lokal tanpa mengganggu proses komunikasi jaringan.
3. Implementasi protokol MQTT berbasis Publish-Subscribe pada ESP32 berhasil menghubungkan sistem otomatisasi kipas/LED berbasis ambang batas suhu (> 30°C) dengan aplikasi pusat kendali MQTTX. Fitur callback terbukti mampu melakukan interupsi kendali manual override (FORCE_ON, FORCE_OFF, AUTO) secara sangat responsif.
4.2 Saran
Saran yang dapat diberikan untuk pengembangan sistem lebih lanjut adalah:
1. Mengimplementasikan Wi-Fi Manager dan memori non-volatile (EEPROM/NVS) untuk penyimpanan kredensial Wi-Fi agar tidak hardcoded pada kode program.
2. Menambahkan mekanisme pemulihan koneksi otomatis (auto-reconnect) pada fungsi MQTT client untuk mengantisipasi potensi terputusnya koneksi ke broker publik emqx.io.
[1] UNESA Computer Architecture Team, "Modul 3: Peripheral Input Output dan Pemrograman Web Server ESP32," Surabaya: Universitas Negeri Surabaya, 2024.
[2] Espressif Systems, "ESP32 Technical Reference Manual Version 4.8," Espressif Systems, 2023.
[3] OASIS Open, "MQTT Version 5.0 Standard Specification," OASIS Standard, 2019.
[4] A. Kurniawan, "IoT Systems: MicroPython Programming for ESP32 and Sensor Integration," Jakarta: Informatika, 2022.
Video Demo: https://www.youtube.com/watch?v=uDMA5kSl_rw
Tidak ada komentar:
Posting Komentar