#define BLYNK_TEMPLATE_ID "TMPL6AQKdBCst"
#define BLYNK_TEMPLATE_NAME "WLC Fluid Mixing"
#define BLYNK_AUTH_TOKEN "RfG4xLWD8aVfypK5y417semgc8Cq8NwH"
#include <WiFiClient.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#include <BlynkSimpleEsp32.h>
#define BLYNK_FIRMWARE_VERSION "1.3.2"
#define BLYNK_PRINT Serial
char auth[] = BLYNK_AUTH_TOKEN; // Token otentikasi dari proyek Blynkmu
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
const int triggerPin_A = 32;
const int echoPin_A = 33;
const int triggerPin_B = 25;
const int echoPin_B = 26;
const int triggerPin_C = 27;
const int echoPin_C = 14;
const int pumpPin1 = 5;
const int pumpPin2 = 18;
float waterLevel_A, waterLevel_B, waterLevel_C;
float threshold = 10.0;
BlynkTimer timer;
void setup() {
Serial.begin(115200);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.display();
delay(2000);
display.clearDisplay();
Blynk.begin(auth, ssid, pass);
pinMode(triggerPin_A, OUTPUT);
pinMode(echoPin_A, INPUT);
pinMode(triggerPin_B, OUTPUT);
pinMode(echoPin_B, INPUT);
pinMode(triggerPin_C, OUTPUT);
pinMode(echoPin_C, INPUT);
pinMode(pumpPin1, OUTPUT);
pinMode(pumpPin2, OUTPUT);
timer.setInterval(1000L, sendSensorData); // Kirim data sensor setiap 1 detik
}
void loop() {
Blynk.run();
timer.run();
}
void sendSensorData() {
waterLevel_A = getWaterLevel(triggerPin_A, echoPin_A);
waterLevel_B = getWaterLevel(triggerPin_B, echoPin_B);
waterLevel_C = getWaterLevel(triggerPin_C, echoPin_C);
Blynk.virtualWrite(V1, waterLevel_A); // Kirim data tinggi air Wadah A ke pin virtual V1 di Blynk
Blynk.virtualWrite(V2, waterLevel_B); // Kirim data tinggi air Wadah B ke pin virtual V2 di Blynk
Blynk.virtualWrite(V3, waterLevel_C); // Kirim data tinggi air Wadah C ke pin virtual V3 di Blynk
// Aktifkan pompa jika tinggi air di wadah A atau B melebihi ambang tertentu
if (waterLevel_A > threshold || waterLevel_B > threshold) {
digitalWrite(pumpPin1, HIGH); // Aktifkan pompa 1
digitalWrite(pumpPin2, HIGH); // Aktifkan pompa 2
} else {
digitalWrite(pumpPin1, LOW); // Matikan pompa 1
digitalWrite(pumpPin2, LOW); // Matikan pompa 2
}
// Tampilkan tinggi air di OLED
display.clearDisplay();
drawPercentbar( 20, 0, 100, 15,waterLevel_A,"A");
drawPercentbar( 20, 20, 100, 15,waterLevel_B,"B");
drawPercentbar( 20, 40, 100, 15,waterLevel_C,"C");
display.display();
delay(200);
}
float getWaterLevel(int triggerPin, int echoPin) {
digitalWrite(triggerPin, LOW);
delayMicroseconds(2);
digitalWrite(triggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(triggerPin, LOW);
float duration = pulseIn(echoPin, HIGH);
float distance = (duration * 0.0343) / 2;
return distance;
}
void drawPercentbar(int x,int y, int width,int height, int progress,String teks)
{
progress = progress > 100 ? 100 : progress;
progress = progress < 0 ? 0 :progress;
float bar = ((float)(width-4) / 100) * progress;
display.drawRect(x, y, width, height, WHITE);
display.fillRect(x+2, y+2, bar , height-4, WHITE);
// Display progress text
if( height >= 15){
display.setCursor((width/2) -3, y+5 );
display.setTextSize(1);
display.setTextColor(WHITE);
if( progress >=50)
display.setTextColor(BLACK, WHITE); // 'inverted' text
display.print(teks);
display.print(" ");
display.print(progress);
display.print("%");
}
}