Making timer with RTC clock

Hello

I am trying to make a scheduler with an esp8266 using RTC time and the TimeLib.h library

I chose for the tests to run on a cycle where 1 hour = 1 second

I can't catch the seconds. Could someone explain to me how to do it?
And possibly tell me if my method is good and if not how to improve my code.

Thanks

#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <TimeLib.h>
#include <WidgetRTC.h>

char auth[] = "31k3lWUXbqt4bbcn4bROU1vI6d42x1C2";
char ssid[] = "xx";
char pass[] = "xx";

BlynkTimer timer;

WidgetRTC rtc;

int temps = second();


BLYNK_CONNECTED() {
  // Synchronize time on connection
  rtc.begin();
}

void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass, IPAddress(10, 3, 141, 1), 8080);

  setSyncInterval(800);
  

  timer.setInterval(1000L, clockDisplay);
  timer.setInterval(1000L, cycle1);
}

void loop()
{
  Blynk.run();
  timer.run();
}

void clockDisplay()
{

  String currentTime = String(hour()) + ":" + minute() + ":" + second();
  String currentDate = String(day()) + " / " + month() + " / " + year();
  Serial.print("Current time: ");
  Serial.print(currentTime);
  Serial.print(" ");
  Serial.print(currentDate);
  Serial.println();

  // Send time to the App
  Blynk.virtualWrite(V1, currentTime);
  // Send date to the App
  Blynk.virtualWrite(V2, currentDate);
}

void cycle1()
{
  if (temps == 7)
  {
    Serial.println("debut de cylcle");
    digitalWrite (15, LOW);
    Serial.println ("lampe on");
    delay(18000);
    Serial.println ("fin de cycle");
    digitalWrite(15, HIGH);
    Serial.print ("lampe off");
  }
  else{
}
}

Do you mean that

  if (temps == 7)

never returns true ?

If so, where in the code is the value of temps ever changed ? Have you tried printing the value of temps before testing it ?

If that is not the problem, then please describe the problem in more detail

You are not only making a timer. You are using Blynk.
If I remember right blynk doesn't like traffic at short intervalls.
updating via blinkserver once per second is a to high frequency.
imagine each and every of the hundred-thousands of Blynk-users are doing this. That would be almost a DdoS-attack.

That's the reason why Blynk is limiting this

Is blynk a substantial requirement of your project or can you throw it out?

best regards Stefan

This will block the code, and the clock update, for 18 seconds: delay(18000) = Ooops..

EDIT: And this int temps = second() is run before the clock has been initialized, you should check what value you get there - if it is 7, the code will block for 18 seconds in each iteration of loop()...

I actually don't have a value, so I placed my function int time = seconds(); after the rtc.begin(); but I still have no value. Maybe my timing is wrong.

But the only other solution I see is to call a cycle end time (in this case when second equals 25) I will work with hour but seconds is better for testing

The problem is not there, I have a dozen sensors that send data every 0.5 seconds and everything works
I also specify that I am on a local server

That's i mean

You need to update the value of temps frequently, each time through loop() would be good, not use blocking code anywhere in the sketch, and test its value as frequently as you update its value

I don't know how i can do it...

Except

