P13 – Đồng hồ thời gian thực qua Wifi với LED ma trận

Trong bài này chúng ta sẽ làm một đồng hồ với thời gian được cập nhật tự động qua Internet bằng kết nối Wifi. Ngoài ra đồng hồ còn hiển thị thông số môi trường như nhiệt độ và độ ẩm. Khác với những bài trước, LED ma trận sẽ được sử dụng cho phần hiển thị.

Thiết bị đầu tiên cần có là một bộ NodeMCU. Có thể sử dụng Arduino nhưng NodeMCU sẽ giúp chúng ta tận dụng tính năng kết nối Wifi với chip wifi ESP có sẵn.

Thiết bị thứ hai là cảm biến môi trường, loại rẻ tiền đơn giản nhất là DHT11. Khi kết nối DHT 11 với vi điều khiển, cần chú ý sử dụng điện trở treo cao tại chân Data. Nếu mạch DHT11 gắn sẵn điện trở thì ta chỉ cần nối dây theo đúng vị trí chân.

Thiết bị quan trọng nhất là chip giải mã MAX7219. Nó giúp đơn giản hóa việc hiển thị trên LED ma trận. Các mạch đèn ma trận gắn sẵn MAX7219 có giá thành không quá cao, kích thước nhỏ gọn, bao gồm cả chip thường và chip dán. Tuy nhiên LED ma trận có kích thước giới hạn và chỉ hỗ trợ 1 màu. Điện áp sử dụng theo khuyến cáo là 5V.

Bo mạch LED ma trận gắn sẵn MAX7219

Với mạch LED gắn sẵn MAX7219, khi lập trình ta cần bổ sung đầy đủ các thư viện. Với một bo 4 đèn LED ma trận, ta có thể sử dụng nguồn 3,3V từ NodeMCU vì dòng ra vẫn đảm bảo. Nếu sử dụng nhiều LED hơn, ta phải dùng nguồn riêng nuôi LED (chân đất gắn chung giữa các mạch).

Có thể xem lại những bài trước để bổ sung thư viện cho ESP và DHT. Thư viện NTPClient có thể bổ sung trực tiếp bằng Library Manager. Thư viện MAX7219 có thể tải của MarkRuys hoặc tại đây

Bổ sung thư viên NTPClient để cập nhật thời gian

Chương trình như sau:

#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <SPI.h>
#include <DHT.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>

const char *ssid     = "ssid";      //Tên wifi
const char *password = "password";  //Mật khẩu

// LED pin  --> ESP
// DIN      --> D7
// CS       --> D6
// CLK      --> D5
#define pinCS             D6
#define DHTPin            D4
#define DHTTYPE           DHT11

//String date;
String weatherString;

int refresh = 0;

int HorizontalDisplays = 4;  // Số Lượng Led Matrix Ngang
int VerticalDisplays = 1;    // Số Lượng Led Matrix dọc
int t = 0;
int h = 0;
Max72xxPanel matrix = Max72xxPanel(pinCS, HorizontalDisplays, VerticalDisplays);

int wait = 50;          // tốc độ chạy, càng lớn càng chạy chậm
int spacer = 2;
int width = 5 + spacer; // Khoảng cách ký tự có thể điều chỉnh

//WiFiClient client;
DHT dht(DHTPin, DHTTYPE);

WiFiUDP ntpUDP;

// By default 'pool.ntp.org' is used with 60 seconds update interval and
// no offset
NTPClient timeClient(ntpUDP, "3.asia.pool.ntp.org", 7*3600, 60000);

// You can specify the time server pool and the offset, (in seconds)
// additionaly you can specify the update interval (in milliseconds).
// NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);

void setup()
{
  Serial.begin(115200);
  dht.begin();
  
  pinMode(DHTPin, INPUT);
 
  matrix.setIntensity(7); // điều chỉnh độ sáng 0-15

  // Tọa Độ Led Matrix bắt đầu 8 * 8
  matrix.setRotation(0, 1);        // 1
  matrix.setRotation(1, 1);        // 2
  matrix.setRotation(2, 1);        // 3
  matrix.setRotation(3, 1);        // 4

  WiFi.begin(ssid, password);

  while ( WiFi.status() != WL_CONNECTED ) 
  {
    delay ( 500 );
    Serial.print ( "." );
  }
  Serial.println( "Got Wifi" );
  timeClient.begin();
}

void loop() 
{
  h = dht.readHumidity();
  t = dht.readTemperature();
  hienthi_t_h();
  DisplayTime();
  delay(10000);
}

void hienthi_t_h()
{
  ScrollText("Du An Nho");
  ScrollText("//bandardalat.com");
   
  weatherString = "Temp:" + String(t) + "`C";
  ScrollText(weatherString);
    
  weatherString = "HUM:" + String(h) + "%";
  ScrollText(weatherString); 
}

// =======================================================================
void DisplayTime() 
{
  timeClient.update();
  matrix.fillScreen(LOW);
  int y = (matrix.height() - 8) / 2;
 
  matrix.drawChar(14, y, (String(":"))[0], HIGH, LOW,1);

  String hour1 = String (timeClient.getHours() / 10);
  String hour2 = String (timeClient.getHours() % 10);
  String min1 = String (timeClient.getMinutes() / 10);
  String min2 = String (timeClient.getMinutes() % 10);
  int xh = 2;
  int xm = 19;

  matrix.drawChar(xh, y, hour1[0], HIGH, LOW, 1);
  matrix.drawChar(xh + 7, y, hour2[0], HIGH, LOW, 1);
  matrix.drawChar(xm, y, min1[0], HIGH, LOW, 1);
  matrix.drawChar(xm + 7, y, min2[0], 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);
  }
}

Leave a Reply

Your email address will not be published. Required fields are marked *