📘 Berdasarkan file ESP32-PROJECTS.pdf

Modul Praktik ESP32 + MicroPython

Halaman ini merangkum proyek ESP32 dari file PDF menjadi tampilan HTML yang mudah dibaca, memiliki navigasi, tabel koneksi komponen, dan tombol salin source code untuk setiap file.

Mulai Belajar

[Basic] LED Sederhana

Membuat LED berkedip (Blink) dengan mengatur pin GPIO ESP32.

Basic • Halaman 1-2

[Basic] Servo Sederhana

Menggerakkan motor servo ke posisi sudut tertentu menggunakan PWM.

Basic • Halaman 2-4

[Basic] Sensor Ultrasonic

Membaca jarak suatu objek menggunakan sensor ultrasonik HC-SR04.

Basic • Halaman 4-6

[Basic] Sensor Suhu DHT22

Membaca suhu dan kelembaban ruangan menggunakan sensor DHT22.

Basic • Halaman 7-8

Servo Motor Sweep

Membuat servo bergerak bolak-balik dari sudut 0° ke 180° dan kembali lagi secara terus-menerus.

Halaman 1-2

Sensor Jarak HC-SR04 + Servo Motor

Servo terbuka otomatis saat objek terdeteksi dalam jarak kurang dari 10 cm.

Halaman 4-6

Sensor Cahaya LDR - LED Otomatis

LED menyala saat kondisi gelap dan mati saat kondisi terang.

Halaman 7-8

Sensor Gerak PIR + Buzzer Alarm

Buzzer berbunyi seperti sirine ketika sensor PIR mendeteksi gerakan.

Halaman 9-10

Sensor Suhu & Kelembaban DHT22 + LCD I2C 16x2

Membaca suhu dan kelembaban dari DHT22 lalu menampilkannya pada LCD I2C 16x2.

Halaman 11-18

Basic Proyek 1 • Halaman 1-2

💡 [Basic] LED Sederhana

Membuat LED berkedip (Blink) dengan mengatur pin GPIO ESP32.

Skema LED Sederhana

Logika Kerja

ESP32 mengirimkan sinyal HIGH dan LOW secara bergantian melalui GPIO 2 yang terhubung ke LED, dengan jeda waktu menggunakan fungsi sleep.

Koneksi Komponen

KomponenPinESP32 Pin
LEDAnode (Panjang)GPIO 2 (via Resistor 220Ω)
LEDCathode (Pendek)GND
main.py python
from machine import Pin 
import time 

# LED terhubung ke GPIO 2 
led = Pin(2, Pin.OUT) 

while True: 
    led.on() 
    print("LED ON") 
    time.sleep(1) 

    led.off() 
    print("LED OFF") 
    time.sleep(1) 
diagram.json json
{ 
  "version": 1, 
  "author": "MicroPython Learner", 
  "editor": "wokwi", 
  "parts": [ 
    { 
      "type": "wokwi-esp32-devkit-v1", 
      "id": "esp", 
      "top": -4.9, 
      "left": -43.4, 
      "attrs": { "env": "micropython-20231227-v1.22.0" } 
    }, 
    { 
      "type": "wokwi-led", 
      "id": "led1", 
      "top": -22.8, 
      "left": 157.4, 
      "attrs": { "color": "red" } 
    }, 
    { 
      "type": "wokwi-resistor", 
      "id": "r1", 
      "top": 72, 
      "left": 105.05, 
      "rotate": 90, 
      "attrs": { "value": "220" } 
    } 
  ], 
  "connections": [ 
    [ "esp:TX0", "$serialMonitor:RX", "", [] ], 
    [ "esp:RX0", "$serialMonitor:TX", "", [] ], 
    [ "esp:D2", "r1:1", "orange", [ "h57.3", "v-77.5" ] ], 
    [ "r1:2", "led1:A", "orange", [] ], 
    [ "led1:C", "esp:GND.1", "black", [ "h-90.2", "v122.1" ] ] 
  ], 
  "dependencies": {} 
} 

Basic Proyek 2 • Halaman 2-4

🔁 [Basic] Servo Sederhana

Menggerakkan motor servo ke posisi sudut tertentu menggunakan PWM.

Skema Servo Sederhana

Logika Kerja

Motor servo diatur ke sudut 0° lalu ke 180° menggunakan fungsi set_angle, yang mengonversi derajat ke lebar pulsa PWM (duty cycle).

Koneksi Komponen

KomponenPinESP32 Pin
ServoV+ (Merah)VIN (5V)
ServoGND (Coklat/Hitam)GND
ServoPWM (Orange/Kuning)GPIO 18
main.py python
from machine import Pin, PWM 
from time import sleep 

# Servo terhubung ke GPIO 18 
servo = PWM(Pin(18), freq=50) 

def set_angle(angle): 
    # Batasi sudut 0 - 180 derajat 
    angle = max(0, min(180, angle)) 

    # Pulsa servo standar 
    min_us = 500      # 0 derajat 
    max_us = 2500     # 180 derajat 

    pulse_us = min_us + (angle / 180) * (max_us - min_us) 

    # Konversi ke duty ESP32 MicroPython, skala 0 - 1023 
    duty = int((pulse_us / 20000) * 1023) 

    servo.duty(duty) 

