Time counter with TimeSpan

Hi there ! I'm trying to make a time counter with TimeSpan and RTClib

I can't use TimeSpan... Can someone help me?

Thanks

TimeOn is variable attached to a slider on Blynk ( between 00 and 23 )

void setupCycle() {


  if (cycle == HIGH) {
    timeOff = timeOn + TimeSpan(0, 12, 0, 0);
    Blynk.virtualWrite(V20, 255);
    Blynk.virtualWrite(V21, 0);

  }
  if (cycle == LOW) {
    timeOff = timeOn + TimeSpan(0, 18, 0, 0); 
    Blynk.virtualWrite(V20, 0);
    Blynk.virtualWrite(V21, 255);
  }
}

error :

C:\Users\Charles\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/WString.h:380:67: note: no known conversion for argument 2 from 'TimeSpan' to 'String&&'
380 | inline String operator +(const __FlashStringHelper *lhs, String &&rhs) {
| ~~~~~~~^
exit status 1
no match for 'operator+' (operand types are 'int' and 'TimeSpan')

Post your full code. Always.


#define BLYNK_PRINT Serial

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

#include <RTClib.h>
#include <WidgetRTC.h>

BlynkTimer timer;

///////////////////////////////////////////VPIN RECEVEUR///////////////////////////////////////////////

WidgetBridge bridge1(V10); //Temp Som

////////////////////////////////////////////////////////WIDGET///////////////////////////////////////////////////////////////////////////////////

WidgetTerminal terminal(V100);
WidgetLED ledGrow(V20);
WidgetLED ledFlow(V21);
WidgetLED etatCyle(V22);

WidgetRTC rtc;

////////////////////////////////////////////////////////CONSTANTE///////////////////////////////////////////////////////////////////////////////////

int timeOn;
int timeOff;

int Hour = hour();

int cycle;
int cycleOn;
int cycleOff;



////////////////////////////////////////////////////////BLYNK///////////////////////////////////////////////////////////////////////////////////

BLYNK_CONNECTED() {
  Blynk.syncAll();
}
BLYNK_WRITE(V1) {
  timeOn = param.asInt();
}
BLYNK_WRITE(V2) {
  cycle = param.asInt();
}
char auth[] = "xx";
char ssid[] = "xx";
char pass[] = "xx";


////////////////////////////////////////////////////////SETUP///////////////////////////////////////////////////////////////////////////////////

void setup()
{
  // Debug console
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass, IPAddress(10, 3, 141, 1), 8080);

  rtc.begin();
  setSyncInterval(500);


  timer.setInterval(1000L, setupCycle);

}

void loop() {

  Blynk.run();
  timer.run();
}

void setupCycle() {


  if (cycle == HIGH) {
    timeOff = timeOn + TimeSpan(0, 12, 0, 0);
    Blynk.virtualWrite(V20, 255);
    Blynk.virtualWrite(V21, 0);

  }
  if (cycle == LOW) {
    timeOff = timeOn + TimeSpan(0, 18, 0, 0); 
    Blynk.virtualWrite(V20, 0);
    Blynk.virtualWrite(V21, 255);
  }
}


The TimeSpan() function returns a TimeSpan object. An object can't be added to an integer.

What is the code supposed to do?

What units of time are timeOn and timeOff? In other words, if timeOn is 1, what does that mean?

TimeOn and TimeOff are variables between 00 and 23 ( hour )
TimeOn and TimeOff define a cycle (which lasts 12 hours or 18 hours)

I need to start from timeOn to count 12 hours or 18 hours and to arrive at timeOff. Between timeOn and timeOff I am in cycleOn else i'm in cycleOff.
During this cylcleOn I perform actions.

Here is a copy of the code with my old modulo system. ( see void etatCycle and void setupCycle ) But it doesn't work properly, that's why I wanted to use TimeSpan.

#define BLYNK_PRINT Serial

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

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

BlynkTimer timer;

///////////////////////////////////////////VPIN RECEVEUR///////////////////////////////////////////////

