Часы с погодой (10 модуле MAX7219 (2 ряда по 5) + DS3231

Нет ответов
dronixon
Offline
Зарегистрирован: 21.05.2018

Ребята помогите подправить скетч пжлста. Проблема в том что бегущая строка должна работать так - [b][size=150]Дата[/size][/b] \ [b][size=150]Погода сейчас[/size][/b] \ [b][size=150]Погода завтра[/size][/b]. Проблема в том, что [b][size=150]Дата бежит 3 раза[/size][/b] и [b][size=150]Погода завтра 3 раза[/size][/b] , а [size=150][b]Погода сейчас[/b][/size] нормально 1 раз. Помогите неумеке.  :smile37:

/**
* Часы и информер погоды на матричном дисплее 16x32
* 
* Контроллер ESP8266F (4Мбайт)
* Графический экран 16x32 на 8 матрицах MAX8219
* 
* Copyright (C) 2016 Алексей Шихарбеев
* http://samopal.pro
*/
#include <arduino.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h> 
#include <ESP8266HTTPClient.h>
#include <WiFiUdp.h>
#include <SPI.h>

//****************************************
//  CLK_PIN     D5 // or SCK
//  DATA_PIN    D7 // or MOSI
//  CS_PIN      D6 // or SS
//****************************************
//ds3231---------------------------------------------
#include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h>
RtcDS3231<TwoWire> Rtc(Wire);
/*
  ++++++++++++++++++++++++++++++++++++
  подключение часов реального времени:
  ds3231    esp8266
   SCL   ->   D1
   SDA   ->   D2
  ++++++++++++++++++++++++++++++++++++
*/
//ds3231--------------------------------------------
/*
  ++++++++++++++++++++++++++++++++++++
  подключение бузера:
  бузер    esp8266
   +   ->   D8
   -   ->   GRD
  ++++++++++++++++++++++++++++++++++++
*/

// https://github.com/adafruit/Adafruit-GFX-Library
#include <Adafruit_GFX.h>
// https://github.com/markruys/arduino-Max72xxPanel
#include <Max72xxPanel.h>
//https://github.com/bblanchon/ArduinoJson
#include <ArduinoJson.h>

const unsigned char logo2 [] PROGMEM = {
0xff, 0xff, 0xdf, 0xfd, 0xcf, 0xf9, 0xc7, 0xf1, 0xc0, 0x01, 0xe0, 0x03, 0xe0, 0x03, 0xc2, 0x11, 
0xc7, 0x39, 0xc2, 0x11, 0x80, 0x01, 0x00, 0xc1, 0x00, 0x03, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0f };

const unsigned char wifi_icon [] PROGMEM = {0x07, 0xfb, 0xfd, 0x1e, 0xee, 0xf6, 0x36, 0xb6 };

const unsigned char digit0 [] PROGMEM = {  0x83,0x01,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x01,0x83 };
const unsigned char digit1 [] PROGMEM = {  0xF7,0xE7,0xC7,0x87,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0x81,0x81 };
const unsigned char digit2 [] PROGMEM = {  0x83,0x01,0x39,0xF9,0xF9,0xF9,0xF3,0xE3,0xC7,0x8F,0x1F,0x3F,0x01,0x01 };
const unsigned char digit3 [] PROGMEM = {  0x83,0x01,0x39,0xF9,0xF9,0xF9,0xE3,0xE3,0xF9,0xF9,0xF9,0x39,0x01,0x83 };
const unsigned char digit4 [] PROGMEM = {  0xF3,0xE3,0xC3,0xC3,0x93,0x93,0x33,0x33,0x01,0x01,0xF3,0xF3,0xF3,0xF3 };
const unsigned char digit5 [] PROGMEM = {  0x01,0x01,0x3F,0x3F,0x3F,0x03,0x01,0xF9,0xF9,0xF9,0xF9,0x39,0x01,0x83 };
const unsigned char digit6 [] PROGMEM = {  0x83,0x01,0x39,0x3F,0x3F,0x03,0x01,0x39,0x39,0x39,0x39,0x39,0x01,0x83};
const unsigned char digit7 [] PROGMEM = {  0x01,0x01,0xF9,0xF9,0xF9,0xF1,0xF3,0xE3,0xE7,0xCF,0xCF,0x9F,0x9F,0x9F };
const unsigned char digit8 [] PROGMEM = {  0x83,0x01,0x39,0x39,0x39,0x83,0x83,0x39,0x39,0x39,0x39,0x39,0x01,0x83 };
const unsigned char digit9 [] PROGMEM = {  0x83,0x01,0x39,0x39,0x39,0x39,0x39,0x01,0x81,0xF9,0xF9,0x39,0x01,0x83 };

String weatherDescription = "";
// Параметры доступа к WiFi
const char W_SSID[] = "TP-LINK_9D246C"; //Точка доступа WiFi
const char W_PASS[] = "DRONIXON"; //Пароль Точки доступа WiFi
// Параметры погодного сервера
String     W_URL    = "http://api.openweathermap.org/data/2.5/weather";
//IPPID. Получить бесплатно: http://openweathermap.org/appid#get
String     W_API    = "cae303e3f280df249ce14db259cb7aa5"; //Ключ openweathermap.org
// Код города  на сервере openweathermap.org
// Ростов = 501175
// Остальные города можно посмотреть http://bulk.openweathermap.org/sample/city.list.json.gz
String     W_ID     = "501175";
//String     W_NAME   = "В Ростове ";

WiFiUDP udp;
const int NTP_PACKET_SIZE = 48; 
byte packetBuffer[ NTP_PACKET_SIZE]; 
const char NTP_SERVER[]   = "0.ru.pool.ntp.org";          
int TZ                    = 3;//Таймзона для Ростова
uint32_t NTP_TIMEOUT      = 600000; //10 минут
uint32_t WEATHER_TIMEOUT  = 600000;  //10 минут
float windSpeed;
String tempz;
String weatherStringz;
String weatherStringz1;
String dataString;
String pressureString;

static const uint8_t monthDays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
#define LEAP_YEAR(Y) (((1970 + Y) > 0 ) && !((1970 + Y) % 4) && (((1970 + Y) % 100) || !((1970 + Y) % 400)))
int hour = 7, minute = 52, second = 0, month = 6, day = 14,dayOfWeek = 4;
int year = 2017;
bool statusUpdateNtpTime = 0;
String y, mon, wd, d, h, m, s, mes;

const int SoundPin    = 15 ;
boolean Biper_ = 0;
bool day_night;
bool Brightnes_=0;
bool Bright_fl=0;

int pinCS = 12; //  D6 Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI )
int numberOfHorizontalDisplays = 5;
int numberOfVerticalDisplays   = 2;

Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

int disp = 1;
String tape = "";
int wait = 18; // In milliseconds

int spacer = 1;
int width = 5 + spacer; // The font width is 5 pixels

uint32_t ms, ms0=0, ms1=0, ms2=0, ms3=0, ms_mode=0;
uint32_t tm         = 0;
uint32_t t_cur      = 0;    
long  t_correct     = 0;
bool  pp = false;
int   mode = 0;

void setup() {
   Serial.begin(115200);
//ds3231---------------------------------------------
 // Serial.print("compiled: ");
 // Serial.print(__DATE__);
//  Serial.println(__TIME__);

  //--------RTC SETUP ------------

  Rtc.Begin();
  Rtc.Begin();
  Rtc.Enable32kHzPin(false);
  Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
  //ds3231---------------------------------------------

 
// Настройка дисплея
    matrix.setIntensity(0); // Use a value between 0 and 15 for brightness

// Порядок матриц
    matrix.setPosition(0, 4, 1); // The first display is at <0, 0>
    matrix.setPosition(1, 3, 1); // The first display is at <0, 0>
    matrix.setPosition(2, 2, 1); // The first display is at <0, 0>
    matrix.setPosition(3, 1, 1); // The first display is at <0, 0>
    matrix.setPosition(4, 0, 1); 
    matrix.setPosition(5, 0, 0); // The first display is at <0, 0>
    matrix.setPosition(6, 1, 0); // The first display is at <0, 0>
    matrix.setPosition(7, 2, 0); // The first display is at <0, 0>
    matrix.setPosition(8, 3, 0); // The first display is at <0, 0>
    matrix.setPosition(9, 4, 0);
// Ориентация каждой матрицы
   matrix.setRotation(0, 3);    // The first display is position upside down
   matrix.setRotation(1, 3);    // The first display is position upside down
   matrix.setRotation(2, 3);    // The first display is position upside down
   matrix.setRotation(3, 3);    // The first display is position upside down
   matrix.setRotation(4, 3);    // The first display is position upside down
   matrix.setRotation(5, 1);    // The first display is position upside down
   matrix.setRotation(6, 1);    // The first display is position upside down
   matrix.setRotation(7, 1);    // The first display is position upside down
   matrix.setRotation(8, 1);
   matrix.setRotation(9, 1);
   
   matrix.fillScreen(LOW);

   
   matrix.drawBitmap(0, 0,  logo2, 16, 16, 0, 1); 

   matrix.write();
   delay(500); 
// Содиняемся с WiFi
  Serial.print("\nConnecting to ");
  Serial.println(W_SSID);

  WiFi.begin(W_SSID, W_PASS);
  for (int i=0;WiFi.status() != WL_CONNECTED&&i<150; i++) {
     Serial.print(".");
// Мигаем значком WiFi
     matrix.drawBitmap(20, 4,  wifi_icon, 8, 8, 0, 1); 
     matrix.write();
     delay(50);
     matrix.fillRect(20, 4, 8, 8, LOW);  
     matrix.write();
     delay(50);
  }
/*
// Содиняемся с WiFi
  Serial.print("\nConnecting to ");
  Serial.println(W_SSID);
  WiFi.begin(W_SSID1, W_PASS1);
  for (int i=0;WiFi.status() != WL_CONNECTED&&i<15; i++) {
     Serial.print(".");
// Минаем значком WiFi
     matrix.drawBitmap(20, 4,  wifi_icon, 8, 8, 0, 1); 
     matrix.write();
     delay(500);
     matrix.fillRect(20, 4, 8, 8, LOW);  
     matrix.write();
     delay(500);
  }
*/




// Выдаем значек WiFi
   matrix.drawBitmap(20, 4,  wifi_icon, 8, 8, 0, 1); 
   matrix.write();

  Serial.println("\nWiFi connected\nIP address: ");
  Serial.println(WiFi.localIP());
  Serial.println();
   
   ms_mode = millis();
    Serial.print("millis = ");
    Serial.println(millis());
// Cоединение для NTP   
   udp.begin(2390);
}
int i_ms0 = 0;



void loop() {
   ms = millis();

 // Опрос NTP сервера
   if(  ms3 == 0 || ms < ms3 || (ms - ms3)>NTP_TIMEOUT ){
       uint32_t t = GetNTP();
       if( t!=0 ){
          ms3 = ms;
          t_correct = t - t_cur;
       }
      // Serial.println(t);
   }  
  
//*********************************************************************
 RtcDateTime now = Rtc.GetDateTime();
  // Яркость дисплея
   if (((now % 3600) / 60) == 0) {
    Biper();
    Brightnes_ = 0;
   }
    else {
     Biper_ = 1; 
     Bright_fl = 0;
    }
     
    int h = (int)( now/3600 )%24;
//hour = (epoch % 86400L) / 3600;
   // minute = (epoch % 3600) / 60;
   // second = epoch % 60;
   if ( Brightnes_ == 0 && Bright_fl == 0 ) {
    if (h >= 8 && h < 22 ) {
      matrix.setIntensity(10);
       day_night = 1;
       Brightnes_ = 1;
       Bright_fl = 1;
      Serial.println("время суток - день");
     }
      
    
    else {
       matrix.setIntensity(0);
     day_night = 0;
      Serial.println("время суток - ночь");
    }
  }
//***********************************************************************************************************
// Цикл бегущей строки   

   if( ms0 == 0 || ms < ms0 || (ms - ms0)>wait ){
       ms0 = ms;
       switch(mode){
           case 0:
           case 1:
           case 3:
           case 4:              
           case 5:              
              break;
           default:
              PrintTicker();
       }
       
   }
   if( ms1 == 0 || ms < ms1 || (ms - ms1)>WEATHER_TIMEOUT ){
       ms1 = ms;
       GetWeather();
       GetWeatherDataz();
      
      tape = dataString + " \x0b3"+ "\x0b3 " + tape + " \x0b3"+ "\x0b3 " + weatherStringz;

   }


   
// Показ часов
  if( ms2 == 0 || ms < ms2 || (ms - ms2)>500 ){
       ms2 = ms;
       t_cur  = ms/1000;
       tm     = t_cur + t_correct;
       switch(mode){
           case 0:
           case 1:
           case 4:              
           case 5:              
              PrintBigTime();
              matrix.fillScreen(LOW);
              break;
           default:
              PrintTime();
}
  
}
      
}

/**
 * Печать времени
 */
void PrintTime(){
    char s[20];
   // matrix.fillRect(6, 0, 40, 8, LOW);  
    matrix.fillRect(0, 0, 40, 8, LOW);
     
    RtcDateTime now = Rtc.GetDateTime();
     
    if( pp )sprintf(s, "%02d:%02d", (int)( now/3600 )%24, (int)( now/60 )%60);
    else sprintf(s, "%02d %02d", (int)( now/3600 )%24, (int)( now/60 )%60);
    
 //   if( pp )sprintf(s, "%02d:%02d", (int)( tm/3600 )%24, (int)( tm/60 )%60);
 //   else sprintf(s, "%02d %02d", (int)( tm/3600 )%24, (int)( tm/60 )%60);
    pp = !pp;
    matrix.setCursor(6, 0);
    matrix.print(s);
    ms_mode = ms;
   
  //Serial.print("pp = ");
 //  Serial.println(pp);
  // Serial.print("!pp = ");
 //  Serial.println(!pp);
}

/**
 * Печать времени большими цифрами
 */
void PrintBigTime(){
    char s[20];
    matrix.fillScreen(LOW);  
     RtcDateTime now = Rtc.GetDateTime();
    int h = (int)( now/3600 )%24;
    int m = (int)( now/60 )%60;
    PrintBigDigit(3,1,h/10);
    PrintBigDigit(11,1,h%10);
    PrintBigDigit(22,1,m/10);
    PrintBigDigit(30,1,m%10);
    if( pp ){
      matrix.fillRect(19, 4,  2, 2, HIGH);
      matrix.fillRect(19, 9, 2, 2, HIGH);
    }
    
    pp = !pp;
    matrix.write();
         
    if( ms -ms_mode > 15000){
         mode++;
       
         if( mode >= 8 )mode = 0;
         ms_mode = ms;
             
         
    }
    
}

/**
 * Печать большой цифры
 */
 void PrintBigDigit(int x, int y, int dig){
    switch(dig){
      case 0  : matrix.drawBitmap(x, y,  digit0, 7, 14, 0, 1); break;
      case 1  : matrix.drawBitmap(x, y,  digit1, 7, 14, 0, 1); break;
      case 2  : matrix.drawBitmap(x, y,  digit2, 7, 14, 0, 1); break;
      case 3  : matrix.drawBitmap(x, y,  digit3, 7, 14, 0, 1); break;
      case 4  : matrix.drawBitmap(x, y,  digit4, 7, 14, 0, 1); break;
      case 5  : matrix.drawBitmap(x, y,  digit5, 7, 14, 0, 1); break;
      case 6  : matrix.drawBitmap(x, y,  digit6, 7, 14, 0, 1); break;
      case 7  : matrix.drawBitmap(x, y,  digit7, 7, 14, 0, 1); break;
      case 8  : matrix.drawBitmap(x, y,  digit8, 7, 14, 0, 1); break;
      case 9  : matrix.drawBitmap(x, y,  digit9, 7, 14, 0, 1); break;
    }
 }

/**'
 * Один такт бегущей строки
 */
void PrintTicker(){
//     matrix.setFont();
tape = utf8rus(tape);
     if( i_ms0 >= width * tape.length() + matrix.width() - 1 - spacer ){
         i_ms0 = 0;
         mode++;
         ms_mode = ms;
     if( mode >=3 )mode=0;
     }

//       for ( int i = 0 ; i < width * tape.length() + matrix.width() - 1 - spacer; i++ ) {
//         matrix.fillScreen(LOW);
         matrix.fillRect(0, 8, 40, 8, LOW);

         int letter = i_ms0 / width;
         int x = (matrix.width() - 1) - i_ms0 % width;
         int y = 8; // center the text vertically

         while ( x + width - spacer >= 0 && letter >= 0 ) {
            if ( letter < tape.length() ) {
               matrix.drawChar(x, y, tape[letter], HIGH, LOW, 1);
           }

         letter--;
         x -= width;
      }

      matrix.write(); // Send bitmap to display

//      delay(wait);
//      }
     i_ms0++;

  
}

/*
 * Перекодировка UTF8 в Windows-1251
 */
String utf8rus(String source)
{
  int i,k;
  String target;
  unsigned char n;
  char m[2] = { '0', '\0' };

  k = source.length(); i = 0;

  while (i < k) {
    n = source[i]; i++;

    if (n >= 0xC0) {
      switch (n) {
        case 0xD0: {
          n = source[i]; i++;
          if (n == 0x81) { n = 0xA8; break; }
//          if (n >= 0x90 && n <= 0xBF) n = n + 0x30;
          if (n >= 0x90 && n <= 0xBF) n = n + 0x2F;
          break;
        }
        case 0xD1: {
          n = source[i]; i++;
          if (n == 0x91) { n = 0xB8; break; }
//          if (n >= 0x80 && n <= 0x8F) n = n + 0x70;
          if (n >= 0x80 && n <= 0x8F) n = n + 0x6F;
          break;
        }
      }
    }
    m[0] = n; target = target + String(m);
  }
return target;
}

/**
 * Получаем погоду с погодного сервера
 */
void GetWeather(){
   HTTPClient client;
   String url = W_URL;
   url += "?id=";
   url += W_ID;
   url += "&APPID=";
   url += W_API;
   url += "&units=metric&lang=ru";
   Serial.println(url);
   client.begin(url);
   int httpCode = client.GET();
   if( httpCode == HTTP_CODE_OK ){
       String httpString = client.getString(); 
       ParseWeather(httpString);
   }
   client.end();

}

/**
 * Парсим погоду
 */
void ParseWeather(String s){
   DynamicJsonBuffer jsonBuffer;
   JsonObject& root = jsonBuffer.parseObject(s);
 Serial.print("сегодня = ");
   Serial.println(s);
   if (!root.success()) {
      Serial.println("Json parsing failed!");
      return;
   }
// Погода    
   tape = " Погода ";
// Температура   
 //  tape += " Tемпература ";
   float t = root["main"]["temp"].as<float>(); 
  
 float clouds = root["clouds"]["all"].as<float>();
//  Serial.print("clouds = ");
  // Serial.println(clouds);
   tape += String(t,1);
   tape += "\x080" ;
     tape += "C ";
    
//Осадки   
   //tape += root["weather"][0]["description"].as<String>();
   weatherDescription += root["weather"][0]["description"].as<String>();
   // Serial.print("Осадки  = ");
  // Serial.println(weatherDescription);
  if (weatherDescription == "снегопад") weatherDescription = "снег";
  if (weatherDescription == "небольшой снегопад") weatherDescription = "небольшой снег";
  if (weatherDescription == "легкий дождь") weatherDescription = "небольшой дождь";
  if (weatherDescription == "слегка облачно") weatherDescription = "малооблачно";
  if (weatherDescription == "умеренный дождь") weatherDescription = "дождь";
  if (weatherDescription == "туманно") weatherDescription = "небольшой туман";
   tape += weatherDescription ;
    
  
// Влажность   
//  tape += " Влажность ";
//  tape += root["main"]["humidity"].as<String>();
//  tape += "% Облачность " + String(clouds,1) + "% ";
// Давление   
//  tape += "Давление ";
//  double p = root["main"]["pressure"].as<double>()/1.33322;
// tape += String((int)p);
   tape += " Ветер ";
// Ветер   
  
   double deg = root["wind"]["deg"];
   if( deg >22.5 && deg <=67.5 )tape += "C-В ";
   else if( deg >67.5 && deg <=112.5 )tape += "В ";
   else if( deg >112.5 && deg <=157.5 )tape += "Ю-В ";
   else if( deg >157.5 && deg <=202.5 )tape += "Ю ";
   else if( deg >202.5 && deg <=247.5 )tape += "Ю-З ";
   else if( deg >247.5 && deg <=292.5 )tape += "З ";
   else if( deg >292.5 && deg <=337.5 )tape += "C-З ";
   else tape += "C ";
   float windSpeed = root["wind"]["speed"].as<float>();
   
   //tape += root["wind"]["speed"].as<String>(0);
  // tape += " м/сек";
   tape += String(windSpeed, 1) + " м/с " ;
// Перекодируем из UNICODE   
   tape = utf8rus(tape);
   s = ""; 
   weatherDescription = "" ;
    
}

 //*********************************************************************
 // DS3231
 //*********************************************************************
#define countof(a) (sizeof(a) / sizeof(a[0]))

void printDateTime(const RtcDateTime dt)
{
  char datestring[20]; snprintf_P(datestring, countof(datestring), PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
                                  dt.Month(),
                                  dt.Day(),
                                  dt.Year(),
                                  dt.Hour(),
                                  dt.Minute(),
                                  dt.Second() );
  Serial.print("datestring = ");
  Serial.println(datestring);
}
//*********************************************************************



// =======================================================================
// Берем ПРОГНОЗ!!! погоды с сайта openweathermap.org
// =======================================================================



void GetWeatherDataz(){
   HTTPClient client;
   String url = "http://api.openweathermap.org/data/2.5/forecast/daily?id=" + W_ID + "&units=metric&appid=" + W_API + "&lang=ru" + "&cnt=2";
  
   Serial.println(url);
   client.begin(url);
   int httpCode = client.GET();
   if( httpCode == HTTP_CODE_OK ){
       String httpString = client.getString(); 
       
       ParseWeather1(httpString);
   }
   client.end();
}
 void ParseWeather1(String s1){
   DynamicJsonBuffer jsonBuffer;
   JsonObject& root = jsonBuffer.parseObject(s1);
   Serial.print("Прогноз ответ = ");
   Serial.println(s1);
   if (!root.success()) {
      Serial.println("Json parsing failed!");
      return;
   }
 
 float lon = root ["city"]["coord"]["lon"].as<float>();
 float lat = root ["city"]["coord"]["lat"].as<float>();
   
  float wSpeed = root ["list"][1]["speed"].as<float>();
  int wDeg = root ["list"][1]["deg"].as<int>();
   Serial.print("ветер = ");
   Serial.println(wSpeed);
   Serial.println(wDeg);
  String zhakMin;
  String znakMax;
  float tempMin = root ["list"][1]["temp"]["min"].as<float>();
  if (tempMin > 0) zhakMin = "+";
  else zhakMin = "";

  float tempMax = root ["list"][1]["temp"]["max"].as<float>();
  if (tempMax > 0) znakMax = "+";
  else znakMax = "";
double p = root["list"][1]["pressure"].as<double>()/1.33322;
float clouds = root["list"][1]["clouds"].as<float>();   
   weatherDescription = root ["list"][1]["weather"][0]["description"].as<String>();
   Serial.print("погода=");
   Serial.println(weatherDescription); 
  if (weatherDescription == "снегопад") weatherDescription = "снег";
  if (weatherDescription == "небольшой снегопад") weatherDescription = "небольшой снег";
  if (weatherDescription == "легкий дождь") weatherDescription = "небольшой дождь";
  if (weatherDescription == "слегка облачно") weatherDescription = "малооблачно";
  if (weatherDescription == "умеренный дождь") weatherDescription = "дождь";
  if (weatherDescription == "туманно") weatherDescription = "небольшой туман";
  // weatherDescription += " ";
  weatherStringz = " Завтра от " + zhakMin + String(tempMin, 1) + " до " + znakMax + String(tempMax, 1) + "\x080" + "C ";
  // weatherStringz += weatherDescription;
  // weatherStringz += " Давление ";
  // weatherStringz += String((int)p);
  // weatherStringz += " мм.рт.ст ";
  //  weatherStringz += "Влажность ";
 //  weatherStringz += root["list"][0]["humidity"].as<String>();
  //  weatherStringz += "% " ;
 
  // weatherStringz += " Облачность " + String(clouds,1) + "%";
  String windDegString;

  if (wDeg >= 345 || wDeg <= 22) windDegString = "";
  if (wDeg >= 23 && wDeg <= 68) windDegString = "C-В";
  if (wDeg >= 69 && wDeg <= 114) windDegString = "В";
  if (wDeg >= 115 && wDeg <= 160) windDegString = "Ю-В";
  if (wDeg >= 161 && wDeg <= 206) windDegString = "Ю";
  if (wDeg >= 207 && wDeg <= 252) windDegString = "Ю-З";
  if (wDeg >= 253 && wDeg <= 298) windDegString = "З";
  if (wDeg >= 299 && wDeg <= 344) windDegString = "C-З";

   weatherStringz += " Ветер " + windDegString + " " + String(wSpeed, 1) + " м/с";
 // tape += weatherStringz;
//  tape = utf8rus(tape);
   
  weatherStringz = utf8rus(weatherStringz);
   s1 = ""; 
   weatherDescription = "" ;
 
}

  
  
// =======================================================================
/**
 * Посылаем и парсим запрос к NTP серверу
 */
time_t GetNTP(void) {
  IPAddress ntpIP;
  time_t tm = 0;
  WiFi.hostByName(NTP_SERVER, ntpIP); 
  sendNTPpacket(ntpIP); 
  delay(1000);
 
  int cb = udp.parsePacket();
  if (!cb) {
    return tm;
  }
  else {
// Читаем пакет в буфер    
    udp.read(packetBuffer, NTP_PACKET_SIZE); 
// 4 байта начиная с 40-го сождержат таймстамп времени - число секунд 
// от 01.01.1900   
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// Конвертируем два слова в переменную long
    unsigned long secsSince1900 = highWord << 16 | lowWord;
// Конвертируем в UNIX-таймстамп (число секунд от 01.01.1970
    const unsigned long seventyYears = 2208988800UL;
    unsigned long epoch = secsSince1900 - seventyYears;


// Делаем поправку на местную тайм-зону
     
    tm = epoch + TZ*3600;  
    epoch = tm;      
    year = 0;
    int days = 0;
    uint32_t time;
    time = epoch / 86400;
    hour = (epoch % 86400L) / 3600;
    minute = (epoch % 3600) / 60;
    second = epoch % 60;
    dayOfWeek = (((time) + 4) % 7) + 1;
    while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
      year++; 
   }
   days -= LEAP_YEAR(year) ? 366 : 365;
    time -= days;
    days = 0;
    month = 0;
    uint8_t monthLength = 0;
    for(month = 0; month < 12; month++) {
      if(month == 1) {
        if(LEAP_YEAR(year)) monthLength = 29;
        else monthLength = 28;
      }
      else monthLength = monthDays[month];
      if(time >= monthLength) time -= monthLength;
      else break;
    }
    month = month + 1;
    day = time + 1;
    year += 1970;
   }
    if (month == 1) mon = "января";
    if (month == 2) mon = "февраля";
    if (month == 3) mon = "марта";
    if (month == 4) mon = "апреля";
    if (month == 5) mon = "мая";
    if (month == 6) mon = "июня";
    if (month == 7) mon = "июля";
    if (month == 8) mon = "августа";
    if (month == 9) mon = "cентября";
    if (month == 10) mon = "октября";
    if (month == 11) mon = "ноября";
    if (month == 12) mon = "декабря";

    if (dayOfWeek == 2) wd = "Понедельник";
    if (dayOfWeek == 3) wd = "Вторник";
    if (dayOfWeek == 4) wd = "Cреда";
    if (dayOfWeek == 5) wd = "Четверг";
    if (dayOfWeek == 6) wd = "Пятница";
    if (dayOfWeek == 7) wd = "Cуббота";
    if (dayOfWeek == 1) wd = "Воскресенье";
     dataString = " Cегодня " + wd + " " + String(day) + " " + mon + " " + String(year) + " г. " ;
     dataString = utf8rus(dataString);

  RtcDateTime compiled = RtcDateTime(year, month, day, hour, minute, second);
  if (!Rtc.IsDateTimeValid()) 
    {
     Serial.println("RTC потерял доверие к DateTime!");

      Rtc.SetDateTime(compiled);
    }

    if (!Rtc.GetIsRunning())
    {
        Serial.println("RTC не был активно запущен, начиная с этого момента");
        Rtc.SetIsRunning(true);
    }

    RtcDateTime now = Rtc.GetDateTime();
    
   // Serial.print("now = ");
   // Serial.println(now);
  //  Serial.print("compiled = ");
   // Serial.println(compiled);
   
    if (now !=  compiled) 
    {
        Serial.println("Время модуля отличается от времени сервера  (Синхронизируем время)");
        Rtc.SetDateTime(compiled);
    }
   // else if (now > compiled) 
   // {
   //     Serial.println("RTC новее, чем время компиляции. (это ожидается)");
  //      Rtc.SetDateTime(compiled);
  //  }
    else if (now == compiled) 
    {
        Serial.println("Время модуля соответствует  времени сервера (Синхронизация  не нужна)");
    }
    printDateTime(now);

//   Serial.print("month = ");
 //  Serial.println(mon);
 // Serial.print("day = ");
 //  Serial.println(day);
 //  Serial.print("year = ");
//   Serial.println( year);
  //  Serial.print("dayOfWeek = ");
 //  Serial.println(wd);
   
 //  Serial.print("hour = ");
 //  Serial.println( (tm  % 86400L) / 3600);
 // Serial.print("minute = ");
  // Serial.println((tm  % 3600) / 60);
 //  Serial.print("second = ");
 //  Serial.println( tm  % 60);
    
   
  return tm;
}


/**
 * Посылаем запрос NTP серверу на заданный адрес
 */
unsigned long sendNTPpacket(IPAddress& address)
{
// Очистка буфера в 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Формируем строку зыпроса NTP сервера
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
 // Посылаем запрос на NTP сервер (123 порт)
  udp.beginPacket(address, 123); 
  udp.write(packetBuffer, NTP_PACKET_SIZE);
  udp.endPacket();
}
//==========================================================
void Biper() {
  if (day_night == 1 && Biper_ == 1 ) {
    tone(SoundPin, 1000);//////////////////////////////////////////////////////////////////////////////////////////////////////
    delay(1000);
    noTone(SoundPin);//////////////////////////////////////////////////////////////////////////////////////////////////////
    Biper_ = 0;
  } 
}
// =======================================================================