# Posisi awal 
set_angle(0) 
sleep(1) 

# Putar servo ke 180 derajat 
set_angle(180) 
sleep(5) 

# Kembali ke posisi awal 
set_angle(0) 
sleep(1) 

# Opsional: matikan sinyal PWM setelah selesai 
servo.deinit() 
diagram.json json
{ 
  "version": 1, 
  "author": "MicroPython Learner", 
  "editor": "wokwi", 
  "parts": [ 
    { 
      "type": "wokwi-esp32-devkit-v1", 
      "id": "esp", 
      "top": 0, 
      "left": 0, 
      "attrs": { 
        "env": "micropython-20231227-v1.22.0" 
      } 
    }, 
    { 
      "type": "wokwi-servo", 
      "id": "servo1", 
      "top": -88.4, 
      "left": 153.6, 
      "attrs": { 
        "hornColor": "Red" 
      } 
    } 
  ], 
  "connections": [ 
    [ "esp:TX0", "$serialMonitor:RX", "", [] ], 
    [ "esp:RX0", "$serialMonitor:TX", "", [] ], 
    [ "servo1:V+", "esp:VIN", "red", [ "h-38.4", "v9.7", "h-144", "v177.7" ] ], 
    [ "servo1:GND", "esp:GND.1", "black", [ "v28.8", "h-19.2", "v158.6" ] ], 
    [ "servo1:PWM", "esp:D18", "orange", [ "h-28.8", "v101.1" ] ] 
  ], 
  "dependencies": {} 
} 

Basic Proyek 3 • Halaman 4-6

📏 [Basic] Sensor Ultrasonic

Membaca jarak suatu objek menggunakan sensor ultrasonik HC-SR04.

Skema HC-SR04

Logika Kerja

Sensor mengirim pulsa ultrasonik (trigger) dan mengukur waktu pantulan (echo). Waktu tersebut dikonversi menjadi jarak (cm) dan ditampilkan pada console.

Koneksi Komponen

KomponenPinESP32 Pin
HC-SR04VCCVIN (5V)
HC-SR04GNDGND
HC-SR04TRIGGPIO 5
HC-SR04ECHOGPIO 18
main.py python
""" 
============================================= 
  SENSOR JARAK HC-SR04 
  ESP32 MicroPython | Wokwi Simulator 
============================================= 
  Logika: Membaca jarak benda menggunakan 
          sensor ultrasonik HC-SR04. 
============================================= 
""" 

from machine import Pin, time_pulse_us 
import time 

# --- Konfigurasi Pin --- 
trig = Pin(5, Pin.OUT) 
echo = Pin(18, Pin.IN) 
 
# --- Konfigurasi --- 
TIMEOUT_US = 30000      # Timeout pulsa dalam mikrodetik 
JARAK_DETEKSI = 10      # Batas deteksi dalam cm 

# --- Fungsi Sensor --- 
def get_distance(): 
    """Mengukur jarak menggunakan sensor ultrasonik dalam cm.""" 

    # Pastikan trigger LOW terlebih dahulu 
    trig.value(0) 
    time.sleep_us(2) 

    # Kirim pulsa trigger selama 10 mikrodetik 
    trig.value(1) 
    time.sleep_us(10) 
    trig.value(0) 

    # Baca durasi pantulan pada pin echo 
    duration = time_pulse_us(echo, 1, TIMEOUT_US) 

    # Jika timeout atau gagal membaca 
    if duration < 0: 
        return 0 

    # Rumus jarak: 
    # jarak = waktu / 2 / 29.1 
    # dibagi 2 karena gelombang pergi-pulang 
    distance = (duration / 2) / 29.1 

    return distance 

# --- Program Utama --- 
print("=" * 44) 
print("  📏 SENSOR JARAK HC-SR04") 
print("=" * 44) 

while True: 
    jarak = get_distance() 
    if jarak == 0: 
        print("Sensor tidak membaca jarak / timeout") 
    elif jarak < JARAK_DETEKSI: 
        print(f"Jarak: {jarak:5.1f} cm | [!] Objek TERDETEKSI") 
    else: 
        print(f"Jarak: {jarak:5.1f} cm | [ ] Aman") 
    time.sleep(0.5) 
