Minggu, 27 September 2026

LAPORAN PRAKTIKUM MINGGU KE-3: Sistem Monitoring Suhu dan Kelembaban Udara

Disusun Oleh:
Risqi Prasdika(24051204008)
Rahmat Ari Setyarto(24051204010)
Carmelio Sivandra A.(24051204116)
Rifqi Syawal(24051204198)
Azzam Ghifari(24051204178)

BAB IPENDAHULUAN
1.1 Latar Belakang

Suhu dan kelembapan menentukan kenyamanan penghuni ruangan, kualitas hasil budidaya, umur peralatan elektronik, dan mutu barang gudang. Panas berlebih menurunkan kinerja prosesor dan mempercepat kerusakan komponen di ruang server. Kelembapan tinggi memicu korosi dan jamur; kelembapan rendah meningkatkan risiko pelepasan muatan statis. Rumah kaca, kandang ternak, dan ruang penyimpanan makanan pun menuntut suhu stabil dalam rentang tertentu.

Termometer dan higrometer konvensional mengandalkan petugas yang membaca alat pada jam tertentu, dan cara ini menyimpan empat celah: data terputus di antara dua pembacaan, pemantauan bergantung pada kehadiran petugas, tidak ada peringatan saat nilai melewati batas aman, dan kipas atau ventilasi baru menyala setelah petugas menyalakannya secara manual sehingga pendinginan terlambat jika suhu naik di luar jam pemeriksaan.

Internet of Things (IoT) menutup celah ini dengan menghubungkan sensor, mikrokontroler, dan jaringan komputer: sensor membaca kondisi lingkungan, mikrokontroler mengolah dan mengirim data, dan pengguna memantau hasilnya lewat peramban atau ponsel. ESP32 buatan Espressif Systems cocok untuk peran ini. Chip ini membawa dua inti prosesor, modul Wi-Fi dan Bluetooth terintegrasi, ADC, keluaran PWM, dan dukungan pustaka luas di Arduino IDE maupun PlatformIO. Harganya terjangkau, sehingga satu perangkat merangkap node sensor sekaligus pengendali aktuator.

Banyak pengembang menjalankan web server langsung di ESP32: pengguna membuka alamat IP perangkat dari jaringan lokal untuk membaca suhu dan kelembapan, lalu mengubah mode kipas. Pendekatan ini sederhana tetapi terbatas. Jangkauannya hanya mencapai jaringan lokal. Setiap klien yang membuka koneksi TCP menggerus SRAM 520 KB yang tersedia. Halaman web harus melakukan polling berulang untuk data terbaru, dan ESP32 sendiri tidak bisa mendistribusikan data ke banyak penerima sekaligus tanpa perantara.

MQTT (Message Queuing Telemetry Transport) mengatasi keterbatasan ini lewat model publish/subscribe dengan broker sebagai perantara. ESP32 memublikasikan data ke sebuah topic, dan setiap pelanggan topik itu dashboard, aplikasi ponsel, atau Node-RED menerima data tanpa perlu mengetahui alamat ESP32. Header MQTT yang hanya 2 byte membuat protokol ini hemat bandwidth dan memori, sementara fitur Quality of Service (QoS), retained message, dan Last Will and Testament (LWT) menjaga keandalan pada jaringan Wi-Fi yang tidak stabil.

Pengendalian kipas otomatis melengkapi sistem ini. ESP32 membandingkan suhu terukur dengan ambang batas, lalu menggerakkan relay atau MOSFET untuk menyalakan kipas. Histeresis mencegah kipas hidup-mati berulang di sekitar nilai ambang, dan pengguna tetap bisa mengambil alih kipas lewat perintah manual dari MQTT atau halaman web.

Berdasarkan uraian ini, penelitian mengimplementasikan ESP32 sebagai node pemantau lingkungan dengan web server lokal, memublikasikan data sensor ke broker MQTT, dan mengendalikan kipas dalam mode otomatis maupun manual. Penelitian menguji akurasi sensor, latensi pengiriman data, dan ketepatan respons kipas terhadap perubahan suhu.

1.2 Rumusan Masalah

Bagaimana merancang perangkat keras berbasis ESP32 yang membaca sensor suhu dan kelembapan serta menggerakkan kipas melalui relay atau driver transistor ?

Bagaimana mengimplementasikan web server pada ESP32 untuk menampilkan data suhu dan kelembapan serta mengubah mode kontrol kipas ?

Bagaimana mengimplementasikan protokol MQTT pada ESP32, meliputi struktur topic, format payload, dan pemilihan QoS, untuk mengirim data sensor dan menerima perintah kontrol ?

Bagaimana menerapkan logika kontrol kipas otomatis berbasis ambang suhu dengan histeresis, dan bagaimana logika itu berpindah antara mode otomatis dan manual ?

Bagaimana unjuk kerja sistem, diukur dari akurasi sensor, latensi pengiriman data, tingkat kehilangan paket, dan waktu respons kipas ?


1.3 Tujuan Laporan

Laporan ini bertujuan menjelaskan rancangan sistem monitoring suhu dan kelembapan berbasis ESP32-C3 dengan sensor DHT22 melalui simulasi Wokwi. Pembahasan mencakup hubungan antarkomponen, persiapan perangkat lunak, dan alur program yang membaca sensor secara berkala, menampilkan data pada LCD 16×2, serta menyimpan hasil pembacaan ke kartu microSD. Laporan ini juga menjelaskan penggunaan Serial Monitor untuk memeriksa status sistem, membaca sensor, dan mengelola catatan pengukuran.

