0

so I have an application in which there are 2 specific times (eg 9AM, 6PM) where a variable curPos is updated. Everything is converted in ms since 00:00 (9AM = 32400000, 6PM = 64800000). Now, the actions (curPos updates) should be triggered every day at these times. To retrieve the current real time (always in ms) I'm sending a http request to a website. This is done only once in the setup().

The idea is that I have to access somehow (http request) the current real time in order to determine when are 9AM and 6PM in my ESP8266, since the start of the sketch. The current real time is needed only once at the beginning (in case there's an issue and the sketch restarts). Then I can calculate the difference between the current real time and the timers.

The next step would be to translate the values into a 24hour cycle starting at the startup/reset time, so that it can repeat itself without need to request again the real time.

I'm lost in the logic on how to deal with this and with millis() to check when it's time to trigger one of the actions.

This is what I'm doing now with the HTPP GET payload in the setup() (I can successfully retrieve the 3 values in ms from the GET response)

      String payload = http.getString();

      int commaIndex = payload.indexOf(',');
      int secondCommaIndex = payload.indexOf(',', commaIndex + 1); //Search for the next comma just after the first

      mainTime = payload.substring(0, commaIndex).toInt(); //current real time in ms
      timers[0] = payload.substring(commaIndex + 1, secondCommaIndex).toInt(); //9AM in ms
      timers[1] = payload.substring(secondCommaIndex + 1).toInt()); //6PM in ms

      timers[0] = abs(mainTime - timers[0]); //the time difference before reaching the first timer (in ms)
      timers[1] = abs(mainTime - timers[1]); //the time difference before reaching the second timer (in ms)

      // my attempt to turn the time differences into a 24hrs "local" (in the sketch) time
      //dayMs is 24hrs in ms (86400000)
      if(timers[0] < 0)
        timers[0] = dayMs - timers[0];

      if(timers[1] < 0)
        timers[1] = dayMs - timers[1];

and in the loop I'd need a comparison (I think) but I'm just really lost on this

//I think millis need to be reset after 24hrs since the start of the sketch?

if(millis() == timers[0]){ 
      curPos = 1; //first timer expired then trigger
  }else if(millis() == timers[1]){
      curPos = 7; //second timer expired then trigger
  }

thanks!

  • you think that you catch the exact millisecond to trigger the event? – Juraj Aug 10 '18 at 16:18
  • 1
    it would be better to set time to TimeLib and then test if it is 9AM or 6PM. – Juraj Aug 10 '18 at 16:19
  • Indeed. You can also use NTP to grab the current time off the internet and feed it to TimeLib. – Majenko Aug 10 '18 at 16:25
  • set up a tick variable ... increment it inside the loop() every second or every minute (even every hour ... whatever works for you) .... then simply monitor the value of tick – jsotola Aug 10 '18 at 16:39
  • thanks, so: - I don't think I can catch the exact ms to trigger the event and I'm looking for suggestions on how to do this. - I tried NTP and there were issues with the timezone so the http request is a good substitute. - Ok for the tick variable but I'm still a bit confused on how to turn everything in 24hrs (since the original time). - I will check TimeLib (I assume is a Library?) – Ska Frenz Aug 10 '18 at 18:06
1

For time-keeping on a long-term basis, you are going to run up against clock drift and offsets from tick-tracking. You may be better off using a real-time-clock (RTC) such as the DS1307. This and RTCs like it are often available in breakout boards with a coin-cell battery holder built in.

You would still get the time from your HTTP or NTP source, but the RTC will be much better at keeping the "right" time as you would expect a wristwatch or desk clock to do, versus using the MCU for counting milliseconds.

You can use Ticks or millis() to set up a periodic read of the RTC every second or every 10 seconds, etc. Avoid using the MCU clock for long-term real-world time keeping.

0

I describe how I do it in my project. I use the Time library a.k.a TimeLib. I set the time I retrieved not by NTP but over modbus from a device which is the source of other data in my project. In your case, you have the http request.

The input to set the time to TimeLib is UNIX epoch. Epoch are seconds from 1970-01-01. If you set only the seconds of the current day, the date would stay 1970-01-01.

And then I have for example this function

boolean restHours() {

  const int BEGIN_HOUR = 9;
  const int END_HOUR = 22;

  int hourNow = hour(now());

  if (hourNow >= BEGIN_HOUR && hourNow < END_HOUR) {
    if (state == RegulatorState::REST) {
      state = RegulatorState::MONITORING;
    }
    return false;
  }
  if (state == RegulatorState::MONITORING) {
    state = RegulatorState::REST;
    clearData();
  }
  return true;
}

now() returns the 'epoch' time. hour(now()) returns the current hour.

or in other function I test if it the should be executed. it enables the execution of the rest of the function only in interval 9:00 to 10:00

void susCalibLoop() {

  const byte SUSCALIB_HOUR = 9;
  static boolean done = false;

  int hourNow = hour(now());

  if (hourNow != SUSCALIB_HOUR) {
    if (done) {
      done = false;
    }
    return;
  }
  if (done)
    return;
...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.