diagram.json json
{ 
  "version": 1, 
  "author": "MicroPython Learner", 
  "editor": "wokwi", 
  "parts": [ 
    { 
      "type": "wokwi-esp32-devkit-v1", 
      "id": "esp", 
      "top": 0, 
      "left": 0, 
      "attrs": { 
        "env": "micropython-20231227-v1.22.0" 
      } 
    }, 
    { 
      "type": "wokwi-hc-sr04", 
      "id": "sonic1", 
      "top": -142.5, 
      "left": -4.1, 
      "attrs": { 
        "distance": "50" 
      } 
    } 
  ], 
  "connections": [ 
    [ "esp:TX0", "$serialMonitor:RX", "", [] ], 
    [ "esp:RX0", "$serialMonitor:TX", "", [] ], 
    [ "sonic1:VCC", "esp:VIN", "red", [ "v38.4", "h-86.4", "v153.6" ] ], 
    [ "sonic1:GND", "esp:GND.1", "black", [ "v28.8", "h27.6", "v153.6" ] ], 
    [ "sonic1:TRIG", "esp:D5", "blue", [ "v10", "h130", "v120" ] ], 
    [ "sonic1:ECHO", "esp:D18", "green", [ "v20", "h130", "v165" ] ] 
  ], 
  "dependencies": {} 
} 

Basic Proyek 4 • Halaman 7-8

🌡️ [Basic] Sensor Suhu DHT22

Membaca suhu dan kelembaban ruangan menggunakan sensor DHT22.

Skema DHT22

Logika Kerja

Menggunakan pustaka dht bawaan MicroPython untuk membaca sensor DHT22 pada interval tertentu dan menampilkannya di Serial Monitor.

Koneksi Komponen

KomponenPinESP32 Pin
DHT22VCC3V3
DHT22GNDGND
DHT22SDA / DataGPIO 15
main.py python
""" 
============================================= 
  SENSOR SUHU & KELEMBABAN DHT22 
  ESP32 MicroPython | Wokwi Simulator 
============================================= 
  Logika: 
  ESP32 membaca suhu dan kelembaban dari 
  sensor DHT22, lalu menampilkannya pada 
  Serial Monitor. 
============================================= 
""" 

from machine import Pin 
import dht 
import time 

# --- Konfigurasi Pin --- 
sensor = dht.DHT22(Pin(15)) 

# --- Konfigurasi --- 
INTERVAL = 2   # Interval pembacaan sensor dalam detik 

# --- Program Utama --- 
print("=" * 44) 
print("  🌡️ SENSOR SUHU & KELEMBABAN DHT22") 
print("=" * 44) 

while True: 
    try: 
        # Membaca data dari sensor DHT22 
        sensor.measure() 

        suhu = sensor.temperature() 
        kelembaban = sensor.humidity() 

        print(f"Suhu       : {suhu:.1f} °C") 
        print(f"Kelembaban : {kelembaban:.1f} %") 
        print("-" * 44) 

    except Exception as e: 
        print("Gagal membaca sensor DHT22") 
        print("Error:", e) 
        print("-" * 44) 

    time.sleep(INTERVAL) 
diagram.json json
{ 
  "version": 1, 
  "author": "MicroPython Learner", 
  "editor": "wokwi", 
  "parts": [ 
    { 
      "type": "board-esp32-devkit-c-v4", 
      "id": "esp", 
      "top": -57.6, 
      "left": 129.64, 
      "attrs": { "env": "micropython-20231227-v1.22.0" } 
    }, 
    { "type": "wokwi-dht22", "id": "dht1", "top": -18.9, "left": 23.4, 
"attrs": {} } 
  ], 
  "connections": [ 
    [ "esp:TX", "$serialMonitor:RX", "", [] ], 
    [ "esp:RX", "$serialMonitor:TX", "", [] ], 
    [ "dht1:VCC", "esp:3V3", "red", [ "h-28.8", "v-124.8" ] ], 
    [ "dht1:GND", "esp:GND.1", "black", [ "v67.2", "h38.4", "v-67.2", 
"h28.65" ] ], 
    [ "dht1:SDA", "esp:15", "green", [ "v76.8", "h211.3", "v-57.6" ] ] 
  ], 
  "dependencies": {} 
} 

Proyek 1 • Halaman 1-2

🔁 Servo Motor Sweep

Membuat servo bergerak bolak-balik dari sudut 0° ke 180° dan kembali lagi secara terus-menerus.

Skema servo-sweep

Logika Kerja

Servo menerima sinyal PWM dari ESP32 pada pin D18. Program mengubah nilai sudut menjadi duty cycle dalam nanodetik.

  • Cocok untuk latihan dasar PWM dan kalibrasi sudut servo 0-180°.

Koneksi Komponen

KomponenPinESP32 Pin
Servo MotorV+VIN (5V)
Servo MotorGNDGND
Servo MotorPWMD18 / GPIO 18
SerialTX0/RX0Serial Monitor
main.py python
"""
=============================================
SERVO MOTOR SWEEP
ESP32 MicroPython | Wokwi Simulator
=============================================
Logika: Servo bergerak bolak-balik
dari 0 ke 180 derajat.
=============================================
"""
from machine import Pin, PWM
import time

# --- Konfigurasi Pin ---
servo = PWM(Pin(18), freq=50)

# --- Konfigurasi Servo ---
DUTY_MIN = 500000    # 0 derajat  (0.5 ms)
DUTY_MAX = 2400000   # 180 derajat (2.4 ms)
STEP = 10            # Langkah per gerakan (derajat)
DELAY = 0.05         # Jeda antar langkah (detik)
PAUSE = 1            # Jeda di ujung (detik)

