Часы с погодой от yandex. ESP8266 + дисплей ILI9341

вчера полез искать скетч, залил и, всё слетело, скорее всего дело в библиотеке TFT, для начала запустите оригинальный скетч, DHT22 оказалось что нету, так что пробовать придётся вам

код не причёсывался, датчик DHT-11

/*    27.04.2023
      29.04.2023 - модифицировано (с) UA6EM
      08.11.2023 - подключен датчик DHT-11 (код не причёсывался)
      
   ILI9341 with ESP8266 and Wemos D1
  // Display SDO/MISO  to NodeMCU pin D6
  // Display LED       to NodeMCU pin D2
  // Display SCK       to NodeMCU pin D5
  // Display SDI/MOSI  to NodeMCU pin D7
  // Display DC (RS/AO)to NodeMCU pin D3
  // Display RESET     to NodeMCU pin D4
  // Display CS        to NodeMCU pin D8
  // Display GND       to NodeMCU pin GND (0V)
  // Display VCC       to NodeMCU 3.3V

   mod (c) UA6EM WEMOS D1 mini (clone)
  Pin   Function  ESP-8266  Pin
  TX    TXD       TXD
  RX    RXD       RXD
  A0    Analog    input,    max 3.3V input  A0
  D0    IO                  GPIO16
  D1    IO,       SCL       GPIO5
  D2    IO,       SDA       GPIO4
  D3    IO,      10k P-up   GPIO0
  D4    IO,      10k P-up   GPIO2 BUILTIN_LED
  D5    IO,       SCK       GPIO14
  D6    IO,       MISO      GPIO12
  D7    IO,       MOSI      GPIO13
  D8    IO,       SS        GPIO15 10k Pull-down,
  G     Ground    GND
  5V    5V        -
  3V3   3.3V      3.3V
  RST   Reset     RST

*/
/*--------------- libraries ----------------------*/
#include <ArduinoJson.h>                    //version - 6.21.1 ONLY
#include <ESP8266WiFi.h>
#include <SPI.h>
#include <TimeLib.h>
#include <ArduinoOTA.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <TFT_eSPI.h>                        // version=2.5.23
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>

#include <Adafruit_Sensor.h>
#include <DHT.h>
//#include <DHT_U.h>
#define DHTPIN D1
//#define DHTTYPE DHT22                  // DHT 22 (AM2302)
#define DHTTYPE DHT11
//DHT_Unified dht(DHTPIN, DHTTYPE);
DHT dht(DHTPIN, DHTTYPE);


