Skip to content

sntp callback: use a recurrent schedule function #6888

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 10, 2019

Conversation

d-a-v
Copy link
Collaborator

@d-a-v d-a-v commented Dec 7, 2019

A scheduled function used as callback had to wait for next loop() but user may loop on yield().
Using a recurrent scheduled function executed once instead of a simple scheduled function is a fix for this use case.

fixes https://gitter.im/esp8266/Arduino?at=5deb83131659720ca8145e26

@hasenradball
Copy link
Contributor

When using schedule_function(_settimeofday_cb); and a delay(100) for instancs of yield() to wait for the cb there is no change!
Do we have understood the root cause completely?

@hasenradball
Copy link
Contributor

Here is the test sketch:

#include <Arduino.h>
#include <time.h>
#include <coredecls.h>
#include <ESP8266WiFi.h>

const char * _ssid {"ssid"};
const char * _password {"password"};

// ### --- Class Unix_Time --- ###
class Unix_Time {
  private:
    time_t _ti{0};
    static bool _initOK;
    bool _initOK2{false};

  public:
    Unix_Time(void);
    ~Unix_Time(void);

    static void set_initOK(void);
    static bool get_initOK(void);
    void set_initOK2(void);
    bool get_initOK2(void);
    bool Init(void);
    time_t getTime(void);
};
bool Unix_Time::_initOK{false};

Unix_Time::Unix_Time() {
  //  settimeofday_cb([&]() {
  //    Unix_Time::set_initOK();
  //  });

  // for future usage if settimeofday_cb() can handle functional pointers
  settimeofday_cb(std::bind(&Unix_Time::set_initOK2, this));
  configTime(0, 0, "ptbtime1.ptb.de", "ptbtime2.ptb.de", "ptbtime3.ptb.de");
}

Unix_Time::~Unix_Time(void) {}

void Unix_Time::set_initOK(void) {
  _initOK = true;
}

void Unix_Time::set_initOK2(void) {
  _initOK2 = true;
}

bool Unix_Time::get_initOK2(void) {
  return _initOK2;
}

bool Unix_Time::get_initOK(void) {
  return _initOK;
}

time_t Unix_Time::getTime(void) {
  //if (!_initOK) return;
  _ti = time(nullptr);
  return _ti;
}
// ### --- Class Unix_Time --- ###

Unix_Time utc;

void setup() {
  Serial.begin(115200);
  while (!Serial) yield();

  Serial.printf(" WiFi mode set to WIFI_STA: %s\n", WiFi.mode(WIFI_STA) ? "Success!" : "Failed!");
  WiFi.begin(_ssid, _password);

  while ((WiFi.status() != WL_CONNECTED)) {
    delay(100);
    Serial.print(" ");
    Serial.print(WiFi.status());
  }
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("");
    Serial.print(" Verbunden mit: ");
    Serial.println(WiFi.SSID());
    Serial.print(" IP address: ");
    Serial.println(WiFi.localIP());
    Serial.print("\n");
  }
  Serial.println(utc.getTime());
  Serial.println(">>> set Clock");
  while (!utc.get_initOK2()) {
    Serial.println("...no cb received");
    Serial.println(utc.getTime());
    delay(1000);
  }
  Serial.print(utc.getTime());
}

void loop() {
  // put your main code here, to run repeatedly:

}

@d-a-v
Copy link
Collaborator Author

d-a-v commented Dec 7, 2019

You may have not applied the PR (which is not merged yet).
Your MCVE works correctly with it.

00:02:36.229 ->  IP address: 10.0.1.154
00:02:36.262 -> 
00:02:36.262 -> 28803
00:02:36.262 -> >>> set Clock
00:02:36.262 -> ...no cb received
00:02:36.262 -> 28803
00:02:37.258 -> 1575759756
(((then silent)))

@hasenradball
Copy link
Contributor

Hi I have tested it with the PR also, then it works, right. But with your description above I understood the rootcause was the yield(). But when using delay(500) for instance without the PR, there is no change.
So I did not understand the effect of of the PR.
Where can I look up the definition of the schedule_function?

@hasenradball
Copy link
Contributor

Is a cb as static function (2.5.2) differently invoked as the functional solution as now in 2.6.2?

@d-a-v
Copy link
Collaborator Author

d-a-v commented Dec 8, 2019

In 2.5.2, the function was called from within an ISR-like context that prevented to use most of the API.
It has been changed to a functionnal that runs like a normal/user context. But the call is deferred to the end of next loop().

The current PR allows the call to be made at next yield(), delay() or loop() call.

(documentation is in cores/esp8266/Schedule.h)

@hasenradball
Copy link
Contributor

hasenradball commented Dec 8, 2019

Ah now I think I catched the issue. If I had called it in the loop() funktion it would have worked, but when I am calling it in the setup() it can not work by definition, right?
Thanks for your fast PR! :-)

@d-a-v d-a-v merged commit 72a4dde into esp8266:master Dec 10, 2019
@d-a-v d-a-v deleted the sntpcallabckfix branch December 10, 2019 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants