…well…better late then never…
@Costas
I got it.
The timer wil not run right way because the line code, it’s mistake.
nowseconds = ((hour() * 3600) + (minute() * 60) + second());
It mus be changed like the right one:
nowseconds = long(hour() * 3600L) + long(minute() * 60L) + long(second());
Timer using Time Input Widgets will be awesome!
Thank you for useful application on Blynk.
Dear all, where I can find the last version of code ?
The one in the first post includes all corrections ?
Thanks
Hi mate,
Can you summarise the corrections you are taking about?
hi sir, i want to ask you a question… if i want to change the output from the lamp into buzzer, means that i want to make an alarm clock instead… how can i do that which line should i change or i need to add another code for that to set the buzzer as the output… i know we need to determine(select) which pin we connect the buzzer(in the coding) but i do not know where in your coding sir all i see is the virtual pin… btw i’m using nodemcu ESP-12E module as the microcontroller
thank you for your reply, i’m a newbies in this advanced coding but i’m ready to learn
sorry for my poor English hope you can understand @psoro @Costas
hi sir, if not disturbing you… can i know where i can get the sketch 'TestLED" i already search it in example(arduino IDE), github i don’t know which one… if i can get the link is also excellent… i will try to understand the code first
Tq sir @Costas
TestLED isn’t a sketch, it’s a variable within the sketch used for this project - see post #1 in the topic…
Pete.
Hola, antes que nada pido disculpas si no se puede escribir en otro idioma, pero vi que eres español y la verdad que no me llevo muy bien con el ingles.
Tu proyecto me encanto y lo estoy usando perfectamente, ahora queria saber si seria posible agregar un boton fisico para cambiar el estado manual de on a off?
si pudieras darme una mano con el codigo estaria encantado.
desde ya Muchas gracias
nice project, can you send your lastest code and QR code? thanks you
Help me, timer input is not working properly, today is Monday, I changed but the system kept your previous settings.
You have to adjust the day in your sketch.
For blynk, the first day of the week is Sunday, not monday.
Latest Status Eeprom Write. You check in there from the first boot.
Hi. love the project.
I’ve modified this project a fair bit to have time input to operate 2 separate irrigation zones. Managed to get it all working.
The next bit of functionality im keen to add is a ‘cycle/soak’ where the watering time is split up to allow time for the water to soak in before more water is added. My very crude attempt is to divide the total time input duration by 5 (3 running intervals and 2 soak intervals) and run a new function turning the relay on/off and then calling the next function (cycle_soak_1/2/3/4/5). You’ll see the first timer called in the “BLYNK_WRITE(V10)//Zone 1 time input handling” section and then the subsequent cycle_soak functions at the end of the V10 Write.
Some of the problems i’m having with this
- The 10second check doesnt seem to happen once the Zone 1 Cycle/Soak has kicked off (no updated on the terminal.
- reinstating to normal checking of the next input time doesnt appear to be working
A couple of notes
- i’ve only implemented the CYcle/soak on Zone1 at this stage for testing
- i’ve commented out some of the original code as im testing incase i need to retrieve later on
Any help, or better ideas on how to achieve would be greatly appreciated.
And thanks again for the project to begin with
// changes to allow cycle and soak in auto mode
/**************************************************************
* timeinput.ino Demonstrate interaction of Time library with
* Blynk's TimeInput widget.
* App project setup:
* RTC widget (no pin required!!!)
* V1 : Manual/auto1 button
* V2: On-off button
* Terminal on V3 // Label will be the clock + wifi signal!!!!
*
* Time Input widget on V10 (Auto)
* Button selection for Time Input (Auto) on V11
*
**************************************************************/
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
//#include <SimpleTimer.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
SimpleTimer timer;
WidgetRTC rtc;
WidgetTerminal terminal(V3);
//#define server "blynk.cloud-com" // or "blynk.cloud-com" for Blynk's cloud server
#define TestLED 2 // on board LED pin assignment
char Date[16];
char Time[16];
char auth[] = "xxxx";
char ssid[] = "xxxx";
char pass[] = "xxxx";
long startsecondswd; // weekday start time in seconds
long stopsecondswd; // weekday stop time in seconds
long nowseconds; // time now in seconds
bool isFirstConnect = true;
String displaycurrenttimepluswifi;
int wifisignal;
int manual=0;
int oldstatus;
int zone1 = 4; // digital pin for relay 1
int zone2 = 5; // digital pin for relay 2
int auto1;
int zone1_state;
int zone2_state;
int timerID;
long cycle_soak_int;
void setup()
{
pinMode(TestLED, OUTPUT);
digitalWrite(TestLED, LOW); // set LED OFF
digitalWrite(zone1, LOW);
digitalWrite(zone2,LOW);
pinMode(zone1,OUTPUT);
pinMode(zone2,OUTPUT);
Serial.begin(115200);
Serial.println("\Starting");
Blynk.begin(auth, ssid, pass);
int mytimeout = millis() / 1000;
while (Blynk.connect() == false) { // try to connect to server for 10 seconds
if((millis() / 1000) > mytimeout + 8){ // try local server if not connected within 9 seconds
break;
}
}
rtc.begin();
Blynk.syncVirtual(V2);
Blynk.syncVirtual(V6);
Blynk.syncVirtual(V1);
timer.setInterval(10000L, activetoday); // check every 10 SECONDS if schedule should run today
timer.setInterval(30000L, reconnectBlynk); // check every 30s if still connected to server
timer.setInterval(5000L, clockvalue); // check value for time
timer.setInterval(5000L, sendWifi); // Wi-Fi singal
}
BLYNK_CONNECTED() {
if (isFirstConnect) {
Blynk.syncAll();
Blynk.notify("TIMER STARTING!!!!");
isFirstConnect = false;
}
}
void sendWifi() {
wifisignal = map(WiFi.RSSI(), -105, -40, 0, 100);
}
void clockvalue() // Digital clock display of the time
{
int gmthour = hour();
if (gmthour == 24){
gmthour = 0;
}
String displayhour = String(gmthour, DEC);
int hourdigits = displayhour.length();
if(hourdigits == 1){
displayhour = "0" + displayhour;
}
String displayminute = String(minute(), DEC);
int minutedigits = displayminute.length();
if(minutedigits == 1){
displayminute = "0" + displayminute;
}
displaycurrenttimepluswifi = " Clock: " + displayhour + ":" + displayminute + " Signal: " + wifisignal +" %";
Blynk.setProperty(V3, "label", displaycurrenttimepluswifi);
}
void activetoday(){ // check if schedule should run today
if(year() != 1970){
if (auto1==1) {
Blynk.syncVirtual(V10); // sync timeinput widget
Blynk.syncVirtual(V20);
}
}
}
void checklastbuttonpressed (){
if((auto1==1)){ oldstatus=1;}
}
void restorelastbuttonpressed (){
if(oldstatus==1){auto1=1;}
}
//void resetTerminal()
//{
// timer.setTimeout(50, checklastbuttonpressed);
// terminal.println();
// terminal.println();
// terminal.println("New MODE has been selected");
// terminal.println("Wait for update (Max 10 Seconds)");
// terminal.println();
// terminal.println();
// terminal.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
// terminal.flush();
//}
void resetManual()
{
Blynk.virtualWrite(V1, 0); //Turn OFF Manual Mode Widget
Blynk.virtualWrite(V2, 0); //Turn OFF Button Widget Device
Blynk.virtualWrite(V6, 0); //Turn OFF Button Widget Device
digitalWrite(TestLED, LOW); // set LED OFF
digitalWrite(zone1, LOW);
digitalWrite(zone2, LOW);
}
BLYNK_WRITE(V1) // Manual/auto selection
{
if (param.asInt()==1) {
manual=1;
terminal.println();
terminal.println("Manual MODE is ON");
terminal.println("Press Zone ON/OFF buttons as required");
terminal.println();
terminal.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
terminal.flush();
checklastbuttonpressed ();
auto1=0;
} else {
restorelastbuttonpressed ();
manual=0;
//timer.setTimeout(50, resetTerminal);
timer.setTimeout(50, resetManual);
timer.setTimeout(50, checklastbuttonpressed);
auto1=1;
terminal.println();
terminal.println("Manual MODE is OFF");
terminal.println("Auto MODE restored from last status");
terminal.println("Wait for update (Max 10 Seconds)");
terminal.println();
terminal.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
terminal.flush();
}
}
BLYNK_WRITE(V2) // Zone 1 ON-OFF Manual
{
if (param.asInt()==1) { // boton encendido
terminal.println();
terminal.println("Manual MODE is ON");
terminal.println("Zone 1 is ON");
terminal.println();
terminal.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
terminal.flush();
if (manual==0){ //está en modo auto1mático
checklastbuttonpressed ();
manual=1;
auto1=0;
digitalWrite(TestLED, HIGH); // set LED ON
digitalWrite(zone1, HIGH);
Blynk.virtualWrite(V2, 1); //Turn ON Button Widget
Blynk.virtualWrite(V1, 1); //Turn OFF Auto Mode
} else { //está en modo manual
auto1=0;
Blynk.virtualWrite(V2, 1); //Turn ON Button Widget
Blynk.virtualWrite(V1, 1); //Turn OFF Auto Mode
digitalWrite(TestLED, HIGH); // set LED ON
digitalWrite(zone1, HIGH);
}
}else {
terminal.println();
terminal.println("Manual MODE is ON");
terminal.println("Press ON/OFF button if required");
terminal.println("Zone 1 is OFF");
terminal.println();
terminal.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
terminal.flush();
if (manual==0){ //modo auto1mático
checklastbuttonpressed ();
manual=1;
auto1=0;
Blynk.virtualWrite(V1, 1); //Turn OFF Auto Mode
digitalWrite(TestLED, LOW); // set LED OFF
digitalWrite(zone1, LOW);
Blynk.virtualWrite(V2, 0); //Turn OFF Button Widget
} else {
auto1=0;
Blynk.virtualWrite(V1, 1); //Turn OFF Auto Mode
digitalWrite(TestLED, LOW); // set LED OFF
digitalWrite(zone1, LOW);
Blynk.virtualWrite(V2, 0); //Turn OFF Button Widget
}
}
}
BLYNK_WRITE(V6) // Zone 2 ON-OFF Manual
{
if (param.asInt()==1) { // boton encendido
terminal.println();
terminal.println("Manual MODE is ON");
terminal.println("Zone 2 is ON");
terminal.println();
terminal.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
terminal.flush();
if (manual==0){ //está en modo auto1mático
checklastbuttonpressed ();
manual=1;
auto1=0;
digitalWrite(TestLED, HIGH); // set LED ON
digitalWrite(zone2, HIGH);
Blynk.virtualWrite(V6, 1); //Turn ON Button Widget
Blynk.virtualWrite(V1, 1); //Turn OFF Auto Mode
} else { //está en modo manual
auto1=0;
Blynk.virtualWrite(V6, 1); //Turn ON Button Widget
Blynk.virtualWrite(V1, 1); //Turn OFF Auto Mode
digitalWrite(TestLED, HIGH); // set LED ON
digitalWrite(zone2, HIGH);
}
}else {
terminal.println();
terminal.println("Manual MODE is ON");
terminal.println("Press ON/OFF button if required");
terminal.println("Zone 2 is OFF");
terminal.println();
terminal.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
terminal.flush();
if (manual==0){ //modo auto1mático
checklastbuttonpressed ();
manual=1;
auto1=0;
Blynk.virtualWrite(V1, 1); //Turn OFF Auto Mode
digitalWrite(TestLED, LOW); // set LED OFF
digitalWrite(zone2, LOW);
Blynk.virtualWrite(V6, 0); //Turn OFF Button Widget
} else {
auto1=0;
Blynk.virtualWrite(V1, 1); //Turn OFF Auto Mode
digitalWrite(TestLED, LOW); // set LED OFF
digitalWrite(zone2, LOW);
Blynk.virtualWrite(V6, 0); //Turn OFF Button Widget
}
}
}
BLYNK_WRITE(V10)//Zone 1 time input handling
{
if (auto1==1) {
sprintf(Date, "%02d/%02d/%04d", day(), month(), year());
sprintf(Time, "%02d:%02d:%02d", hour(), minute(), second());
TimeInputParam t(param);
terminal.println("GENERAL:");
terminal.println(String(" Time zone: ") + t.getTZ()); // Timezone is already added to start/stop time
terminal.println(" Ensure at least ONE day is selected for each zone");
terminal.println();
terminal.println("ZONE 1:");
terminal.print(" Schedule checked at: ");
terminal.println(Time);
terminal.flush();
int dayadjustment = -1;
if(weekday() == 1){
dayadjustment = 6; // needed for Sunday, Time library is day 1 and Blynk is day 7
}
if(t.isWeekdaySelected(weekday() + dayadjustment)){ //Time library starts week on Sunday, Blynk on Monday
terminal.println(" Auto ACTIVE today");
terminal.println(" Cycle/Soak Active. 3 equal intervals of watering split up by 2 equal intervals of soak");
terminal.flush();
if (t.hasStartTime()) // Process start time
{
if(t.getStartMinute()<10){
terminal.println(String(" Scheduled Start: ") + t.getStartHour() + ":0" + t.getStartMinute());
}else{
terminal.println(String(" Scheduled Start: ") + t.getStartHour() + ":" + t.getStartMinute());
}
terminal.flush();
}
if (t.hasStopTime()) // Process stop time
{
if(t.getStopMinute()<10){
terminal.println(String(" Scheduled Stop : ") + t.getStopHour() + ":0" + t.getStopMinute());
}else{
terminal.println(String(" Scheduled Stop : ") + t.getStopHour() + ":" + t.getStopMinute());
}
int durationwd = ((t.getStopHour()*3600 + t.getStopMinute()*60 + t.getStopSecond()) - (t.getStartHour()*3600 + t.getStartMinute()*60 + t.getStartSecond()))/60;
cycle_soak_int = (durationwd*60*1000)/5;
terminal.print(" Total Duration (mins):");
terminal.println(durationwd);
terminal.print(" Total Watering Time over 3 intervals (mins):");
terminal.println((cycle_soak_int/1000/60)*3);
terminal.print(" Total Soak Time over 2 intervals (mins):");
terminal.println((cycle_soak_int/1000/60)*2);
terminal.flush();
}
// Display timezone details, for information purposes only
terminal.flush();
// for (int i = 1; i <= 7; i++) { // Process weekdays (1. Mon, 2. Tue, 3. Wed, ...)
// if (t.isWeekdaySelected(i)) {
// terminal.println(String("Zone 1 Days ") + i + " is selected");
// terminal.flush();
// }
// }
nowseconds = ((hour() * 3600) + (minute() * 60) + second());
startsecondswd = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);
//Serial.println(startsecondswd); // used for debugging
if(nowseconds >= startsecondswd){
terminal.print(" Auto STARTED at");
if(t.getStartMinute()<10){
terminal.println(String(" ") + t.getStartHour() + ":0" + t.getStartMinute());
}else{
terminal.println(String(" ") + t.getStartHour() + ":" + t.getStartMinute());
}
terminal.flush();
if(nowseconds <= startsecondswd + 90){ // 90s on 60s timer ensures 1 trigger command is sent
digitalWrite(TestLED, HIGH); // set LED ON
digitalWrite(zone1, HIGH);
Serial.println("Zone 1 active");
timer.deleteTimer(timerID);
timerID = timer.setTimeout(cycle_soak_int, cycle_soak_1);
Serial.print("Cycle for: ");
Serial.print(cycle_soak_int/1000/60);
Serial.println(" minutes");
Blynk.virtualWrite(V2, 1);
// code here to switch the relay ON
}
}
else{
Blynk.virtualWrite(V2,0);
terminal.println();
terminal.println(" Auto NOT STARTED today");
terminal.flush();
}
stopsecondswd = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
//Serial.println(stopsecondswd); // used for debugging
if(nowseconds >= stopsecondswd){
digitalWrite(TestLED, LOW); // set LED OFF
digitalWrite(zone1, LOW);
Blynk.virtualWrite(V2, 0);
terminal.print(" Auto STOPPED at");
if(t.getStopMinute()<10){
terminal.println(String(" ") + t.getStopHour() + ":0" + t.getStopMinute());
}else{
terminal.println(String(" ") + t.getStopHour() + ":" + t.getStopMinute());
}
terminal.flush();
if(nowseconds <= stopsecondswd + 90){ // 90s on 60s timer ensures 1 trigger command is sent
digitalWrite(TestLED, LOW); // set LED OFF
digitalWrite(zone1, LOW);
Blynk.virtualWrite(V2, 0);
// code here to switch the relay OFF
}
}
else{
if(nowseconds >= startsecondswd){
digitalWrite(TestLED, HIGH); // set LED ON
digitalWrite(zone1, HIGH);
Blynk.virtualWrite(V2, 1);
terminal.println(" Auto is ON");
terminal.flush();
}
}
}
else{
terminal.println();
terminal.println(" Auto INACTIVE today");
terminal.flush();
// nothing to do today, check again in 30 SECONDS time
}
terminal.println();
}
}
void cycle_soak_1(){
Serial.print("Soak for : ");
Serial.print(cycle_soak_int/1000/60);
Serial.println(" minutes");
digitalWrite(zone1, LOW);
Blynk.virtualWrite(V2, 0);
timer.deleteTimer(timerID);
timerID = timer.setTimeout(cycle_soak_int, cycle_soak_2);
}
void cycle_soak_2(){
Serial.print("Cycle (2nd) for: ");
Serial.print(cycle_soak_int/1000/60);
Serial.println(" minutes");
digitalWrite(zone1, HIGH);
Blynk.virtualWrite(V2, 1);
timer.deleteTimer(timerID);
timerID = timer.setTimeout(cycle_soak_int, cycle_soak_3);
}
void cycle_soak_3(){
Serial.print("Soak (2nd) for: ");
Serial.print(cycle_soak_int/1000/60);
Serial.println(" minutes");
digitalWrite(zone1, LOW);
Blynk.virtualWrite(V2, 0);
timer.deleteTimer(timerID);
timerID = timer.setTimeout(cycle_soak_int, cycle_soak_4);
}
void cycle_soak_4(){
Serial.print("Cycle (3rd) for: ");
Serial.print(cycle_soak_int/1000/60);
Serial.println(" minutes");
digitalWrite(zone1, HIGH);
Blynk.virtualWrite(V2, 1);
timer.deleteTimer(timerID);
timerID = timer.setTimeout(cycle_soak_int, cycle_soak_5);
}
void cycle_soak_5(){
Serial.print("End of cycle/soak");
digitalWrite(zone1, LOW);
Blynk.virtualWrite(V2, 0);
timer.deleteTimer(timerID);
}
BLYNK_WRITE(V20)//Zone 2 time input handling
{
if (auto1==1) {
sprintf(Date, "%02d/%02d/%04d", day(), month(), year());
sprintf(Time, "%02d:%02d:%02d", hour(), minute(), second());
TimeInputParam t(param);
terminal.println("ZONE 2:");
terminal.print(" Schedule checked at: ");
terminal.println(Time);
terminal.flush();
int dayadjustment = -1;
if(weekday() == 1){
dayadjustment = 6; // needed for Sunday, Time library is day 1 and Blynk is day 7
}
if(t.isWeekdaySelected(weekday() + dayadjustment)){ //Time library starts week on Sunday, Blynk on Monday
terminal.println(" Auto ACTIVE today");
terminal.flush();
if (t.hasStartTime()) // Process start time
{
if(t.getStartMinute()<10){
terminal.println(String(" Scheduled Start: ") + t.getStartHour() + ":0" + t.getStartMinute());
}else{
terminal.println(String(" Scheduled Start: ") + t.getStartHour() + ":" + t.getStartMinute());
}
terminal.flush();
}
if (t.hasStopTime()) // Process stop time
{
if(t.getStopMinute()<10){
terminal.println(String(" Scheduled Stop : ") + t.getStopHour() + ":0" + t.getStopMinute());
}else{
terminal.println(String(" Scheduled Stop : ") + t.getStopHour() + ":" + t.getStopMinute());
}
int durationwd = ((t.getStopHour()*3600 + t.getStopMinute()*60 + t.getStopSecond()) - (t.getStartHour()*3600 + t.getStartMinute()*60 + t.getStartSecond()))/60;
terminal.print(" Duration (mins):");
terminal.println(durationwd);
terminal.flush();
}
// Display timezone details, for information purposes only
// terminal.println(String("Time zone offset: ") + t.getTZ_Offset()); // Get timezone offset (in seconds)
terminal.flush();
// for (int i = 1; i <= 7; i++) { // Process weekdays (1. Mon, 2. Tue, 3. Wed, ...)
// if (t.isWeekdaySelected(i)) {
// terminal.println(String("Zone 2 Days ") + i + " is selected");
// terminal.flush();
// }
// }
nowseconds = ((hour() * 3600) + (minute() * 60) + second());
startsecondswd = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);
//Serial.println(startsecondswd); // used for debugging
if(nowseconds >= startsecondswd){
terminal.print(" Auto STARTED at");
if(t.getStartMinute()<10){
terminal.println(String(" ") + t.getStartHour() + ":0" + t.getStartMinute());
}else{
terminal.println(String(" ") + t.getStartHour() + ":" + t.getStartMinute());
}
terminal.flush();
if(nowseconds <= startsecondswd + 90){ // 90s on 60s timer ensures 1 trigger command is sent
digitalWrite(TestLED, HIGH); // set LED ON
digitalWrite(zone2, HIGH);
Blynk.virtualWrite(V6, 1);
// code here to switch the relay ON
}
}
else{
Blynk.virtualWrite(V6,0);
terminal.println();
terminal.println(" Auto NOT STARTED today");
terminal.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
terminal.flush();
}
stopsecondswd = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
//Serial.println(stopsecondswd); // used for debugging
if(nowseconds >= stopsecondswd){
digitalWrite(TestLED, LOW); // set LED OFF
digitalWrite(zone2, LOW);
Blynk.virtualWrite(V6, 0);
terminal.print(" Auto STOPPED at");
if(t.getStopMinute()<10){
terminal.println(String(" ") + t.getStopHour() + ":0" + t.getStopMinute());
}else{
terminal.println(String(" ") + t.getStopHour() + ":" + t.getStopMinute());
}
terminal.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
terminal.flush();
if(nowseconds <= stopsecondswd + 90){ // 90s on 60s timer ensures 1 trigger command is sent
digitalWrite(TestLED, LOW); // set LED OFF
digitalWrite(zone2, LOW);
Blynk.virtualWrite(V6, 0);
// code here to switch the relay OFF
}
}
else{
if(nowseconds >= startsecondswd){
digitalWrite(TestLED, HIGH); // set LED ON
digitalWrite(zone2, HIGH);
Blynk.virtualWrite(V6, 1);
terminal.println(" Auto is ON");
terminal.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
terminal.flush();
}
}
}
else{
terminal.println();
terminal.println(" Auto INACTIVE today");
terminal.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
terminal.flush();
// nothing to do today, check again in 30 SECONDS time
}
terminal.println();
}
}
void reconnectBlynk() {
if (!Blynk.connected()) {
if(Blynk.connect()) {
BLYNK_LOG("Reconnected");
} else {
BLYNK_LOG("Not reconnected");
}
}
}
void loop()
{
if (Blynk.connected()) {
Blynk.run();
}
timer.run();
}
Just water 1 minute exactly every other day …