Rancangan tersebut menjadi dasar pengembangan sistem IoT yang dibahas pada bagian pendahuluan, yaitu pemantauan melalui web server, pertukaran data menggunakan MQTT, dan pengendalian kipas otomatis maupun manual. Program yang dicantumkan dalam laporan masih berfokus pada pemantauan dan pencatatan lokal, sehingga evaluasi komunikasi jaringan dan respons kipas memerlukan implementasi serta pengujian lanjutan.

1.4 Manfaat Penulisan

Penulisan laporan ini membantu mahasiswa memahami hubungan antara sensor, mikrokontroler, perangkat tampilan, dan media penyimpanan dalam sistem monitoring lingkungan. Melalui rancangan yang disajikan, mahasiswa dapat mempelajari pembacaan DHT22, komunikasi I2C untuk LCD, komunikasi SPI untuk kartu microSD, serta penjadwalan pembacaan sensor dan perubahan keadaan LED menggunakan fungsi millis().

Laporan ini juga menyediakan acuan untuk menyiapkan simulasi, menelusuri alur program, dan memeriksa fungsi sistem melalui Serial Monitor. Pencatatan suhu dan kelembapan ke dalam berkas memberi dasar untuk pengolahan data pada tahap berikutnya. Rancangan ini dapat dikembangkan lebih lanjut dengan koneksi jaringan dan aktuator, kemudian diuji pada perangkat fisik untuk menilai kesesuaiannya dengan kebutuhan pemantauan lingkungan.

BAB IITINJAUAN PUSTAKA
2.1 Dasar Teori

IoT menghubungkan perangkat bersensor ke jaringan agar perangkat bertukar data tanpa perantara manusia. Perangkat berkomunikasi dengan dua cara: pada polling, penerima meminta data berulang kali; pada push, pengirim mengirim data begitu data siap. Soni dan Makwana menilai protokol push lebih cocok untuk perangkat IoT karena ringan dan produktif [1]. Pemantauan lingkungan mencakup suhu (tingkat panas udara dalam derajat Celsius) dan kelembapan relatif (perbandingan tekanan uap air aktual terhadap tekanan uap air jenuh pada suhu yang sama, dalam persen). Macheso dkk. menyebut bahwa menjaga proses pada rentang suhu dan kelembapan tertentu memerlukan web server berbiaya dan berdaya rendah yang memantau kedua besaran itu dalam waktu nyata [2].

ESP32 memenuhi kebutuhan ini. Maier dkk. mendefinisikannya sebagai system on chip berbiaya dan berdaya rendah dengan Wi-Fi dan Bluetooth terintegrasi, memakai prosesor dual-core Tensilica Xtensa LX6 [3]. Modulnya memuat antena, osilator, dan memori flash, sehingga pengembang tidak perlu merangkai komponen itu sendiri [3]. Macheso dkk. memakai papan NodeMCU-32S dan memrogramnya lewat Arduino IDE untuk membangun web server pemantau suhu [2]. Pin GPIO ESP32 berlogika 3,3 V dan tidak mampu mengalirkan arus sebesar kebutuhan kipas, sehingga kipas memerlukan relay atau transistor sebagai penggerak.

DHT22 mengukur suhu dan kelembapan lalu mengirim datanya lewat satu kabel data. Sensor ini memerlukan jeda minimal dua detik antara dua pembacaan, sehingga program membacanya pada interval yang lebih besar. Macheso dkk. menghubungkan DHT22 ke ESP32 untuk memantau suhu dan kelembapan dalam waktu nyata [2], dan Roihan dkk. memakai pasangan yang sama sebagai sumber data untuk kipas otomatis [4]. Sensor berbiaya rendah menyimpang dari alat ukur acuan, sehingga penelitian ini membandingkan DHT22 dengan termohigrometer referensi dan menghitung galatnya.

Roihan dkk. mengendalikan kipas DC 12 V dengan modul relay dari ESP32 [4]. Relay bekerja sebagai saklar elektromekanis yang memisahkan sisi kontrol berdaya kecil dari sisi beban berdaya besar: ESP32 mengirim sinyal HIGH atau LOW ke pin masukan relay, dan relay menutup atau membuka rangkaian kipas. Banyak modul relay berjenis active-low, sehingga relay aktif saat pin berlogika LOW.

HTTP memakai pola permintaan dan balasan, sehingga halaman yang menampilkan data terbaru harus mengirim permintaan berulang. Macheso dkk. merancang web server asinkron berbiaya rendah pada ESP32 dengan DHT22 [2]; server asinkron menerima permintaan tanpa memblokir program utama, sehingga ESP32 tetap membaca sensor selagi melayani klien. Rancangan semacam ini memakai tiga alamat: satu menyajikan halaman dashboard, satu mengembalikan data sensor dalam format JSON, dan satu mengubah mode dan status kipas. Jangkauan server terbatas pada jaringan lokal, dan memori ESP32 membatasi jumlah klien. Pendekatan push milik MQTT mengatasi kedua keterbatasan ini [1].

Soni dan Makwana menyebut MQTT sebagai protokol push paling banyak dipakai dibanding XMPP dan AMQP, dengan ciri ringan dan hemat bandwidth [1]. MQTT memiliki tiga komponen: publisher mengirim pesan ke sebuah topic, subscriber berlangganan topic untuk menerima pesan tertentu, dan broker menerima semua pesan dari publisher, menyaringnya, lalu meneruskannya ke subscriber yang berminat [1]. Broker sebagai perantara membuat publisher dan subscriber tidak perlu tahu alamat satu sama lain. Topic berupa string berjenjang dengan garis miring sebagai pemisah tingkat, misalnya ruang1/sensor/suhu; tanda + menggantikan satu tingkat, dan tanda # menggantikan semua tingkat di bawahnya. MQTT menyediakan tiga level Quality of Service: level 0 mengirim paling banyak satu kali tanpa konfirmasi, level 1 mengirim minimal satu kali dengan konfirmasi, dan level 2 mengirim tepat satu kali lewat empat langkah jabat tangan. Retained message membuat broker menyimpan pesan terakhir sebuah topic untuk subscriber baru, sedangkan Last Will and Testament membuat broker mempublikasikan pesan titipan saat klien terputus tanpa pamit. Soni dan Makwana mencatat bahwa setiap broker memiliki keterbatasan dan belum ada yang menerapkan prioritas data [1]. Karena itu, penelitian ini memilih broker dan level QoS sesuai kebutuhan sistem. Roihan dkk. mengirim data lewat broker shiftr.io setiap 10 detik dan tidak kehilangan paket selama pengujian [4]. Penelitian ini memakai QoS 0 untuk data sensor, karena data berikutnya menggantikan data yang hilang, dan QoS 1 untuk perintah kipas, karena perintah tidak boleh hilang.

Roihan dkk. membangun prototipe kipas otomatis berdasarkan suhu ruangan dengan ESP32 sebagai pengendali utama, dan mencatat waktu respons kontrol sekitar 760 ms [4]. Mereka menyebut penelitian sebelumnya umumnya mengandalkan kontrol lokal, sedangkan sistem mereka menambah pemantauan web lewat MQTT [4]. Kontrol on-off dengan satu ambang menyalakan dan mematikan kipas berulang kali saat suhu bergerak di sekitar ambang tersebut. Gejala ini disebut chattering dan memperpendek umur relay. Histeresis memakai dua ambang, T_on dan T_off, dengan T_on lebih besar daripada T_off: kipas menyala saat suhu mencapai atau melewati T_on, mati saat suhu turun ke T_off atau lebih rendah, dan mempertahankan keadaan sebelumnya di antara keduanya. Sistem memiliki dua mode. Pada mode otomatis, ESP32 menjalankan aturan histeresis ini. Pada mode manual, ESP32 mengikuti perintah pengguna dari halaman web atau MQTT.

Roihan dkk. menilai sistem lewat waktu respons kontrol dan kehilangan paket [4]. Penelitian ini memakai empat parameter sejenis. Penelitian ini mengukur galat sensor dengan RMSE, akar dari rata-rata kuadrat selisih antara pembacaan DHT22 dan alat ukur referensi. Latensi adalah waktu terima dikurangi waktu kirim. Tingkat kehilangan paket adalah jumlah pesan terkirim dikurangi jumlah pesan terterima, dibagi jumlah pesan terkirim, lalu dikali 100%. Waktu respons kipas adalah selang dari suhu melewati ambang sampai kipas menyala.

2.2 Komponen

Berikut adalah daftar perangkat keras dan perangkat lunak yang digunakan dalam simulasi dan implementasi Proyek Minggu Ke-3:

NoKomponen / Software
11 half breadboard
21 ESP32-C3-MINI-1
31 dht22
41 LED Merah
51 Resistor 220 ohm
61 Resistor 10k ohm
71 microSd card
81 lcd 16x2 (l2c)
BAB IIIPEMBAHASAN
3.1 Penjelasan Simulasi
Install Arduino CLI

Langkah 1: Download

Buka: https://arduino.github.io/arduino-cli/latest/installation/

Pilih Windows → Windows 64-bit

Download file: arduino-cli_latest_Windows_64bit.zip

Langkah 2: Ekstrak

Buat folder: C:\arduino-cli\

Ekstrak isi ZIP ke folder tersebut

Pastikan ada file: C:\arduino-cli\arduino-cli.exe

Langkah 3: Tambahkan ke PATH

Tekan Win + R → ketik sysdm.cpl → Enter

Tab Advanced → klik Environment Variables

Di bagian User variables → pilih Path → klik Edit

Klik New → tambahkan: C:\arduino-cli\

OK → OK → OK

Tutup dan buka ulang VS Code

Langkah 4: Verifikasi

Buka Terminal di VS Code (Ctrl + ~), jalankan:

powershell

arduino-cli version

Harus muncul: arduino-cli Version: 1.x.x ...

SETUP ARDUINO CLI
🅰️ Update Index & Tambah Board Manager

powershell

arduino-cli core update-index
arduino-cli config init
arduino-cli config add board_manager.additional_urls https://espressif.github.io/arduino-esp32/package_esp32_index.json
arduino-cli core update-index
🅱️ Install ESP32 Core
arduino-cli core install esp32:esp32

