TKK_E32211416/FIXAFTERREVISI.ino

285 lines
7.2 KiB
C++

#include <DHT.h>
#include <ThingerESP32.h>
#include <HX711.h>
#include <ESP32Servo.h>
#include <Ultrasonic.h>
#include <time.h>
#define DOUT_PIN 25
#define CLK_PIN 27
#define RELAY_PIN_2 18
#define RELAY_PIN_1 19
#define TRIGGER_PIN 12
#define ECHO_PIN 14
#define DHTPIN 23
#define DHTTYPE DHT11
#define USERNAME "btwnty"
#define DEVICE_ID "esp32"
#define DEVICE_CREDENTIAL "AfUm_FeJ@Zr@pIN?"
#define SSID "arya"
#define SSID_PASSWORD "12345678"
const char* ntpServer = "0.pool.ntp.org";
const long gmtOffset_sec = 6L * 60L * 60L;
const int daylightOffset_sec = 3600;
const long interval = 5000;
DHT dht(DHTPIN, DHTTYPE);
ThingerESP32 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);
Servo myServo;
HX711 scale;
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
unsigned long notifikasiterakhir = 0;
unsigned long conditionStartTime = 0;
bool relayActive1 = true;
bool relayActive2 = false;
unsigned long relay1StartTime = 0;
unsigned long relay2StartTime = 0;
const float bebanmax = 30.0;
const unsigned long durasiRelayAktif = 2500;
const float suhumin = 30;
const float suhumax = 35;
const int tinggiWadah = 20;
unsigned long bacaSensorTerakhir = 0;
const unsigned long bacaSensorInterval = 1000;
enum WiFiState { DISCONNECTED, CONNECTING, CONNECTED };
WiFiState wifiState = DISCONNECTED;
unsigned long wifiConnectStartTime = 0;
const unsigned long wifiReconectInterval = 5000;
void setup() {
Serial.begin(9600);
thing.add_wifi(SSID, SSID_PASSWORD);
myServo.attach(5);
myServo.write(0);
dht.begin();
pinMode(RELAY_PIN_2, OUTPUT);
pinMode(RELAY_PIN_1, OUTPUT);
digitalWrite(RELAY_PIN_2, HIGH);
digitalWrite(RELAY_PIN_1, HIGH);
scale.begin(DOUT_PIN, CLK_PIN);
scale.set_scale(-1057.89);
scale.tare(0);
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
thing["servoControl"] << [](pson& in) {
if (in.is_empty()) {
return;
}
myServo.write(75);
delay(1000);
myServo.write(0);
};
thing["sensorData"] >> [](pson& out) {
float temperature = dht.readTemperature();
float weight = getWeight();
float distance = ultrasonic.read();
int ketinggianPakan = tinggiWadah - distance;
struct tm timeinfo;
if (getLocalTime(&timeinfo)) {
char timeStr[30];
strftime(timeStr, sizeof(timeStr), "%d %B %Y %H:%M:%S", &timeinfo);
String timeString = String(timeStr);
out["Waktu"] = timeString;
} else {
out["Waktu"] = "Failed to obtain time";
}
out["Suhu"] = temperature;
out["Beban Kotoran"] = weight;
out["Ketinggian Pakan"] = ketinggianPakan;
};
wifiState = DISCONNECTED;
}
void loop() {
unsigned long currentTime = millis();
koneksiwifi();
thing.handle();
if (currentTime - bacaSensorTerakhir >= bacaSensorInterval) {
bacaSensorTerakhir = currentTime;
float temperature = dht.readTemperature();
float weight = getWeight();
unsigned int distance = ultrasonic.read();
int ketinggianPakan = tinggiWadah - distance;
handleNotifications(ketinggianPakan, currentTime);
handleRelayControls(temperature, weight, currentTime);
handleServoSchedule();
struct tm timeinfo;
if (getLocalTime(&timeinfo)) {
Serial.print(&timeinfo, "%d %B %Y %H:%M:%S\t");
} else {
Serial.print("Failed to obtain time");
}
Serial.print("Weight: ");
Serial.print(weight);
Serial.print(" g\t");
Serial.print("Ketinggian Pakan: ");
Serial.print(ketinggianPakan);
Serial.print(" cm\t");
Serial.print("Suhu: ");
Serial.print(temperature);
Serial.println(" °C");
}
}
void koneksiwifi() {
unsigned long currentTime = millis();
switch (wifiState) {
case DISCONNECTED:
WiFi.begin(SSID, SSID_PASSWORD);
wifiState = CONNECTING;
wifiConnectStartTime = currentTime;
Serial.println("Connecting to WiFi...");
break;
case CONNECTING:
if (WiFi.status() == WL_CONNECTED) {
Serial.println("WiFi connected.");
wifiState = CONNECTED;
} else if (currentTime - wifiConnectStartTime >= wifiReconectInterval) {
wifiState = DISCONNECTED;
Serial.println("Retrying WiFi connection...");
}
break;
case CONNECTED:
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi disconnected.");
wifiState = DISCONNECTED;
}
break;
}
}
float getWeight() {
float weight = scale.get_units(10);
if (weight >= -2.0 && weight <= 2.0) {
return 0.0;
}
return weight;
}
void moveServo() {
myServo.write(75);
delay(1000);
myServo.write(0);
pson data;
data["action"] = "servo_moved";
thing.write_bucket("Servo", data);
}
void handleNotifications(int ketinggianPakan, unsigned long currentTime) {
if (ketinggianPakan <= 2) { // Notifikasi "habis"
if (conditionStartTime == 0) {
conditionStartTime = currentTime;
} else if (currentTime - conditionStartTime >= 5 * 1000) {
if (currentTime - notifikasiterakhir >= 60 * 1000 && wifiState == CONNECTED) {
Serial.println("Mengirim Notifikasi Habis...");
bool result = thing.call_endpoint("notifikasi_habis");
if (result) {
Serial.println("Notifikasi Habis Sukses Terkirim.");
} else {
Serial.println("Gagal Mengirim Notifikasi Habis.");
}
notifikasiterakhir = currentTime;
}
}
} else if (ketinggianPakan < 5) { // Notifikasi "hampir habis"
if (conditionStartTime == 0) {
conditionStartTime = currentTime;
} else if (currentTime - conditionStartTime >= 5 * 1000) {
if (currentTime - notifikasiterakhir >= 60 * 1000 && wifiState == CONNECTED) {
Serial.println("Mengirim Notifikasi Hampir Habis");
bool result = thing.call_endpoint("notifikasi_hampir_habis");
if (result) {
Serial.println("Berhasil Mengirim Notifikasi Hampir Habis.");
} else {
Serial.println("Gagal Mengirim Notifikasi Hampir Habis.");
}
notifikasiterakhir = currentTime;
}
}
} else {
conditionStartTime = 0;
}
}
void handleRelayControls(float temperature, float weight, unsigned long currentTime) {
if (!isnan(temperature)) {
if (temperature > suhumax && !relayActive1) {
digitalWrite(RELAY_PIN_2, HIGH);
relayActive1 = true;
} else if (temperature <= suhumin && relayActive1) {
digitalWrite(RELAY_PIN_2, LOW);
relayActive1 = false;
}
}
if (weight > bebanmax && !relayActive2) {
digitalWrite(RELAY_PIN_1, LOW);
relayActive2 = true;
relay2StartTime = currentTime;
}
if (relayActive2 && (currentTime - relay2StartTime >= durasiRelayAktif)) {
digitalWrite(RELAY_PIN_1, HIGH);
relayActive2 = false;
scale.tare();
}
}
void handleServoSchedule() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
return;
}
int currentHour = timeinfo.tm_hour;
int currentMinute = timeinfo.tm_min;
int currentSecond = timeinfo.tm_sec;
if (currentHour == 6 && currentMinute == 0 && currentSecond == 1) {
moveServo();
}
if (currentHour == 11 && currentMinute == 0 && currentSecond == 1) {
moveServo();
}
if (currentHour == 16 && currentMinute == 0 && currentSecond == 1) {
moveServo();
}
if (currentHour == 21 && currentMinute == 0 && currentSecond == 1) {
moveServo();
}
}