WidgetBridge bridge1(V10); //Temp Som

////////////////////////////////////////////////////////WIDGET///////////////////////////////////////////////////////////////////////////////////

WidgetTerminal terminal(V100);
WidgetLED ledGrow(V20);
WidgetLED ledFlow(V21);
WidgetLED etatCyle(V22);
WidgetLED ledRV1(V23);
WidgetLED ledRV2(V24);
WidgetLED ledLampe(V25);

WidgetRTC rtc;

////////////////////////////////////////////////////////CONSTANTE///////////////////////////////////////////////////////////////////////////////////

int timeOn;
int timeOff;
int cycle;
int Hour = hour();

int cycleOn;
int cycleOff;

int tempSom;
int thermoCycleOn;
int thermoCycleOff;
int relaisV1 = 16; //relaisD0
int relaisV2 = 5;  //relaisD1
int relaisLamp = 4; //relaisD2
int hysteresisV2 = 2;
int hysteresisV1 = 1;

////////////////////////////////////////////////////////BLYNK///////////////////////////////////////////////////////////////////////////////////

BLYNK_CONNECTED() {
  Blynk.syncAll();
}
BLYNK_WRITE(V1) {
  timeOn = param.asInt();
}
BLYNK_WRITE(V2) {
  cycle = param.asInt();
}
BLYNK_WRITE(V6) {
  thermoCycleOn = param.asFloat();
}
BLYNK_WRITE(V7) {
  thermoCycleOff = param.asFloat();
}
BLYNK_WRITE(V10) {
  tempSom = param.asInt();
}
char auth[] = "qDBecyJbbi_zoSijVAHK7gy0FX4AH_Bo";
char ssid[] = "BlynkServeur";
char pass[] = "azeqsd123";


////////////////////////////////////////////////////////SETUP///////////////////////////////////////////////////////////////////////////////////

void setup()
{
  // Debug console
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass, IPAddress(10, 3, 141, 1), 8080);

  rtc.begin();
  setSyncInterval(500);

  pinMode(16, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(16, HIGH);
  pinMode(5, HIGH);
  pinMode(4, HIGH);


  timer.setInterval(1000L, setupCycle);
  timer.setInterval(1000L, printTerminal);
  timer.setInterval(1000L, etatCycle);
  timer.setInterval(1000L, temperatureCycleOn);
  timer.setInterval(1000L, temperatureCycleOff);
  timer.setInterval(1000L, lampe);

  terminal.clear();
  terminal.println("Controleur Indoor V1.2");
  terminal.println("");
  terminal.println("---------------------------");
  terminal.flush();
}

void loop() {

  Blynk.run();
  timer.run();
}

////////////////////////////////////////////////////////DEBUG///////////////////////////////////////////////////////////////////////////////////


void printTerminal() {

  int Hour = hour();
  Serial.println("---------------------------");
  Serial.println("");
  Serial.print("Time On :  ");
  Serial.println(timeOn);
  Serial.print("Time Off:  ");
  Serial.println(timeOff);
  Serial.print("Heure actuelle : ");
  Serial.println(Hour);
  Serial.print("Temperature Sommité : ");
  Serial.println(tempSom);
  Serial.print("THermostat cycleOff : ");
  Serial.println(thermoCycleOff);
  Serial.print("THermostat cycleOn : ");
  Serial.println(thermoCycleOn);

  Serial.println("");
  Serial.println("---------------------------");

  terminal.print("Time On :  ");
  terminal.println(timeOn);
  terminal.print("Time Off:  ");
  terminal.println(timeOff);
  //terminal.print("Heure actuelle : ");
  //terminal.println(Hour);
  terminal.println("");
  terminal.println("---------------------------");
  terminal.println("");



  terminal.flush();
}

////////////////////////////////////////////////////////SELECTION CYCLE///////////////////////////////////////////////////////////////////////////////////