⏱️ Proses ini butuh 5-10 menit (~500MB download). Sabar ya!

Verifikasi:

arduino-cli core list

Harus muncul:

IDInstalled Latest Name
esp32:esp32 3.3.123.3.12 esp32
🅲 Install Library Pendukung

powershell

arduino-cli lib install "DHT sensor library"
arduino-cli lib install "LiquidCrystal I2C"

⚠️ JANGAN install library SD via CLI! Library SD untuk ESP32 sudah built-in di core esp32:esp32. Kalau sudah terlanjur install, hapus:

powershell

arduino-cli lib uninstall SD

Verifikasi:

powershell

arduino-cli lib list

Harus muncul:

NameInstalled
DHT sensor library1.4.6
LiquidCrystal I2C1.1.4
SETUP EXTENSION WOKWI VS CODE
🅰️ Install Extension

Buka VS Code

Tekan Ctrl + Shift + X (buka panel Extensions)

Cari: Wokwi Simulator

Pilih yang Publisher: Wokwi (ikon biru)

Klik Install

Restart VS Code saat diminta

🅱️ Aktivasi Lisensi

Tekan Ctrl + Shift + P → ketik Wokwi: Request a License

Akan muncul notifikasi dengan instruksi

Buka browser → https://wokwi.com/arduino/install

Login dengan akun Wokwi (Google/GitHub/email)

Copy license token yang muncul (format: wokwi-xxxx-xxxx-xxxx)

Kembali ke VS Code → Ctrl + Shift + P → Wokwi: Activate License

Paste token → Enter

✅ Jika berhasil: pojok kanan bawah muncul "Wokwi license activated"

STRUKTUR FOLDER PROJECT
📁 Struktur Folder Akhir
ESP32-SensorMonitor/
│
├── .vscode/
│   └── settings.json              ← Konfigurasi includePath
│
├── build/                          ← Auto-generate saat compile
│   └── esp32.esp32.esp32c3/
│       ├── ESP32-SensorMonitor.ino.bin
│       ├── ESP32-SensorMonitor.ino.elf
│       └── ESP32-SensorMonitor.ino.map
│
├── ESP32-SensorMonitor.ino         ← Kode utama ESP32
├── diagram.json                    ← Konfigurasi komponen & wiring
├── libraries.txt                   ← Daftar library (untuk Wokwi)
├── wokwi.toml                      ← Konfigurasi build
└── compile.ps1                     ← (Opsional) Script compile
MEMBUAT FILE-FILE PROJECT
📄 File 1: ESP32-SensorMonitor.ino

Copy seluruh kode dari file ESP32-SensorMonitor.ino yang sudah saya lampirkan ke file ini.

⚠️ PENTING: Pastikan nama file sesuai dengan yang ada di wokwi.toml:

File: ESP32-SensorMonitor.ino

wokwi.toml: ESP32-SensorMonitor.ino.bin ✅

📄 File 2: diagram.json

Copy seluruh isi dari file diagram.json yang sudah saya lampirkan.

📄 File 3: wokwi.toml

Copy seluruh isi dari file wokwi.tomlyang sudah saya lampirkan.

📄 File 4: libraries.txt

Copy seluruh isi dari file libraries.txt yang sudah saya lampirkan.

💡 Catatan: File ini hanya dibaca oleh Wokwi web untuk tahu library apa yang harus di-load. Di VS Code + Arduino CLI, library harus di-install via arduino-cli lib install (sudah dilakukan di langkah 3).

📄 File 5: .vscode/settings.json

Buat folder .vscode/ di root project, lalu buat file settings.json:

Copy seluruh isi dari file .vscode/settings.json yang sudah saya lampirkan.

📌 Sesuaikan path dengan lokasi install Arduino CLI di komputermu. Cek dengan:

powershell

arduino-cli config dump

Cari baris data.dir dan user.dir.

📄 File 6: compile.ps1 (Opsional, tapi sangat membantu)

powershell

# compile.ps1 — Script compile otomatis
Write-Host "🔧 Compiling ESP32-C3..." -ForegroundColor Cyan
Write-Host ""
arduino-cli compile `
    --fqbn esp32:esp32:esp32c3 `
    --output-dir build/esp32.esp32.esp32c3 `
    --warnings none `
    .
if ($LASTEXITCODE -eq 0) {
    Write-Host ""
    Write-Host "✅ Compile sukses!" -ForegroundColor Green
    Write-Host "📁 Output:" -ForegroundColor Yellow
    Get-ChildItem build\esp32.esp32.esp32c3\ | Format-Table Name, Length
    Write-Host ""
    Write-Host "▶️  Langkah selanjutnya:" -ForegroundColor Cyan
    Write-Host "   Ctrl + Shift + P → 'Wokwi: Start Simulator'" -ForegroundColor White
} else {
    Write-Host ""
    Write-Host "❌ Compile gagal! Cek error di atas." -ForegroundColor Red
}
COMPILE PROJECT
🅰️ Cara 1: Via Terminal (Manual)

Buka Terminal di VS Code (Ctrl + ~), lalu jalankan:

powershell

arduino-cli compile --fqbn esp32:esp32:esp32c3 --output-dir build/esp32.esp32.esp32c3 .