/*--------------- Project ----------------------*/
#include "Fonts_Img/ArialRoundedMTBold_36.h" // щрифты
#include "Fonts_Img/FreeSansBold6.h"
#include "Fonts_Img/FreeSansBold10.h"
#include "Fonts_Img/FreeSansBold14.h"
#include "settings.h"                       // Настройки - ввести свои данные!!!
#include "functions.h"                      // функции обработки
#include "Fonts_Img/html.h"                 // веб-страница
/*--------------- Image ----------------------*/
#ifdef theme                                //выбор иконок погоды
#include "Fonts_Img/weather_img2.h"
#else
#include "Fonts_Img/weather_img1.h"
#endif
#define ENABLE_OTA_UPDATE true              // OTA обновление
/*--------------- Fonts ----------------------*/
#define AR36 &ArialRoundedMTBold_36         // шрифт температура сейчас 
#define RU14 &FreeSansBold14pt8b            // шрифт рус. дата
#define RU10 &FreeSansBold10pt8b            // шрифт рус. температура период
#define RU6 &FreeSansBold6pt8b              // шрифт рус. восход, закат
/*---- ILI9341 with ESP8266 and Wemos D1 -----*/
//#define TFT_CS   D8
//#define TFT_DC   D3
//#define TFT_RST  D4
#define TFT_MOSI D7
//#define TFT_MISO D6
#define TFT_CLK  D5
#define LED_PIN  D2           // управление яркостью дисплея 
#define Serial_Print          // отладка для работы  - закоментить
#define LED_BRIGHTNESS 30     // яркость дисплея при старте
WiFiUDP Udp;
TFT_eSPI tft = TFT_eSPI();    // Use hardware SPI
WiFiManager wifiManager;
ESP8266WebServer server_web(80);
weather_t weather;
StaticJsonDocument<8000> doc;
bool decode_json(String jsonStr);
bool get_YA_Weather();
String convert_unix_time(int unix_time);
String get_description_condition(String str);
String get_partName(String pName);
String getSeason(String season);
time_t prevDisplay = 0;
double temperature = 0.0;
double humidity = 0;
double pressure = 0;
/*------------------- print Img weather --------------------------*/
void print_Img(int x, int y, String condition, String daytime) {
  int w, h;
  w = 60; h = 60;                                          // ширина, высота иконки
  if ((condition == "clear") and (daytime == "d"))         //Ясно день
    tft.pushImage(x, y, w, h, img_100);
  if ((condition == "clear") and (daytime == "n"))         //Ясно ночь
    tft.pushImage(x, y, w, h, img_150);
  if ((condition == "partly-cloudy") and (daytime == "d")) //Малооблачно день
    tft.pushImage(x, y, w, h, img_104);
  if ((condition == "partly-cloudy") and (daytime == "n")) //Малооблачно ночь
    tft.pushImage(x, y, w, h, img_154);
  if ((condition == "cloudy") and (daytime == "d"))        //Облачно день
    tft.pushImage(x, y, w, h, img_104);
  if ((condition == "cloudy") and (daytime == "n"))        //Облачно ночь
    tft.pushImage(x, y, w, h, img_154);
  if (condition == "overcast")                             //Пасмурно
    tft.pushImage(x, y, w, h, img_102);
  if ((condition == "drizzle") or  (condition == "light-rain") or (condition == "rain")) //Небольшой дождь, Дождь
    tft.pushImage(x, y, w, h, img_306);
  if ((condition == "moderate-rain") or  (condition == "heavy-rain") or (condition == "continuous-heavy-rain") or (condition == "showers")) //Сильный дождь, Ливень
    tft.pushImage(x, y, w, h, img_310);
  if (condition == "wet-snow")                              //Дождь со снегом
    tft.pushImage(x, y, w, h, img_404);
  if ((condition == "light-snow") or  (condition == "snow") or (condition == "snow-showers")) //Снег
    tft.pushImage(x, y, w, h, img_403);
  if (condition == "hail")                                  //Град
    tft.pushImage(x, y, w, h, img_313);
  if ((condition == "thunderstorm") or  (condition == "thunderstorm-with-rain") or (condition == "thunderstorm-with-hail")) //Дождь,гроза
    tft.pushImage(x, y, w, h, img_303);
} // end print_Img

/*------------------- TFT weather --------------------------*/
void TFT_dht()
{
  // тут вывести домашние датчики
  int xpos = 110; // координаты отрисовки температуры
  float temp = dht.readTemperature();
  float hum = dht.readHumidity();
  uint8_t itemp = (uint8_t)temp;
  uint8_t ihum = (uint8_t)hum;
  
  tft.setTextColor(TFT_MAGENTA, TFT_BLACK, true); // для температуры
  tft.drawString(("+"), xpos + 10, 207);
  tft.drawString((String(itemp)), xpos + 18, 207);
  tft.setTextFont(0);
  tft.drawString((" o"), xpos + 34, 207);
  tft.setFreeFont(RU6);
  tft.drawString((" C"), xpos + 45, 207);
  tft.setTextColor(TFT_CYAN, TFT_BLACK, true);   // для влажности
  tft.drawString((String(ihum)), xpos + 17, 223);
  tft.drawString(("%"), xpos + 40, 223); 
}

