Wi-Fi Интернет-Часы с погодой на ESP8266 (nodemcu) и десяти светодиодных матрицах 8х8 с драйвером MAX7219

Ответить
Сергей
Сообщения: 4
Зарегистрирован: Вт ноя 28, 2017 6:58 pm

Wi-Fi Интернет-Часы с погодой на ESP8266 (nodemcu) и десяти светодиодных матрицах 8х8 с драйвером MAX7219

Сообщение Сергей » Вт апр 24, 2018 8:55 pm

Часто просыпаюсь ночью, гляну время и дальше пытаюсь спать, и так раз по 5-7 за ночь. Надоело вглядываться в маленькие часики ночью. А ещё надоели часики с микросхемой DS1302/DS1307, которые постоянно надо подстраивать.

Пробовал делать на DS3231, работают точно! Ну и решил сделать большие и точные часы, которые было бы видно одним полуоткрытым глазом :)

В наличии были модули на ESP8266 типа "бутерброд" и NodeMCU v3 Lua, остановился на втором. А поскольку эти модули просто созданы для подключения к Wi-Fi, то появилась задумка синхронизировать время с NTP серверами через интернет. Потом и вовсе решил отказаться от использования RTC модуля на DS3231.

В качестве дисплея выбрал светодиодные матрицы 8х8 с драйвером MAX7219, на алиекспрессе они имеются в виде годовых/полуготовых модулей. Долго думал, из скольки модулей собирать, в сети много проектов 1х3, 1х4 модулей (8х24, 8х32 точек), маловато! Нашёл проект 2х4 (16х32 точек) (найду - дам ссылку), размер уже боле-менее!

В наличии была одна матрица из набора Arduino без драйвера, всё, на что она сгодилась - прикинуть размер экрана :)
Порылся на Алиекспрессе, если заказывать сразу десяток штук - выходит дешевле, чем поштучно 8 штук оО Ну и сразу обрисовался размер дисплея! 2х5 (16х40 точек) :D

Что получилось - смотрите на видео!



По Wi-Fi конектится к роутеру, получает с интернета время (раз в минуту, можно настроить) и погоду.

Десять одинарных модулей (Микросхему нужно паять самостоятельно

Десять одинарных модулей (микросхемы распаяны, но немного подороже)

CH340 nodemcu V3 Lua WI-FI

Наверно зимой доделаю часики, в планах нарисовать одностороннюю плату (кое-чего накидал в SprintLayout ещё прошлой зимой), впаять туда все модули-матрицы, со стороны фольги впаять отдельный (голый) модуль ESP8266 (ESP-12F).

Но что то задумался... Есть матричные модули зелёного цвета, сразу 10 модулей по 4 шт Может спаять большой экран 10х4 из зелёных матриц, а те 10 красных, что есть - поставить одной строкой снизу. Но это придётся делать большую плату, да и корпус на 3Д принтере печатать придётся из частей. Пока думаю...

Код писал в Arduino IDE. За основу был взят код из проекта 16х32 с samopal.pro

Код: Выделить всё

//#include <Time.h>
#include <TimeLib.h>
#include <arduino.h>
#include <ESP8266WiFi.h>

#include <WiFiClient.h> 
#include <ESP8266HTTPClient.h>
#include <WiFiUdp.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
MDNSResponder mdns;
ESP8266WebServer server(80);
String webPage = "";
#include <SPI.h>

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

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,0xE7,0x81 };
const unsigned char digit2 [] PROGMEM = {  0x83,0x01,0x39,0x39,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,0x31,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 };

const unsigned char m_digit0 [] PROGMEM = { B01100000, B10010000, B10010000, B10010000, B10010000, B10010000, B01100000};
const unsigned char m_digit1 [] PROGMEM = { B00100000, B01100000, B10100000, B00100000, B00100000, B00100000, B11110000};
const unsigned char m_digit2 [] PROGMEM = { B01100000, B10010000, B00010000, B00100000, B01000000, B10000000, B11110000};
const unsigned char m_digit_sep [] PROGMEM = { B00000000, B11100000, B00000000, B00000000, B11100000};

const unsigned char ms_digit0 [] PROGMEM = { B01100000, B10010000, B10010000, B10010000, B01100000};
const unsigned char ms_digit1 [] PROGMEM = { B00100000, B01100000, B00100000, B00100000, B01110000};
const unsigned char ms_digit2 [] PROGMEM = { B01100000, B10010000, B00100000, B01000000, B11110000};
const unsigned char ms_digit3 [] PROGMEM = { B01100000, B00010000, B00100000, B00010000, B01100000};
const unsigned char ms_digit4 [] PROGMEM = { B00100000, B01100000, B10100000, B11110000, B00100000};
const unsigned char ms_digit5 [] PROGMEM = { B11110000, B10000000, B11100000, B00010000, B11100000};
const unsigned char ms_digit6 [] PROGMEM = { B01100000, B10000000, B11100000, B10010000, B01100000};
const unsigned char ms_digit7 [] PROGMEM = { B11110000, B00010000, B00100000, B01000000, B01000000};
const unsigned char ms_digit8 [] PROGMEM = { B01100000, B10010000, B01100000, B10010000, B01100000};
const unsigned char ms_digit9 [] PROGMEM = { B01100000, B10010000, B01110000, B00010000, B01100000};

// Параметры доступа к WiFi
const char W_SSID[] = "Имя точки доступа";
const char W_PASS[] = "пароль к точке доступа";

// Параметры погодного сервера
String     W_URL    = "http://api.openweathermap.org/data/2.5/weather";
String     W_API    = "8у3c8537ed0c00eа62f83с880b423376"; //IPPID. Получить бесплатно: http://openweathermap.org/appid#get
// Код города на сервере openweathermap.org
// Москва = 524901, Челябинск = 1508291
// Остальные города можно посмотреть http://bulk.openweathermap.org/sample/city.list.json.gz
String     W_ID     = "1508291";
String     W_NAME   = "В Челябинске ";

// Параметры NTP сервера
WiFiUDP udp;
const int NTP_PACKET_SIZE = 48; 
byte packetBuffer[ NTP_PACKET_SIZE]; 
const char NTP_SERVER[]   = "0.ru.pool.ntp.org";          
int TZ                    = 5;//Таймзона для Челябинска
uint32_t NTP_TIMEOUT      = 600000; //10 минут

// Подключение экрана
// Если голый модуль:     DIN -> GPIO_13 (MOSI), CLK -> GPIO_14 (SCK), CS -> GPIO_0 (задан параметром pinCS)
// Для модуля NodeMCU V3: DIN -> D7pin (MOSI),   CLK -> D5pin (SCK),   CS -> D3pin
int pinCS = 0; // 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);

// Настройка бегущей строки
String tape_weather = "";
String tape_date = "";
byte wait = 40; // Задержка бегущей строки в мс (меньше число - больше скорость)
byte spacer = 1;// Разделитель между буквами в 1 пиксел
byte width = 5 + spacer; // The font width is 5 pixels

uint32_t i_ms0 = 0;
uint32_t ms, ms0=0, ms1=0, ms2=0, ms3=0, ms4=0, ms_mode=0;
uint32_t tm         = 0;
uint32_t t_cur      = 0;    
long  t_correct     = 0;
bool  pp = false; // Флаг разделителя часы/минуты (1Гц)
byte  mode = 0;
bool  clear_flag = false;

void setup() {
  // Просто тестовая HTML страничка, доступная в браузере по IP адресу устройства.
  webPage += "<!DOCTYPE html>\n<html>\n<head>\n<title>ESP8266 LED Matrix Clock</title>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />";
  webPage += "\n</head>\n<body>";
  webPage += "<h1>ESP8266 LED Matrix Clock</h1><p>Socket #1 <a href=\"socket1On\"><button>ON</button></a>&nbsp;<a href=\"socket1Off\"><button>OFF</button></a></p>";
  webPage += "<p>Socket #2 <a href=\"socket2On\"><button>ON</button></a>&nbsp;<a href=\"socket2Off\"><button>OFF</button></a></p>";
  webPage += "\n</body>\n</html>";
  
  Serial.begin(115200);
// Настройка дисплея
  matrix.setIntensity(0); // Яркость экрана (от 0 до 15)
// Порядок матриц (порядковый номер матрицы, позиция модуля в экране по Х, позиция модуля в экране по Y)
  matrix.setPosition(0, 5, 0); 
  matrix.setPosition(1, 6, 0); 
  matrix.setPosition(2, 7, 0); 
  matrix.setPosition(3, 8, 0); 
  matrix.setPosition(4, 9, 0); 
  matrix.setPosition(5, 0, 1); 
  matrix.setPosition(6, 1, 1); 
  matrix.setPosition(7, 2, 1);
  matrix.setPosition(8, 3, 1); 
  matrix.setPosition(9, 4, 1);
// Ориентация матриц (порядковый номер матрицы, количество поворотов на 90 градусов)
  matrix.setRotation(0, 1);    
  matrix.setRotation(1, 1);
  matrix.setRotation(2, 1);
  matrix.setRotation(3, 1);
  matrix.setRotation(4, 1);
  matrix.setRotation(5, 1);   
  matrix.setRotation(6, 1);
  matrix.setRotation(7, 1);
  matrix.setRotation(8, 1);
  matrix.setRotation(9, 1);

  matrix.fillScreen(LOW); // Очищаем экран
  delay(500); // Ждем пол секунды
// Содиняемся с WiFi
  Serial.print("\nConnecting to ");
  Serial.println(W_SSID); // Выводим в монитор порта имя точки доступа
  WiFi.mode(WIFI_STA);
  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(250);
    matrix.fillRect(20, 4, 8, 8, LOW);  
    matrix.write();
    delay(250);
  }