void setupCycle() {

  int Hour = hour();

  if (cycle == HIGH) {
    timeOff = (timeOn + 18) % 24;
    Blynk.virtualWrite(V20, 255);
    Blynk.virtualWrite(V21, 0);

  }
  if (cycle == LOW) {
    timeOff = (timeOn + 12) % 24;
    Blynk.virtualWrite(V20, 0);
    Blynk.virtualWrite(V21, 255);
  }
}



////////////////////////////////////////////////////////ETAT CYCLE///////////////////////////////////////////////////////////////////////////////////

void etatCycle() {
  int Hour = hour();
  if (Hour >= timeOn && Hour <= timeOff) // pour tester si cycleOn doit passer à 1
  {
    cycleOn = 1;
    cycleOff = 0;
    Serial.println("Cycle On");
    terminal.println("Cycle On");
    Blynk.virtualWrite(V22, 255);
    
  }
  if (Hour >= timeOff && Hour <= timeOn) // pour tester si cycleOn doit passer à 0
    // necessaire pour arrêter quand Hour = timeOff
    // sinon le cycle ne sera pas respecté, un else ne convient pas
  {
    cycleOff = 1;
    cycleOn = 0;
    Serial.println("Cycle Off");
    terminal.println("Cycle Off");
    Blynk.virtualWrite(V22, 0);
  }
}

void temperatureCycleOn()
{
  if (tempSom >= (thermoCycleOn + hysteresisV1) && cycleOn == 1)
  {

    digitalWrite(relaisV1, LOW); ///// HIGH = 0
    Blynk.virtualWrite(V23, 255);
    Serial.println("relais V1 On / Cycle On ");
  }

  if (tempSom <= (thermoCycleOn - hysteresisV1) && cycleOn == 1)
  {

    digitalWrite(relaisV1, HIGH);  ///// HIGH = 0
    Blynk.virtualWrite(V23, 0);
    Serial.println("relais V1 Off / Cycle On ");

  }

  if (tempSom >= (thermoCycleOn + hysteresisV2) && cycleOn == 1)
  {

    digitalWrite(relaisV2, LOW); ///// HIGH = 0
    Blynk.virtualWrite(V24, 255);
    Serial.println("relais V2 On / Cycle On ");
  }

  if (tempSom <= (thermoCycleOn - hysteresisV2) && cycleOn == 1)
  {

    digitalWrite(relaisV2, HIGH);  ///// HIGH = 0
    Blynk.virtualWrite(V24, 0);
    Serial.println("relais V2 Off / Cycle On ");

  }
}

void temperatureCycleOff()
{
  if (tempSom >= (thermoCycleOff + hysteresisV1) && cycleOff == 1)
  {

    digitalWrite(relaisV1, LOW); ///// HIGH = 0
    Blynk.virtualWrite(V23, 255);
    Serial.println("relais V1 On / Cycle Off ");
  }

  if (tempSom <= (thermoCycleOff - hysteresisV1) && cycleOff == 1)
  {

    digitalWrite(relaisV1, HIGH);  ///// HIGH = 0
    Blynk.virtualWrite(V23, 0);
    Serial.println("relais V1 Off / Cycle Off ");

  }

  if (tempSom >= (thermoCycleOff + hysteresisV2) && cycleOff == 1)
  {

    digitalWrite(relaisV2, LOW); ///// HIGH = 0
    Blynk.virtualWrite(V24, 255);
    Serial.println("relais V2 On / Cycle Off ");
  }

  if (tempSom <= (thermoCycleOff - hysteresisV2) && cycleOff == 1)
  {

    digitalWrite(relaisV2, HIGH);  ///// HIGH = 0
    Blynk.virtualWrite(V24, 0);
    Serial.println("relais V2 Off / Cycle Off ");

  }
}

void lampe()
{
  if ( cycleOn == 1 )
  {
    digitalWrite(relaisLamp, LOW);
    Blynk.virtualWrite(V25, 255);

  }
  else
  {
    digitalWrite(relaisLamp, HIGH);
    Blynk.virtualWrite(V25, 0);
  }
}