# --- Fungsi Servo ---
def set_angle(angle):
    """Mengkonversi sudut (0-180) ke duty cycle (ns)."""
    duty_ns = int(DUTY_MIN + (angle / 180) * (DUTY_MAX - DUTY_MIN))
    servo.duty_ns(duty_ns)

# --- Program Utama ---
print("=" * 40)
print(" SERVO MOTOR SWEEP 0 - 180 derajat")
print("=" * 40)

while True:
    print(">> Gerak 0 -> 180 derajat")
    for degree in range(0, 181, STEP):
        set_angle(degree)
        time.sleep(DELAY)
    time.sleep(PAUSE)

    print("<< Gerak 180 -> 0 derajat")
    for degree in range(180, -1, -STEP):
        set_angle(degree)
        time.sleep(DELAY)
    time.sleep(PAUSE)
diagram.json json
{
  "version": 1,
  "author": "MicroPython Learner",
  "editor": "wokwi",
  "parts": [
    {
      "type": "wokwi-esp32-devkit-v1",
      "id": "esp",
      "top": 0,
      "left": 0,
      "attrs": { "env": "micropython-20231227-v1.22.0" }
    },
    {
      "type": "wokwi-servo",
      "id": "servo1",
      "top": -88.4,
      "left": 153.6,
      "attrs": { "hornColor": "Red" }
    }
  ],
  "connections": [
    [ "esp:TX0", "$serialMonitor:RX", "", [] ],
    [ "esp:RX0", "$serialMonitor:TX", "", [] ],
    [ "servo1:V+", "esp:VIN", "red", [ "h-38.4", "v9.7", "h-144", "v177.7" ] ],
    [ "servo1:GND", "esp:GND.1", "black", [ "v28.8", "h-19.2", "v158.6" ] ],
    [ "servo1:PWM", "esp:D18", "orange", [ "h-28.8", "v101.1" ] ]
  ],
  "dependencies": {}
}

Proyek 2 • Halaman 4-6

📏 Sensor Jarak HC-SR04 + Servo Motor

Servo terbuka otomatis saat objek terdeteksi dalam jarak kurang dari 10 cm.

Skema hcsr04-servo

Logika Kerja

HC-SR04 mengirim pulsa ultrasonik melalui TRIG dan membaca pantulan pada ECHO. Jika jarak di bawah ambang, servo bergerak ke sudut buka.

  • Pada hardware nyata, pin ECHO HC-SR04 umumnya 5V. Gunakan pembagi tegangan/level shifter agar aman untuk input ESP32 3.3V.

Koneksi Komponen

KomponenPinESP32 Pin
HC-SR04VCCVIN (5V)
HC-SR04GNDGND
HC-SR04TRIGD5 / GPIO 5
HC-SR04ECHOD18 / GPIO 18
Servo MotorV+VIN (5V)
Servo MotorGNDGND
Servo MotorPWMD4 / GPIO 4
SerialTX0/RX0Serial Monitor
main.py python
"""
=============================================
SENSOR JARAK HC-SR04 + SERVO MOTOR
ESP32 MicroPython | Wokwi Simulator
=============================================
Logika: Servo terbuka (180) saat objek
terdeteksi dalam jarak < 10 cm.
=============================================
"""
from machine import Pin, PWM, time_pulse_us
import time

# --- Konfigurasi Pin ---
trig = Pin(5, Pin.OUT)
echo = Pin(18, Pin.IN)
servo = PWM(Pin(4), freq=50)

# --- Konfigurasi ---
JARAK_DETEKSI = 10   # Jarak trigger (cm)
TIMEOUT_US = 30000   # Timeout pulsa (us) ~ 4-5m
DUTY_MIN = 500000    # 0 derajat  (0.5 ms)
DUTY_MAX = 2400000   # 180 derajat (2.4 ms)
SUDUT_BUKA = 180     # Sudut servo saat terbuka
SUDUT_TUTUP = 0      # Sudut servo saat tertutup

# --- Fungsi Sensor ---
def get_distance():
    """Mengukur jarak menggunakan sensor ultrasonik (cm)."""
    trig.value(0)
    time.sleep_us(2)
    trig.value(1)
    time.sleep_us(10)
    trig.value(0)

    duration = time_pulse_us(echo, 1, TIMEOUT_US)
    if duration < 0:
        return 0
    return (duration / 2) / 29.1

# --- Fungsi Servo ---
def set_servo(angle):
    """Menggerakkan servo ke sudut tertentu (0-180)."""
    duty_ns = int(DUTY_MIN + (angle / 180) * (DUTY_MAX - DUTY_MIN))
    servo.duty_ns(duty_ns)

# --- Program Utama ---
print("=" * 44)
print(" 📏 SENSOR JARAK + SERVO OTOMATIS")
print(f" Trigger jarak < {JARAK_DETEKSI} cm")
print("=" * 44)