//Выдаем значек WiFi
  matrix.drawBitmap(20, 4, wifi_icon, 8, 8, 0, 1); 
  matrix.write();

  Serial.println("\nWiFi connected\nIP address: ");
  Serial.println(WiFi.localIP()); // Выводим в монитор порта IP адрес подключения
  Serial.println();

  if (mdns.begin("ESP_Matrix_Clock", WiFi.localIP())) {
    Serial.println("MDNS responder started");
    //  "Запущен MDNSresponder"
  }
  server.on("/", [](){
    server.send(200, "text/html", webPage);
  });
  server.begin();
  Serial.println("HTTP server started");
   
  ms_mode = millis();
//Cоединение для NTP   
  udp.begin(2390);
} // END SETUP

void loop() {
  server.handleClient();
  ms = millis();
  //Serial.println(mode);
  // Цикл бегущей строки   
  if( ms0 == 0 || ms < ms0 || (ms - ms0)>wait ){
    ms0 = ms;
    switch(mode){
      case 0: break;
      case 1: break;
      case 2: break;
      case 3: break;
      case 4: break;
      case 5: break;
      case 6: if(clear_flag){ clear_flag = !clear_flag; matrix.fillScreen(LOW); matrix.write(); }; PrintTicker(tape_date);     break;
      case 7: PrintTicker(tape_weather);  break;
    } 
  }
   if( ms1 == 0 || ms < ms1 || (ms - ms1)>300000 ){ // Получаем погоду раз в 5 минуты
       ms1 = ms;
       GetWeather();
   }
   if( ms4 == 0 || ms < ms4 || (ms - ms4)>1000 ){
       ms4 = ms;
       GetDate();
   }
// Показ часов
  if( ms2 == 0 || ms < ms2 || (ms - ms2)>500 ){
    ms2 = ms;
    t_cur  = ms/1000;
    tm     = t_cur + t_correct;
    switch(mode){
      case 0: PrintBigTime(); break;
      case 1: PrintBigTime(); break;
      case 2: PrintBigTime(); break;
      case 3: PrintBigTime(); break;
      case 4: PrintBigTime(); break;
      case 5: PrintBigTime(); break;
      case 6: PrintTime();    break;
      case 7: PrintTime();    break;
    }
  }
   
// Опрос NTP сервера
   if(  ms3 == 0 || ms < ms3 || (ms - ms3)>NTP_TIMEOUT ){
       uint32_t t = GetNTP();
       if( t!=0 ){ ms3 = ms; t_correct = t - t_cur; }
   }
}

// Печать времени
void PrintTime(){
    int time_sec = second();
    int time_min = minute();
    int time_hour = hour();
    char s[10];
    matrix.fillRect(0, 0, 40, 8, LOW);     
    sprintf(s, "%02d", time_hour);
    matrix.setCursor(2, 0);
    matrix.print(s);
    if( pp ) matrix.drawBitmap(14, 1, m_digit_sep, 1, 5, 1, 0);
    else     matrix.drawBitmap(14, 1, m_digit_sep, 1, 5, 0, 0);
    sprintf(s, "%02d", time_min);
    matrix.setCursor(16, 0);
    matrix.print(s);
    PrintMiniSecondDigit(29,2,time_sec/10);
    PrintMiniSecondDigit(34,2,time_sec%10);
    pp = !pp;
    //ms_mode = ms;
}