void cycle1()
{
  if (temps == 7)
  {
    Serial.println("debut de cylcle");
    digitalWrite (15, LOW);
    Serial.println ("lampe on");
if else (temps == 18)
{
    Serial.println ("fin de cycle");
    digitalWrite(15, HIGH);
    Serial.print ("lampe off");
  }
  else{
}
}

You think it good like that ?

what does

mean?
temps like time?
and if it is time what kind of time?
seconds?, minutes?, hours?, daily hour?

I did not expect that you use things like delay(18000) in your code if you want to have an RTC-clock.

There is a very different approach for timing. Non-blocking timing
It is so completely different that you have to think really new.

As long as you try to think of this non-blocking timing it is a delay-similar thing
you will block yourself and it is just confusing. Because it is really different.

Here is a tutorial that explains the basic principle:

best regards Stefan

No. As @StefanL38 has pointed out you have got the syntax if if/else if wrong.

I have asked before and got no answer. Where is the value of temps being updated in the sketch ?

You initialise it

int temps = second();

but after that what changes it ?

Sorry it's my bad, i'm tired !

If is looking if temps == 7 no ?

What is the best approach in your opinion ?

RTC based or millis ?

It can look to see whether temps equals 7 as long as you want but if you don't update the value of temps then how will it ever equal 7 ?

Suppose that you had an old fashioned wind up clock that was not running and you set it to a time of 1 o'clock. How long do you think it would be until the clock showed 7 o'clock ?

You are using an ESP8266. If this ESP8266 is connected to WiFi the onboard RTC will be updated by the WiFi-connection in the backround.
RTC is more precise than function millis().

But your problem is at an

other place

your basic code is

unable to work for timing!

there is only

one place

where you assign a value to variable "temps"
it is this line

int temps = second();

in all the rest of the code your variables "temps" gets

never updated / never changed

how should this variable ever become

  if (temps == 7)

????????????????????????????

best regards Stefan

I try to understand but I have learning disabilities, it's not easy for me.

Can you give me an example?

example of what?

It might be that you have difficulties to learn. But there is no way around precise information.

best regards Stefan

My question about the non working clock was an example of the problem with your code

In your sketch where does the time, particularly the seconds value, come from ?

Ok now my programmer works, but I lost the RTC display. At launch all my displays are at zero and count the time from the ignition of the ESP

Sketch :

#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <TimeLib.h>
#include <WidgetRTC.h>

char auth[] = "xxx";
char ssid[] = "xxxx";
char pass[] = "xxx";

BlynkTimer timer;

WidgetRTC rtc;


BLYNK_CONNECTED() {
  // Synchronize time on connection
  
}

int OnHours = 7;
int OffHours = 25;


void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass, IPAddress(10, 3, 141, 1), 8080);
  rtc.begin();

  setSyncInterval(800);

  timer.setInterval(1000L, clockDisplay);
  timer.setInterval(1000L, cycle1);
}

void loop()
{
  Blynk.run();
  timer.run();
}

void clockDisplay()
{

  String currentTime = String(hour()) + ":" + minute() + ":" + second();
  String currentDate = String(day()) + " / " + month() + " / " + year();
  Serial.print("Current time: ");
  Serial.print(currentTime);
  Serial.print(" ");
  Serial.print(currentDate);
  Serial.println();

  // Send time to the App
  Blynk.virtualWrite(V1, currentTime);
  // Send date to the App
  Blynk.virtualWrite(V2, currentDate);
}

void cycle1()
{

  int Hours = second();
  if (Hours == OnHours)
  {
    Serial.print("debut de cylcle ");
    digitalWrite (15, HIGH);
    Serial.println ("lampe on");
  }

  if (Hours == OffHours)
  {
    Serial.print("fin de cylcle ");
    digitalWrite (15, LOW);
    Serial.println ("lampe off");
  }


}

EDIT : my bad i forgot RTC widget on Blynk

If the intent is to have the pin HIGH for 7 seconds/hours and LOW for 25, that is not what the code does. It will become HIGH whenever the second/hour is 7 and LOW again when it becomes 25 (hour will never become 25). If the goal is to have the pin HIGH for 18 seconds/hours and LOW for 25, you could use a one-shot timer to turn it LOW.

#define PIN_NUM 15
#define TIME_HIGH_MS 18000UL

void cycle1()
{
  if ((second() == 7) && (digitalRead(PIN_NUM) == LOW))
  {
    digitalWrite(PIN_NUM, HIGH);
    timer.setTimeout(TIME_HIGH_MS, cycle2);
  }
}

void cycle2()
{
  digitalWrite(PIN_NUM, LOW);
}

Even though I am not familiar with the timer library, the example should do the job without blocking.

  timer.setInterval(1000L, clockDisplay);
  timer.setInterval(1000L, cycle1);

I know very little about Blynk but shouldn't you have 2 timer objects if you want to call 2 separate functions at the end of the period ?

To me, those 2 lines of code say "run the clockDisplay function every second. No, sorry, I have changed my mind. Run the cycle1 function every second" In other words, never call the clockDisplay function

BlynkTimer is a subclass to SimpleTimer which allows multiple timer slots. So no, you do not need multiple instances. :grinning:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.