⏱️ Compile pertama kali: 2-5 menit (download toolchain)

⚡ Compile berikutnya: 10-30 detik (cached)

🅱️ Cara 2: Via Script PowerShell

powershell

.\compile.ps1

💡 Kalau muncul error running scripts is disabled, buka PowerShell as Administrator dan jalankan:

powershell

Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
✅ Cek Hasil Compile

Setelah compile sukses, cek folder build/esp32.esp32.esp32c3/:

powershell

dir build\esp32.esp32.esp32c3\

Harus muncul:

Name                                     Length
----                                     ------
ESP32-SensorMonitor.ino.bin              ~900KB    ← Firmware
ESP32-SensorMonitor.ino.elf              ~15MB     ← Debug symbols
ESP32-SensorMonitor.ino.map              ~5MB      ← Memory map

⚠️ PENTING: Nama file .bin dan .elf HARUS sesuai dengan yang ada di wokwi.toml. Kalau nama berbeda, rename file .ino kamu atau edit wokwi.toml.

MENJALANKAN SIMULASI
🅰️ Start Simulator

Tekan Ctrl + Shift + P (Command Palette)

Ketik: Wokwi: Start Simulator

Pilih dari daftar

Atau via Wokwi Sidebar:

Klik ikon Wokwi di Activity Bar kiri

Klik ▶️ Start Simulation

🅱️ Yang Akan Muncul

Panel Wokwi Simulator akan terbuka dengan:

🔴 LED merah berkedip (heartbeat)

📺 LCD menampilkan "Booting..." lalu "Suhu: XX.X C"

🌡️ DHT22 sensor

💾 SD Card adapter

🧩 Breadboard dengan wiring

🅲 Serial Monitor

Untuk melihat log:

Klik ikon Serial Monitor di toolbar bawah Wokwi, atau

Ctrl + Shift + P → Wokwi: Show Serial Monitor

Output yang diharapkan:

=========================================
  ESP32-C3 Sensor Monitor (Data Logger)
=========================================
[LCD] OK (SDA=8, SCL=9)
[DHT] OK (pin=4)
[SD] Init SPI...
[SD] Mounted OK
[SD] Total: 7 MB
=========================================
  Ketik 'help' di Serial Monitor
=========================================
[DHT] Suhu: 24.0 C | Hum: 40.0 %
[SD] Logged → datalog.txt
[DHT] Suhu: 24.1 C | Hum: 40.2 %
[SD] Logged → datalog.txt
TESTING FITUR

Semua fitur bisa dites via Serial Monitor. Klik kolom input di bawah Serial Monitor, ketik perintah, tekan Enter.

🎯 Perintah yang Tersedia
PerintahFungsi
helpTampilkan menu bantuan
statusStatus sistem (SD, sensor)
dataBaca sensor sekarang
logTampilkan isi datalog.txt
sdinfoInfo SD Card + daftar file
clearHapus datalog.txt
📝 Contoh Test
Test 1: Cek Status Sistem

ketik status di terminal saat running simulasi seperti ini :

Output:

Lampiran gambar simulasi
=== STATUS SISTEM ===
SD Ready : YES
Suhu     : 24.0 C
Hum      : 40.0 %
Uptime   : 65986 ms
=====================
Test 2: Baca Sensor On-Demand

ketik data di terminal

Output:

[DHT] Suhu: 24.1 C | Hum: 40.2 %
Test 3: Lihat Data Log

ketik log terminal

Output:

=== ISI datalog.txt ===
Suhu: 24.0 C, Kelembapan: 40.0 %
Suhu: 24.1 C, Kelembapan: 40.2 %
Suhu: 24.0 C, Kelembapan: 40.1 %
=======================
Test 4: Info SD Card

sdinfo

Output:

=== SD CARD INFO ===
  Total : 7 MB
  Used  : 0 MB
  Files :
    /datalog.txt         (150 bytes)
====================
Test 5: Hapus Log

clear

Output:

[SD] datalog.txt dihapus
🎯 Verifikasi Fitur
FiturCara VerifikasiStatus
LCDLihat panel Wokwi LCD menampilkan suhu✅/❌
DHT22Serial Monitor log [DHT] Suhu: ...✅/❌
SD CardSerial Monitor log [SD] Logged + perintah sdinfo✅/❌
LEDLED merah berkedip tiap 1 detik✅/❌
3.2 Program

Berikut adalah seluruh kode sumber (source code) resmi yang digunakan dalam praktikum minggu ketiga:

