Search Code

Projekt internetových hodín s RGB LED maticou ESP32-S3 - 5 dúhových farieb

Projekt internetových hodín s RGB LED maticou ESP32-S3 - 5 dúhových farieb

ESP32-S3 internetové hodiny s dúhovým farebným efektom

Tento projekt sú ESP32-S3 RGB Matrix internetové hodiny, ktoré sa pripájajú k Wi-Fi, synchronizujú miestny čas z NTP servera a posúvajú čas vo formáte HH:MM cez vstavanú 8×8 RGB NeoMatrix maticu. Na rozdiel od verzií s pevnou alebo náhodnou farbou tieto hodiny používajú plynulý dúhový farebný efekt, kde sa každý znak pri posúvaní plynule mení cez RGB spektrum. Hodiny tiež pravidelne zobrazujú dátum a automaticky upravujú jas medzi dňom a nocou.

ESP32-s3_internet_clock_animation

Ako tieto hodiny fungujú

Po napájaní cez USB-C sa ESP32-S3 pripojí k vašej Wi-Fi sieti a získa aktuálny miestny čas z internetu. Displej normálne posúva čas, ale v definovanom intervale sa prepne na zobrazenie dátumu. Čas aj dátum sú vykreslené pomocou dynamického dúhového efektu, čo vytvára živý a animovaný displej na malej 8×8 matici.

Použité knižnice

Sketch sa spolieha na nasledujúce knižnice:

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

Nainštalujte Adafruit NeoMatrix pomocou Arduino Library Manager. Jeho závislosti vrátane Adafruit GFX Library a Adafruit NeoPixel sa nainštalujú automaticky.

Dôležitá konfigurácia používateľa

Dátový pin matice (vstavaná RGB matica)

Aj keď je RGB matica pripojená k doske ESP32-S3, dátový pin musí byť stále definovaný v kóde:

#define MATRIX_PIN 14

GPIO 14 sa bežne používa na ESP32-S3 RGB matrix doskách. Ak váš variant dosky používa iný pin, aktualizujte túto hodnotu.

Wi-Fi SSID a heslo (rozlišujú sa veľké a malé písmená)

Nahraďte Wi-Fi prihlasovacie údaje vašimi sieťovými údajmi:

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

Dôležité: Wi-Fi SSID rozlišuje veľké a malé písmená. SSID s názvom "Book" nie je to isté ako "book". Ak sa veľkosť písmen presne nezhoduje, ESP32-S3 sa nepripojí.

NTP server, časové pásmo a letný čas

Hodiny synchronizujú čas pomocou internetového NTP servera:

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

Miestny čas sa vypočíta pomocou týchto offsetov:

// Toronto-ish: UTC-5, plus 1 hour DST
const long  gmtOffset_sec     = -5 * 3600;
const int   daylightOffset_sec = 3600;
  • gmtOffset_sec: UTC offset v sekundách (príklad: UTC-5 = -5 * 3600)
  • daylightOffset_sec: Použite 3600, ak je aktívny letný čas, alebo 0, ak sa nepoužíva

Tieto hodnoty sa aplikujú pomocou:

configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

Automatický jas deň / noc

Jas sa automaticky mení na základe aktuálnej hodiny:

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

Medzi 22:00 a 6:00 sa matica stlmí, aby sa znížilo oslnenie. Počas denných hodín sa obnoví normálny jas.

Dúhový farebný efekt

Tento projekt používa klasické RGB farebné koleso na generovanie plynulých dúhových farieb. Každý znak je vykreslený s mierne odlišným farebným offsetom a farby sa v priebehu času posúvajú, čo vytvára plynulú dúhovú animáciu.

// 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);
}

Keď sa text posúva, každý znak prechádza cez RGB spektrum, čo vytvára nepretržitý dúhový efekt, ktorý vyzerá obzvlášť pôsobivo na malej 8×8 obrazovke.

Správanie zobrazenia času a dátumu

Hodiny udržiavajú samostatné buffery pre čas a dátum:

  • Čas: HH:MM
  • Dátum: MMM DD (napríklad JAN 08)

Dátum sa zobrazuje v pevnom intervale:

const uint32_t dateIntervalMs = 60000; // Show date every 1 minute

Na konci každého úplného cyklu posúvania kód rozhodne, či bude pokračovať v zobrazovaní času alebo prepne na dátum.

Logika posúvania na 8×8 matici

Pretože displej je široký iba 8 pixelov, text sa plynulo posúva sprava doľava. Keď text úplne opustí obrazovku, kurzor sa resetuje a na ďalší prechod sa načíta ďalší obsah (čas alebo dátum).

Demonštrácia

Po nahratí sketchu a napájaní dosky cez USB-C:

  • ESP32-S3 sa pripojí k vašej Wi-Fi sieti
  • Čas sa synchronizuje z internetu
  • Čas sa posúva vo formáte HH:MM
  • Dátum sa zobrazuje pravidelne
  • Všetok text je vykreslený s plynulým animovaným dúhovým efektom
  • Displej sa automaticky stlmí v noci a rozjasní počas dňa

Downloady a odkazy

Kompletný zdrojový kód je uvedený nižšie v tomto článku. Užitočné nástroje a referencie, vrátane výberu farieb RGB, sú tiež prepojené nižšie v tomto článku.

Images

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

Resources & references

Files📁

Fritzing File