Tutorial Belanja komponen

Tutorial › Servo & Motor

Tirai Otomatis Stepper

ESP32-WROOM-32D23D22TX0RX0D21D19D18D5TX2RX2D4D2D15GND3V3ENVPVND34D35D32D33D25D26D27D14D12D13GNDVINULN2003IN1IN2IN3IN4−+ULN2003 + stepper 28BYJ-48S+−Modul LDR KY-018

Tirai kecil yang terbuka sendiri saat pagi terang dan menutup saat malam. Stepper 28BYJ-48 menggulung tali tirai, dan LDR menilai terang-gelap. Dari Klenik tirai bisa dibuka-tutup manual, dan mode otomatis bisa dinyalakan kembali kapan saja.

Penggerak stepper sama dengan proyek 095. Tirai dianggap tertutup saat ESP32 menyala (posisi 0) dan terbuka penuh setelah 5 putaran motor. Ukur jumlah putaran yang pas untuk tirai atau gulungan tali milikmu, lalu ubah LANGKAH_BUKA.

LDR dibaca setiap 5 detik. Ada dua batas: tirai dibuka kalau angka di bawah 1500 (terang) dan ditutup kalau di atas 3000 (gelap). Di antara keduanya, misalnya saat mendung atau senja, tirai tidak bergerak, jadi tidak buka-tutup bolak-balik.

Perintah manual dari dashboard otomatis mematikan mode otomatis. Kalau tidak, tirai yang kamu tutup siang hari akan langsung dibuka lagi oleh LDR.

Komponen

KomponenQtyHarga
ESP32 DOIT DevKit V1 30 pin1Rp75.000
Motor Stepper 28BYJ-48 DC 5V 4-Phase 5-Wire Ardu1Rp15.500
Driver Stepper ULN2003 5V 28BYJ-48 Module Board 1Rp10.000
Modul sensor cahaya LDR1Rp7.200
Kabel jumper female-female 10 cm (isi 10)isi 10, terpakai 91Rp3.500
Kabel micro USB data 30 cmopsional, kalau belum punya kabel micro USB data1Rp11.700
Total (tanpa opsional)Rp111.200
Daftar komponen proyek ini otomatis masuk ke pesan. Hapus yang sudah kamu punya sebelum dikirim.

Langkah 1: Rangkai komponen

Sambungkan kabel sesuai gambar di atas. Kalau gambar dan tabel terlihat berbeda, ikuti tabel.

DariKeKabel
ULN2003 + stepper 28BYJ-48 IN1→D19 GPIO19biru
ULN2003 + stepper 28BYJ-48 IN2→D18 GPIO18hijau
ULN2003 + stepper 28BYJ-48 IN3→D5 GPIO5kuning
ULN2003 + stepper 28BYJ-48 IN4→D4 GPIO4oranye
ULN2003 + stepper 28BYJ-48 −→GNDhitam
ULN2003 + stepper 28BYJ-48 +→VINmerah
Modul LDR KY-018 S→D34 GPIO34ungu
Modul LDR KY-018 +→3V3merah
Modul LDR KY-018 −→GNDhitam

Langkah 2: Siapkan dashboard Klenik

Mode Otomatisichibot/budi1234/p096/otomatis
Otomatis
0 detik lalu
Tirai Manualichibot/budi1234/p096/tirai
Buka
0 detik lalu
Tiraiichibot/budi1234/p096/terbuka
TERBUKA
0 detik lalu
Bacaan LDRichibot/budi1234/p096/cahaya
040951240
0 detik lalu
Riwayat Tiraiichibot/budi1234/p096/log
Tirai dibuka (pagi)
Tirai ditutup (manual)
Tirai ditutup (malam)
0 detik lalu

Cara cepat: unduh p096.json, ganti budi1234 dengan KODE-mu, lalu import di Klenik (menu titik tiga → Export / Import → Import → Ganti total). Langkah lengkapnya ada di Panduan Klenik.

WidgetTopicSetting
Switch
Mode Otomatis
ichibot/KODE/p096/otomatispayload ON / OFF
Switch
Tirai Manual
ichibot/KODE/p096/tiraipayload ON / OFF
Indikator Boolean
Tirai
ichibot/KODE/p096/terbukaON = 1 “TERBUKA”, OFF = 0
Gauge
Bacaan LDR
ichibot/KODE/p096/cahaya0–4095
Text Log
Riwayat Tirai
ichibot/KODE/p096/logmenampilkan teks masuk

Langkah 3: Upload kode