void TFT_weather()
{
  get_YA_Weather(); // запрос погоды с яндекс
  tft.fillRect ( 2, 123, 316, 115, TFT_BLACK);                     //область погоды очищаем для перерисовки
  print_Img(2, 124, weather.fact.condition, weather.fact.daytime); //рисуем картинку на TFT текущая погода
  tft.setFreeFont(AR36);
  tft.setTextColor(TFT_YELLOW, TFT_BLACK, true);
  int xpos = 65; // координаты отрисовки температуры
  if (weather.fact.temp > 0)
    xpos += tft.drawString("+" + String(weather.fact.temp), xpos, 130); // добавляем "+" к положительной текущей температуре
  else
    xpos += tft.drawString(String(weather.fact.temp), xpos, 130);      // текущая температура
  tft.setTextFont(2);
  xpos += tft.drawString(" o", xpos, 130); //  " °C" добавляем градус к температуре
  tft.setFreeFont(AR36);
  xpos += tft.drawString("C", xpos, 130);
  tft.setFreeFont(RU10);
  tft.setTextColor(TFT_WHITE, TFT_BLACK, true);
  tft.drawString(utf8rus( get_description_condition(weather.fact.condition )), 5, 184); // текущая погода
  tft.setTextColor(TFT_CYAN, TFT_BLACK, true);
  tft.drawString(String(weather.fact.pressure_mm) + utf8rus(" мм.р.ст."), 65, 165);     // текущее давление
  tft.setTextColor(TFT_DARKGREY, TFT_BLACK, true);
  tft.drawString(utf8rus(get_partName(weather.forecast.parts[0].part_name)), 184, 185);        // 1-й период погода
  print_Img(184, 125, weather.forecast.parts[0].condition, weather.forecast.parts[0].daytime); //рисуем картинку на TFT 1-й период
  tft.drawString(utf8rus(get_partName(weather.forecast.parts[1].part_name)), 254, 185);        // 2-й период погода
  print_Img(254, 125, weather.forecast.parts[1].condition, weather.forecast.parts[1].daytime); //рисуем картинку на TFT 2-й период
  tft.setTextColor(TFT_YELLOW, TFT_BLACK, true);
  xpos = 184;                                              // 1-й период температура " °C"
  if (weather.forecast.parts[0].temp_avg > 0)
    xpos += tft.drawString("+" + String(weather.forecast.parts[0].temp_avg), xpos, 210);
  else
    xpos += tft.drawString(String(weather.forecast.parts[0].temp_avg), xpos, 210);
  tft.setTextFont(0);
  xpos += tft.drawString(" o", xpos, 210); //  " °C" добавляем градус к температуре
  tft.setFreeFont(RU10);
  xpos += tft.drawString("C", xpos, 210);
  xpos = 254;                                              // 2-й период температура
  if (weather.forecast.parts[1].temp_avg > 0)
    xpos += tft.drawString("+" + String(weather.forecast.parts[1].temp_avg), xpos, 210); // добавляем "+" к положительной температуре
  else
    xpos += tft.drawString(String(weather.forecast.parts[1].temp_avg), xpos, 210);
  tft.setTextFont(0);
  xpos += tft.drawString(" o", xpos, 210); //  " °C" добавляем градус к температуре
  tft.setFreeFont(RU10);
  xpos += tft.drawString("C", xpos, 210);

  tft.setTextColor(TFT_GREENYELLOW, TFT_BLACK, true);
  tft.setFreeFont(RU6);
  xpos = tft.drawString(utf8rus("Восход:"), 5, 207);
  tft.drawString(weather.forecast.sunrise, xpos + 10, 207);       // Восход
  tft.drawString(utf8rus("Закат:"), 5, 223);                      // выравниваем время восхода и заката
  tft.drawString(weather.forecast.sunset, xpos + 10, 223); // Закат

  // тут вывести домашние датчики
   TFT_dht();

  tft.drawLine( 256, 40, 256, 115, TFT_GREENYELLOW );      //область секунд и дня недели 1
  tft.drawLine( 256, 85, 316, 85, TFT_GREENYELLOW );       //область секунд и дня недели 2
  tft.drawRect( 1, 1, 319, 122, TFT_NAVY );                //область часы и дата
  tft.drawRect( 1, 122, 319, 118, TFT_NAVY );              //область погоды
  tft.drawLine( 182, 122, 182, 240, TFT_NAVY );            //область периодов погоды
} // end TFT_weather