// Печать времени большими цифрами
void PrintBigTime(){
  if(!clear_flag) clear_flag = !clear_flag;
  char s[20];
  matrix.fillScreen(LOW);  
  int h = (int)( tm/3600 )%24;
  int m = (int)( tm/60 )%60;
  PrintBigDigit(1,1,h/10);
  PrintBigDigit(10,1,h%10);
  PrintBigDigit(23,1,m/10);
  PrintBigDigit(32,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 > 5000){
    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 PrintMiniSecondDigit(int x, int y, int dig){
  switch(dig){
    case 0  : matrix.drawBitmap(x, y,  ms_digit0, 4, 5, 1, 0); break;
    case 1  : matrix.drawBitmap(x, y,  ms_digit1, 4, 5, 1, 0); break;
    case 2  : matrix.drawBitmap(x, y,  ms_digit2, 4, 5, 1, 0); break;
    case 3  : matrix.drawBitmap(x, y,  ms_digit3, 4, 5, 1, 0); break;
    case 4  : matrix.drawBitmap(x, y,  ms_digit4, 4, 5, 1, 0); break;
    case 5  : matrix.drawBitmap(x, y,  ms_digit5, 4, 5, 1, 0); break;
    case 6  : matrix.drawBitmap(x, y,  ms_digit6, 4, 5, 1, 0); break;
    case 7  : matrix.drawBitmap(x, y,  ms_digit7, 4, 5, 1, 0); break;
    case 8  : matrix.drawBitmap(x, y,  ms_digit8, 4, 5, 1, 0); break;
    case 9  : matrix.drawBitmap(x, y,  ms_digit9, 4, 5, 1, 0); break;
  }
}
void GetDate(){
  int date_month_num = month();
  String date_month = "";
  switch(date_month_num){
    case 1   : date_month = "Января";   break;
    case 2   : date_month = "Февраля";  break;
    case 3   : date_month = "Марта";    break;
    case 4   : date_month = "Апреля";   break;
    case 5   : date_month = "Мая";      break;
    case 6   : date_month = "Июня";     break;
    case 7   : date_month = "Июля";     break;
    case 8   : date_month = "Августа";  break;
    case 9   : date_month = "Сентября"; break;
    case 10  : date_month = "Октября";  break;
    case 11  : date_month = "Ноября";   break;
    case 12  : date_month = "Декабря";  break;
  }
  
  int date_weekday_num = weekday();
  String date_weekday = "";
  switch(date_weekday_num){
    case 1   : date_weekday = "Воскресенье";  break;
    case 2   : date_weekday = "Понедельник";  break;
    case 3   : date_weekday = "Вторник";      break;
    case 4   : date_weekday = "Среда";        break;
    case 5   : date_weekday = "Четверг";      break;
    case 6   : date_weekday = "Пятница";      break;
    case 7   : date_weekday = "Суббота";      break;
  }

  tape_date = "Сегодня ";
  tape_date += date_weekday;
  tape_date += " ";
  tape_date += day();
  tape_date += " ";
  tape_date += date_month;
  tape_date += ", ";
  tape_date += year();
  tape_date += " года.";
  tape_date = utf8rus(tape_date);
}

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

  matrix.fillRect(0, 8, 32, 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
  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();
    //Serial.println(httpString); 
    ParseWeather(httpString);
  }
  client.end();
}

// Парсим погоду
void ParseWeather(String s){
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.parseObject(s);
  if (!root.success()) {
    Serial.println("Json parsing failed!");
    return;
  }
// Погода   
  tape_weather = W_NAME;
  tape_weather += root["weather"][0]["description"].as<String>();
// Температура   
  tape_weather += ", Температура ";
  int t = root["main"]["temp"].as<int>(); 
  tape_weather += String(t);
  tape_weather += (char)128;
// Влажность   
  tape_weather += "С, Влажность ";
  tape_weather += root["main"]["humidity"].as<String>();
// Давление   
  tape_weather += "%, Давление ";
  double p = root["main"]["pressure"].as<double>()/1.33322;
  tape_weather += String((int)p);
// Ветер   
  tape_weather += "мм. Ветер ";
  double deg = root["wind"]["deg"];
  if( deg >22.5 && deg <=67.5 )tape_weather += "северо-восточный ";
  else if( deg >67.5 && deg <=112.5 )tape_weather += "восточный ";
  else if( deg >112.5 && deg <=157.5 )tape_weather += "юго-восточный ";
  else if( deg >157.5 && deg <=202.5 )tape_weather += "южный ";
  else if( deg >202.5 && deg <=247.5 )tape_weather += "юго-западный ";
  else if( deg >247.5 && deg <=292.5 )tape_weather += "западный ";
  else if( deg >292.5 && deg <=337.5 )tape_weather += "северо-западный ";
  else tape_weather += "северный ";
  tape_weather += root["wind"]["speed"].as<String>();
  tape_weather += " м/с.    ";
  // Перекодируем из UNICODE   
  tape_weather = utf8rus(tape_weather);
  s = ""; 
}

// Посылаем и парсим запрос к NTP серверу
time_t GetNTP(void) {
  IPAddress ntpIP;
  time_t tm = 0;
  WiFi.hostByName(NTP_SERVER, ntpIP); 
  sendNTPpacket(ntpIP); 
  delay(1000); // это надо убрать, переделав на millis(), чтоб не вызывало подтормаживания.
  
  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;
    setTime(tm);   
  }
  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();
}
Для адекватной работы с русскими буквами нужно в библиотеке Adafruit-GFX заменить файл glcdfont.c из архива

