• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar
  • Skip to secondary sidebar
  • Skip to footer

У Павла!

  • Контроллеры
    • Arduino
      • Приборы
      • Музыка
      • Проекты Arduino
      • Уроки Arduino
      • Игры на Arduino
      • Роботы на Ардуино
      • FLProg
    • Одноплатные ПК
      • Orange pi
      • Raspberry pi
        • Raspberry pi pico
        • Raspberry pi server
        • Проекты Raspberry pi
    • ESP
      • ESP8266
        • NodeMCU
      • ESP32
      • M5stack
    • Другие контроллеры
      • STM32
  • Умный дом
    • Home Assistant
      • Автоматизации
    • Tuya
    • Bluetooth
    • ESPHome
    • Frigate
    • Telegram
    • Яндекс
  • ЧПУ
  • 3d печать
  • Об авторе

Реализация часов на светодиодной матрице Max7219 и NodeMCU

28 сентября, 2017

Для реализации часов нам понадобится:

Плата NodeMCU: http://ali.pub/1qdz7a

Матрица 8×8: http://ali.pub/1uwnyl

Прежде чем приступить к материалу, я Вас попрошу, если нравится то, что я делаю и хотите следить за моей деятельностью, то рекомендую подписаться на мой телеграмм канал: https://t.me/ypavla
Там я публикую новости о вышедших видео, статьях и разные устройства для умного дома и не только показываю.
Спасибо за внимание, теперь продолжим.

 

Данный скетч работает таким образом:

ESP8266 подключается к Wi-fi сети, после этого подключается к сервису http://openweathermap.org, берет с этого сервиса информацию о погоде, а именно Температуру, влажность, давление, скорость ветра. С сервиса google берет время и выводит эту всю информацию по очереди на светодиодную матрицу в виде бегущей строки.

Схема подключения у нас выглядит вот так:

esp8266 D7 D5 D3 VCC Gnd
Matrix DIN Clk CS 3.3v Gnd

После подключения всех компонентов необходимо скопировать программный код приведенный ниже и вставить его в программу Arduino IDE и загрузить этот программный код в саму плату Arduino.

Собственно сам скетч:

 


/*
Подключения:
NodeMCU    -> Matrix
MOSI-D7-GPIO13  -> DIN
CLK-D5-GPIO14   -> Clk
GPIO0-D3        -> LOAD
*/

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <ArduinoJson.h>

// =======================================================================
// Конфигурация устройства:
// =======================================================================
const char* ssid     = "NETGEAR";                      // SSID
const char* password = "14111990";                    // пароль
String weatherKey = "6ce91e933fffe3deb537e017";  // Чтобы получить API ключь, перейдите по ссылке http://openweathermap.org/api
String weatherLang = "&lang=ru";
String cityID = "472045"; //Voronezh
// =======================================================================


WiFiClient client;

String weatherMain = "";
String weatherDescription = "";
String weatherLocation = "";
String country;
int humidity;
int pressure;
float temp;
float tempMin, tempMax;
int clouds;
float windSpeed;
String date;
String currencyRates;
String weatherString;

long period;
int offset=1,refresh=0;
int pinCS = 0; // Подключение пина CS
int numberOfHorizontalDisplays = 4; // Количество светодиодных матриц по Горизонтали
int numberOfVerticalDisplays = 1; // Количество светодиодных матриц по Вертикали
String decodedMsg;
Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);
//matrix.cp437(true);

int wait = 50; // скорость бегущей строки

int spacer = 2;
int width = 5 + spacer; // Регулируем расстояние между символами

void setup(void) {

matrix.setIntensity(13); // Яркость матрицы от 0 до 15


// начальные координаты матриц 8*8
  matrix.setRotation(0, 1);        // 1 матрица
  matrix.setRotation(1, 1);        // 2 матрица
  matrix.setRotation(2, 1);        // 3 матрица
  matrix.setRotation(3, 1);        // 4 матрица


  Serial.begin(115200);                           // Дебаг
  WiFi.mode(WIFI_STA);                           
  WiFi.begin(ssid, password);                         // Подключаемся к WIFI
  while (WiFi.status() != WL_CONNECTED) {         // Ждем до посинения
    delay(500);
    Serial.print(".");
  }



}

// =======================================================================
#define MAX_DIGITS 16
byte dig[MAX_DIGITS]={0};
byte digold[MAX_DIGITS]={0};
byte digtrans[MAX_DIGITS]={0};
int updCnt = 0;
int dots = 0;
long dotTime = 0;
long clkTime = 0;
int dx=0;
int dy=0;
byte del=0;
int h,m,s;
// =======================================================================
void loop(void) {




if(updCnt<=0) { // каждые 10 циклов получаем данные времени и погоды updCnt = 10; Serial.println("Getting data ..."); getWeatherData(); getTime(); Serial.println("Data loaded"); clkTime = millis(); } if(millis()-clkTime > 15000 && !del && dots) { //каждые 15 секунд запускаем бегущую строку
//ScrollText(utf8rus("Хорошего дня!")); //тут текст строки, потом будет погода и т.д.
ScrollText(utf8rus(weatherString));
    updCnt--;
    clkTime = millis();
  }


  
DisplayTime();
  if(millis()-dotTime > 500) {
    dotTime = millis();
    dots = !dots;
  }


}

// =======================================================================
void DisplayTime(){
    updateTime();
    matrix.fillScreen(LOW);
    int y = (matrix.height() - 8) / 2; // Центрируем текст по Вертикали

    
    if(s & 1){matrix.drawChar(14, y, (String(":"))[0], HIGH, LOW, 1);} //каждую четную секунду печатаем двоеточие по центру (чтобы мигало)
    else{matrix.drawChar(14, y, (String(" "))[0], HIGH, LOW, 1);}
    
    String hour1 = String (h/10);
    String hour2 = String (h%10);
    String min1 = String (m/10);
    String min2 = String (m%10);
    String sec1 = String (s/10);
    String sec2 = String (s%10);
    int xh = 2;
    int xm = 19;
//    int xs = 28;

    matrix.drawChar(xh, y, hour1[0], HIGH, LOW, 1);
    matrix.drawChar(xh+6, y, hour2[0], HIGH, LOW, 1);
    matrix.drawChar(xm, y, min1[0], HIGH, LOW, 1);
    matrix.drawChar(xm+6, y, min2[0], HIGH, LOW, 1);
//    matrix.drawChar(xs, y, sec1[0], HIGH, LOW, 1);
//    matrix.drawChar(xs+6, y, sec2[0], HIGH, LOW, 1);  


  
    matrix.write(); // Вывод на дисплей
}

// =======================================================================
void DisplayText(String text){
    matrix.fillScreen(LOW);
    for (int i=0; i<text.length(); i++){
    
    int letter =(matrix.width())- i * (width-1);
    int x = (matrix.width() +1) -letter;
    int y = (matrix.height() - 8) / 2; // Центрируем текст по Вертикали
    matrix.drawChar(x, y, text[i], HIGH, LOW, 1);
    matrix.write(); // Вывод на дисплей
    
    }

}
// =======================================================================
void ScrollText (String text){
    for ( int i = 0 ; i < width * text.length() + matrix.width() - 1 - spacer; i++ ) { if (refresh==1) i=0; refresh=0; matrix.fillScreen(LOW); int letter = i / width; int x = (matrix.width() - 1) - i % width; int y = (matrix.height() - 8) / 2; // Центрируем текст по Вертикали while ( x + width - spacer >= 0 && letter >= 0 ) {
      if ( letter < text.length() ) {
        matrix.drawChar(x, y, text[letter], HIGH, LOW, 1);
      }
      letter--;
      x -= width;
    }
    matrix.write(); // Вывод на дисплей
    delay(wait);
  }
}


// =======================================================================
// Берем погоду с сайта openweathermap.org
// =======================================================================



const char *weatherHost = "api.openweathermap.org";

void getWeatherData()
{
  Serial.print("connecting to "); Serial.println(weatherHost);
  if (client.connect(weatherHost, 80)) {
    client.println(String("GET /data/2.5/weather?id=") + cityID + "&units=metric&appid=" + weatherKey + weatherLang + "\r\n" +
                "Host: " + weatherHost + "\r\nUser-Agent: ArduinoWiFi/1.1\r\n" +
                "Connection: close\r\n\r\n");
  } else {
    Serial.println("connection failed");
    return;
  }
  String line;
  int repeatCounter = 0;
  while (!client.available() && repeatCounter < 10) {
    delay(500);
    Serial.println("w.");
    repeatCounter++;
  }
  while (client.connected() && client.available()) {
    char c = client.read(); 
    if (c == '[' || c == ']') c = ' ';
    line += c;
  }

  client.stop();

  DynamicJsonBuffer jsonBuf;
  JsonObject &root = jsonBuf.parseObject(line);
  if (!root.success())
  {
    Serial.println("parseObject() failed");
    return;
  }
  //weatherMain = root["weather"]["main"].as<String>();
  weatherDescription = root["weather"]["description"].as<String>();
  weatherDescription.toLowerCase();
  //  weatherLocation = root["name"].as<String>();
  //  country = root["sys"]["country"].as<String>();
  temp = root["main"]["temp"];
  humidity = root["main"]["humidity"];
  pressure = root["main"]["pressure"];
  tempMin = root["main"]["temp_min"];
  tempMax = root["main"]["temp_max"];
  windSpeed = root["wind"]["speed"];
  clouds = root["clouds"]["all"];
  String deg = String(char('~'+25));
  weatherString = "t: " + String(temp,1)+" ";
  weatherString += weatherDescription;
  weatherString += " Влажн.: " + String(humidity) + "% ";
  weatherString += "Давл.: " + String(pressure/1.3332239) + " мм ";
//  weatherString += "Облачность: " + String(clouds) + "% ";
  weatherString += "Ветер: " + String(windSpeed,1) + "М/с";
}