/*------------ TFT Clocktime -----------------------------*/
void draw_Clocktime()
{
  String str;
  int len;
  uint8_t hh = hour(), mm = minute(), ss = second(); // Get H, M, S from compile time
  if ((hh == 0) and (mm == 0) and (ss == 0))
  {
    tft.fillRect ( 5, 40, 53, 76, TFT_BLACK);        // Очистить первый 0 в "00" в часах в 00:00:00 от остатка двойки 23:59:59
    tft.fillRect ( 2, 2, 314, 40, TFT_BLACK);        // Очистить дату
    tft.fillRect ( 262, 89, 56, 30, TFT_BLACK);      // Очистить день недели
  }

  if (( hh == 0 ) and ( mm == 0 ))
  {
    tft.setFreeFont(RU10);
    tft.setTextColor(TFT_YELLOW, TFT_BLACK, true);
    str = utf8rus( days[ weekday() ] );
    tft.drawString( str, 265, 87 ); // день недели
    str = utf8rus( String( day() ) + " " + months[ month() ] + " " + year() );  // день, месяц и год
    tft.drawString( str, 10 /*80  - tft.textWidth(str) / 2 */, 2 );

    tft.setFreeFont(RU14);
    tft.setTextColor(TFT_CYAN, TFT_BLACK, true);
    str = "UA6EM";
    tft.drawString( str, 220 /*80  - tft.textWidth(str) / 2 */, 2 );

    tft.setTextColor(TFT_WHITE, TFT_BLACK, true);
  }
  byte omm = 99, oss = 99;
  byte xcolon = 0, xsecs = 0;
  int xpos = 5;   // // d:\arduino-1.8.19\...\libraries\TFT_eSPI\examples\320 x 240\TFT_Clock_Digital
  int ypos = 40;                                          // Верхний левый угол текста часов
  int ysecs = ypos + 24;
  if (omm != mm) {                                        // Обновлять часы и минуты каждую минуту
    omm = mm;
    // рисуем часы и минуты
    tft.setTextColor(TFT_BLACK, TFT_BLACK, true);
    if (hh < 10) xpos += tft.drawChar('0', xpos, ypos, 8); // Добавить 0 в часы  для 24-часового формата и сохранение позиции на дисплее.
    tft.setTextColor(TFT_WHITE, TFT_BLACK, true);
    xpos += tft.drawNumber(hh, xpos, ypos, 8);             // рисуем часы
    xcolon = xpos;                                         // Сохранение координат двоеточия, чтобы мигать позже
    xpos += tft.drawChar(':', xpos, ypos - 8, 8);
    if (mm < 10) xpos += tft.drawChar('0', xpos, ypos, 8); // Добавить 0 в минуты
    xpos += tft.drawNumber(mm, xpos, ypos, 8);             // рисуем минуты
    xsecs = xpos;                                          // Сохранение положения секунд «x» для последующих обновлений дисплея
  }
  if (oss != ss) {                                         // Перерисовывать секунды каждую секунду
    oss = ss;
    xpos = xsecs;
    if (ss % 2) {                                          // Включить/выключить двоеточие
      tft.setTextColor(TFT_BLACK, TFT_BLACK, true);              // затемнить двоеточие
      tft.drawChar(':', xcolon, ypos - 8, 8);              // Час:минута двоеточие
      tft.setTextColor(TFT_WHITE, TFT_BLACK, true);              // Вернуть цвет
    }
    else {
      tft.drawChar(':', xcolon, ypos - 8, 8);              // Час:минута двоеточие
    }
    //рисуем секунды
    if (ss < 10) xpos += tft.drawChar('0', xpos + 8, ypos - 3, 6); // Добавить 0
    tft.drawNumber(ss, xpos + 8, ypos - 3, 6);                 // рисуем секунды
  }
} // end TFT Clocktime

void refresh_display()
{
  draw_Clocktime();
  if ( ( minute() == 59 ) && ( second() == 59 ) )	//обновление погоды 1 раз в 59 мин 59 секунд
  {
    TFT_weather();
    
    serial_digitalClockDisplay();
    Serial.println("Get weather");
  }
   if ( ( second() == 59 ) ) TFT_dht();
} // end  refresh_display


