Search Code

Dự án Đồng hồ Internet Ma trận LED RGB ESP32-S3 - 5 Màu cầu vồng

Dự án Đồng hồ Internet Ma trận LED RGB ESP32-S3 - 5 Màu cầu vồng

Đồng hồ Internet ESP32-S3 với Hiệu ứng Màu Cầu vồng

Dự án này là Đồng hồ Internet Ma trận RGB ESP32-S3 kết nối Wi-Fi, đồng bộ thời gian địa phương từ máy chủ NTP và cuộn thời gian ở định dạng HH:MM trên Ma trận Neo 8×8 RGB tích hợp. Không giống như các phiên bản màu cố định hoặc ngẫu nhiên, đồng hồ này sử dụng hiệu ứng màu cầu vồng mượt mà, trong đó mỗi ký tự liên tục chuyển qua quang phổ RGB khi cuộn. Đồng hồ cũng hiển thị định kỳ ngày tháng và tự động điều chỉnh độ sáng giữa ngày và đêm.

Hoạt ảnh đồng hồ internet ESP32-s3

Cách hoạt động của đồng hồ này

Sau khi được cấp nguồn qua USB-C, ESP32-S3 kết nối với mạng Wi-Fi của bạn và lấy thời gian địa phương hiện tại từ internet. Màn hình thường cuộn thời gian, nhưng ở một khoảng thời gian xác định, nó chuyển sang hiển thị ngày tháng. Cả thời gian và ngày tháng đều được hiển thị bằng hiệu ứng cầu vồng động, tạo ra màn hình sống động và đầy màu sắc trên ma trận 8×8 nhỏ.

Các thư viện được sử dụng

Bản phác thảo dựa trên các thư viện sau:

#include <WiFi.h>
#include "time.h"
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

Cài đặt Adafruit NeoMatrix bằng Trình quản lý thư viện Arduino. Các phần phụ thuộc của nó, bao gồm Adafruit GFX LibraryAdafruit NeoPixel, sẽ được cài đặt tự động.

Cấu hình người dùng quan trọng

Chân dữ liệu ma trận (ma trận RGB tích hợp)

Mặc dù ma trận RGB được gắn vào bo mạch ESP32-S3, chân dữ liệu vẫn phải được xác định trong mã:

#define MATRIX_PIN 14

GPIO 14 thường được sử dụng trên các bo mạch ma trận RGB ESP32-S3. Nếu biến thể bo mạch của bạn sử dụng chân khác, hãy cập nhật giá trị này.

SSID và mật khẩu Wi-Fi (phân biệt chữ hoa/thường)

Thay thế thông tin đăng nhập Wi-Fi bằng thông tin mạng của riêng bạn:

const char* WIFI_SSID     = "your WIFI";
const char* WIFI_PASSWORD = "passW0rd";

Quan trọng: SSID Wi-Fi phân biệt chữ hoa/thường. SSID có tên "Book" không giống với "book". Nếu chữ hoa/thường không khớp chính xác, ESP32-S3 sẽ không kết nối được.

Máy chủ NTP, múi giờ và giờ mùa hè

Đồng hồ đồng bộ thời gian bằng máy chủ NTP internet:

const char* ntpServer = "pool.ntp.org";

Thời gian địa phương được tính bằng các độ lệch sau:

// Gần Toronto: UTC-5, cộng thêm 1 giờ DST
const long  gmtOffset_sec     = -5 * 3600;
const int   daylightOffset_sec = 3600;
  • gmtOffset_sec: Độ lệch UTC tính bằng giây (ví dụ: UTC-5 = -5 * 3600)
  • daylightOffset_sec: Sử dụng 3600 nếu DST đang hoạt động hoặc 0 nếu không sử dụng

Các giá trị này được áp dụng bằng:

configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

Tự động điều chỉnh độ sáng ngày / đêm

Độ sáng tự động thay đổi dựa trên giờ hiện tại:

const int DAY_BRIGHTNESS = 40;
const int NIGHT_BRIGHTNESS = 5;
const int NIGHT_START_HOUR = 22;
const int NIGHT_END_HOUR = 6;

Từ 10 giờ tối đến 6 giờ sáng, ma trận giảm độ sáng để giảm chói. Trong giờ ban ngày, độ sáng bình thường được khôi phục.

Hiệu ứng màu cầu vồng

Dự án này sử dụng bánh xe màu RGB cổ điển để tạo ra màu cầu vồng mượt mà. Mỗi ký tự được vẽ với độ lệch màu hơi khác nhau và các màu chuyển dịch theo thời gian, tạo ra hoạt ảnh cầu vồng chảy.

// Trợ giúp tạo Màu Cầu vồng
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return matrix.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return matrix.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return matrix.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

Khi văn bản cuộn, mỗi ký tự tiến qua quang phổ RGB, tạo ra hiệu ứng cầu vồng liên tục trông đặc biệt ấn tượng trên màn hình 8×8 nhỏ.

Hành vi hiển thị thời gian và ngày tháng

Đồng hồ duy trì các bộ đệm riêng biệt cho thời gian và ngày tháng:

  • Thời gian: HH:MM
  • Ngày tháng: MMM DD (ví dụ: JAN 08)

Ngày tháng được hiển thị ở một khoảng thời gian cố định:

const uint32_t dateIntervalMs = 60000; // Hiển thị ngày mỗi 1 phút

Vào cuối mỗi chu kỳ cuộn đầy đủ, mã quyết định tiếp tục hiển thị thời gian hay chuyển sang ngày tháng.

Logic cuộn trên ma trận 8×8

Vì màn hình chỉ rộng 8 pixel, văn bản cuộn mượt mà từ phải sang trái. Khi văn bản hoàn toàn thoát khỏi màn hình, con trỏ được đặt lại và nội dung tiếp theo (thời gian hoặc ngày tháng) được tải cho lần chạy tiếp theo.

Trình diễn

Sau khi tải bản phác thảo lên và cấp nguồn cho bo mạch qua USB-C:

  • ESP32-S3 kết nối với mạng Wi-Fi của bạn
  • Thời gian được đồng bộ từ internet
  • Thời gian cuộn ở định dạng HH:MM
  • Ngày tháng xuất hiện định kỳ
  • Tất cả văn bản được hiển thị với hiệu ứng cầu vồng động mượt mà
  • Màn hình tự động giảm độ sáng vào ban đêm và tăng độ sáng vào ban ngày

Tải xuống và liên kết

Bài viết này cung cấp mã nguồn hoàn chỉnh bên dưới. Các công cụ hữu ích và tài liệu tham khảo, bao gồm cả RGB Color Picker, cũng được liên kết bên dưới bài viết này.

Hình ảnh

ESP32 S3 Matrix
ESP32 S3 Matrix
ESP32 S3 Matrix  pin out
ESP32 S3 Matrix pin out
ESP32-S3_RGB_8x8_matrix-3
ESP32-S3_RGB_8x8_matrix-3
ESP32-S3_RGB_8x8_matrix1
ESP32-S3_RGB_8x8_matrix1
ESP32-S3_RGB_8x8_matrix-2
ESP32-S3_RGB_8x8_matrix-2
ESP32-s3_internet_clock_animation
ESP32-s3_internet_clock_animation
872-ESP32-S3 RGB LED Matrix Internte Clock Project 5 - Rainbow Color
Ngôn ngữ: C++
/*
 * =====================================================================================
 * ESP32-S3 CLOCK - RAINBOW DATE & SOLID TIME - Project 5- RAINBOW MODE
 * =====================================================================================
 watch video https://youtube.com/shorts/4iWjLiD7fS8
 📚⬇️ Download and resource page https://robojax.com/RJT842
 * Author: Gemini (AI Thought Partner) & Ahmad Shamshiri (Robojax.com)
 * Date: 07 Jan 2026

 * =====================================================================================
 * ESP32-S3 INTERNET RGB CLOCK - RAINBOW MODE

 * * FEATURES: 
 * - Full Rainbow: Time and Date use flowing rainbow colors.
 * - Auto-Brightness: Dims at night (22:00 to 06:00).
 * - Custom WiFi: Robust connection logic with retries.
 * =====================================================================================
 */

#include <WiFi.h>
#include "time.h"
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#define MATRIX_PIN 14

// 👇 REPLACE these with your real home WiFi name & password
const char* WIFI_SSID     = "your WIFI";
const char* WIFI_PASSWORD = "passW0rd";

// NTP (time) server
const char* ntpServer = "pool.ntp.org";

