繁体   English   中英

尝试在自定义 class (ESP8266) 中使用 NTPClient 时出现异常

[英]Getting an exception when try to use NTPClient in a custom class (ESP8266)

当我尝试在自定义 class RealTimeService 中使用 NTPClient 时出现异常(见下文)。 请告知为什么以及如何解决它。 谢谢你。

文件实时服务.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

文件实时服务.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");
  }
}

文件 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);
}

它在 function RealTimeService::_update() 中的 _ntp.begin() 行抛出异常;

User exception (panic/abort/assert)

解码后的堆栈是:

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

您在RealTimeService::_createNtpClient()中定义udp并将其传递给NTPClient NTPClientRealTimeService::_createNtpClient()返回后会继续需要它,但是udp会失效。 即使NTPClient复制它,它的析构函数也会被调用,从而使它使用的资源无效。

您需要将udp更改为一个实例变量,这样它就会像_ntp一样存在。

class RealTimeService {
  private:
    WiFiUDP _udp;
    NTPClient _ntp;
...

NTPClient RealTimeService::_createNtpClient() {
  NTPClient ntp(_udp, "pool.ntp.org", 3600, 86400000);

您的代码还反复调用_ntp.begin() 您应该确保您使用的 NTP 库允许这样做; 有时编写库时,它们的begin()方法只能被调用一次。

除了@romkey的回答之外,您还可以完全跳过_createNtpClient并在构造函数中移动字段的初始化。 更紧凑的东西,比如

#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)
{
}

...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM