#define BLYNK_TEMPLATE_ID "TMPL64-PTQxbQ"
#define BLYNK_TEMPLATE_NAME "water smart systems"
#define BLYNK_AUTH_TOKEN "obfhr6knwgcSdUoKjFZEivQb14PXcg1b"
#include <BlynkSimpleEsp32.h>
#include <ArduinoJson.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <FlowMeter.h>
// char ssid[] = "afif.khoury";
// char pass[] = "jaad2013";
// char auth[] = "DyeApTOWfgJqcChV15wmL1xpykWn7jhx";
int relayPins[] = {23, 22, 21, 5};
int pushButtonPin = 18;
FlowMeter meters[] = {FlowMeter(1), FlowMeter(2), FlowMeter(3), FlowMeter(4), FlowMeter(5)};
const unsigned long period = 1000;
int relayStates[] = {HIGH, HIGH, HIGH, HIGH};
int pushButtonState = HIGH;
int currentState = 0;
unsigned long startTime = 0;
#define FLOW_CALIBRATION 7.5
#define VPIN_RESET V9
volatile long pulseCounts[5];
float flowRates[5];
unsigned long oldTimes[5];
BlynkTimer timer;
BLYNK_WRITE(V0) { toggleRelay(0); }
BLYNK_WRITE(V1) { toggleRelay(1); }
BLYNK_WRITE(V2) { toggleRelay(2); }
BLYNK_WRITE(V3) { toggleRelay(3); }
BLYNK_WRITE(V4) { handleButtonPress(); }
void toggleRelay(int index) {
relayStates[index] = relayStates[index] == HIGH ? LOW : HIGH;
digitalWrite(relayPins[index], relayStates[index]);
// Update corresponding virtual pins
switch (index) {
case 0:
Blynk.virtualWrite(V0, relayStates[index] == HIGH ? 0 : 1);
Blynk.virtualWrite(V3, relayStates[index == 0 ? 3 : index - 1] == HIGH ? 0 : 1);
break;
case 1:
Blynk.virtualWrite(V1, relayStates[index] == HIGH ? 0 : 1);
break;
case 2:
Blynk.virtualWrite(V2, relayStates[index] == HIGH ? 0 : 1);
break;
case 3:
Blynk.virtualWrite(V3, relayStates[index] == HIGH ? 0 : 1);
Blynk.virtualWrite(V0, relayStates[index == 3 ? 0 : index + 1] == HIGH ? 0 : 1);
break;
}
}
void handleButtonPress() {
Blynk.virtualWrite(V4, 1);
int i = pushButtonState != LOW ? (toggleRelay(0), toggleRelay(1), currentState = 1, startTime = millis(), 0) : HIGH;
pushButtonState = i == 0 ? LOW : HIGH;
if (currentState > 0 && millis() - startTime >= 7000) {
toggleRelay(currentState);
toggleRelay((currentState + 1) % 4);
currentState = (currentState + 1) % 4;
startTime = millis();
}
}
void checkPhysicalButton() {
pushButtonState = digitalRead(pushButtonPin) == LOW ? (toggleRelay(0), toggleRelay(1), currentState = 1, startTime = millis(), LOW) : HIGH;
if (currentState > 0 && millis() - startTime >= 7000) {
toggleRelay(currentState);
toggleRelay((currentState + 1) % 4);
currentState = (currentState + 1) % 4;
startTime = millis();
}
}
void Meter1ISR() {
meters[0].count();
}
void Meter2ISR() {
meters[1].count();
}
void Meter3ISR() {
meters[2].count();
}
void Meter4ISR() {
meters[3].count();
}
void Meter5ISR() {
meters[4].count();
}
BLYNK_WRITE(VPIN_RESET) {
if (param.asInt() == 0) Serial.println("Clearing Data");
}
void setup() {
Serial.begin(115200);
WiFi.begin("Wokwi-GUEST");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting...");
}
Serial.println("Connected");
Blynk.config(BLYNK_AUTH_TOKEN);
attachInterrupt(digitalPinToInterrupt(34), Meter1ISR, RISING);
attachInterrupt(digitalPinToInterrupt(35), Meter2ISR, RISING);
attachInterrupt(digitalPinToInterrupt(33), Meter3ISR, RISING);
attachInterrupt(digitalPinToInterrupt(32), Meter4ISR, RISING);
attachInterrupt(digitalPinToInterrupt(25), Meter5ISR, RISING);
for (int i = 0; i < 5; ++i) {
meters[i].reset();
}
for (int i = 0; i < 4; ++i) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], HIGH);
}
pinMode(pushButtonPin, INPUT_PULLUP);
timer.setInterval(100L, []() { Blynk.virtualWrite(V4, 1); });
}
void loop() {
Blynk.run();
timer.run();
checkPhysicalButton();
// Non-blocking delay using millis
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= period) {
// Your existing loop code here
for (int i = 0; i < 5; ++i) {
meters[i].tick(period);
Blynk.virtualWrite(V11 + i, meters[i].getCurrentFlowrate());
Serial.println("M" + String(i + 1) + " " + String(meters[i].getCurrentFlowrate()) + " l/min, " + String(meters[i].getTotalVolume()) + " l total.");
}
previousMillis = currentMillis;
}
}