A. ESP32-SensorMonitor\diagram.json
{
  "version": 1,
  "author": "Risqi Prasdika",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-breadboard-half", "id": "bb1", "top": 189, "left": -160.4, "attrs": {} },
    { "type": "board-esp32-c3-devkitm-1", "id": "esp", "top": 239.7, "left": 178.62, "attrs": {} },
    { "type": "wokwi-dht22", "id": "dht1", "top": 38.7, "left": 196.2, "attrs": {} },
    {
      "type": "wokwi-resistor",
      "id": "r1",
      "top": 167.15,
      "left": -172.8,
      "attrs": { "value": "10000" }
    },
    {
      "type": "wokwi-lcd1602",
      "id": "lcd1",
      "top": 25.6,
      "left": -119.2,
      "attrs": { "pins": "i2c" }
    },
    { "type": "wokwi-microsd-card", "id": "sd1", "top": 163.43, "left": 182.47, "attrs": {} },
    { "type": "wokwi-led", "id": "led1", "top": 102, "left": -159.4, "attrs": { "color": "red" } },
    {
      "type": "wokwi-resistor",
      "id": "r2",
      "top": 167.15,
      "left": -96,
      "attrs": { "value": "220" }
    }
  ],
  "connections": [
    [ "esp:TX", "$serialMonitor:RX", "", [] ],
    [ "esp:RX", "$serialMonitor:TX", "", [] ],
    [ "esp:3V3.1", "bb1:tp.25", "green", [ "h0" ] ],
    [ "esp:GND.1", "bb1:tn.25", "black", [ "h0" ] ],
    [ "esp:5V.1", "lcd1:VCC", "red",  [ "h0" ] ],
    [ "lcd1:GND", "bb1:tn.24", "black", [ "h0" ] ],
    [ "lcd1:SDA", "esp:8", "green", [ "h0" ] ],
    [ "lcd1:SCL", "esp:9", "green", [ "h0" ] ],
    [ "dht1:VCC", "bb1:tp.23", "red",   [ "v0" ] ],
    [ "dht1:GND", "bb1:tn.23", "black", [ "v0" ] ],
    [ "dht1:SDA", "esp:4",     "green", [ "v0" ] ],
    [ "r1:1",     "bb1:tp.22", "green", [ "v0" ] ],
    [ "r1:2",     "esp:4",     "green", [ "v0" ] ],
    [ "sd1:VCC", "bb1:tp.21", "red",   [ "h0" ] ],
    [ "sd1:GND", "bb1:tn.21", "black", [ "h0" ] ],
    [ "sd1:CS",  "esp:5",     "green", [ "h0" ] ],
    [ "sd1:SCK", "esp:6",     "green", [ "h0" ] ],
    [ "sd1:DI",  "esp:7",     "green", [ "h0" ] ],
    [ "sd1:DO",  "esp:2",     "green", [ "h0" ] ],
    [ "led1:A", "r2:2", "green", [ "v0" ] ],
    [ "led1:C", "bb1:tn.22", "green", [ "v0" ] ],
    [ "r2:1",   "esp:1", "green", [ "v0" ] ]
  ],
  "dependencies": {}
}
B. ESP32-SensorMonitor\ESP32-SensorMonitor.ino
#include <SD.h>
#include <SPI.h>
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// ===================== PIN =====================
#define DHT_PIN       4
#define DHT_TYPE      DHT22
#define LED_PIN       1
#define SD_CS_PIN     5
#define SD_SCK_PIN    6
#define SD_MISO_PIN   2
#define SD_MOSI_PIN   7
#define LCD_SDA_PIN   8
#define LCD_SCL_PIN   9
#define LCD_ADDR      0x27
// ===================== OBJEK =====================
DHT               dht(DHT_PIN, DHT_TYPE);
LiquidCrystal_I2C lcd(LCD_ADDR, 16, 2);
SPIClass          sdSPI(FSPI);
// ===================== STATE =====================
unsigned long lastRead  = 0;
unsigned long lastBlink = 0;
const unsigned long READ_INTERVAL  = 2000;
const unsigned long BLINK_INTERVAL = 1000;
float lastTemp = 0.0;
float lastHum  = 0.0;
bool  ledState = false;
bool  sdReady  = false;
// =====================================================================
//  FUNGSI BANTU
// =====================================================================
void logToSD(float t, float h) {
  if (!sdReady) return;
  File f = SD.open("/datalog.txt", FILE_APPEND);
  if (f) {
    f.printf("Suhu: %.1f C, Kelembapan: %.1f %%\n", t, h);
    f.close();
    Serial.println("[SD] Logged → datalog.txt");
  } else {
    Serial.println("[SD] GAGAL buka datalog.txt");
  }
}
void updateLCD(float t, float h) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.printf("Suhu: %.1f C", t);
  lcd.setCursor(0, 1);
  lcd.printf("Hum:  %.1f %%", h);
}
void lcdInfo(const char* l1, const char* l2) {
  lcd.clear();
  lcd.setCursor(0, 0); lcd.print(l1);
  lcd.setCursor(0, 1); lcd.print(l2);
}
// =====================================================================
//  SERIAL COMMAND HANDLER
// =====================================================================
void handleSerialCommand(String cmd) {
  cmd.trim();
  cmd.toLowerCase();
  if (cmd == "help") {
    Serial.println("\n=== Perintah tersedia ===");
    Serial.println("  help      → tampilkan menu ini");
    Serial.println("  status    → status sistem");
    Serial.println("  data      → baca sensor sekarang");
    Serial.println("  log       → tampilkan datalog.txt");
    Serial.println("  sdinfo    → info SD Card");
    Serial.println("  clear     → hapus datalog.txt");
    Serial.println("=========================\n");
  }
  else if (cmd == "status") {
    Serial.println("\n=== STATUS SISTEM ===");
    Serial.printf("  SD Ready : %s\n", sdReady ? "YES" : "NO");
    Serial.printf("  Suhu     : %.1f C\n", lastTemp);
    Serial.printf("  Hum      : %.1f %%\n", lastHum);
    Serial.printf("  Uptime   : %lu ms\n", millis());
    Serial.println("=====================\n");
  }
  else if (cmd == "data") {
    float t = dht.readTemperature();
    float h = dht.readHumidity();
    if (isnan(t) || isnan(h)) {
      Serial.println("[DHT] Error baca sensor!");
    } else {
      Serial.printf("[DHT] Suhu: %.1f C | Hum: %.1f %%\n", t, h);
    }
  }
  else if (cmd == "log") {
    if (!sdReady) { Serial.println("[SD] Tidak siap"); return; }
    File f = SD.open("/datalog.txt");
    if (f) {
      Serial.println("\n=== ISI datalog.txt ===");
      while (f.available()) Serial.write(f.read());
      Serial.println("=======================\n");
      f.close();
    } else {
      Serial.println("[SD] File kosong");
    }
  }
  else if (cmd == "sdinfo") {
    if (!sdReady) { Serial.println("[SD] Tidak siap"); return; }
    Serial.println("\n=== SD CARD INFO ===");
    Serial.printf("  Total : %llu MB\n", SD.totalBytes() / (1024ULL * 1024ULL));
    Serial.printf("  Used  : %llu MB\n", SD.usedBytes()  / (1024ULL * 1024ULL));
    Serial.println("  Files :");
    File root = SD.open("/");
    File entry = root.openNextFile();
    while (entry) {
      Serial.printf("    /%-20s (%u bytes)\n", entry.name(), entry.size());
      entry = root.openNextFile();
    }
    root.close();
    Serial.println("====================\n");
  }
  else if (cmd == "clear") {
    if (!sdReady) return;
    SD.remove("/datalog.txt");
    Serial.println("[SD] datalog.txt dihapus");
  }
  else {
    Serial.printf("[CMD] Perintah tidak dikenal: '%s' (ketik 'help')\n", cmd.c_str());
  }
}
// =====================================================================
//  SETUP
// =====================================================================
void setup() {
  Serial.begin(115200);
  delay(500);
  Serial.println();
  Serial.println("=========================================");
  Serial.println("  ESP32-C3 Sensor Monitor (Data Logger)");
  Serial.println("=========================================");
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  // ----- I2C + LCD -----
  Wire.begin(LCD_SDA_PIN, LCD_SCL_PIN);
  lcd.init();
  lcd.backlight();
  lcdInfo("Booting...", "ESP32-C3");
  Serial.println("[LCD] OK (SDA=8, SCL=9)");
  // ----- DHT22 -----
  dht.begin();
  Serial.println("[DHT] OK (pin=4)");
  // ----- SD Card -----
  Serial.println("[SD] Init SPI...");
  sdSPI.begin(SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN, SD_CS_PIN);
  delay(200);
  if (!SD.begin(SD_CS_PIN, sdSPI)) {
    Serial.println("[SD] Mount FAILED!");
    sdReady = false;
  } else {
    sdReady = true;
    Serial.println("[SD] Mounted OK");
    Serial.printf("[SD] Total: %llu MB\n", SD.totalBytes() / (1024ULL * 1024ULL));
  }
  Serial.println("=========================================");
  Serial.println("  Ketik 'help' di Serial Monitor");
  Serial.println("=========================================");
  lcd.clear();
}
// =====================================================================
//  LOOP
// =====================================================================
void loop() {
  // ----- Serial Command -----
  if (Serial.available()) {
    String cmd = Serial.readStringUntil('\n');
    handleSerialCommand(cmd);
  }
  unsigned long now = millis();
  // ----- LED Blink -----
  if (now - lastBlink >= BLINK_INTERVAL) {
    lastBlink = now;
    ledState = !ledState;
    digitalWrite(LED_PIN, ledState ? HIGH : LOW);
  }
  // ----- Baca Sensor -----
  if (now - lastRead >= READ_INTERVAL) {
    lastRead = now;
    float t = dht.readTemperature();
    float h = dht.readHumidity();
    if (isnan(t) || isnan(h)) {
      Serial.println("[DHT] ERROR!");
      lcdInfo("Sensor Error!", "Cek DHT22");
      return;
    }
    lastTemp = t;
    lastHum  = h;
    Serial.printf("[DHT] Suhu: %.1f C | Hum: %.1f %%\n", t, h);
    updateLCD(t, h);
    logToSD(t, h);
  }
}
C. ESP32-SensorMonitor\libraries.txt
# Wokwi Library List
# See https://docs.wokwi.com/guides/libraries
DHT sensor library
LiquidCrystal I2C
SD
D. ESP32-SensorMonitor\wokwi.toml
[wokwi]
version = 1
firmware = "build/esp32.esp32.esp32c3/ESP32-SensorMonitor.ino.bin"
elf = "build/esp32.esp32.esp32c3/ESP32-SensorMonitor.ino.elf"
E. ESP32-SensorMonitor\.vscode\settings.json
{
  "wokwi.arduinoCliPath": "C:\\arduino-cli\\arduino-cli.exe",
  "wokwi.autoStartSimulation": false,
  "files.associations": {
    "*.ino": "cpp"
  },
  "C_Cpp.default.includePath": [
    "C:/Users/{username}/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.3.12/cores/esp32",
    "C:/Users/{username}/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.3.12/libraries/**",
    "C:/Users/{username}/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.3.12/tools/sdk/esp32c3/include/**",
    "C:/Users/{username}/Documents/Arduino/libraries/**"
  ],
  "C_Cpp.default.browse.path": [
    "C:/Users/{username}/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.3.12/**"
  ],
  "C_Cpp.default.defines": [
    "ARDUINO=200",
    "ARDUINO_ARCH_ESP32",
    "ESP32"
  ]
}
BAB IVPENUTUP
4.1 Kesimpulan

