TKK_E32231121/FILE KODE ESP32.ino

687 lines
12 KiB
C++

#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include <Wire.h>
#include "RTClib.h"
#include "time.h"
#include <Preferences.h>
// =====================================
// OBJECT
// =====================================
Preferences prefs;
RTC_DS3231 rtc;
WiFiClientSecure client;
// =====================================
// WIFI
// =====================================
const char* ssid = "Galaxy A16 2CF8";
const char* password = "bismillah";
// =====================================
// FIREBASE
// =====================================
String baseURL =
"https://smartcabai-default-rtdb.firebaseio.com/";
// =====================================
// PIN
// =====================================
#define SENSOR_PIN 34
#define RELAY_AIR 26
#define RELAY_PESTISIDA 27
// =====================================
// KALIBRASI SENSOR
// =====================================
int nilaiKering = 3000;
int nilaiBasah = 2200;
int batasKering = 60;
// =====================================
// VARIABEL SISTEM
// =====================================
String mode = "AUTO";
String airStatus = "OFF";
String pestStatus = "OFF";
bool pestisidaNyala = false;
unsigned long waktuMulaiPestisida = 0;
unsigned long lastSemprotUnix = 0;
unsigned long lastFirebase = 0;
unsigned long lastGetMode = 0;
unsigned long lastManualGet = 0;
unsigned long firebaseCooldown = 0;
bool firebaseError = false;
// =====================================
// CONNECT WIFI
// =====================================
void connectWiFi() {
WiFi.mode(WIFI_STA);
WiFi.setSleep(false);
WiFi.setAutoReconnect(true);
WiFi.persistent(true);
WiFi.config(
INADDR_NONE,
INADDR_NONE,
INADDR_NONE,
IPAddress(8,8,8,8),
IPAddress(8,8,4,4)
);
WiFi.begin(ssid, password);
Serial.print("Connecting WiFi");
int timeout = 0;
while (WiFi.status() != WL_CONNECTED &&
timeout < 20) {
delay(500);
Serial.print(".");
timeout++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi Connected");
Serial.print("IP : ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nOFFLINE MODE");
}
}
// =====================================
// FIREBASE GET
// =====================================
String getFirebase(String path) {
if (WiFi.status() != WL_CONNECTED) {
return "";
}
HTTPClient http;
String url = baseURL + path + ".json";
http.begin(client, url);
http.setTimeout(10000);
int httpCode = http.GET();
String hasil = "";
if (httpCode > 0) {
hasil = http.getString();
hasil.replace("\"", "");
hasil.trim();
} else {
firebaseError = true;
firebaseCooldown = millis();
}
http.end();
delay(100);
return hasil;
}
// =====================================
// FIREBASE PUT
// =====================================
// =====================================
// FIREBASE PUT
// =====================================
void putFirebase(String path,
String value,
bool isString = false) {
if (WiFi.status() != WL_CONNECTED) {
return;
}
HTTPClient http;
String url = baseURL + path + ".json";
http.begin(client, url);
http.setTimeout(5000);
http.addHeader(
"Content-Type",
"application/json"
);
String payload;
if (isString) {
payload = "\"" + value + "\"";
} else {
payload = value;
}
int httpCode =
http.PUT(payload);
if (httpCode <= 0) {
firebaseError = true;
firebaseCooldown = millis();
}
http.end();
}
// =====================================
// GET UNIX RTC
// =====================================
unsigned long getUnixTimeRTC() {
DateTime now = rtc.now();
Serial.print("Tanggal RTC : ");
Serial.print(now.day());
Serial.print("/");
Serial.print(now.month());
Serial.print("/");
Serial.print(now.year());
Serial.print(" ");
Serial.print(now.hour());
Serial.print(":");
Serial.print(now.minute());
Serial.print(":");
Serial.println(now.second());
Serial.print("NOW UNIX : ");
Serial.println(now.unixtime());
Serial.print("LAST UNIX : ");
Serial.println(lastSemprotUnix);
return now.unixtime();
}
// =====================================
// SETUP
// =====================================
void setup() {
Serial.begin(115200);
prefs.begin("spray", false);
client.setInsecure();
// =================================
// RELAY
// =================================
pinMode(RELAY_AIR, OUTPUT);
pinMode(RELAY_PESTISIDA, OUTPUT);
digitalWrite(RELAY_AIR, HIGH);
digitalWrite(RELAY_PESTISIDA, HIGH);
// =================================
// RTC
// =================================
Wire.begin(21, 22);
if (!rtc.begin()) {
Serial.println("RTC ERROR");
while (1);
}
// =================================
// WIFI
// =================================
connectWiFi();
// =================================
// SYNC RTC DARI INTERNET
// =================================
configTime(7 * 3600,
0,
"pool.ntp.org");
if (rtc.lostPower()) {
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 SYNC BERHASIL");
} else {
Serial.println("GAGAL SYNC RTC");
}
}
// =================================
// AMBIL DATA LAST SEMPROT
// =================================
String lastData =
getFirebase("last_semprot");
if (lastData != "" &&
lastData != "null" &&
lastData != "0") {
// dari firebase
unsigned long temp = strtoul(
lastData.c_str(),
NULL,
10
);
if(temp > 0) {
lastSemprotUnix = temp;
}
// simpan lokal
prefs.putULong(
"lastUnix",
lastSemprotUnix
);
Serial.println(
"DATA DARI FIREBASE"
);
} else {
// dari memori lokal
lastSemprotUnix =
prefs.getULong(
"lastUnix",
0
);
Serial.println(
"DATA DARI MEMORI LOKAL"
);
// jika belum ada data
if (lastSemprotUnix == 0) {
lastSemprotUnix =
rtc.now().unixtime();
Serial.print("LAST SEMPROT BARU: ");
Serial.println(lastSemprotUnix);
prefs.putULong(
"lastUnix",
lastSemprotUnix
);
Serial.println(
"DATA BARU DIBUAT"
);
}
}
Serial.println("SYSTEM READY");
}
// =====================================
// LOOP
// =====================================
void loop() {
if(WiFi.status()!=WL_CONNECTED) {
WiFi.reconnect();
}
// =================================
// FIREBASE COOLDOWN
// =================================
if (firebaseError &&
millis() - firebaseCooldown < 10000) {
delay(1000);
return;
}
firebaseError = false;
// =================================
// STATUS WIFI
// =================================
bool wifiConnected =
(WiFi.status() == WL_CONNECTED);
if (!wifiConnected) {
mode = "AUTO";
}
// =================================
// AMBIL MODE DARI FIREBASE
// =================================
if (wifiConnected &&
millis() - lastGetMode >= 10000) {
String firebaseMode =
getFirebase("mode");
if (firebaseMode != "") {
mode = firebaseMode;
mode.trim();
}
lastGetMode = millis();
}
// =================================
// BACA SENSOR
// =================================
int adc = analogRead(SENSOR_PIN);
float kelembapan =
((float)(nilaiKering - adc) /
(nilaiKering - nilaiBasah))
* 100;
kelembapan =
constrain(
kelembapan,
0,
100
);
// =================================
// RTC
// =================================
DateTime now = rtc.now();
int jam = now.hour();
int menit = now.minute();
// =================================
// HITUNG COUNTDOWN
// =================================
unsigned long nowUnix =
now.unixtime();
unsigned long intervalDetik =
120UL * 3600UL;
unsigned long elapsedDetik =
nowUnix - lastSemprotUnix;
long sisaDetik;
if (elapsedDetik >= intervalDetik) {
sisaDetik = 0;
} else {
sisaDetik = intervalDetik - elapsedDetik;
}
// =================================
// FORMAT COUNTDOWN
// =================================
int hariSisa = sisaDetik / 86400;
int jamSisa = (sisaDetik % 86400) / 3600;
int menitSisa = (sisaDetik % 3600) / 60;
int detikSisa = sisaDetik % 60;
String countdown;
if (sisaDetik > 0) {
countdown =
String(hariSisa) + " Hari " +
String(jamSisa) + " Jam " +
String(menitSisa) + " Menit " +
String(detikSisa) + " Detik";
} else {
countdown = "Siap Semprot";
}
// =================================
// KIRIM FIREBASE
// =================================
if (wifiConnected &&
millis() - lastFirebase >= 1000) {
putFirebase(
"kelembapan",
String(kelembapan, 1)
);
putFirebase(
"jeda_penyemprotan",
countdown,
true
);
lastFirebase = millis();
}
// =================================
// SERIAL MONITOR
// =================================
Serial.print("Mode : ");
Serial.print(mode);
Serial.print(" ADC: ");
Serial.print(adc);
Serial.print(
" || Kelembapan : "
);
Serial.print(
kelembapan,
1
);
Serial.print("%");
Serial.print(
" ||Jeda Penyemprotan : "
);
Serial.print(countdown);
Serial.print(" || ");
if (wifiConnected) {
Serial.println("ONLINE");
} else {
Serial.println("OFFLINE");
}
// =================================
// MODE AUTO
// =================================
if (mode == "AUTO") {
// =============================
// POMPA AIR
// =============================
if (kelembapan <
batasKering) {
digitalWrite(
RELAY_AIR,
LOW
);
} else {
digitalWrite(
RELAY_AIR,
HIGH
);
}
// =============================
// PESTISIDA OTOMATIS
// =============================
if (sisaDetik <= 0 &&
!pestisidaNyala &&
WiFi.status()==WL_CONNECTED) {
Serial.println("PESTISIDA MULAI");
digitalWrite(
RELAY_PESTISIDA,
LOW
);
pestisidaNyala = true;
waktuMulaiPestisida =
millis();
}
// =============================
// MATIKAN PESTISIDA
// =============================
if (pestisidaNyala &&
millis() -
waktuMulaiPestisida
>= 7000) {
Serial.println("PESTISIDA SELESAI");
digitalWrite(
RELAY_PESTISIDA,
HIGH
);
pestisidaNyala = false;
lastSemprotUnix =
rtc.now().unixtime();
// simpan firebase
putFirebase(
"last_semprot",
String(lastSemprotUnix)
);
// simpan lokal
prefs.putULong(
"lastUnix",
lastSemprotUnix
);
}
}
// =================================
// MODE MANUAL
// =================================
else if (mode == "MANUAL" &&
wifiConnected) {
// =============================
// AMBIL STATUS MANUAL
// =============================
if (millis() -
lastManualGet >= 5000) {
airStatus =
getFirebase("pompa_air");
pestStatus =
getFirebase(
"pompa_pestisida"
);
lastManualGet =
millis();
}
// =============================
// POMPA AIR
// =============================
if (airStatus == "ON") {
digitalWrite(
RELAY_AIR,
LOW
);
} else {
digitalWrite(
RELAY_AIR,
HIGH
);
}
// =============================
// POMPA PESTISIDA
// =============================
if (pestStatus == "ON") {
digitalWrite(
RELAY_PESTISIDA,
LOW
);
} else {
digitalWrite(
RELAY_PESTISIDA,
HIGH
);
}
}
delay(3000);
}