/*------------------ setup -----------------------------------*/
void setup()
{
  pinMode(LED_PIN, OUTPUT);
  analogWriteFreq(32768);
  analogWrite(LED_PIN, LED_BRIGHTNESS); // первоначальная яркость дисплея
  Serial.begin(115200);
  delay(250);
  
  // вставка кода датчика DHT
  pinMode(D1, INPUT_PULLUP);
  dht.begin();
  //sensor_t sensor;
  //dht.temperature().getSensor(&sensor);
  
  // Раскомментировать и запустить один раз, если надо стереть всю сохраненную информацию о WiFi в памяти ESP8266
  //wifiManager.resetSettings();
  tft.begin();
  tft.setSwapBytes(true); //Используется 16-битным pushImage() для изменения порядка байтов в цветах.
  tft.setRotation(1);
  tft.setTextSize(2);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_WHITE, TFT_BLACK, true);
  tft.setCursor(0, 26);
  tft.println("Connecting");
  Serial.println("");
  Serial.println("NTP Clock");
  Serial.print("Connecting to ");
  Serial.println(WiFi.SSID());
  initWiFi();
  tft.println("");
  tft.println(WiFi.SSID());
  tft.print("IP: ");
  tft.println(WiFi.localIP());
  tft.println("Starting UDP");
  Udp.begin(localPort);
  tft.print("Local port ");
  tft.println(Udp.localPort());
  tft.println("Time sync");
  setSyncProvider(getNtpTime); //Функция setSyncProvider(getTimeFunction) настраивает время
  setSyncInterval(3600);       // Функция setSyncInterval(interval) задает количество секунд между синхронизациями
  tft.println("Weather request");
  display_brightness();
  delay(2500); // читаем что вывели на дисплей
  if ( ENABLE_OTA_UPDATE )
  {
    tft.println("Begin OTA handler Esp8266_Clock");
    initOTA(); // обновление по WiFi
  }
  tft.setTextSize(1);
  tft.fillScreen(TFT_BLACK);
  String str;
  tft.setFreeFont(RU10);
  tft.setTextColor(TFT_YELLOW, TFT_BLACK, true);
  str = utf8rus( days[ weekday() ] ); // день недели
  tft.drawString( str, 265, 87 );
  str = utf8rus( String( day() ) + " " + months[ month() ] + " " + year() ); // день, месяц и год

  // tft.drawString( str, 160 - tft.textWidth(str) / 2, 2 );
  // str = utf8rus( String( day() ) + " " + months[ month() ] + " " + year() );  // день, месяц и год
  tft.drawString( str, 10 /*80  - tft.textWidth(str) / 2 */, 2 );

  tft.setFreeFont(RU14);
  tft.setTextColor(TFT_CYAN, TFT_BLACK, true);
  str = "UA6EM";
  tft.drawString( str, 220 /*80  - tft.textWidth(str) / 2 */, 2 );

  tft.setTextColor(TFT_WHITE, TFT_BLACK, true);
  server_web.on("/", handle_OnConnect);
  server_web.on("/update", handle_update);
  server_web.onNotFound(handle_NotFound); //любой URL, отличный от указанного в server.on() = ответить HTTP-статусом 404 (Not Found)
  server_web.begin();//запустить сервер
  draw_Clocktime();
  TFT_weather(); // отрисовка погоды
}//end setup

/*------------------ loop -----------------------------------*/
void loop()
// датчик температуры
//  static float temp = 20;
//  static float hum = 57;

{
  if ( ENABLE_OTA_UPDATE )
  {
    ArduinoOTA.handle();
  }

  if (timeStatus() != timeNotSet)
  {
    // обновляем дисплей только если время поменялось
    if (now() != prevDisplay)  //Функция now() считывает время, прошедшее с 1 января 1970 года (в секундах).
    {
      prevDisplay = now();     //Конструкция time_t t = now() сохраняет текущее время в переменную t.
      display_brightness();
      refresh_display();
    }
  }
  if ((millis() > 60 * 1000) and (year() == 1970) and (WiFi.status() == WL_CONNECTED)) //при старте время не было задано
  {
    restart();
  }
  server_web.handleClient();
} //end loop

/*------------------ web-html -----------------------------------*/
void handle_OnConnect() {
  Serial.println("Web started");
  server_web.send(200, "text/html", index_html);

} // end handle_OnConnect

void handle_update() {
  server_web.send(200, "text/html", index_html);
  slider_day = server_web.arg("brightness_day").toInt();
  day_ = server_web.arg("hour_day").toInt();
  slider_night = server_web.arg("brightness_night").toInt();
  night_ = server_web.arg("hour_night").toInt();
  Serial.println(slider_day);
  Serial.println(day_);
  Serial.println(slider_night);
  Serial.println(night_);
} // end handle_update

void handle_NotFound() {
  server_web.send(404, "text/plain", "Not found");
} // end handle_NotFound

// перезапуск ESP8266
void restart()
{
  Serial.println("Restart ESP...");
  ESP.restart();
} // end restart