Berdasarkan rangkaian dan program yang disajikan, sistem dirancang menggunakan ESP32-C3 sebagai pengendali, DHT22 sebagai sensor suhu dan kelembapan, LCD 16×2 sebagai tampilan lokal, dan kartu microSD sebagai media pencatatan. Program menetapkan interval pembacaan sensor sebesar 2.000 ms dan interval perubahan keadaan LED sebesar 1.000 ms. Alur program mengarahkan pembacaan yang valid ke LCD dan Serial Monitor, lalu mencoba menambahkannya ke berkas datalog.txt apabila kartu microSD siap digunakan. Nilai interval tersebut merupakan pengaturan dalam kode, bukan hasil pengukuran waktu pelaksanaan.

Program menyediakan perintah help, status, data, log, sdinfo, dan clear untuk membantu pemeriksaan serta pengelolaan data melalui Serial Monitor. Penanganan kesalahan pembacaan sensor dilakukan dengan menampilkan pesan kesalahan dan melewati pembaruan data pada siklus tersebut. Ketika inisialisasi kartu microSD gagal, program menonaktifkan pencatatan ke kartu tanpa menghentikan fungsi pembacaan sensor dan tampilan lokal.

Cakupan program yang dicantumkan belum meliputi web server, MQTT, dan pengendalian kipas yang dibahas pada pendahuluan. Oleh karena itu, kesimpulan laporan terbatas pada rancangan dan alur kerja pemantauan serta pencatatan lokal. Contoh keluaran dan langkah pengujian yang disajikan belum cukup untuk menetapkan nilai akurasi sensor, latensi pengiriman, kehilangan paket, atau waktu respons kipas.

