Reputation: 2603
I'm getting an exception (see below) when I try to use NTPClient in my custom class RealTimeService. Please advise why and how to fix it. Thank you.
File RealTimeService.h:
#ifndef RealTimeLib
#define RealTimeLib
#include <NTPClient.h>
#include <WiFiUdp.h>
class RealTimeService {
private:
NTPClient _ntp;
NTPClient _createNtpClient();
void _update();
public:
RealTimeService();
void begin();
};
#endif
File RealTimeService.cpp:
#include "RealTimeService.h"
RealTimeService::RealTimeService() :
_ntp(_createNtpClient())
{
}
NTPClient RealTimeService::_createNtpClient() {
WiFiUDP udp;
NTPClient ntp(udp, "pool.ntp.org", 3600, 86400000);
return ntp;
}
void RealTimeService::begin() {
_update();
}
void RealTimeService::_update() {
_ntp.begin(); // Throws an exception
if(_ntp.update()) {
long time = _ntp.getEpochTime();
} else {
Serial.print("Failed to get time from server.\n");
}
}
File WebServerSecure.ino:
#include <ESP8266WiFi.h>
#include "RealTimeService.h"
#ifndef STASSID
#define STASSID "Sedmikraska"
#define STAPSK "38098246"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
RealTimeService realTime;
void setup(void) {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
realTime.begin();
}
void loop(void) {
delay(1000);
}
It throws an exception in function RealTimeService::_update() at line _ntp.begin();
User exception (panic/abort/assert)
And the decoded stack is:
0x4020714a: HardwareSerial::begin(unsigned long, SerialConfig, SerialMode, unsigned char, bool) at C:\Users\user\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\HardwareSerial.cpp line 51
0x4020804c: __unhandled_exception_cpp() at C:\Users\user\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 229
0x4020a07c: NTPClient::begin(int) at C:\Users\user\Documents\Arduino\libraries\NTPClient\NTPClient.cpp line 61
0x40202544: NTPClient::begin() at C:\Users\user\Documents\Arduino\libraries\NTPClient\NTPClient.cpp line 53
0x40201028: RealTimeService::_update() at C:\Users\user\AppData\Local\Temp\arduino_build_506039\sketch\RealTimeService.cpp line 20
0x40201b04: ESP8266WiFiSTAClass::status() at C:\Users\user\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266WiFi\src\ESP8266WiFiSTA.cpp line 634
0x40201058: RealTimeService::begin() at C:\Users\user\AppData\Local\Temp\arduino_build_506039\sketch\RealTimeService.cpp line 16
0x4020115c: setup() at C:\Users\user\Documents\Arduino\WebServerSecure/WebServerSecure.ino line 23
0x40208224: loop_wrapper() at C:\Users\user\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 194
Upvotes: 1
Views: 625
Reputation: 2787
In addition to @romkey's answer, you could probably skip _createNtpClient
altogether and move the initialization of the fields in the constructor. Something more compact, like
#ifndef RealTimeLib
#define RealTimeLib
#include <WiFiUdp.h>
#include <NTPClient.h>
class RealTimeService {
private:
WiFiUDP _udp;
NTPClient _ntp;
...
public:
RealTimeService();
...
};
#endif
#include "RealTimeService.h"
RealTimeService::RealTimeService() :
_udp(),
_ntp(_udp, "pool.ntp.org", 3600, 86400000)
{
}
...
Upvotes: 0
Reputation: 7109
You define udp
in RealTimeService::_createNtpClient()
and pass it to NTPClient
. NTPClient
will continue to need it after RealTimeService::_createNtpClient()
returns, but udp
will become invalid. Even if NTPClient
copies it, its destructor is called, invalidating the resources it used.
You need to change udp
to be an instance variable so that it will survive as long as _ntp
does.
class RealTimeService {
private:
WiFiUDP _udp;
NTPClient _ntp;
...
and
NTPClient RealTimeService::_createNtpClient() {
NTPClient ntp(_udp, "pool.ntp.org", 3600, 86400000);
Your code is also calling _ntp.begin()
repeatedly. You should ensure that the NTP library you're using allows for this; sometimes libraries are written so that their begin()
method can only be called once.
Upvotes: 2