void display_brightness() // яркость дисплея
{
  if ( ( hour() >= day_ ) and ( hour() < night_ ) )
  {
    analogWrite(LED_PIN, slider_day);
  }
  else
  {
    analogWrite(LED_PIN, slider_night);
  }
} // end display_brightness
/*------------------ WiFi -----------------------------------*/
void initWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin();//переключиться в режим станции и подключиться к последней точке доступа на основе данных, сохраненных во flash-памяти.
  //  WiFi.begin(ssid, pass);
  //Если persistent - false,то SSID и пароль будут записаны на flash-память только если новые значения не будут соответствовать тем, что хранятся во flash-памяти.
  WiFi.persistent(false);
  WiFi.setAutoReconnect(true);// true, модуль сделает попытку повторного подключения к точке доступа, а если false, то нет.
  Serial.println("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED && millis() < 15 * 1000) {
    delay(500);
    Serial.print(".");
  }

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  }
  else {
    Serial.println("WiFi not connected, starting WiFiManager");
    tft.println("WiFi not connected...");
    tft.println("Starting WiFiManager");
    tft.println("SSID: ESP8266-Clock");
    tft.print("IP address: ");
    tft.println("192.168.4.1");
    wifiManager.autoConnect("ESP8266-Clock");
    delay(2000);
  }
} // end initWiFi
/*------------------ json -----------------------------------*/
bool decode_json(String jsonStr) // https://github.com/discover1977/YWInformer
{
  DeserializationError error = deserializeJson(doc, jsonStr); // преобразовать строку JSON в структуру
  if (error) {    // Проверяем успешность парсинга.
    String errorStr = error.c_str();
    Serial.println("errorStr: ");  Serial.print(errorStr);
    return false;
  } else {
    Serial.println("deserializeJson() без ошибок.");
    JsonObject doc_YA = doc.as<JsonObject>();
    weather.fact.condition = doc_YA["fact"]["condition"].as<const char *>(); // парсинг данных из JsonObject
    weather.fact.daytime = doc_YA["fact"]["daytime"].as<const char *>();
    weather.fact.feels_like = doc_YA["fact"]["feels_like"].as<int8_t>();
    weather.fact.humidity = doc_YA["fact"]["humidity"].as<uint8_t>();
    weather.fact.icon = doc_YA["fact"]["icon"].as<const char *>();
    weather.fact.obs_time = doc_YA["fact"]["obs_time"].as<int>();
    weather.fact.polar = doc_YA["fact"]["polar"].as<bool>();
    weather.fact.pressure_mm = doc_YA["fact"]["pressure_mm"].as<uint16_t>();
    weather.fact.pressure_pa = doc_YA["fact"]["pressure_pa"].as<uint16_t>();
    weather.fact.season = doc_YA["fact"]["season"].as<const char *>();
    weather.fact.temp = doc_YA["fact"]["temp"].as<int8_t>();
    weather.fact.temp_water = doc_YA["fact"]["temp_water"].as<int8_t>();
    weather.fact.wind_dir = doc_YA["fact"]["wind_dir"].as<const char *>();
    weather.fact.wind_gust = doc_YA["fact"]["wind_gust"].as<float>();
    weather.fact.wind_speed = doc_YA["fact"]["wind_speed"].as<float>();
    weather.forecast.date = doc_YA["forecast"]["date"].as<String>();
    weather.forecast.date_ts = doc_YA["forecast"]["date_ts"].as<int>();
    weather.forecast.moon_code = doc_YA["forecast"]["moon_code"].as<uint8_t>();
    weather.forecast.moon_text = doc_YA["forecast"]["moon_text"].as<const char *>();
    for (uint8_t i = 0; i < 2; i++)
    {
      weather.forecast.parts[i].condition = doc_YA["forecast"]["parts"][i]["condition"].as<const char *>();
      weather.forecast.parts[i].daytime = doc_YA["forecast"]["parts"][i]["daytime"].as<const char *>();
      weather.forecast.parts[i].feels_like = doc_YA["forecast"]["parts"][i]["feels_like"].as<int8_t>();
      weather.forecast.parts[i].humidity = doc_YA["forecast"]["parts"][i]["humidity"].as<uint8_t>();
      weather.forecast.parts[i].icon = doc_YA["forecast"]["parts"][i]["icon"].as<const char *>();
      weather.forecast.parts[i].part_name = doc_YA["forecast"]["parts"][i]["part_name"].as<const char *>();
      weather.forecast.parts[i].polar = doc_YA["forecast"]["parts"][i]["polar"].as<bool>();
      weather.forecast.parts[i].prec_mm = doc_YA["forecast"]["parts"][i]["prec_mm"].as<float>();
      weather.forecast.parts[i].prec_period = doc_YA["forecast"]["parts"][i]["prec_period"].as<uint16_t>();
      weather.forecast.parts[i].prec_prob = doc_YA["forecast"]["parts"][i]["prec_prob"].as<uint8_t>();
      weather.forecast.parts[i].pressure_mm = doc_YA["forecast"]["parts"][i]["pressure_mm"].as<uint16_t>();
      weather.forecast.parts[i].pressure_pa = doc_YA["forecast"]["parts"][i]["pressure_pa"].as<uint16_t>();
      weather.forecast.parts[i].temp_avg = doc_YA["forecast"]["parts"][i]["temp_avg"].as<int8_t>();
      weather.forecast.parts[i].temp_max = doc_YA["forecast"]["parts"][i]["temp_max"].as<int8_t>();
      weather.forecast.parts[i].temp_min = doc_YA["forecast"]["parts"][i]["temp_min"].as<int8_t>();
      weather.forecast.parts[i].temp_water = doc_YA["forecast"]["parts"][i]["temp_water"].as<uint8_t>();
      weather.forecast.parts[i].wind_dir = doc_YA["forecast"]["parts"][i]["wind_dir"].as<const char *>();
      weather.forecast.parts[i].wind_gust = doc_YA["forecast"]["parts"][i]["wind_gust"].as<float>();
      weather.forecast.parts[i].wind_speed = doc_YA["forecast"]["parts"][i]["wind_speed"].as<float>();
    }
    weather.forecast.sunrise = doc_YA["forecast"]["sunrise"].as<const char *>();
    weather.forecast.sunset = doc_YA["forecast"]["sunset"].as<const char *>();
    weather.forecast.week = doc_YA["forecast"]["week"].as<uint8_t>();
    weather.info.lat = doc_YA["info"]["lat"].as<float>();
    weather.info.lon = doc_YA["info"]["lon"].as<float>();
    weather.info.url = doc_YA["info"]["url"].as<const char *>();
    weather.now = doc_YA["now"].as<int>();
    weather.now_dt = doc_YA["now_dt"].as<const char *>();
    return true;
  }
} // end decode_json