// Toronto-ish: UTC-5, plus 1 hour DST. 
const long  gmtOffset_sec     = -5 * 3600;  // -5 hours
const int   daylightOffset_sec = 3600;      // +1 hour for DST

// --- BRIGHTNESS CONFIGURATION ---
const int DAY_BRIGHTNESS = 40;
const int NIGHT_BRIGHTNESS = 5;
const int NIGHT_START_HOUR = 22;
const int NIGHT_END_HOUR = 6;

// --- INTERVALS & TRACKING ---
unsigned long lastDateShowMs = 0;
const uint32_t dateIntervalMs = 60000; // Show date every 1 minute
bool isShowingDate = false;

Adafruit_NeoMatrix matrix(8, 8, MATRIX_PIN,
  NEO_MATRIX_TOP    + NEO_MATRIX_LEFT +
  NEO_MATRIX_ROWS   + NEO_MATRIX_PROGRESSIVE,
  NEO_RGB           + NEO_KHZ800);

char timeText[6] = "00:00";
char dateText[10] = "";
char currentDisplayText[12] = ""; 
int16_t scrollX = 8;
unsigned long lastScrollMs = 0;
const uint16_t scrollIntervalMs = 100;
unsigned long lastTimeUpdateMs = 0;

// Helper to create Rainbow Colors
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return matrix.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return matrix.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return matrix.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

void updateClockData() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) return;
  
  // Update Time and Date strings
  snprintf(timeText, sizeof(timeText), "%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min);
  strftime(dateText, sizeof(dateText), "%b %d", &timeinfo);
  for (int i = 0; dateText[i]; i++) dateText[i] = toupper(dateText[i]);

  // Handle Night Dimming
  if (timeinfo.tm_hour >= NIGHT_START_HOUR || timeinfo.tm_hour < NIGHT_END_HOUR) {
    matrix.setBrightness(NIGHT_BRIGHTNESS);
  } else {
    matrix.setBrightness(DAY_BRIGHTNESS);
  }
}

void scrollDisplay() {
  matrix.fillScreen(0);
  
  int len = strlen(currentDisplayText);
  int16_t x = scrollX;

  // Draw each character with a shifting rainbow color
  for (int i = 0; i < len; i++) {
    uint8_t colorPos = (uint8_t)((i * 30) + (millis() / 5)); 
    matrix.setTextColor(Wheel(colorPos));
    matrix.setCursor(x + (i * 6), 0);
    matrix.print(currentDisplayText[i]);
  }

  matrix.show();
  scrollX--;

  int16_t textWidth = len * 6;
  if (scrollX < -textWidth) {
    scrollX = matrix.width();
    
    // Switch between Date and Time at end of cycle
    if (millis() - lastDateShowMs > dateIntervalMs) {
      strcpy(currentDisplayText, dateText);
      lastDateShowMs = millis();
      isShowingDate = true;
    } else {
      strcpy(currentDisplayText, timeText);
      isShowingDate = false;
    }
  }
}

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("\nESP32-S3 Rainbow Clock Initializing...");

  // Connect to WiFi
  Serial.print("Connecting to WiFi: ");
  Serial.println(WIFI_SSID);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  int retries = 0;
  while (WiFi.status() != WL_CONNECTED && retries < 30) { // ~15s timeout
    delay(500);
    Serial.print(".");
    retries++;
  }
  Serial.println();

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi connection FAILED");
  } else {
    Serial.print("WiFi connected. IP: ");
    Serial.println(WiFi.localIP());
  }

  // Configure time via NTP
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  Serial.println("Waiting for time...");
  delay(2000); // small wait for initial sync

  matrix.begin();
  matrix.setTextWrap(false);
  matrix.setBrightness(DAY_BRIGHTNESS);
  
  updateClockData();
  strcpy(currentDisplayText, timeText); // Load initial time
}

void loop() {
  unsigned long now = millis();

  // Update time digits and check brightness every second
  if (now - lastTimeUpdateMs >= 1000) {
    lastTimeUpdateMs = now;
    updateClockData(); 
  }

  // Handle the scrolling animation
  if (now - lastScrollMs >= scrollIntervalMs) {
    lastScrollMs = now;
    scrollDisplay();
  }
}

Tài nguyên & tài liệu tham khảo

Tập tin📁

Tập tin Fritzing