Search Code

ESP32-S3 RGB LED矩陣網絡時鐘項目 - 5 彩虹色

ESP32-S3 RGB LED矩陣網絡時鐘項目 - 5 彩虹色

ESP32-S3 彩虹色效果互聯網時鐘

呢個項目係一個 ESP32-S3 RGB Matrix 互聯網時鐘,佢會連接 Wi-Fi、從 NTP 伺服器同步本地時間,並且以 HH:MM 格式喺內置嘅 8×8 RGB NeoMatrix 上面滾動顯示時間。同純色或者隨機顏色版本唔同,呢個時鐘用咗一個平滑嘅彩虹色效果,每個字元喺滾動嘅時候會持續咁喺 RGB 光譜入面轉換。個時鐘亦都會定期顯示日期,並且自動調整日頭同夜晚嘅亮度。

ESP32-s3_internet_clock_animation

呢個時鐘點樣運作

一旦透過 USB-C 供電,ESP32-S3 就會連接你嘅 Wi-Fi 網絡,並且從互聯網攞返當前嘅本地時間。顯示屏正常會滾動顯示時間,但係去到一個設定嘅間隔就會切換去顯示日期。時間同日期都用一個動態嘅彩虹效果嚟渲染,喺細細個 8×8 matrix 上面創造出一個鮮豔同有動畫感嘅顯示。

用到嘅程式庫

呢個 sketch 依賴以下嘅程式庫:

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

用 Arduino Library Manager 安裝 Adafruit NeoMatrix。佢嘅依賴項目,包括 Adafruit GFX LibraryAdafruit NeoPixel,會自動安裝。

重要嘅用戶設定

Matrix 數據引腳(內置 RGB matrix)

雖然 RGB matrix 係連接咗喺 ESP32-S3 板上面,但係數據引腳仍然要喺程式碼入面定義:

#define MATRIX_PIN 14

GPIO 14 通常用喺 ESP32-S3 RGB matrix 板上面。如果你嘅板嘅變體用咗唔同嘅引腳,就要更新呢個數值。

Wi-Fi SSID 同密碼(大小寫敏感)

將 Wi-Fi 憑證換成你自己嘅網絡資料:

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

重要: Wi-Fi SSID 係大小寫敏感嘅。一個叫做 "Book" 嘅 SSID 同 "book" 係唔一樣嘅。如果大細階唔完全脗合,ESP32-S3 就會連接失敗。

NTP 伺服器、時區同夏令時間

個時鐘用一個互聯網 NTP 伺服器嚟同步時間:

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

本地時間用以下嘅偏移量嚟計算:

// 多倫多附近:UTC-5,加 1 個鐘夏令時間
const long  gmtOffset_sec     = -5 * 3600;
const int   daylightOffset_sec = 3600;
  • gmtOffset_sec:UTC 偏移量(以秒計)(例子:UTC-5 = -5 * 3600
  • daylightOffset_sec:如果夏令時間生效就用 3600,如果冇用就用 0

呢啲數值會用以下方式套用:

configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

自動日頭 / 夜晚亮度

亮度會根據當前嘅鐘數自動改變:

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

喺夜晚 10 點到朝早 6 點之間,matrix 會調暗嚟減少刺眼。喺日頭時段,就會恢復正常嘅亮度。

彩虹色效果

呢個項目用咗一個經典嘅 RGB 色輪嚟產生平滑嘅彩虹色。每個字元都用一個稍微唔同嘅顏色偏移嚟繪製,而且啲顏色會隨住時間轉變,產生一個流動嘅彩虹動畫。

// 輔助函數嚟建立彩虹色
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);
}

當文字滾動嘅時候,每個字元都會喺 RGB 光譜入面前進,創造出一個連續嘅彩虹效果,喺細細個 8×8 顯示屏上面睇起上嚟特別有睇頭。

時間同日期顯示行為

個時鐘分別為時間同日期維持獨立嘅緩衝區:

  • 時間: HH:MM
  • 日期: MMM DD(例如 JAN 08

日期會以一個固定嘅間隔顯示:

const uint32_t dateIntervalMs = 60000; // 每 1 分鐘顯示日期

喺每個完整滾動週期結束嘅時候,程式碼會決定繼續顯示時間定係切換去顯示日期。

喺 8×8 matrix 上面嘅滾動邏輯

因為顯示屏得 8 像素闊,文字會由右至左平滑咁滾動。一旦文字完全離開畫面,游標就會重置,跟住下一段內容(時間或者日期)就會載入嚟做下一次嘅滾動。

示範

上載咗 sketch 並且透過 USB-C 供電之後:

  • ESP32-S3 會連接你嘅 Wi-Fi 網絡
  • 時間會從互聯網同步
  • 時間會以 HH:MM 格式滾動顯示
  • 日期會定期出現
  • 所有文字都用一個平滑嘅動畫彩虹效果嚟渲染
  • 顯示屏夜晚會自動調暗,日頭會自動變光

下載同連結

完整原始碼提供喺呢篇文章下面。實用工具同參考資料,包括RGB顏色揀色器,亦都連結咗喺呢篇文章下面。

圖片

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
語言: 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();
  }
}

資源與參考資料

文件📁

Fritzing 文件