/*-------------- Weather code -------------------------*/
bool get_YA_Weather()                  // запрос погоды с яндекс
{
  bool flag_weater;
  if (WiFi.status() == WL_CONNECTED) { // проверяем соединение WiFi
    HTTPClient http;                   // Отправляем HTTP GET запрос
    String _host = "api.weather.yandex.ru";
    // String _uri = "/v2/informers?lat=44.228376&lon=42.048277";// + String(lat, 6) + "&lon=" + String(lon, 6);
    String _uri = "/v2/informers?lat=" + String(lat, 6) + "&lon=" + String(lon, 6);

    Serial.println();
    Serial.print("Строка запроса: ");
    Serial.println(_uri);

    WiFiClient client;
    client.stop();
    http.begin(client, _host, 80, _uri, true);
    // http.addHeader("X-Yandex-API-Key", "796b0bc4-1337-4f34-ba6f-a56db2f0bfde");   // Key#1
    http.addHeader("X-Yandex-API-Key", "bb82ec4c-726d-4a5c-9a43-ce78cdaade5a");// ); // Key#2
    int httpCode = http.GET();

    if (httpCode > 0) {
      String response = http.getString();
      Serial.println("Ответ яндекса  ");
      printStr(response);       //выводим ответ yandex
      decode_json(response);    // парсинг данных из JsonObject

#ifdef  Serial_Print        //  отладка      
      Serial.println(" - - fact - - ");
      Serial.println(get_description_condition(weather.fact.condition));
      Serial.println(weather.fact.daytime);
      Serial.println(weather.fact.feels_like);
      Serial.println(weather.fact.humidity);
      Serial.println(weather.fact.icon);
      Serial.println(convert_unix_time(weather.fact.obs_time));
      Serial.println(weather.fact.polar);
      Serial.println(weather.fact.pressure_mm);
      Serial.println(weather.fact.pressure_pa);
      Serial.println(getSeason(weather.fact.season));
      Serial.println(weather.fact.temp);
      Serial.println(weather.fact.temp_water);
      Serial.println(weather.fact.wind_dir);
      Serial.println(weather.fact.wind_gust);
      Serial.println(weather.fact.wind_speed);
      Serial.println(" - - forecast - - ");
      Serial.println(weather.forecast.date);
      Serial.println(convert_unix_time(weather.forecast.date_ts));
      Serial.println(weather.forecast.moon_code);
      Serial.println(weather.forecast.moon_text);
      for (uint8_t i = 0; i < 2; i++)
      {
        Serial.print(" - - part: = "); Serial.println(i);
        Serial.println(get_description_condition(weather.forecast.parts[i].condition));
        Serial.println(weather.forecast.parts[i].daytime);
        Serial.println(weather.forecast.parts[i].feels_like);
        Serial.println(weather.forecast.parts[i].humidity);
        Serial.println(weather.forecast.parts[i].icon);
        Serial.println(get_partName(weather.forecast.parts[i].part_name));
        Serial.println(weather.forecast.parts[i].polar);
        Serial.println(weather.forecast.parts[i].prec_mm);
        Serial.println(weather.forecast.parts[i].prec_period);
        Serial.println(weather.forecast.parts[i].prec_prob);
        Serial.println(weather.forecast.parts[i].pressure_mm);
        Serial.println(weather.forecast.parts[i].pressure_pa);
        Serial.println(weather.forecast.parts[i].temp_avg);
        Serial.println(weather.forecast.parts[i].temp_max);
        Serial.println(weather.forecast.parts[i].temp_min);
        Serial.println(weather.forecast.parts[i].temp_water);
        Serial.println(weather.forecast.parts[i].wind_dir);
        Serial.println(weather.forecast.parts[i].wind_gust);
        Serial.println(weather.forecast.parts[i].wind_speed);
      } //for
      Serial.println(" - - forecast - - ");
      Serial.println(weather.forecast.sunrise);
      Serial.println(weather.forecast.sunset);
      Serial.println(weather.forecast.week);
      Serial.println(" - - info - - ");
      Serial.println(weather.info.lat, 6);
      Serial.println(weather.info.lon, 6);
      Serial.println(weather.info.url);
      Serial.println(" - - now - - ");
      //	  Serial.println(weather.now);
      Serial.println(convert_unix_time(weather.now));
      Serial.println(weather.now_dt);
#endif
      client.stop();
      http.end();
      flag_weater = true;
      //return true;
      //flag_weater = true;
    }
    else
    {
      Serial.println("Connection failed");
      client.stop();
      http.end();
      flag_weater = false;
      //return false;
      //flag_weater = false;
    }
  }
  return flag_weater;
  //return true;
} // end getWeather