Never say that without explaining what you mean.

How will using TimeSpan() help?

In my current code (the last one posted) I check if the current hour "hour" is between timeOn and timeOff. The problem is when timeOff exceeds 00 ( midnight ) the function no longer checks.

TimeSpan from what I understand counts the hours. Which is perfect for my use to find timeOff and therefore cycleOff

Your problem that your timeOn and timeOff are "one-day variables", so it depended from the date and it will be difficult to use it through midnight. To solve this problem, you could add days of the week or month to the times.
Another option is using the absolute time representation - seconds since 1st jan 1970) for your timeOn and timeOff. Measuring time such mode will be independent from midnight change

And as far as I can see the TimeSpan is not suitable for this task at all

I agree. I do not think using TimeSpan() will help at all with this problem.

Needs to be something like

  if (timeOn < timeOff && Hour >= timeOn && Hour <= timeOff || timeOn >= timeOff && (Hour >= timeOff || Hour <= timeOn))

I could also use millis, but in case of disconnection, or cut I lose time.

I'll test it, I'll let you know

Thanks

It is very convenient to use "minutes past midnight" (or seconds) for timer interval functions.

This demonstration code works for any interval, including intervals that span midnight.

The function within_interval() checks whether a given time of day is within the start and stop times.

void setup() {
  Serial.begin(9600);

  //start and stop times, in minutes past midnight
  
  int start_minutes = 23 * 60 + 58;  //start at 23:58
  int end_minutes = 2; //00:02
  
  Serial.print("start time in minutes past midnight ");
  Serial.print(start_minutes);
  Serial.print(", stop time ");
  Serial.println(end_minutes);
  Serial.println();
  Serial.println("Time in minutes past midnight");

  // test the within_interval function
  // loop index i simulates RTC time input
  
  for (int i = 0; i < 10; i++) { //count some minutes, beginning at 23:56, modulo 1440
    int now_minutes = (23 * 60 + 56 + i) % 1440;  //time, minutes past midnight
    Serial.print(now_minutes);
    Serial.print("\t"); //tab
    // print interval check function state
    Serial.print (" interval check function returns ");
    Serial.println(within_interval(start_minutes, end_minutes, now_minutes));
  }
}

// within_interval function determines whether the current time in minutes past midnight
// is within the timed interval start and end, also in minutes past midnight
// ***range may span midnight***

#define MIN_PER_DAY 1440
byte within_interval(int start, int end, int now) {
  int duration = (end - start + MIN_PER_DAY) % MIN_PER_DAY;
  int time_on = (now - start + MIN_PER_DAY) % MIN_PER_DAY;
  if (time_on < duration) return 1;  //within interval
  return 0;  //not within interval
}

void loop() {}

it does not solve the problem of TO - it not works if start time and end time are in the different days

It solves the stated problem.

"Different days" is an entirely separate issue.

I think you want:
timeOff = timeOn + TimeSpan(0, 12, 0, 0).totalSeconds();

See: RTClib: TimeSpan Class Reference

I may have got it wrong earlier...

if (timeOn < timeOff && Hour >= timeOn && Hour <= timeOff || timeOn >= timeOff && (Hour >= timeOn || Hour <= timeOff))

Maybe the first "IF" you gave me only works for the LOW cycle ( timeOn + 12 ) not for the HIGH cycle ( timeOn + 18 )

I will test

After reading the verification of the current time in contribution to timeSpam, I tell myself that the verification of the current time proposed by PaulRB avoids counting problems

No, I think the earlier version might not work for time periods containing midnight. Hopefully the later version fixes that.

It's just well seen! I also improved by outputting the "=" before each timeOff otherwise cycleOff = timeOff + 1 hour

Thank you very much for your help !

I am going to use a battery-powered RTC module, when I receive it is I have installation problems I could ask you?

Why would you use that? You don't need it with Blynk, the time is supplied by the Blynk server. If the Arduino cannot connect to the Blynk server, will your code run at all?