#include <WiFi.h>
#include "time.h"
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
#include <FirebaseESP32.h>
#include "addons/TokenHelper.h"
#include "addons/RTDBHelper.h"
LiquidCrystal_I2C lcd(0x27, 20, 4);
#define DHT_SENSOR_PIN 4
#define DHT_SENSOR_TYPE DHT22
DHT dht_sensor(DHT_SENSOR_PIN, DHT_SENSOR_TYPE);
#define API_KEY "AIzaSyBRUCrOn_Gr1BeHY9OqCPVKsRntGbPkWG4"
#define USER_EMAIL "[email protected]"
#define USER_PASSWORD "12345678"
#define DATABASE_URL "https://esp32-demo-wokwi-default-rtdb.asia-southeast1.firebasedatabase.app/"
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;
String uid;
String databasePath;
String tempPath = "/temperature";
String humPath = "/humidity";
String datePath = "/date";
String timePath = "/time";
String phasePath = "/phase";
String parentPath;
int timestamp;
FirebaseJson json;
unsigned long sendDataPrevMillis = 0;
unsigned long timerDelay = 120000;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 6 * 3600;
const int daylightOffset_sec = 3600;
const int buttonPin = 27;
String fase_tumbuh = "INKUBASI";
int buttonState = 0;
int lastButtonState = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
bool confirmModeChange = false;
bool modeChanged = false;
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
pinMode(buttonPin, INPUT);
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("CONNECTED");
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
delay(5000);
dht_sensor.begin();
delay(5000);
config.api_key = API_KEY;
auth.user.email = USER_EMAIL;
auth.user.password = USER_PASSWORD;
config.database_url = DATABASE_URL;
Firebase.reconnectWiFi(true);
fbdo.setResponseSize(4096);
config.token_status_callback = tokenStatusCallback; //see addons/TokenHelper.h
// Assign the maximum retry of token generation
config.max_token_generation_retry = 5;
// Initialize the library with the Firebase authen and config
Firebase.begin(&config, &auth);
// Getting the user UID might take a few seconds
Serial.println("Getting User UID");
while ((auth.token.uid) == "") {
Serial.print('.');
delay(1000);
}
// Print user UID
uid = auth.token.uid.c_str();
Serial.print("User UID: ");
Serial.println(uid);
// Update database path
databasePath = "/UsersData/" + uid + "/readings";
}
void loop() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Ubah fase ke");
lcd.setCursor(0, 1);
lcd.print(fase_tumbuh == "INKUBASI" ? "PRODUKSI?" : "INKUBASI?");
delay(5000); // Menunggu selama 5 detik untuk input
// Mengecek tombol
for (unsigned long start = millis(); millis() - start < 5000; ) {
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
if (fase_tumbuh == "INKUBASI") {
fase_tumbuh = "PRODUKSI";
} else {
fase_tumbuh = "INKUBASI";
}
Serial.println("Fase: " + fase_tumbuh);
modeChanged = true;
lcd.setCursor(0, 0);
lcd.print("FASE BERUBAH");
lcd.setCursor(0, 1);
lcd.print("FASE " + fase_tumbuh);
delay(2000);
break;
}
}
}
lastButtonState = reading;
}
if (!modeChanged) {
Serial.println("Tidak ada perubahan mode");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("FASE TIDAK BERUBAH");
delay(2000);
}
// Menampilkan data
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("MENGAMBIL DATA...");
delay(2000);
float hum = dht_sensor.readHumidity();
float temp = dht_sensor.readTemperature();
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Gagal Memperoleh Waktu");
}
char dateBuffer[16];
char timeBuffer[16];
strftime(dateBuffer, sizeof(dateBuffer), "%d-%m-%Y", &timeinfo);
strftime(timeBuffer, sizeof(timeBuffer), "%H:%M:%S", &timeinfo);
String dateStr = String(dateBuffer);
String timeStr = String(timeBuffer);
if (isnan(hum) || isnan(temp)) {
Serial.println("Gagal memperoleh nilai suhu dan kelembapan");
lcd.setCursor(0, 0);
lcd.print("GAGAL MENGAMBIL DATA");
} else {
Serial.print("Suhu: ");
Serial.println(temp);
Serial.print("Kelembapan: ");
Serial.println(hum);
Serial.print("Tanggal Pengukuran: ");
Serial.println(dateStr);
Serial.print("Waktu Pengukuran: ");
Serial.println(timeStr);
Serial.print("Fase tumbuh: ");
Serial.println(fase_tumbuh);
Serial.println("----------------");
lcd.setCursor(0, 0);
lcd.print("BERHASIL AMBIL DATA");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("TEMP: " + String(temp) + " C");
lcd.setCursor(0, 1);
lcd.print("HUM: " + String(hum) + " %");
lcd.setCursor(0, 2);
lcd.print("WAKTU: " + timeStr);
lcd.setCursor(0, 3);
lcd.print("FASE: " + fase_tumbuh);
if (Firebase.ready() && (millis() - sendDataPrevMillis > timerDelay || sendDataPrevMillis == 0)){
sendDataPrevMillis = millis();
timestamp = getLocalTime(&timeinfo);
parentPath= databasePath + "/" + String(timestamp);
json.clear(); // Clear the JSON object before setting new data
json.set(tempPath.c_str(), temp);
json.set(humPath.c_str(), hum);
json.set(datePath.c_str(), dateStr);
json.set(timePath.c_str(), timeStr);
json.set(phasePath.c_str(), fase_tumbuh);
Serial.printf("Set json... %s\n", Firebase.set(fbdo, parentPath.c_str(), json) ? "ok" : fbdo.errorReason().c_str());
}
}
delay(100000);
modeChanged = false; // Reset flag untuk siklus berikutnya
}