add Arduino code folder
This commit is contained in:
parent
0bcd9c4d21
commit
17079b84d0
|
@ -0,0 +1,497 @@
|
||||||
|
#include <LiquidCrystal_I2C.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <FirebaseESP32.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#include "RTClib.h"
|
||||||
|
#include <Stepper.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <WiFiManager.h>
|
||||||
|
|
||||||
|
// Firebase config
|
||||||
|
#define FIREBASE_HOST "https://coba-smartmedibox-default-rtdb.firebaseio.com"
|
||||||
|
#define FIREBASE_AUTH "AIzaSyAUVen3yiSUrNJw7HnRif0_IBmUdeStY0c"
|
||||||
|
|
||||||
|
FirebaseData fbdo;
|
||||||
|
FirebaseAuth auth;
|
||||||
|
FirebaseConfig config;
|
||||||
|
|
||||||
|
bool signupOK = false;
|
||||||
|
|
||||||
|
// RTC
|
||||||
|
RTC_DS3231 rtc;
|
||||||
|
|
||||||
|
LiquidCrystal_I2C lcd(0x27, 16, 2);
|
||||||
|
|
||||||
|
// Stepper motor
|
||||||
|
const int stepsPerRevolution = 2038;
|
||||||
|
#define IN1 32
|
||||||
|
#define IN2 33
|
||||||
|
#define IN3 25
|
||||||
|
#define IN4 26
|
||||||
|
Stepper kotak1(stepsPerRevolution, IN1, IN3, IN2, IN4);
|
||||||
|
|
||||||
|
#define IN5 17
|
||||||
|
#define IN6 5
|
||||||
|
#define IN7 18
|
||||||
|
#define IN8 19
|
||||||
|
Stepper kotak2(stepsPerRevolution, IN5, IN7, IN6, IN8);
|
||||||
|
|
||||||
|
// Jadwal dari Firebase
|
||||||
|
int kotak1Schedule[4][2];
|
||||||
|
int kotak2Schedule[4][2];
|
||||||
|
bool kotak1Activated[4] = {false, false, false, false};
|
||||||
|
bool kotak2Activated[4] = {false, false, false, false};
|
||||||
|
bool kotak1AlarmActive[4] = {false, false, false, false};
|
||||||
|
bool kotak2AlarmActive[4] = {false, false, false, false};
|
||||||
|
|
||||||
|
// Pin tambahan
|
||||||
|
const int buzzerPin = 27;
|
||||||
|
const int ledPin = 14;
|
||||||
|
const int buttonPin1 = 34;
|
||||||
|
const int buttonPin2 = 23;
|
||||||
|
|
||||||
|
int lastButtonState1 = LOW;
|
||||||
|
bool buttonPressed1 = false;
|
||||||
|
bool lastButtonStatus1 = false;
|
||||||
|
bool buttonStatus1 = false;
|
||||||
|
|
||||||
|
int lastButtonState2 = LOW;
|
||||||
|
bool buttonPressed2 = false;
|
||||||
|
bool lastButtonStatus2 = false;
|
||||||
|
bool buttonStatus2 = false;
|
||||||
|
|
||||||
|
unsigned long buttonTriggerTime1 = 0;
|
||||||
|
bool shouldResetFirebaseButton1 = false;
|
||||||
|
|
||||||
|
unsigned long buttonTriggerTime2 = 0;
|
||||||
|
bool shouldResetFirebaseButton2 = false;
|
||||||
|
|
||||||
|
unsigned long lastUpdateTime = 0;
|
||||||
|
const unsigned long updateInterval = 60000; // 60 detik
|
||||||
|
|
||||||
|
unsigned long lastUpdateTime2 = 0;
|
||||||
|
const unsigned long updateInterval2 = 30000; // 60 detik
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
Wire.begin(21, 22);
|
||||||
|
lcd.init();
|
||||||
|
lcd.backlight();
|
||||||
|
lcd.begin(16, 2);
|
||||||
|
lcd.clear();
|
||||||
|
lcd.setCursor(1, 0);
|
||||||
|
lcd.print("Hubungkan Wifi");
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFiManager wm;
|
||||||
|
wm.resetSettings();
|
||||||
|
|
||||||
|
bool res;
|
||||||
|
res = wm.autoConnect("AutoConnectAP", "password");
|
||||||
|
|
||||||
|
Serial.println("Hubungkan Wifi.....");
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
Serial.println("Gagal konek");
|
||||||
|
} else {
|
||||||
|
Serial.println("Berhasil konek");
|
||||||
|
}
|
||||||
|
|
||||||
|
lcd.clear();
|
||||||
|
lcd.setCursor(1, 0);
|
||||||
|
lcd.print("Wifi Terhubung");
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
config.database_url = FIREBASE_HOST;
|
||||||
|
config.api_key = FIREBASE_AUTH;
|
||||||
|
if (Firebase.signUp(&config, &auth, "", "")) {
|
||||||
|
Serial.println("Firebase signup ok");
|
||||||
|
signupOK = true;
|
||||||
|
} else {
|
||||||
|
Serial.printf("%s\n", config.signer.signupError.message.c_str());
|
||||||
|
}
|
||||||
|
Firebase.begin(&config, &auth);
|
||||||
|
|
||||||
|
Firebase.reconnectWiFi(true);
|
||||||
|
|
||||||
|
if (!rtc.begin()) {
|
||||||
|
Serial.println("RTC tidak terdeteksi!");
|
||||||
|
while (1);
|
||||||
|
} else {
|
||||||
|
setRTCfromNTP(); // Sinkronkan waktu RTC dari internet saat awal nyala
|
||||||
|
}
|
||||||
|
|
||||||
|
kotak1.setSpeed(5);
|
||||||
|
kotak2.setSpeed(5);
|
||||||
|
pinMode(buzzerPin, OUTPUT);
|
||||||
|
pinMode(ledPin, OUTPUT);
|
||||||
|
pinMode(buttonPin1, INPUT);
|
||||||
|
pinMode(buttonPin2, INPUT);
|
||||||
|
|
||||||
|
lcd.clear();
|
||||||
|
lcd.setCursor(1, 0);
|
||||||
|
lcd.print("Smart Medicine");
|
||||||
|
lcd.setCursor(6, 1);
|
||||||
|
lcd.print("Box");
|
||||||
|
delay(2000);
|
||||||
|
updateFromFirebase();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRTCfromNTP() {
|
||||||
|
configTime(25200, 0, "pool.ntp.org"); // WIB = UTC+7 = 25200 detik offset
|
||||||
|
struct tm timeinfo;
|
||||||
|
if (getLocalTime(&timeinfo)) {
|
||||||
|
rtc.adjust(DateTime(
|
||||||
|
timeinfo.tm_year + 1900,
|
||||||
|
timeinfo.tm_mon + 1,
|
||||||
|
timeinfo.tm_mday,
|
||||||
|
timeinfo.tm_hour,
|
||||||
|
timeinfo.tm_min,
|
||||||
|
timeinfo.tm_sec
|
||||||
|
));
|
||||||
|
Serial.println("RTC disinkronkan dengan waktu NTP (WIB)");
|
||||||
|
} else {
|
||||||
|
Serial.println("Gagal mendapatkan waktu dari NTP");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateFromFirebase() {
|
||||||
|
// Kotak 1
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
String pathJam = "/jadwal/kotak1/" + String(i) + "/jam";
|
||||||
|
String pathMenit = "/jadwal/kotak1/" + String(i) + "/menit";
|
||||||
|
|
||||||
|
if (Firebase.getInt(fbdo, pathJam)) {
|
||||||
|
kotak1Schedule[i][0] = fbdo.intData();
|
||||||
|
} else {
|
||||||
|
kotak1Schedule[i][0] = -1; // Tandai tidak valid
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Firebase.getInt(fbdo, pathMenit)) {
|
||||||
|
kotak1Schedule[i][1] = fbdo.intData();
|
||||||
|
} else {
|
||||||
|
kotak1Schedule[i][1] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kotak 2
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
String pathJam = "/jadwal/kotak2/" + String(i) + "/jam";
|
||||||
|
String pathMenit = "/jadwal/kotak2/" + String(i) + "/menit";
|
||||||
|
|
||||||
|
if (Firebase.getInt(fbdo, pathJam)) {
|
||||||
|
kotak2Schedule[i][0] = fbdo.intData();
|
||||||
|
} else {
|
||||||
|
kotak2Schedule[i][0] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Firebase.getInt(fbdo, pathMenit)) {
|
||||||
|
kotak2Schedule[i][1] = fbdo.intData();
|
||||||
|
} else {
|
||||||
|
kotak2Schedule[i][1] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fbdo.clear(); // Bersihkan setelah digunakan
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcdI2c() {
|
||||||
|
DateTime now = rtc.now();
|
||||||
|
int waktuSekarang = now.hour() * 60 + now.minute();
|
||||||
|
|
||||||
|
int waktuTerdekat1 = 24 * 60 + 1;
|
||||||
|
int indexTerdekat1 = -1;
|
||||||
|
int waktuTerdekatBesok1 = 24 * 60 + 1;
|
||||||
|
int indexTerdekatBesok1 = -1;
|
||||||
|
|
||||||
|
int waktuTerdekat2 = 24 * 60 + 1;
|
||||||
|
int indexTerdekat2 = -1;
|
||||||
|
int waktuTerdekatBesok2 = 24 * 60 + 1;
|
||||||
|
int indexTerdekatBesok2 = -1;
|
||||||
|
|
||||||
|
// Cari jadwal terdekat kotak 1
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
int jam = kotak1Schedule[i][0];
|
||||||
|
int menit = kotak1Schedule[i][1];
|
||||||
|
if (jam < 0 || menit < 0) continue;
|
||||||
|
|
||||||
|
int waktuJadwal = jam * 60 + menit;
|
||||||
|
if (waktuJadwal >= waktuSekarang && waktuJadwal - waktuSekarang < waktuTerdekat1) {
|
||||||
|
waktuTerdekat1 = waktuJadwal - waktuSekarang;
|
||||||
|
indexTerdekat1 = i;
|
||||||
|
}
|
||||||
|
if (waktuJadwal < waktuTerdekatBesok1) {
|
||||||
|
waktuTerdekatBesok1 = waktuJadwal;
|
||||||
|
indexTerdekatBesok1 = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cari jadwal terdekat kotak 2
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
int jam = kotak2Schedule[i][0];
|
||||||
|
int menit = kotak2Schedule[i][1];
|
||||||
|
if (jam < 0 || menit < 0) continue;
|
||||||
|
|
||||||
|
int waktuJadwal = jam * 60 + menit;
|
||||||
|
if (waktuJadwal >= waktuSekarang && waktuJadwal - waktuSekarang < waktuTerdekat2) {
|
||||||
|
waktuTerdekat2 = waktuJadwal - waktuSekarang;
|
||||||
|
indexTerdekat2 = i;
|
||||||
|
}
|
||||||
|
if (waktuJadwal < waktuTerdekatBesok2) {
|
||||||
|
waktuTerdekatBesok2 = waktuJadwal;
|
||||||
|
indexTerdekatBesok2 = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lcd.clear();
|
||||||
|
|
||||||
|
// Tampilkan Kotak 1
|
||||||
|
lcd.setCursor(0, 0);
|
||||||
|
lcd.print("Kotak 1 = ");
|
||||||
|
int jam1 = -1, menit1 = -1;
|
||||||
|
if (indexTerdekat1 != -1) {
|
||||||
|
jam1 = kotak1Schedule[indexTerdekat1][0];
|
||||||
|
menit1 = kotak1Schedule[indexTerdekat1][1];
|
||||||
|
} else if (indexTerdekatBesok1 != -1) {
|
||||||
|
jam1 = kotak1Schedule[indexTerdekatBesok1][0];
|
||||||
|
menit1 = kotak1Schedule[indexTerdekatBesok1][1];
|
||||||
|
}
|
||||||
|
if (jam1 != -1 && menit1 != -1) {
|
||||||
|
if (jam1 < 10) lcd.print("0");
|
||||||
|
lcd.print(jam1);
|
||||||
|
lcd.print(":");
|
||||||
|
if (menit1 < 10) lcd.print("0");
|
||||||
|
lcd.print(menit1);
|
||||||
|
} else {
|
||||||
|
lcd.print("--:--");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tampilkan Kotak 2
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
lcd.print("Kotak 2 = ");
|
||||||
|
int jam2 = -1, menit2 = -1;
|
||||||
|
if (indexTerdekat2 != -1) {
|
||||||
|
jam2 = kotak2Schedule[indexTerdekat2][0];
|
||||||
|
menit2 = kotak2Schedule[indexTerdekat2][1];
|
||||||
|
} else if (indexTerdekatBesok2 != -1) {
|
||||||
|
jam2 = kotak2Schedule[indexTerdekatBesok2][0];
|
||||||
|
menit2 = kotak2Schedule[indexTerdekatBesok2][1];
|
||||||
|
}
|
||||||
|
if (jam2 != -1 && menit2 != -1) {
|
||||||
|
if (jam2 < 10) lcd.print("0");
|
||||||
|
lcd.print(jam2);
|
||||||
|
lcd.print(":");
|
||||||
|
if (menit2 < 10) lcd.print("0");
|
||||||
|
lcd.print(menit2);
|
||||||
|
} else {
|
||||||
|
lcd.print("--:--");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (!Firebase.ready()) {
|
||||||
|
//Serial.println("Firebase tidak ready, mencoba reconnect...");
|
||||||
|
Firebase.begin(&config, &auth);
|
||||||
|
}
|
||||||
|
unsigned long currentMillis = millis();
|
||||||
|
|
||||||
|
// Perbarui jadwal dari Firebase setiap 60 detik
|
||||||
|
if (currentMillis - lastUpdateTime > updateInterval) {
|
||||||
|
updateFromFirebase();
|
||||||
|
lastUpdateTime = currentMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long currentMillis2 = millis();
|
||||||
|
|
||||||
|
// Perbarui jadwal dari Firebase setiap 60 detik
|
||||||
|
if (currentMillis2 - lastUpdateTime2 > updateInterval2) {
|
||||||
|
lcdI2c();
|
||||||
|
lastUpdateTime2 = currentMillis2;
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime now = rtc.now();
|
||||||
|
int h = now.hour();
|
||||||
|
int m = now.minute();
|
||||||
|
|
||||||
|
// Deteksi tombol 1 fisik
|
||||||
|
int currentButtonState1 = digitalRead(buttonPin1);
|
||||||
|
if (currentButtonState1 == HIGH && lastButtonState1 == LOW) {
|
||||||
|
buttonPressed1 = true;
|
||||||
|
Serial.println("Tombol 1 fisik ditekan");
|
||||||
|
}
|
||||||
|
lastButtonState1 = currentButtonState1;
|
||||||
|
|
||||||
|
// Deteksi tombol 2 fisik
|
||||||
|
int currentButtonState2 = digitalRead(buttonPin2);
|
||||||
|
if (currentButtonState2 == HIGH && lastButtonState2 == LOW) {
|
||||||
|
buttonPressed2 = true;
|
||||||
|
Serial.println("Tombol 2 fisik ditekan");
|
||||||
|
}
|
||||||
|
lastButtonState2 = currentButtonState2;
|
||||||
|
|
||||||
|
// Baca status dari Firebase (dari APK)
|
||||||
|
Firebase.getBool(fbdo, "/status/button1");
|
||||||
|
bool firebaseButton1 = fbdo.boolData();
|
||||||
|
|
||||||
|
// Baca status dari Firebase (dari APK)
|
||||||
|
Firebase.getBool(fbdo, "/status/button2");
|
||||||
|
bool firebaseButton2 = fbdo.boolData();
|
||||||
|
|
||||||
|
// Jika tombol fisik ditekan
|
||||||
|
if (buttonPressed1) {
|
||||||
|
Firebase.setBool(fbdo, "/status/button1", true);
|
||||||
|
buttonTriggerTime1 = millis();
|
||||||
|
shouldResetFirebaseButton1 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jika tombol fisik ditekan
|
||||||
|
if (buttonPressed2) {
|
||||||
|
Firebase.setBool(fbdo, "/status/button2", true);
|
||||||
|
buttonTriggerTime2 = millis();
|
||||||
|
shouldResetFirebaseButton2 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jika tombol ditekan dari APK
|
||||||
|
if (firebaseButton1 && !lastButtonStatus1) {
|
||||||
|
buttonStatus1 = true;
|
||||||
|
buttonTriggerTime1 = millis();
|
||||||
|
shouldResetFirebaseButton1 = true;
|
||||||
|
}
|
||||||
|
lastButtonStatus1 = firebaseButton1;
|
||||||
|
|
||||||
|
// Jika tombol ditekan dari APK
|
||||||
|
if (firebaseButton2 && !lastButtonStatus2) {
|
||||||
|
buttonStatus2 = true;
|
||||||
|
buttonTriggerTime2 = millis();
|
||||||
|
shouldResetFirebaseButton2 = true;
|
||||||
|
}
|
||||||
|
lastButtonStatus2 = firebaseButton2;
|
||||||
|
|
||||||
|
// Cek dan jalankan alarm Stepper 1
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
int th = kotak1Schedule[i][0];
|
||||||
|
int tm = kotak1Schedule[i][1];
|
||||||
|
|
||||||
|
// Jika waktunya tiba dan belum dipicu
|
||||||
|
if (h == th && m == tm && !kotak1Activated[i]) {
|
||||||
|
kotak1Activated[i] = true;
|
||||||
|
kotak1AlarmActive[i] = true; // aktifkan alarm
|
||||||
|
|
||||||
|
kotak1.step(128);
|
||||||
|
|
||||||
|
String pathJumlahObat1 = "/jadwal/kotak1/jumlahObat";
|
||||||
|
if (Firebase.getInt(fbdo, pathJumlahObat1)) {
|
||||||
|
int jumlahObat1 = fbdo.intData();
|
||||||
|
if (jumlahObat1 > 0) {
|
||||||
|
jumlahObat1--;
|
||||||
|
Firebase.setInt(fbdo, pathJumlahObat1, jumlahObat1);
|
||||||
|
Serial.printf("Jumlah obat kotak1 berkurang menjadi %d\n", jumlahObat1);
|
||||||
|
} else {
|
||||||
|
Serial.println("Jumlah obat habis atau gagal dibaca");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔔 Jika alarm aktif, tapi tombol belum ditekan
|
||||||
|
if (kotak1AlarmActive[i]) {
|
||||||
|
if (buttonPressed1 || buttonStatus1) {
|
||||||
|
kotak1AlarmActive[i] = false; // matikan alarm
|
||||||
|
digitalWrite(buzzerPin, LOW);
|
||||||
|
digitalWrite(ledPin, LOW);
|
||||||
|
|
||||||
|
Firebase.setBool(fbdo, "/status/kotak1", true);
|
||||||
|
Firebase.setBool(fbdo, "/status/buzzer", false);
|
||||||
|
Firebase.setBool(fbdo, "/status/led", false);
|
||||||
|
} else {
|
||||||
|
digitalWrite(ledPin, HIGH);
|
||||||
|
tone(buzzerPin, 1000);
|
||||||
|
delay(400);
|
||||||
|
noTone(buzzerPin);
|
||||||
|
delay(400);
|
||||||
|
|
||||||
|
Firebase.setBool(fbdo, "/status/alarm1", true);
|
||||||
|
Firebase.setBool(fbdo, "/status/buzzer", true);
|
||||||
|
Firebase.setBool(fbdo, "/status/led", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset aktivasi stepper agar bisa dipicu besok pada jam yang sama
|
||||||
|
if (h != th || m != tm) {
|
||||||
|
kotak1Activated[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cek dan jalankan alarm Stepper 2
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
int th = kotak2Schedule[i][0];
|
||||||
|
int tm = kotak2Schedule[i][1];
|
||||||
|
|
||||||
|
// Jika waktunya tiba dan belum dipicu
|
||||||
|
if (h == th && m == tm && !kotak2Activated[i]) {
|
||||||
|
kotak2Activated[i] = true;
|
||||||
|
kotak2AlarmActive[i] = true; // aktifkan alarm
|
||||||
|
|
||||||
|
kotak2.step(128);
|
||||||
|
|
||||||
|
String pathJumlahObat2 = "/jadwal/kotak2/jumlahObat";
|
||||||
|
if (Firebase.getInt(fbdo, pathJumlahObat2)) {
|
||||||
|
int jumlahObat2 = fbdo.intData();
|
||||||
|
if (jumlahObat2 > 0) {
|
||||||
|
jumlahObat2--;
|
||||||
|
Firebase.setInt(fbdo, pathJumlahObat2, jumlahObat2);
|
||||||
|
Serial.printf("Jumlah obat kotak2 berkurang menjadi %d\n", jumlahObat2);
|
||||||
|
} else {
|
||||||
|
Serial.println("Jumlah obat habis atau gagal dibaca");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔔 Jika alarm aktif, tapi tombol belum ditekan
|
||||||
|
if (kotak2AlarmActive[i]) {
|
||||||
|
if (buttonPressed2 || buttonStatus2) {
|
||||||
|
kotak2AlarmActive[i] = false; // matikan alarm
|
||||||
|
digitalWrite(buzzerPin, LOW);
|
||||||
|
digitalWrite(ledPin, LOW);
|
||||||
|
|
||||||
|
Firebase.setBool(fbdo, "/status/kotak2", true);
|
||||||
|
Firebase.setBool(fbdo, "/status/buzzer", false);
|
||||||
|
Firebase.setBool(fbdo, "/status/led", false);
|
||||||
|
} else {
|
||||||
|
digitalWrite(ledPin, HIGH);
|
||||||
|
tone(buzzerPin, 1000);
|
||||||
|
delay(400);
|
||||||
|
noTone(buzzerPin);
|
||||||
|
delay(400);
|
||||||
|
|
||||||
|
Firebase.setBool(fbdo, "/status/alarm2", true);
|
||||||
|
Firebase.setBool(fbdo, "/status/buzzer", true);
|
||||||
|
Firebase.setBool(fbdo, "/status/led", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset aktivasi stepper agar bisa dipicu besok pada jam yang sama
|
||||||
|
if (h != th || m != tm) {
|
||||||
|
kotak2Activated[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset tombol Firebase ke false setelah 1 detik
|
||||||
|
if (shouldResetFirebaseButton1 && millis() - buttonTriggerTime1 >= 2500) {
|
||||||
|
Firebase.setBool(fbdo, "/status/button1", false);
|
||||||
|
Firebase.setBool(fbdo, "/status/kotak1", false);
|
||||||
|
Firebase.setBool(fbdo, "/status/alarm1", false);
|
||||||
|
shouldResetFirebaseButton1 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset tombol Firebase ke false setelah 1 detik
|
||||||
|
if (shouldResetFirebaseButton2 && millis() - buttonTriggerTime2 >= 2500) {
|
||||||
|
Firebase.setBool(fbdo, "/status/button2", false);
|
||||||
|
Firebase.setBool(fbdo, "/status/kotak2", false);
|
||||||
|
Firebase.setBool(fbdo, "/status/alarm2", false);
|
||||||
|
shouldResetFirebaseButton2 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonPressed1 = false;
|
||||||
|
buttonStatus1 = false;
|
||||||
|
buttonPressed2 = false;
|
||||||
|
buttonStatus2 = false;
|
||||||
|
}
|
Loading…
Reference in New Issue