TKK_E32210446/WaterFlow/kodeprogramesp8266.ino

284 lines
7.2 KiB
C++

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP8266WiFi.h>
#include <RTClib.h>
#include <ThingerESP8266.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <Servo.h>
// WiFi Credentials
const char* ssid = "IANION";
const char* password = "ianryanian";
// Thinger.io Credentials
#define USERNAME "iannion"
#define DEVICE_ID "yono3"
#define DEVICE_CREDENTIAL "H3GFa2M7cN&wYxbk"
RTC_DS3231 rtc;
LiquidCrystal_I2C lcd(0x27, 20, 4);
volatile int flow_frequency = 0;
float vol = 0.0, l_minute;
const unsigned char flowsensor = 13;
const unsigned char buttonPin1 = 14;
const unsigned char buttonPin2 = 12;
const unsigned char buttonPin3 = 2;
const unsigned char buttonPin4 = 16;
unsigned long currentTime;
unsigned long cloopTime;
float volume_per_pulse = 0.004;
float cost_per_liter = 5.07;
float total_cost = 0.0;
Servo servo;
const int servoPin = 3;
const int posisiBuka = 0;
const int posisiTutup = 180;
const unsigned long delayBuka = 1000;
const unsigned long delayTutup = 2000;
int limitSet2Counter = 0;
int limitSet3Counter = 0;
bool kranDitutup = true;
ThingerESP8266 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 25200, 60000);
unsigned long lastThingerUpdateTime = 0;
const unsigned long thingerUpdateInterval = 60000; // Update every 60 seconds
void IRAM_ATTR flow() {
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
if (interrupt_time - last_interrupt_time > 10) {
flow_frequency++;
}
last_interrupt_time = interrupt_time;
}
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
pinMode(flowsensor, INPUT);
digitalWrite(flowsensor, HIGH);
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(buttonPin2, INPUT_PULLUP);
pinMode(buttonPin3, INPUT_PULLUP);
pinMode(buttonPin4, INPUT_PULLUP);
servo.attach(servoPin);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
timeClient.begin();
timeClient.update();
unsigned long epochTime = timeClient.getEpochTime();
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, set time...");
rtc.adjust(DateTime(epochTime));
}
attachInterrupt(digitalPinToInterrupt(flowsensor), flow, RISING);
currentTime = millis();
cloopTime = currentTime;
thing.add_wifi(ssid, password);
thing["meyala"] >> [] (pson & out) {
out["flow_rate"] = String(l_minute);
out["volume"] = String(vol);
out["total_cost"] = String(total_cost);
};
thing["current_time"] >> [](pson& out) {
DateTime now = rtc.now();
char buffer[30];
snprintf(buffer, sizeof(buffer), "%02d/%02d/%d %02d:%02d", now.day(), now.month(), now.year(), now.hour(), now.minute());
out = String(buffer);
};
}
void tutupKatup() {
if (!kranDitutup) {
Serial.println("Menutup katup...");
servo.write(posisiTutup);
delay(delayTutup); // Delay untuk memastikan servo memiliki waktu untuk bergerak
kranDitutup = true;
}
}
void bukaKatup() {
if (kranDitutup) {
Serial.println("Membuka katup...");
servo.write(posisiBuka);
delay(delayBuka); // Delay untuk memastikan servo memiliki waktu untuk bergerak
kranDitutup = false;
}
}
bool kirimDataKeThinger() {
pson data;
data["flow_rate"] = l_minute;
data["volume"] = vol;
data["total_cost"] = total_cost;
bool success = thing.write_bucket("meyala", data);
if (!success) {
Serial.println("Gagal mengirim data ke Thinger.io");
}
return success;
}
void resetData() {
vol = 0;
total_cost = 0.0;
limitSet2Counter = 0;
limitSet3Counter = 0;
Serial.println("Semua pembacaan sensor direset");
// Update Thinger.io dengan nilai reset
kirimDataKeThinger();
// Perbarui tampilan LCD
lcd.setCursor(0, 1);
lcd.print("Flow :0 L/M ");
lcd.setCursor(0, 2);
lcd.print("Volume :0 mL ");
lcd.setCursor(0, 3);
lcd.print("Cost :Rp 0.00 ");
}
void loop() {
DateTime now = rtc.now();
timeClient.update();
unsigned long epochTime = timeClient.getEpochTime();
rtc.adjust(DateTime(epochTime));
lcd.setCursor(0, 0);
if (now.day() < 10) lcd.print('0');
lcd.print(now.day());
lcd.print('/');
if (now.month() < 10) lcd.print('0');
lcd.print(now.month());
lcd.print('/');
lcd.print(now.year());
lcd.print(' ');
if (now.hour() < 10) lcd.print('0');
lcd.print(now.hour());
lcd.print(':');
if (now.minute() < 10) lcd.print('0');
lcd.print(now.minute());
currentTime = millis();
if (currentTime >= (cloopTime + 1000)) {
cloopTime = currentTime;
if (flow_frequency != 0) {
l_minute = (flow_frequency * volume_per_pulse * 60);
Serial.print("Flow: ");
Serial.print(l_minute);
Serial.println(" L/M");
lcd.setCursor(0, 1);
lcd.print("Flow :");
lcd.print(l_minute);
lcd.print(" L/M ");
vol += l_minute / 60;
total_cost += (l_minute / 60) * cost_per_liter;
Serial.print("Volume: ");
Serial.print(vol);
Serial.println(" L");
Serial.print("Volume: ");
Serial.print(vol * 1000);
Serial.println(" mL");
lcd.setCursor(0, 2);
lcd.print("Volume :");
lcd.print(int(vol * 1000));
lcd.print(" mL ");
Serial.print("Cost: Rp ");
Serial.print(total_cost, 2);
Serial.println();
lcd.setCursor(0, 3);
lcd.print("Cost :Rp ");
lcd.print(total_cost, 2);
lcd.print(" ");
if (limitSet2Counter > 0 && vol >= (2.0 * limitSet2Counter)) { // Batasan kelipatan 2 liter
Serial.println("Batas aliran tercapai: " + String(2.0 * limitSet2Counter) + " liter!");
thing.call_endpoint("Notifikasi_Harian"); // kirim notifikasi dengan endpoint
tutupKatup();
}
if (limitSet3Counter > 0 && vol >= (3.0 * limitSet3Counter)) { // Batasan kelipatan 3 liter
Serial.println("Batas aliran tercapai: " + String(3.0 * limitSet3Counter) + " liter!");
thing.call_endpoint("Notifikasi_Harian3"); // kirim notifikasi dengan endpoint
tutupKatup();
}
flow_frequency = 0;
} else {
Serial.println("Flow: 0 L/M");
lcd.setCursor(0, 1);
lcd.print("Flow :0 L/M ");
}
}
if (digitalRead(buttonPin1) == LOW) {
limitSet2Counter++;
limitSet3Counter = 0; // Reset counter untuk batasan 3 liter
Serial.println("Batas aliran ditetapkan untuk 2 liter kelipatan " + String(limitSet2Counter));
lcd.setCursor(0, 3);
lcd.print("Limit :2 L ");
delay(500);
bukaKatup();
}
if (digitalRead(buttonPin2) == LOW) {
limitSet3Counter++;
limitSet2Counter = 0; // Reset counter untuk batasan 2 liter
Serial.println("Batas aliran ditetapkan untuk 3 liter kelipatan " + String(limitSet3Counter));
lcd.setCursor(0, 3);
lcd.print("Limit :3 L ");
delay(500);
bukaKatup();
}
if (digitalRead(buttonPin3) == LOW) {
resetData();
delay(500);
}
if (digitalRead(buttonPin4) == LOW) {
if (kranDitutup) {
bukaKatup();
}
}
if (currentTime - lastThingerUpdateTime >= thingerUpdateInterval) {
lastThingerUpdateTime = currentTime;
kirimDataKeThinger();
}
thing.handle();
delay(10);
}