// =======================================================================
// Берем время у GOOGLE
// =======================================================================

float utcOffset = 3; //поправка часового пояса
long localEpoc = 0;
long localMillisAtUpdate = 0;

void getTime()
{
  WiFiClient client;
  if (!client.connect("www.google.com", 80)) {
    Serial.println("connection to google failed");
    return;
  }

  client.print(String("GET / HTTP/1.1\r\n") +
               String("Host: www.google.com\r\n") +
               String("Connection: close\r\n\r\n"));
  int repeatCounter = 0;
  while (!client.available() && repeatCounter < 10) {
    delay(500);
    //Serial.println(".");
    repeatCounter++;
  }

  String line;
  client.setNoDelay(false);
  while(client.connected() && client.available()) {
    line = client.readStringUntil('\n');
    line.toUpperCase();
    if (line.startsWith("DATE: ")) {
      date = "     "+line.substring(6, 22);
      h = line.substring(23, 25).toInt();
      m = line.substring(26, 28).toInt();
      s = line.substring(29, 31).toInt();
      localMillisAtUpdate = millis();
      localEpoc = (h * 60 * 60 + m * 60 + s);
    }
  }
  client.stop();
}

// =======================================================================r

void updateTime()
{
  long curEpoch = localEpoc + ((millis() - localMillisAtUpdate) / 1000);
  long epoch = round(curEpoch + 3600 * utcOffset + 86400L) % 86400L;
  h = ((epoch  % 86400L) / 3600) % 24;
  m = (epoch % 3600) / 60;
  s = epoch % 60;
}

// =======================================================================


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-1; break; } case 0xD1: { n = source[i]; i++; if (n == 0x91) { n = 0xB8; break; } if (n >= 0x80 && n <= 0x8F) n = n + 0x70-1;
          break;
        }
      }
    }
    m[0] = n; target = target + String(m);
  }
return target;
}

 

Ссылка на скетч: https://yadi.sk/d/hB5cGSMV3NJPtK

Для корректной работы скетча нужно скачать следующие библиотеки:

Adafruit_GFX_Library: https://yadi.sk/d/4wJBlGkP3NJaGb
arduino-Max72xxPanel-master: https://yadi.sk/d/_sMXrMoC3NAcYj

Arduino Json: https://yadi.sk/d/_EbbMgQL3NJQ3Z

 

Ссылка  на автора данного проекта: https://www.youtube.com/channel/UC5Mq-PGM7Ww4Nt0EyUFJo3g

Демонстрация работы данной программы можно увидеть в видео приведенном в конце статьи.

Primary Sidebar

Поиск

Новые записи

  • Автоматизация перезагрузки устройства по команде Ping.
  • Разблокирование и добавление шлюза Xiaomi gateway 3 в Home Assistant для управления Bluetooth устройствами из экосистемы Xiaomi Home (mihome)
  • Интеграция для локального управления (без интернета) ик пультом Tuya работающим по wifi из Home Assistant
  • Транслируем показания с Уличного Bluetooth Датчика температуры по BTHome на дисплей датчика температуры XIaomi LYWSD03MMC
  • Заставляем Bluetooth датчики температуры tuya и xiaomi отправлять данные по Zigbee в Home Assistant.

Официальный YouTube Канал M5Stack:

Подписывайтесь на Телеграм канал

https://t.me/ypavla

Подписаться на YouTube!

Secondary Sidebar




Подписывайтесь на Telegram Канал!

У Павла!

Footer

Copyright_У Павла! © 2025 ·