Library: PubSubClient (Nick O'Leary). Board di Arduino IDE: ESP32 Dev Module. Isi dulu nama WiFi dan password di bagian ISI DULU, lalu ganti budi1234 di baris topic dengan KODE-mu, lalu upload dan buka Serial Monitor (115200).

p096.inoUnduh .ino
// Proyek 096 - Tirai Otomatis Stepper
// Board: ESP32 DOIT DevKit V1 | Dashboard: klenik.ichibot.id
#include <WiFi.h>
#include <PubSubClient.h>

// ===== ISI DULU =====
const char* WIFI_NAMA = "nama-wifi-kamu";
const char* WIFI_PASS = "password-wifi-kamu";

// topic MQTT: ganti budi1234 dengan KODE-mu (sama dengan di dashboard Klenik)
const char* TOPIK_LOG      = "ichibot/budi1234/p096/log";
const char* TOPIK_OTOMATIS = "ichibot/budi1234/p096/otomatis";
const char* TOPIK_TIRAI    = "ichibot/budi1234/p096/tirai";
const char* TOPIK_TERBUKA  = "ichibot/budi1234/p096/terbuka";
const char* TOPIK_CAHAYA   = "ichibot/budi1234/p096/cahaya";

const char* BROKER = "mqtt.ichibot.id";
WiFiClient wifi;
PubSubClient mqtt(wifi);
const int PIN[4] = {19, 18, 5, 4};
const int PIN_LDR = 34;
const long LANGKAH_BUKA = 4096L * 5;  // tirai terbuka penuh = 5 putaran motor
const int LDR_TERANG = 1500, LDR_GELAP = 3000;   // histeresis
const uint8_t URUTAN[8] = {0b1000, 0b1100, 0b0100, 0b0110, 0b0010, 0b0011, 0b0001, 0b1001};
long posisi = 0, tujuan = 0;          // 0 = tertutup (posisi saat dinyalakan)
int fase = 0;
bool otomatis = true;
unsigned long langkahTerakhir = 0, cekTerakhir = 0;

void satuLangkah(int arah) {
  fase = (fase + arah + 8) % 8;
  for (int i = 0; i < 4; i++) digitalWrite(PIN[i], (URUTAN[fase] >> (3 - i)) & 1);
  posisi += arah;
}

void aturTirai(bool buka, const char* sebab) {
  long baru = buka ? LANGKAH_BUKA : 0;
  if (baru == tujuan) return;
  tujuan = baru;
  mqtt.publish(TOPIK_LOG, (String(buka ? "Tirai dibuka" : "Tirai ditutup") + " (" + sebab + ")").c_str());
}

void pesanMasuk(char* t, byte* isi, unsigned int panjang) {
  String topik = t;
  String p;
  for (unsigned int i = 0; i < panjang; i++) p += (char)isi[i];
  if (topik == TOPIK_OTOMATIS) otomatis = (p == "ON");
  else if (topik == TOPIK_TIRAI) {
    otomatis = false;                 // perintah manual mematikan mode otomatis
    mqtt.publish(TOPIK_OTOMATIS, "OFF", true);
    aturTirai(p == "ON", "manual");
  }
}

void langganan() {
  mqtt.subscribe(TOPIK_OTOMATIS);
  mqtt.subscribe(TOPIK_TIRAI);
}

sambungWiFi() dan sambungMQTT(): sama di semua proyek (klik untuk lihat)void sambungWiFi() { WiFi.begin(WIFI_NAMA, WIFI_PASS); Serial.print("WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(" OK, IP " + WiFi.localIP().toString()); } void sambungMQTT() { while (!mqtt.connected()) { if (mqtt.connect(WiFi.macAddress().c_str())) { Serial.println("Terhubung ke Klenik"); langganan(); } else { Serial.println("Broker gagal, coba lagi 3 detik"); delay(3000); } } }
void setup() { Serial.begin(115200); for (int i = 0; i < 4; i++) pinMode(PIN[i], OUTPUT); sambungWiFi(); mqtt.setServer(BROKER, 1883); mqtt.setCallback(pesanMasuk); } void loop() { if (!mqtt.connected()) sambungMQTT(); mqtt.loop(); if (posisi != tujuan) { if (micros() - langkahTerakhir >= 1200) { langkahTerakhir = micros(); satuLangkah(tujuan > posisi ? 1 : -1); if (posisi == tujuan) { for (int i = 0; i < 4; i++) digitalWrite(PIN[i], LOW); mqtt.publish(TOPIK_TERBUKA, posisi ? "1" : "0", true); } } return; // selama bergerak, fokus ke motor } if (millis() - cekTerakhir >= 5000) { cekTerakhir = millis(); int ldr = analogRead(PIN_LDR); // KY-018: makin terang makin kecil mqtt.publish(TOPIK_CAHAYA, String(ldr).c_str()); if (otomatis) { if (ldr < LDR_TERANG) aturTirai(true, "pagi"); else if (ldr > LDR_GELAP) aturTirai(false, "malam"); } } }

Langkah 4: Pahami kodenya

  1. Jarak buka dalam langkah. Huruf L memastikan perkaliannya memakai angka besar (long).
  2. Dua batas cahaya (histeresis). Lihat gauge LDR saat pagi dan malam di ruanganmu, lalu sesuaikan.
  3. Saat tirai bergerak, pembacaan LDR dilewati. Gerakan motor tetap rata tanpa jeda dari analogRead() dan publish().
  4. Manual menang atas otomatis. Switch Mode Otomatis di dashboard ikut bergeser ke OFF.