4.2 Saran

Pengembangan berikutnya perlu menyelaraskan rumusan masalah dengan fungsi yang diimplementasikan. Apabila cakupan web server, MQTT, dan kontrol kipas dipertahankan, rangkaian serta program perlu dilengkapi dengan koneksi jaringan, pengiriman dan penerimaan pesan, serta aktuator dan penggeraknya. Logika kontrol juga perlu mencakup perpindahan mode otomatis dan manual serta histeresis sesuai rancangan pada bagian teori.

Pengujian sebaiknya mendokumentasikan keluaran aktual untuk setiap fitur, termasuk perubahan pembacaan DHT22, tampilan LCD, penambahan dan pembacaan berkas, serta kondisi kegagalan sensor dan kartu microSD. Pengujian pada perangkat fisik perlu membandingkan pembacaan sensor dengan alat ukur acuan. Pengukuran latensi, kehilangan paket, dan waktu respons kipas dilakukan setelah fungsi terkait tersedia, dengan jumlah percobaan dan metode pengukuran yang dijelaskan agar hasilnya dapat diperiksa kembali.

Pencatatan data dapat ditingkatkan dengan menambahkan waktu atau penanda urutan pada setiap pengukuran agar perubahan kondisi lebih mudah ditelusuri. Program juga perlu memeriksa hasil penghapusan berkas sebelum menampilkan pesan berhasil. Kelengkapan lampiran, status verifikasi fitur, dan identitas pustaka perlu diperiksa sebelum laporan difinalkan.

BAB VDAFTAR PUSTAKA

[1] D. Soni and A. Makwana, "A survey on MQTT: A protocol of Internet of Things (IoT)," in Proc. Int. Conf. Telecommun., Power Anal. Comput. Techn. (ICTPACT), Chennai, India, 2017, pp. 173–177.

[2] P. Macheso, S. Chisale, C. Daka, N. Dzupire, J. Mlatho, and D. Mukanyirigira, "Design of standalone asynchronous ESP32 web-server for temperature and humidity monitoring," in Proc. 7th Int. Conf. Adv. Comput. Commun. Syst. (ICACCS), 2021, pp. 635–638, doi: 10.1109/ICACCS51430.2021.9441845.

[3] A. Maier, A. Sharp, and Y. Vagapov, "Comparative analysis and practical implementation of the ESP32 microcontroller module for the Internet of Things," in Proc. Internet Technol. Appl. (ITA), Wrexham, U.K., 2017, pp. 143–148, doi: 10.1109/ITECHA.2017.8101926.

[4] A. Roihan, M. W. Septiano, and E. E. Kurniawan, "Integrasi sensor–aktuator berbasis IoT untuk pengaturan kipas otomatis dan monitoring lingkungan pada rumah pintar," Jurnal Sistem Informasi dan Teknologi (SINTEK), 2026. [lengkapi volume, nomor, halaman, dan DOI dari halaman artikel]

BAB VILAMPIRAN

Video Demo: https://drive.google.com/file/d/1vXkCI_FE5SbISt7SWJd1PGBy5PihcChj/view?usp=sharing

Tidak ada komentar:

Posting Komentar