/*-------------- NTP code -------------------------*/
// https://wikihandbk.com/wiki/Arduino:%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B/TimeNTP_ESP8266WiFi
const int NTP_PACKET_SIZE = 48;      // NTP-время – в первых 48 байтах сообщения
byte packetBuffer[NTP_PACKET_SIZE];  // буфер для хранения входящих и исходящих пакетов
// отправляем NTP-запрос серверу времени по указанному адресу:
void sendNTPpacket(IPAddress &address)
{
  // задаем все байты в буфере на «0»:
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // инициализируем значения для создания NTP-запроса (подробнее о пакетах смотрите по ссылке выше)
  packetBuffer[0] = 0b11100011;   // LI (от «leap indicator», т.е. «индикатор перехода»), версия, режим работы
  packetBuffer[1] = 0;     // слой (или тип часов)
  packetBuffer[2] = 6;     // интервал запросов
  packetBuffer[3] = 0xEC;  // точность
  // 8 байтов с нулями, обозначающие базовую задержку и базовую дисперсию:
  packetBuffer[12] = 49;
  packetBuffer[13] = 0x4E;
  packetBuffer[14] = 49;
  packetBuffer[15] = 52;
  // После заполнения всех указанных полей можно отправлять пакет с запросом о временной метке:
  Udp.beginPacket(address, 123); //  NTP-запросы к порту 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
} // end sendNTPpacket

time_t getNtpTime()
{
  IPAddress ntpServerIP; // IP-адрес NTP-сервера
  while (Udp.parsePacket() > 0) ; // отбраковываем все пакеты, полученные ранее
  Serial.println("Transmit NTP Request"); //  "Передача NTP-запроса"
  WiFi.hostByName(ntpServerName, ntpServerIP);   //  подключаемся к случайному серверу из списка:
  Serial.print(ntpServerName);
  Serial.print(": ");
  Serial.println(ntpServerIP);
  sendNTPpacket(ntpServerIP);
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500) {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE) {
      Serial.println("Receive NTP Response"); // "Получение NTP-ответа"
      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // считываем пакет в буфер
      unsigned long secsSince1900;
      //конвертируем 4 байта (начиная с позиции 40) в длинное целое число:
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
    }
  }
  Serial.println("No NTP Response :-("); //  "Нет NTP-ответа :("
  return 0; // если время получить не удалось, возвращаем «0»
} // end getNtpTime
2 лайка