Пост пока на стадии написания, позже буду дополнять...

bim1405
Сообщения: 1
Зарегистрирован: Пн фев 11, 2019 4:02 am

Re: Wi-Fi Интернет-Часы с погодой на ESP8266 (nodemcu) и десяти светодиодных матрицах 8х8 с драйвером MAX7219

Сообщение bim1405 » Пн фев 11, 2019 4:36 am

Сергей здравствуй. Повторил твой проект на матрицах размером 38х38 мм. Все работает.
Спасибо.
Вложения
20190211_072854.jpg

awiscan
Сообщения: 2
Зарегистрирован: Вс мар 17, 2019 12:32 pm

Re: Wi-Fi Интернет-Часы с погодой на ESP8266 (nodemcu) и десяти светодиодных матрицах 8х8 с драйвером MAX7219

Сообщение awiscan » Вс мар 17, 2019 12:50 pm

Привет умным людям. Судя по датам публикаций сообщений, тема заглохла. Но - человек bim мнение выложил (спасиб),
я повторил это дело - все заработало (была маета с библиотеками). Ежели появятся спрашивающие - пишите, расскажу, как выпендривался...

Сергей
Сообщения: 4
Зарегистрирован: Вт ноя 28, 2017 6:58 pm

Re: Wi-Fi Интернет-Часы с погодой на ESP8266 (nodemcu) и десяти светодиодных матрицах 8х8 с драйвером MAX7219

Сообщение Сергей » Вс мар 24, 2019 7:06 pm

bim1405 писал(а):
Пн фев 11, 2019 4:36 am
Сергей здравствуй. Повторил твой проект на матрицах размером 38х38 мм. Все работает.
Спасибо.
Даже с корпусом - хорошо получилось. У меня пока руки не дошли, 3D принтер приехал, с ним пол года игрался, сейчас квадрокоптер собрал.
Но обязательно буду до ума доводить, отличные часы получились, вся семья бегает погоду посмотреть :)
awiscan писал(а):
Вс мар 17, 2019 12:50 pm
Привет умным людям. Судя по датам публикаций сообщений, тема заглохла. Но - человек bim мнение выложил (спасиб),
я повторил это дело - все заработало (была маета с библиотеками). Ежели появятся спрашивающие - пишите, расскажу, как выпендривался...
И вам привет.

Можно в краце, а лучше подробно, чего там за маета. Вроде только в библиотеке Adafruit-GFX заменить файл glcdfont.c, а то скоро полезу в код чего нибудь крутить, а все либы обновились...

awiscan
Сообщения: 2
Зарегистрирован: Вс мар 17, 2019 12:32 pm

Re: Wi-Fi Интернет-Часы с погодой на ESP8266 (nodemcu) и десяти светодиодных матрицах 8х8 с драйвером MAX7219

Сообщение awiscan » Пт апр 12, 2019 3:04 pm

Здрасте. Неправильно выразился, маета не с библиотеками, а с конфликтами похожих библиотек. Тоже после обновления. Пришлось все новые либы временно отстранить от работы. Да еще openweathermap нервы попортил, API смог получить только через VPN. Корпус выписал, жду.

awiscan
Сообщения: 2
Зарегистрирован: Вс мар 17, 2019 12:32 pm

Re: Wi-Fi Интернет-Часы с погодой на ESP8266 (nodemcu) и десяти светодиодных матрицах 8х8 с драйвером MAX7219

Сообщение awiscan » Пн май 20, 2019 2:03 pm

У меня пока вот так...

Focus
Site Admin
Сообщения: 1
Зарегистрирован: Ср ноя 22, 2017 5:16 pm

Re: Wi-Fi Интернет-Часы с погодой на ESP8266 (nodemcu) и десяти светодиодных матрицах 8х8 с драйвером MAX7219

Сообщение Focus » Вт май 21, 2019 1:55 am

Зеленый все-таки лучше. Как они по яркости?

Ответить