Hi guys,
I’m trying to use the same example to count the time that passes from turning a relay on.
The RTC is working but I don’t understand how to connect it to the “on” and “off”.
I want it to start from 0 when turning on the relay and stop when turning the relay off.
Can you please assist?
#include <BlynkSimpleEsp8266.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "Token";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "ssid";
char pass[] = "pass";
BlynkTimer timer;
WidgetRTC rtc;
// Digital clock display of the time
void clockDisplay()
{
// You can call hour(), minute(), ... at any time
// Please see Time library examples for details
String currentTime = String(hour()) + ":" + minute() + ":" + second();
Serial.print("Current time: ");
Serial.print(currentTime);
Serial.print(" ");
// Send time to the App
Blynk.virtualWrite(V1, currentTime);
}
void setup()
{
Serial.begin(115200);
pinMode(0, OUTPUT);
pinMode(2, OUTPUT);
Blynk.begin(auth, ssid, pass);
rtc.begin();
// Display digital clock every 1 seconds
timer.setInterval(1000L, clockDisplay);
}
BLYNK_WRITE(V1)
{
int i=param.asInt();
if (i==1)
{
delay(300);
digitalWrite(0, HIGH);
digitalWrite(2, HIGH);
delay(1750); // delay 1000 = 1 sec
digitalWrite(0, LOW);
digitalWrite(2, LOW);
}
else
{
digitalWrite(0, LOW);
digitalWrite(2, LOW);
}
}
void loop()
{
Blynk.run();
timer.run();
}```
Thanks a lot for the prompt and detailed answers.
I’m using ESP8266 - 01 that I’m connecting directly to the relay.
I have combined the RTC sample with the one I have but don’t know how to make the condition and the time reset (I have a very poor coding skills)
Hi, OK! @Gunner - I used the first code you added and it works!
The stopwatch start, stop and reset as I wanted.The only problem is that I want to see the time in live and not after I’m stopping it. I tried few things that I saw in the forums but I couldn’t find a way to do it.
I tried to use this:
Blynk.virtualWrite(V2, buf, 1000);
but it basically do nothing
This is the new code:
Can you please help me figure it out?
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "token";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "ssid";
char pass[] = "pass";
int latchButton;
int latchFlag;
int runDays;
int runHours;
int secsRemaining;
int runMinutes;
int runSeconds;
char buf[21];
unsigned long startMillis;
unsigned long endMillis;
unsigned long allSeconds;
//===== Timeed latching button =====
BLYNK_WRITE(V1) { // Button Widget set as switch
latchButton = param.asInt();
if (latchButton == 1 && latchFlag == 0) {
latchFlag = 1; // Keeps from allowing button press more then once while relay activated
startMillis = millis(); // The key command for starting the count
Blynk.virtualWrite(V2, buf, 1000); // Display Widget
digitalWrite(0, HIGH); // Activate digital pin
Serial.println(latchButton);
}
else{
digitalWrite(0, LOW); // Deactivate digital pin
Serial.println("off");
Blynk.virtualWrite(V1, 0); // Reset Latching Button to OFF
latchFlag = 0; // resets to allow next interaction
endMillis = millis(); // The key command for ending the count
// The key process for displaying the converted duration
allSeconds = (endMillis - startMillis) / 1000;
runDays = allSeconds / 86400;
secsRemaining = allSeconds % 86400;
runHours = secsRemaining / 3600;
secsRemaining = allSeconds % 3600;
runMinutes = secsRemaining / 60;
runSeconds = secsRemaining % 60;
sprintf(buf, "Duration: %02d H : %02d M : %02d S", runHours, runMinutes, runSeconds);
Blynk.virtualWrite(V2, buf); // Display Widget showing duration the Switch was
Serial.println(buf);
} // END Timer Function
}
void setup()
{
Serial.begin(115200);
pinMode(0, OUTPUT);
pinMode(2, OUTPUT);
Blynk.begin(auth, ssid, pass);
}
void loop()
{
Blynk.run();
}
You need to put the code that calculates the duration into a separate function, then set-up a timer to call that function - lets say once every second.
You wont get a perfect result, because there is lag in the process of sending the data to the server then to the app, so the seconds may jump forward several seconds at a time, but you should get a reasonable indication of how long the relay has been activated for.
Yes, but you’ve left-out the code that prints the elapsed time to the V2.
I’d put that at the end of your TimeCalculator() function.
You then need a timer to call this once every second.
You’ll need to define the timer, initialise it in your void setup, then include timer.run in your void loop.
Once you have that running then you should refine it a little.
You only want the elapsed time to be calculated and outputted to V2 if the timer is running, so your TimeCalculator() should have an ‘if’ statement which checks if the relay is actuated before doing the calculation of elapsed time and outputting the result.
Thanks a lot Pete. I really appreciate your help
I removed the prints from there and put it in the TimeCalculater(). I added
timer.setInterval(1000L, buf);
In the setup… I hope I did it right…?
I also added the timer.run() in the loop. I still don’t understand something. In the Blynk_Write function I added if and else with startMillis = millis(); and endMillis = millis(); to start the timer and stop it, I should create something similar in the TimeCalculater() as well?
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "token";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "ssid";
char pass[] = "pass";
BlynkTimer timer;
int latchButton;
int latchFlag;
int runDays;
int runHours;
int secsRemaining;
int runMinutes;
int runSeconds;
char buf[21];
unsigned long startMillis;
unsigned long endMillis;
unsigned long allSeconds;
void TimeCalculator()
{
// The key process for displaying the converted duration
allSeconds = (endMillis - startMillis) / 1000;
runDays = allSeconds / 86400;
secsRemaining = allSeconds % 86400;
runHours = secsRemaining / 3600;
secsRemaining = allSeconds % 3600;
runMinutes = secsRemaining / 60;
runSeconds = secsRemaining % 60;
sprintf(buf, "Duration: %02d H : %02d M : %02d S", runHours, runMinutes, runSeconds);
Blynk.virtualWrite(V2, buf); // Display Widget showing duration the Switch was
}
//===== Timeed latching button =====
BLYNK_WRITE(V1) { // Button Widget set as switch
latchButton = param.asInt();
if (latchButton == 1 && latchFlag == 0) {
latchFlag = 1; // Keeps from allowing button press more then once while relay activated
startMillis = millis(); // The key command for starting the count
TimeCalculator();
digitalWrite(0, HIGH); // Activate digital pin
Serial.println(latchButton);
}
else{
digitalWrite(0, LOW); // Deactivate digital pin
Serial.println("off");
Blynk.virtualWrite(V1, 0); // Reset Latching Button to OFF
latchFlag = 0; // resets to allow next interaction
endMillis = millis(); // The key command for ending the count
TimeCalculator();
}
}
void setup()
{
Serial.begin(115200);
pinMode(0, OUTPUT);
pinMode(2, OUTPUT);
Blynk.begin(auth, ssid, pass);
// Display digital clock every 1 seconds
timer.setInterval(1000L, buf);
}
void loop()
{
Blynk.run();
timer.run();
}```
That makes no sense. The timer.setinterval command needs the frequency that a function is going to be called (1000ms in this case) and the name of the function that will be called.
Your function is TimeCalculator not buf
I’m slightly unsure about what TimeCalculator is supposed to be calculating. Without picking through the code in detail, it seems that you’re showing remaining time, not elapsed time. Is that correct?
No, I want to present the elapsed time and it worked well but I wanted to see the elapsed time live and not only the calculation after I’m switching the button to off.
In that case, you need a function that will calculate the elapsed time and write it out to V2, and that function need to run every second.
The function will take the current millis and compare it to when the relay was activated (startMillis)
This will really make your current TimeCalculator function redundant, as when the relay is deactivated, the function will stop updating V2 (provided you used an ‘if’ statement as I suggested earlier).
My concern with your current code is that you’re using variable names like secsRemaining when in actual fact you aren’t using the code to calculate remaining time, just elapsed time.
You’d find it easier to follow when you re-write your code if you use meaningful variable names, and when you declare them add a comment like this:
int runDays; // will hold the calculated number of elapsed whole days (the DD element of DD/HH/MM/SS display of time) since the relay was activated
int runHours; // will hold the calculated number of elapsed whole hours (the HH element of DD/HH/MM/SS display of time) since the relay was activated
int runMinutes; // will hold the calculated number of elapsed whole minutes (the MM element of DD/HH/MM/SS display of time) since the relay was activated
int runSeconds; // will hold the calculated number of elapsed seconds (the SS element of DD/HH/MM/SS display of time) since the relay was activated
Solved! @PeteKnight I created the Time Calculator function like you suggested, changed few things and it worked! Thanks a lot for your help Pete!
Here is the code, in case someone is looking for something similar:
BlynkTimer timer;
int latchButton;
int latchFlag;
int runHours;
int runMinutes;
int runSeconds;
int secsRemaining;
char buf[21];
unsigned long startMillis;
unsigned long endMillis;
unsigned long allSeconds;
//===== Timeed latching button =====
BLYNK_WRITE(V1) { // Button Widget set as switch
latchButton = param.asInt();
if (latchButton == 1 && latchFlag == 0) {
latchFlag = 1; // Keeps from allowing button press more then once while relay activated
digitalWrite(0, HIGH); // Activate digital pin
Serial.println(latchButton); //Debug
}
else{
digitalWrite(0, LOW); // Deactivate digital pin
Serial.println("off"); //Debug
Blynk.virtualWrite(V1, 0); // Reset Latching Button to OFF
latchFlag = 0; // resets to allow next interaction
}
}
void ElapsedTime(){
if (latchFlag == 1){ //When the button is active
endMillis = millis(); //Start the counting from 0
//The key process for displaying the converted duration
allSeconds = (endMillis - startMillis) / 1000;
secsRemaining = allSeconds % 86400;
runHours = secsRemaining / 3600;
secsRemaining = allSeconds % 3600;
runMinutes = secsRemaining / 60;
runSeconds = secsRemaining % 60;
sprintf(buf, "Duration: %02d:%02d:%02d", runHours, runMinutes, runSeconds);
Blynk.virtualWrite(V2, buf); // Display Widget
}
else{
startMillis = millis(); // Stop the counting
}
}
void setup()
{
Serial.begin(115200);
pinMode(0, OUTPUT);
pinMode(2, OUTPUT);
Blynk.begin(auth, ssid, pass);
// Display digital clock every 1 seconds
timer.setInterval(1000L, ElapsedTime);
}
void loop()
{
Blynk.run();
timer.run();
}
Exactly was I was looking for @Natial and @PeteKnight .
Need a slight alteration.
I want the time to be cumulative. Count time while relay is HIGH, pause when relay is LOW, then start count again from paused time after relay is High and so forth.
What happens in the case of a disconnection from cloud?
The relay will stay in its current state and the counter will continue to run if the button widget was set to On at the point when the disconnection occurred.
I’m guessing from your comments/questions that you haven’t actually tried this code for yourself yet? The easiest way to learn is to experiment.
Thank you @PeteKnight for the quick response.
I have tried the code on a Particle Photon and displaying the time the button is pressed in Blynk.
When button is pressed, time is displayed and counting.
After button is pressed again, time stops counting.
When pressing again, it goes back to zero and starts counting. Its not cumulative.
Hi PeteKnight Sir,
I am a beginner and want to make home automation with four relays.
The above code works well for one-Relay count time. But I want to know how to write code for three-Relay. I try but fail to write code for more than one relay.