Buzzer berbunyi bip-bip pada jam minum obat dan terus berbunyi sampai tombol ditekan. Keluarga yang tinggal berjauhan bisa melihat di Klenik apakah obat sudah diminum dan jam berapa, atau malah terlewat.
Jam diambil dari internet seperti proyek 057. Pada jam yang ada di jadwal, alarm menyala: buzzer bip-bip dan indikator di dashboard berubah jadi MINUM OBAT. Alarm hanya mati dengan menekan tombol di alat. Saat itu NodeMCU mencatat jam tombol ditekan ke Text Log.
Kalau 30 menit berlalu tanpa tombol ditekan, alarm berhenti sendiri dan catatannya ditulis TERLEWAT. Anggota keluarga bisa melihat catatan itu dari HP mana pun.
Komponen
| Komponen | Qty | Harga |
|---|---|---|
| NodeMCU ESP8266 V3 (Lolin) | 1 | Rp42.000 |
| Modul buzzer aktif KY-012 | 1 | Rp7.500 |
| Push button 6×6 mm (isi 10)isi 10, terpakai 1 | 1 | Rp4.750 |
| Breadboard mini 170 titik | 1 | Rp4.875 |
| Kabel jumper male-female 10 cm (isi 10)isi 10, terpakai 2 | 1 | Rp3.500 |
| Kabel jumper female-female 10 cm (isi 10)isi 10, terpakai 3 | 1 | Rp3.500 |
| Kabel micro USB data 30 cmopsional, kalau belum punya kabel micro USB data | 1 | Rp11.700 |
| Total (tanpa opsional) | Rp66.125 |
Langkah 1: Rangkai komponen
Sambungkan kabel sesuai gambar di atas. Kalau gambar dan tabel terlihat berbeda, ikuti tabel.
| Dari | Ke | Kabel | |
|---|---|---|---|
| Push button 6×6 mm 1 | → | D5 GPIO14 | biru |
| Push button 6×6 mm 2 | → | G | hitam |
| Modul buzzer aktif KY-012 S | → | D2 GPIO4 | kuning |
| Modul buzzer aktif KY-012 + | → | 3V | merah |
| Modul buzzer aktif KY-012 − | → | G | hitam |
Langkah 2: Siapkan dashboard Klenik
Cara cepat: unduh p058.json, ganti budi1234 dengan KODE-mu, lalu import di Klenik (menu titik tiga → Export / Import → Import → Ganti total). Langkah lengkapnya ada di Panduan Klenik.
| Widget | Topic | Setting |
|---|---|---|
| Indikator Boolean Pengingat | ichibot/KODE/p058/alarm | ON = 1 “MINUM OBAT”, OFF = 0 |
| TEXT_INPUT Jadwal Obat | ichibot/KODE/p058/jadwal | teks bebas |
| Text Log Catatan Obat | ichibot/KODE/p058/log | menampilkan teks masuk |
Langkah 3: Upload kode
Library: PubSubClient (Nick O'Leary). Board di Arduino IDE: NodeMCU 1.0 (ESP-12E 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).
// Proyek 058 - Pengingat Minum Obat
// Board: NodeMCU ESP8266 V3 | Dashboard: klenik.ichibot.id
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <time.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_ALARM = "ichibot/budi1234/p058/alarm";
const char* TOPIK_JADWAL = "ichibot/budi1234/p058/jadwal";
const char* TOPIK_LOG = "ichibot/budi1234/p058/log";
const char* BROKER = "mqtt.ichibot.id";
WiFiClient wifi;
PubSubClient mqtt(wifi);
const int BUZZER = D2, TOMBOL = D5;
String jadwal = "07:00,13:00,19:00";
String menitTadi = "", jamObat = "";
bool berbunyi = false;
unsigned long alarmMulai = 0;
String jamSekarang() {
time_t t = time(nullptr);
char buf[6];
strftime(buf, sizeof(buf), "%H:%M", localtime(&t));
return String(buf);
}
void setAlarm(bool v) {
berbunyi = v;
digitalWrite(BUZZER, LOW);
mqtt.publish(TOPIK_ALARM, v ? "1" : "0", true);
}
void pesanMasuk(char* t, byte* isi, unsigned int panjang) {
String p;
for (unsigned int i = 0; i < panjang; i++) p += (char)isi[i];
p.trim();
if (p.length() && p != jadwal) {
jadwal = p;
mqtt.publish(TOPIK_JADWAL, jadwal.c_str(), true);
mqtt.publish(TOPIK_LOG, ("Jadwal obat: " + jadwal).c_str());
}
}
void langganan() {
mqtt.subscribe(TOPIK_JADWAL);
}
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);
pinMode(BUZZER, OUTPUT);
pinMode(TOMBOL, INPUT_PULLUP);
sambungWiFi();
configTime(7 * 3600, 0, "pool.ntp.org");
mqtt.setServer(BROKER, 1883);
mqtt.setCallback(pesanMasuk);
}
void loop() {
if (!mqtt.connected()) sambungMQTT();
mqtt.loop();
if (time(nullptr) > 1700000000) {
String menit = jamSekarang();
if (menit != menitTadi) {
menitTadi = menit;
if (!berbunyi && ("," + jadwal + ",").indexOf("," + menit + ",") >= 0) {
jamObat = menit;
alarmMulai = millis();
setAlarm(true);
mqtt.publish(TOPIK_LOG, ("Waktunya minum obat " + jamObat).c_str());
}
}
}
if (berbunyi) {
digitalWrite(BUZZER, (millis() / 500) % 2); // bip-bip setiap setengah detik
if (digitalRead(TOMBOL) == LOW) {
setAlarm(false);
mqtt.publish(TOPIK_LOG, ("Obat " + jamObat + " diminum jam " + jamSekarang()).c_str());
} else if (millis() - alarmMulai > 30UL * 60 * 1000) {
setAlarm(false);
mqtt.publish(TOPIK_LOG, ("Obat " + jamObat + " TERLEWAT").c_str());
}
}
}Langkah 4: Pahami kodenya
- Sama dengan bel sekolah (proyek 057), ditambah syarat
!berbunyi: alarm yang masih berbunyi tidak ditimpa jadwal berikutnya. - Bip-bip tanpa
delay().millis() / 500naik satu tiap setengah detik, dan% 2membuatnya bergantian 0 dan 1. - Batas 30 menit. Huruf
ULmembuat perhitungan memakai angka besar (unsigned long), jadi hasil 1.800.000 tidak meluap.