Библиотека IsTimeSet — Назначение переменных

Я получаю текущее время с помощью примера кода istimneforset, все работает нормально.

теперь я хочу получить текущее время из функции "Serial.println(timeClient.getFormattedTime());" и я пытаюсь кэшировать первый символ массива.

код:

#include <NTPClient.h>
// Изменяем следующую строку для использования с другой картой/щитом
#include <ESP8266WiFi.h>
//#включить <WiFi.h> // для экрана WiFi
//#включить <WiFi101.h> // для шилда WiFi 101 или MKR1000
#include <WiFiUdp.h>

const char *ssid =" *";
const char *password = "*";

WiFiUDP ntpUDP;
// инициализировано смещением времени на 10 часов
NTPClient timeClient(ntpUDP, "pool.ntp.org", 36000, 60000);
// ЧЧ:ММ:СС
// timeClient инициализируется на 10:00:00, если он не получает пакет NTP
// до получения тайм-аута в 100 мс.
// Без isTimeSet() светодиод горел бы, даже если время было
// еще не был установлен правильно.


const int hour = 10;
const int minute = 0;

void setup(){
  Serial.begin(9600);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay (500);
    Serial.print(".");
  }

  timeClient.begin();
}

void loop() {
  timeClient.update();

 //Serial.println(timeClient.getFormattedTime());

 int stund2  = (timeClient.getFormattedTime()[0]);

Serial.println(stund2);

}

к сожалению, это всегда дает мне неправильное значение. моя цель - иметь текущий час в переменной. Кто-нибудь может мне помочь? спасибо!

, 👍0

Обсуждение

Какое значение вы получаете? Почему это неправильно?, @chrisl

Serial.println(timeClient.getFormattedTime()); -> 01:41:58 Serial.println(stund2); -> 48, @Mike


2 ответа


Лучший ответ:

0

Есть несколько сообщений в темах здесь и здесь, предлагающие использовать NTPClient здесь.

Кроме того, если мы проверим, что копия NTPClient.cpp в репозитории GIT начинается со строки 155 мы видим функцию для getFormattedTime():

String NTPClient::getFormattedTime(unsigned long secs) {
  unsigned long rawTime = secs ? secs : this->getEpochTime();
  unsigned long hours = (rawTime % 86400L) / 3600;
  String hoursStr = hours < 10 ? "0" + String(hours) : String(hours);

  unsigned long minutes = (rawTime % 3600) / 60;
  String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes);

  unsigned long seconds = rawTime % 60;
  String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds);

  return hoursStr + ":" + minuteStr + ":" + secondStr;
}

...мы видим, что эта функция возвращает строку вида "чч:мм:сс" где чч – часы, мм – минуты, а сс – секунды.

Чтобы извлечь только часы, нам пришлось бы "вырезать" строку или проанализируйте строку с помощью ":" используйте только символ "hh" часть строки и преобразовать ее обратно в число.

Это сложно. Вместо этого рассмотрите возможность использования функции getHours():

int NTPClient::getHours() {
  return ((this->getEpochTime()  % 86400L) / 3600);
}

... это использует время эпохи после удаления даты (по модулю 86400) и удаления минут и секунд (разделение на 3600), оставляя только часы.

,

0

Хотя st2000 дал хороший ответ о том, как это сделать, я хотел объяснить, что на самом деле пошло не так с вашим первым решением.

Вы видите разницу между двоичными данными и данными в кодировке ASCII. Использование timeClient.getFormattedTime() даст вам строку в кодировке ASCII. Такая строка представляет собой массив char, каждый из которых представляет один символ (в соответствии с таблицей ASCII), пока строка не завершится нулевым символом \0.

Вы берете первый символ и присваиваете его целочисленной переменной. Значение будет напрямую скопировано в эту переменную. Но первым элементом в этом массиве char является цифра ASCII 0, эквивалентная десятичному 48. И это то, что вы получаете из своего кода. Также поле часа этой строки имеет ширину 2 символа, поэтому вам нужно прочитать их оба, а не только первый символ.

Если вы хотите извлечь числа из строки, вы не можете просто присвоить их. Вам нужно правильно анализировать данные. Для этого вы должны токенизировать строку (разделить ее на отдельные части с данными) (например, с помощью strtok()), а затем проанализировать каждый токен с помощью соответствующей функции. Чтобы проанализировать целочисленное значение из строки, вы можете использовать atoi(). Эта функция будет читать строку до тех пор, пока не появится символ, отличный от цифры, и преобразовать его в целое число.

Итак, поскольку нас интересует только первое число/токен в этой строке, вы можете не использовать токенизацию и просто проанализировать эту строку (поскольку после количества часов всегда есть : символ, который не является цифрой):

int stund2 = atoi(timeClient.getFormattedTime());

Я не проверял это, но оно также должно работать, хотя и не так эффективно, как решение st2000, поскольку синтаксический анализ строковых данных обычно сложнее, чем работа непосредственно с целыми числами.

,