Использование c_str() для String для IPAddress с NTPClient дает неправильные значения
Библиотеки
- NTPClient
Плата
Плата Olimex ESP32-POE
Поведение
Я написал код, который подключает плату к локальному NTP-серверу (который является встроенной платой). Я попытался назначить IP-адрес указанного выше NTP-сервера, используя IPAddress
, а затем преобразовать его в c_str()
для передачи в конструктор NTPClient
следующим образом. :
WiFiUDP ntpUDP; // объект сокета udp для NTP
IPAddress NTPServer(192.168.3.11); // IP-адрес локального NTP-сервера
NTPClient timeClient(ntpUDP, NTPServer.toString().c_str(), 0, 60000);
Причина этого в том, что класс NTPClient
использует const char*
для IP-адреса NTP-сервера.
Значения, полученные после того, как код высветится на плате, неверны, поскольку временные метки имеют год 2106
.
Наоборот, когда я использую
NTPClient timeClient(ntpUDP, "192.168.3.11", 0, 60000);
и запустить код на плате, это дает мне идеальные значения времени UTC.
Почему здесь некоторое несоответствие?
Код
#include <Wire.h>
#include <ETH.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <RTClib.h>
WiFiUDP ntpUDP;
/* IP CONF for NODE */
///////// >>>> ИЗМЕНИТЬ значения здесь <<<< ////////
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); // Это работает
NTPClient timeClient(ntpUDP, NTPServer.toString().c_str(), 0, 60000); // Это не будет (предоставляет метки времени 2106)
void setup() {
// поместите сюда код установки для однократного запуска:
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() {
// поместите сюда ваш основной код для многократного запуска:
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);
}
@Shan-Desai, 👍2
Обсуждение1 ответ
Лучший ответ:
Объект String, созданный в качестве возврата из IPAddress.toString() в качестве параметра конструктору NtpClient, является временным. Он содержит массив символов, возвращаемый функцией c_str(). NTPClient не копирует строку, а только сохраняет ссылку на нее. И указанная строка (массив символов) не существует в то время, когда NTPClient хочет ее использовать.
class TestClass {
public:
TestClass(const char* _ip) : ip(_ip) { }
void test() {
Serial.println("--");
Serial.println(ip);
Serial.println("--");
}
private:
const char* ip;
};
//Строка s("abc");
// Тест тестового класса (s.c_str()); <- это работает
TestClass Test(String("abc").c_str()); // <- это не может работать
void setup() {
Serial.begin(9600);
Test.test();
}
- Предотвращает ли toCharArray создание строки в куче?
- форматирование строк в Arduino для вывода
- Проблемы с преобразованием byte[] в String
- Как преобразовать форматированный оператор print в строковую переменную?
- Преобразование строки в IP-адрес
- Чтение строки, разделенной запятыми
- Как прочитать входящие ШЕСТНАДЦАТИРИЧНОЕ значение из serial метод read ()?
- Использование AysncUDPMessage для ESP32 для отправки строковых данных
Разве вы не имеете в виду
toString().c_str()
, а неtoString.c_str()
?, @MajenkoИзвините опечатка! Я имел в виду последнее., @Shan-Desai
Я так и думал, поскольку первый не компилируется. Простой тест печати на серийный номер работает нормально. Я предлагаю добавить это в вашу программу, чтобы убедиться, что она действительно конвертирует ее неправильно, а не что-то еще.
Serial.println(NTPServer.toString().c_str());
, @Majenko