while True:
    jarak = get_distance()

    if jarak > 0 and jarak < JARAK_DETEKSI:
        print(f"Jarak: {jarak:5.1f} cm | [!] TERDETEKSI -> Servo BUKA")
        set_servo(SUDUT_BUKA)
    else:
        print(f"Jarak: {jarak:5.1f} cm | [ ] Aman -> Servo TUTUP")
        set_servo(SUDUT_TUTUP)

    time.sleep(0.1)
diagram.json json
{
  "version": 1,
  "author": "MicroPython Learner",
  "editor": "wokwi",
  "parts": [
    {
      "type": "wokwi-esp32-devkit-v1",
      "id": "esp",
      "top": 0,
      "left": 0,
      "attrs": { "env": "micropython-20231227-v1.22.0" }
    },
    {
      "type": "wokwi-hc-sr04",
      "id": "sonic1",
      "top": -142.5,
      "left": -4.1,
      "attrs": { "distance": "2" }
    },
    {
      "type": "wokwi-servo",
      "id": "servo1",
      "top": 17.2,
      "left": 182.4,
      "attrs": { "hornColor": "Red" }
    }
  ],
  "connections": [
    [ "esp:TX0", "$serialMonitor:RX", "", [] ],
    [ "esp:RX0", "$serialMonitor:TX", "", [] ],
    [ "sonic1:VCC", "esp:VIN", "red", [ "v38.4", "h-86.4", "v153.6", "v14.5" ] ],
    [ "sonic1:GND", "esp:GND.1", "black", [ "v28.8", "h27.6", "v153.6", "h-9.6", "v14.6" ] ],
    [ "sonic1:TRIG", "esp:D5", "blue", [ "v10", "h130", "v120" ] ],
    [ "sonic1:ECHO", "esp:D18", "green", [ "v20", "h130", "v165" ] ],
    [ "servo1:V+", "esp:VIN", "red", [ "h-20", "v135", "h-179.2", "v-56" ] ],
    [ "servo1:GND", "esp:GND.1", "black", [ "h-30", "v125", "h-25.2", "v-46" ] ],
    [ "servo1:PWM", "esp:D4", "orange", [ "h-40", "v-35", "h-24.8", "v66" ] ]
  ],
  "dependencies": {}
}

Proyek 3 • Halaman 7-8

💡 Sensor Cahaya LDR - LED Otomatis

LED menyala saat kondisi gelap dan mati saat kondisi terang.

Skema ldr-led

Logika Kerja

ESP32 membaca nilai analog LDR pada pin GPIO 34. Jika nilai ADC lebih rendah dari threshold, LED pada GPIO 32 dinyalakan.

  • Nilai threshold dapat disesuaikan berdasarkan kondisi cahaya ruangan atau nilai ADC hasil kalibrasi.

Koneksi Komponen

KomponenPinESP32 Pin
LDR SensorVCC3V3
LDR SensorGNDGND
LDR SensorAOGPIO 34 / Analog Input
LDR SensorDOGPIO 35 / Digital Input
Resistor 220ΩPin 1GPIO 32
Resistor 220ΩPin 2LED Anode (A)
LED MerahCathode (C)GND
main.py python
"""
=============================================
SENSOR CAHAYA (LDR) - LED Otomatis
ESP32 MicroPython | Wokwi Simulator
=============================================
Logika: LED menyala saat gelap,
LED mati saat terang.
=============================================
"""
from machine import Pin, ADC
import time

# --- Konfigurasi Pin ---
ldr_analog = ADC(Pin(34))
ldr_analog.atten(ADC.ATTN_11DB)      # Range 0 - 3.3V
ldr_analog.width(ADC.WIDTH_12BIT)    # Resolusi 0 - 4095

ldr_digital = Pin(35, Pin.IN)
led = Pin(32, Pin.OUT)

# --- Threshold ---
# Pada Wokwi: nilai ADC rendah = gelap, tinggi = terang
THRESHOLD_GELAP = 1000

# --- Program Utama ---
print("=" * 44)
print(" 💡 SENSOR CAHAYA - Lampu Otomatis")
print("=" * 44)

while True:
    nilai = ldr_analog.read()
    persen = round((nilai / 4095) * 100, 1)

    if nilai < THRESHOLD_GELAP:
        led.on()
        status = "🌙 GELAP → LED ON "
    else:
        led.off()
        status = "☀️ TERANG → LED OFF"

    print(f"ADC: {nilai:4d} | Cahaya: {persen:5.1f}% | {status}")
    time.sleep(0.5)
diagram.json json
{
  "version": 1,
  "author": "Jojo",
  "editor": "wokwi",
  "parts": [
    {
      "type": "board-esp32-devkit-c-v4",
      "id": "esp",
      "top": 9.6,
      "left": 52.84,
      "attrs": { "env": "micropython-20231227-v1.22.0" }
    },
    {
      "type": "wokwi-photoresistor-sensor",
      "id": "ldr1",
      "top": -50,
      "left": -150,
      "attrs": {}
    },
    {
      "type": "wokwi-led",
      "id": "led1",
      "top": 150,
      "left": -73,
      "attrs": { "color": "red" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r1",
      "top": 158.4,
      "left": -19.75,
      "rotate": 90,
      "attrs": { "value": "220" }
    }
  ],
  "connections": [
    [ "esp:TX", "$serialMonitor:RX", "", [] ],
    [ "esp:RX", "$serialMonitor:TX", "", [] ],
    [ "ldr1:VCC", "esp:3V3", "red", [ "h0" ] ],
    [ "ldr1:GND", "esp:GND.2", "black", [ "h0" ] ],
    [ "ldr1:AO", "esp:34", "green", [ "h16.4", "v81.3" ] ],
    [ "ldr1:DO", "esp:35", "blue", [ "h6.8", "v100.6" ] ],
    [ "r1:1", "esp:32", "orange", [ "h38.4", "v-38.4" ] ],
    [ "r1:2", "led1:A", "orange", [ "h0" ] ],
    [ "led1:C", "esp:GND.1", "black", [ "v19.2", "h93.8", "v-48" ] ]
  ],
  "dependencies": {}
}

Proyek 4 • Halaman 9-10

🚨 Sensor Gerak PIR + Buzzer Alarm

Buzzer berbunyi seperti sirine ketika sensor PIR mendeteksi gerakan.

Skema pir-buzzer

Logika Kerja

PIR memberikan sinyal HIGH ketika mendeteksi gerakan. ESP32 menyalakan buzzer dengan variasi frekuensi agar terdengar seperti alarm.

  • COOLDOWN mencegah alarm berulang terlalu cepat setelah satu deteksi gerakan.

Koneksi Komponen

KomponenPinESP32 Pin
PIR SensorVCC3V3
PIR SensorGNDGND
PIR SensorOUTGPIO 23
BuzzerPin 1GPIO 25
BuzzerPin 2GND
main.py python
"""
=============================================
SENSOR GERAK PIR + BUZZER ALARM
ESP32 MicroPython | Wokwi Simulator
=============================================
Logika: Buzzer berbunyi saat gerakan
terdeteksi oleh sensor PIR.
=============================================
"""
from machine import Pin, PWM
import time

# --- Konfigurasi Pin ---
pir = Pin(23, Pin.IN)
buzzer = PWM(Pin(25), freq=1000, duty=0)

# --- Konfigurasi ---
DURASI_ALARM = 2    # Durasi buzzer berbunyi (detik)
FREKUENSI = 1500    # Frekuensi buzzer (Hz)
COOLDOWN = 3        # Jeda antar deteksi (detik)

# --- Fungsi Alarm ---
def bunyikan_alarm():
    """Bunyi alarm naik-turun seperti sirine."""
    for _ in range(4):
        buzzer.freq(1500)
        buzzer.duty(512)
        time.sleep_ms(250)

        buzzer.freq(2500)
        buzzer.duty(512)
        time.sleep_ms(250)

    buzzer.duty(0)

# --- Program Utama ---
print("=" * 44)
print(" 🚨 SENSOR GERAK PIR + BUZZER ALARM")
print("=" * 44)
print(" Menunggu gerakan...")
print()

while True:
    if pir.value() == 1:
        print("[!] GERAKAN TERDETEKSI! -> Alarm aktif")
        bunyikan_alarm()
        print(" Cooldown", COOLDOWN, "detik...")
        time.sleep(COOLDOWN)
    else:
        print("[ ] Tidak ada gerakan")
        time.sleep(0.5)
diagram.json json
{
  "version": 1,
  "author": "Jojo",
  "editor": "wokwi",
  "parts": [
    {
      "type": "board-esp32-devkit-c-v4",
      "id": "esp",
      "top": -19.2,
      "left": 72.04,
      "attrs": { "env": "micropython-20231227-v1.22.0" }
    },
    {
      "type": "wokwi-pir-motion-sensor",
      "id": "pir1",
      "top": 13.6,
      "left": -64.98,
      "attrs": {}
    },
    {
      "type": "wokwi-buzzer",
      "id": "bz1",
      "top": 127.2,
      "left": -132.6,
      "attrs": { "volume": "0.1" }
    }
  ],
  "connections": [
    [ "esp:TX", "$serialMonitor:RX", "", [] ],
    [ "esp:RX", "$serialMonitor:TX", "", [] ],
    [ "pir1:VCC", "esp:3V3", "red", [ "v9.6", "h76.8", "v-105.6" ] ],
    [ "pir1:GND", "esp:GND.2", "black", [ "v144", "h201.34", "v-240" ] ],
    [ "pir1:OUT", "esp:23", "green", [ "v124.8", "h201.46", "v-211.2" ] ],
    [ "bz1:1", "esp:25", "orange", [ "v9.6", "h163.2", "v-134.4" ] ],
    [ "bz1:2", "esp:GND.1", "black", [ "h134", "v-76.8" ] ]
  ],
  "dependencies": {}
}

Proyek 5 • Halaman 11-18

🌡️ Sensor Suhu & Kelembaban DHT22 + LCD I2C 16x2

Membaca suhu dan kelembaban dari DHT22 lalu menampilkannya pada LCD I2C 16x2.

Skema dht22-lcd

Logika Kerja

DHT22 dibaca pada GPIO 15. LCD I2C menggunakan SDA GPIO 21 dan SCL GPIO 22 untuk menampilkan suhu serta kelembaban.

  • Pastikan file lcd_api.py dan i2c_lcd.py berada satu folder dengan main.py pada proyek Wokwi/MicroPython.

Koneksi Komponen

KomponenPinESP32 Pin
DHT22VCC3V3
DHT22GNDGND
DHT22SDA / DataGPIO 15
LCD I2C 16x2VCC5V
LCD I2C 16x2GNDGND
LCD I2C 16x2SDAGPIO 21
LCD I2C 16x2SCLGPIO 22
main.py python
"""
=============================================
SENSOR SUHU & KELEMBABAN DHT22
+ LCD I2C 16x2
ESP32 MicroPython | Wokwi Simulator
=============================================
Logika: Membaca suhu dan kelembaban
lalu menampilkan di LCD 16x2.
=============================================
"""
from machine import Pin, SoftI2C
from i2c_lcd import I2cLcd
import dht
import time

# --- Konfigurasi Pin ---
sensor = dht.DHT22(Pin(15))
i2c = SoftI2C(sda=Pin(21), scl=Pin(22), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16)

# --- Konfigurasi ---
INTERVAL = 2    # Interval pembacaan (detik)

# --- Karakter Kustom ---
# Simbol derajat (°)
CHAR_DERAJAT = bytearray([0x06, 0x09, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00])
# Simbol tetesan air
CHAR_TETES = bytearray([0x04, 0x04, 0x0A, 0x0A, 0x11, 0x11, 0x0E, 0x00])

# --- Fungsi LCD ---
def lcd_init():
    """Inisialisasi LCD dengan karakter kustom."""
    lcd.clear()

    # Simpan karakter kustom di posisi 0 dan 1
    lcd.hal_write_command(0x40)  # CGRAM address 0
    for b in CHAR_DERAJAT:
        lcd.hal_write_data(b)
    for b in CHAR_TETES:
        lcd.hal_write_data(b)

def tampil_lcd(suhu, kelembaban):
    """Menampilkan data ke LCD 16x2."""
    lcd.move_to(0, 0)
    lcd.putstr("Suhu : {:.1f} ".format(suhu))
    lcd.putchar(chr(0))  # Simbol derajat
    lcd.putstr("C ")

    lcd.move_to(0, 1)
    lcd.putchar(chr(1))  # Simbol tetes
    lcd.putstr("Humi : {:.1f} % ".format(kelembaban))

# --- Program Utama ---
print("=" * 44)
print(" 🌡️ MONITOR SUHU & KELEMBABAN DHT22")
print("=" * 44)

lcd_init()
lcd.backlight_on()

# Tampil splash screen
lcd.move_to(0, 0)
lcd.putstr(" DHT22 Monitor ")
lcd.move_to(0, 1)
lcd.putstr(" Loading... ")
time.sleep(2)
lcd.clear()

while True:
    try:
        sensor.measure()
        suhu = sensor.temperature()
        humi = sensor.humidity()

        # Tampil di LCD
        tampil_lcd(suhu, humi)

        # Tampil di Serial Monitor
        print(f"Suhu: {suhu:.1f} C | Kelembaban: {humi:.1f} %")

    except Exception as e:
        print(f"Error baca sensor: {e}")
        lcd.move_to(0, 0)
        lcd.putstr("Sensor Error!  ")
        lcd.move_to(0, 1)
        lcd.putstr("Cek koneksi... ")

    time.sleep(INTERVAL)
diagram.json json
{
  "version": 1,
  "author": "Jojo",
  "editor": "wokwi",
  "parts": [
    {
      "type": "board-esp32-devkit-c-v4",
      "id": "esp",
      "top": 0,
      "left": 33.64,
      "attrs": { "env": "micropython-20231227-v1.22.0" }
    },
    {
      "type": "wokwi-dht22",
      "id": "dht1",
      "top": 48.3,
      "left": 263.4,
      "attrs": {}
    },
    {
      "type": "wokwi-lcd1602",
      "id": "lcd1",
      "top": 256,
      "left": 111.2,
      "attrs": { "pins": "i2c" }
    }
  ],
  "connections": [
    [ "esp:TX", "$serialMonitor:RX", "", [] ],
    [ "esp:RX", "$serialMonitor:TX", "", [] ],
    [ "dht1:VCC", "esp:3V3", "red", [ "h-28.8", "v-182.4", "h-211.35" ] ],
    [ "dht1:GND", "esp:GND.2", "black", [ "v38.4", "h-115.2" ] ],
    [ "dht1:SDA", "esp:15", "green", [ "v19.2", "h-172.7", "v57.6" ] ],
    [ "lcd1:GND", "esp:GND.1", "black", [ "h-115.2", "v-134.4" ] ],
    [ "lcd1:VCC", "esp:5V", "red", [ "h-105.6", "v-95.9" ] ],
    [ "lcd1:SDA", "esp:21", "blue", [ "h-163.2", "v-364.6", "h201.6", "v134.4" ] ],
    [ "lcd1:SCL", "esp:22", "purple", [ "h-134.4", "v-354.9", "h182.4", "v86.4" ] ]
  ],
  "dependencies": {}
}
lcd_api.py python
"""lcd_api.py
LCD API base class for MicroPython.
"""
import time

class LcdApi:
    LCD_CLR = 0x01
    LCD_HOME = 0x02
    LCD_ENTRY_MODE = 0x04
    LCD_ENTRY_INC = 0x02
    LCD_ON_CTRL = 0x08
    LCD_ON_DISPLAY = 0x04
    LCD_FUNCTION = 0x20
    LCD_FUNCTION_2LINES = 0x08
    LCD_BACKLIGHT = 0x08

    def __init__(self, num_lines, num_columns):
        self.num_lines = num_lines
        self.num_columns = num_columns
        self.cursor_x = 0
        self.cursor_y = 0
        self.backlight = True

        self.hal_write_init_nibble(self.LCD_FUNCTION | self.LCD_FUNCTION_2LINES)
        time.sleep_ms(5)
        self.hal_write_init_nibble(self.LCD_FUNCTION | self.LCD_FUNCTION_2LINES)
        time.sleep_ms(1)
        self.hal_write_init_nibble(self.LCD_FUNCTION | self.LCD_FUNCTION_2LINES)
        time.sleep_ms(1)

        self.hal_write_command(self.LCD_FUNCTION | self.LCD_FUNCTION_2LINES)
        self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY)
        self.hal_write_command(self.LCD_CLR)
        time.sleep_ms(2)
        self.hal_write_command(self.LCD_ENTRY_MODE | self.LCD_ENTRY_INC)

    def clear(self):
        self.hal_write_command(self.LCD_CLR)
        self.cursor_x = 0
        self.cursor_y = 0
        time.sleep_ms(2)

    def move_to(self, cursor_x, cursor_y):
        self.cursor_x = cursor_x
        self.cursor_y = cursor_y
        addr = cursor_x & 0x3f
        if cursor_y & 1:
            addr += 0x40
        if cursor_y & 2:
            addr += self.num_columns
        self.hal_write_command(0x80 | addr)

    def putchar(self, char):
        self.hal_write_data(ord(char))
        self.cursor_x += 1

    def putstr(self, string):
        for char in string:
            self.putchar(char)

    def backlight_on(self):
        self.backlight = True
        self.hal_backlight_on()

    def backlight_off(self):
        self.backlight = False
        self.hal_backlight_off()

    def hal_backlight_on(self):
        pass

    def hal_backlight_off(self):
        pass

    def hal_write_command(self, cmd):
        raise NotImplementedError

    def hal_write_data(self, data):
        raise NotImplementedError

    def hal_write_init_nibble(self, nibble):
        raise NotImplementedError
