2

Libraries

Board

Olimex ESP32-POE board

Behaviour

I have written a code that connects the board to a local NTP Server (which is an embedded board). I tried assigning the IP Address of the above NTP Server using IPAddress and then convert it to c_str() to pass into the NTPClient constructor as follows:

 WiFiUDP ntpUDP; // udp socket object for NTP
 IPAddress NTPServer(192.168.3.11); // Local NTP Server IP Address
 NTPClient timeClient(ntpUDP, NTPServer.toString().c_str(), 0, 60000);

The reason for this is because the NTPClient class uses const char* for the IP Address of the NTP Server.

The values that are obtained once the code is flashed on the board are wrong because the timestamps are have the year 2106.

On the contrary, when I use

 NTPClient timeClient(ntpUDP, "192.168.3.11", 0, 60000);

and run the code on the board, this provides me perfect values of UTC time.

Why is there some discrepancy here?

Code

#include <Wire.h>
#include <ETH.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <RTClib.h>
WiFiUDP ntpUDP;
/* IP CONF for NODE */
///////// >>>> MODIFY Values Here <<<< ////////
const IPAddress node_static_ip(192, 168, 3, 101);
const IPAddress default_gateway(192, 168, 3, 250);
const IPAddress subnet_mask(255, 255, 255, 0);
const IPAddress dns_add(192, 168, 3, 250);
const IPAddress NTPServer(192, 168, 3, 11);
NTPClient timeClient(ntpUDP, "192.168.3.11", 0, 60000); // This works
NTPClient timeClient(ntpUDP, NTPServer.toString().c_str(), 0, 60000); // This won't (provides timestamps of 2106)
void setup() {
 // put your setup code here, to run once:
 Wire.begin(I2C_SDA, I2C_SCL);
 Serial.begin(115200);
 ETH.begin();
 ETH.config(node_static_ip, default_gateway, subnet_mask, dns_add);
 delay(1000);
 if (!rtc.begin()) {
 Serial.println("No RTC");
 }
 timeClient.begin();
}
void loop() {
 // put your main code here, to run repeatedly:
 timeClient.update();
 Serial.println(timeClient.getEpochTime());
 DateTime now_time(timeClient.getEpochTime());
 Serial.print(now_time.year(), DEC);
 Serial.print('/');
 Serial.print(now_time.month(), DEC);
 Serial.print('/');
 Serial.print(now_time.day(), DEC);
 Serial.print(now_time.hour(), DEC);
 Serial.print(':');
 Serial.print(now_time.minute(), DEC);
 Serial.print(':');
 Serial.print(now_time.second(), DEC);
Serial.println();
 delay(2000);
}
VE7JRO
2,51519 gold badges27 silver badges29 bronze badges
asked Nov 8, 2018 at 17:09
3
  • 1
    Don't you mean toString().c_str(), not toString.c_str()? Commented Nov 8, 2018 at 17:37
  • Sorry Typo! I meant the latter. Commented Nov 8, 2018 at 17:39
  • 1
    I thought so, since the former doesn't compile. A simple test of printing to serial works fine. I suggest adding that into your program to make sure it's actually converting it wrong and not something else. Serial.println(NTPServer.toString().c_str()); Commented Nov 8, 2018 at 17:42

1 Answer 1

5

The String object created as return from IPAddress.toString() as parameter to constructor of NtpClient is temporary. It contains the char array returned by c_str(). NTPClient doesn't copy the string, only stores a reference to it. And the referenced string (char array) doesn't exist at the time the NTPClient wants to use it.

class TestClass {
public:
 TestClass(const char* _ip) : ip(_ip) { }
 void test() {
 Serial.println("--");
 Serial.println(ip);
 Serial.println("--");
 }
private:
 const char* ip;
};
//String s("abc");
//TestClass Test(s.c_str()); <- this works
TestClass Test(String("abc").c_str()); // <- this can't work
void setup() {
 Serial.begin(9600);
 Test.test();
}
answered Nov 8, 2018 at 18:07

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.