i2c_lcd.py python
"""i2c_lcd.py
I2C LCD driver for MicroPython.
"""
from lcd_api import LcdApi
from machine import I2C
import time

MASK_RS = 0x01
MASK_RW = 0x02
MASK_E = 0x04
SHIFT_BACKLIGHT = 3
SHIFT_DATA = 4

class I2cLcd(LcdApi):
    def __init__(self, i2c, i2c_addr, num_lines, num_columns):
        self.i2c = i2c
        self.i2c_addr = i2c_addr
        self.i2c.writeto(self.i2c_addr, bytearray([0]))
        time.sleep_ms(20)
        super().__init__(num_lines, num_columns)

    def hal_write_init_nibble(self, nibble):
        byte = ((nibble >> 4) & 0x0f) << SHIFT_DATA
        self.i2c.writeto(self.i2c_addr, bytearray([byte | MASK_E]))
        self.i2c.writeto(self.i2c_addr, bytearray([byte]))

    def hal_backlight_on(self):
        self.i2c.writeto(self.i2c_addr, bytearray([1 << SHIFT_BACKLIGHT]))

    def hal_backlight_off(self):
        self.i2c.writeto(self.i2c_addr, bytearray([0]))

    def hal_write_command(self, cmd):
        self._write_byte(cmd, 0)

    def hal_write_data(self, data):
        self._write_byte(data, MASK_RS)

    def _write_byte(self, byte, rs):
        bl = (1 << SHIFT_BACKLIGHT) if self.backlight else 0

        # High nibble
        high = (((byte >> 4) & 0x0f) << SHIFT_DATA) | rs | bl
        self.i2c.writeto(self.i2c_addr, bytearray([high | MASK_E]))
        self.i2c.writeto(self.i2c_addr, bytearray([high]))

        # Low nibble
        low = ((byte & 0x0f) << SHIFT_DATA) | rs | bl
        self.i2c.writeto(self.i2c_addr, bytearray([low | MASK_E]))
        self.i2c.writeto(self.i2c_addr, bytearray([low]))
Kode berhasil disalin.