/*
ESP32-C3 Mini — WiFi NTP Clock on 32x8 WS2812B NeoPixel Matrix
India Standard Time (UTC+5:30)
Arvind Patil / AI Centre Nandurbar
Wiring:
NeoPixel DIN -> GPIO4 (330ohm resistor inline)
NeoPixel 5V -> 5V / VBUS
NeoPixel GND -> GND (common ground with ESP32-C3)
1000uF capacitor across matrix 5V/GND recommended.
Libraries required (Library Manager):
- Adafruit NeoMatrix
- Adafruit NeoPixel
- Adafruit GFX Library
*/
#include <WiFi.h>
#include <time.h>
#include <Adafruit_NeoPixel.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
// ---------- USER CONFIG ----------
const char* WIFI_SSID = "Airtel_aevi_6035";
const char* WIFI_PASSWORD = "air262829";
#define MATRIX_PIN 5
#define MATRIX_W 32
#define MATRIX_H 8
#define BRIGHTNESS 40 // keep low: 256 LEDs on USB power budget
// IST = UTC + 5:30, no daylight saving
const long GMT_OFFSET_SEC = 5 * 3600 + 1800;
const int DAYLIGHT_OFFSET_SEC = 0;
const char* NTP_SERVER = "pool.ntp.org";
// ----------------------------------
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(
MATRIX_W, MATRIX_H, MATRIX_PIN,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG,
NEO_GRB + NEO_KHZ800
);
uint16_t colorGold, colorGreen, colorCyan, colorRed;
uint16_t currentColor;
int colorCycle = 0;
int scrollX = MATRIX_W;
unsigned long lastScrollMove = 0;
unsigned long lastColonBlink = 0;
bool colonOn = true;
enum Mode { MODE_TIME, MODE_SECONDS, MODE_SCROLL_DATE };
Mode mode = MODE_TIME;
unsigned long lastModeSwitch = 0;
const unsigned long MODE_DURATION_MS = 15000; // rotate every 15s
void connectWiFi() {
matrix.fillScreen(0);
matrix.setCursor(0, 0);
matrix.setTextColor(colorGold);
matrix.print("WIFI");
matrix.show();
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
unsigned long start = millis();
while (WiFi.status() != WL_CONNECTED && millis() - start < 20000) {
delay(300);
}
if (WiFi.status() == WL_CONNECTED) {
Serial.print("Connected. IP: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("WiFi connection failed, will retry in loop().");
}
}
void syncTime() {
configTime(GMT_OFFSET_SEC, DAYLIGHT_OFFSET_SEC, NTP_SERVER);
struct tm timeinfo;
int attempts = 0;
while (!getLocalTime(&timeinfo) && attempts < 10) {
delay(500);
attempts++;
}
}
void setup() {
Serial.begin(115200);
matrix.begin();
matrix.setTextWrap(false);
matrix.setBrightness(BRIGHTNESS);
matrix.setTextSize(1);
colorGold = matrix.Color(224, 184, 74);
colorGreen = matrix.Color(56, 255, 106);
colorCyan = matrix.Color(77, 224, 255);
colorRed = matrix.Color(255, 59, 59);
currentColor = colorGold;
connectWiFi();
if (WiFi.status() == WL_CONNECTED) {
syncTime();
}
}
void drawClockFace(struct tm &t, bool showSeconds) {
matrix.fillScreen(0);
matrix.setTextColor(currentColor);
char buf[12];
if (showSeconds) {
// HH:MM:SS scaled tighter; fallback HH:MM with blinking colon if it overflows 32px
snprintf(buf, sizeof(buf), "%02d:%02d:%02d", t.tm_hour, t.tm_min, t.tm_sec);
} else {
snprintf(buf, sizeof(buf), "%02d%c%02d", t.tm_hour, colonOn ? ':' : ' ', t.tm_min);
}
matrix.setCursor(showSeconds ? -8 : 1, 0);
matrix.print(buf);
matrix.show();
}
void drawScrollDate(struct tm &t) {
static const char* days[] = {"SUN","MON","TUE","WED","THU","FRI","SAT"};
static const char* mons[] = {"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"};
char buf[40];
snprintf(buf, sizeof(buf), "%s %d %s IST ",
days[t.tm_wday], t.tm_mday, mons[t.tm_mon]);
matrix.fillScreen(0);
matrix.setTextColor(currentColor);
matrix.setCursor(scrollX, 0);
matrix.print(buf);
matrix.show();
int textWidthPx = strlen(buf) * 6;
if (--scrollX < -textWidthPx) scrollX = MATRIX_W;
}
void loop() {
// reconnect handling
if (WiFi.status() != WL_CONNECTED) {
connectWiFi();
if (WiFi.status() == WL_CONNECTED) syncTime();
}
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
delay(500);
return;
}
unsigned long now = millis();
// rotate display mode
if (now - lastModeSwitch > MODE_DURATION_MS) {
lastModeSwitch = now;
mode = (Mode)((mode + 1) % 3);
scrollX = MATRIX_W;
}
// blink colon every 500ms in MODE_TIME
if (now - lastColonBlink > 500) {
lastColonBlink = now;
colonOn = !colonOn;
}
switch (mode) {
case MODE_TIME:
drawClockFace(timeinfo, false);
delay(60);
break;
case MODE_SECONDS:
drawClockFace(timeinfo, true);
delay(200);
break;
case MODE_SCROLL_DATE:
if (now - lastScrollMove > 60) {
lastScrollMove = now;
drawScrollDate(timeinfo);
}
break;
}
}
Loading
esp32-c3-devkitm-1
esp32-c3-devkitm-1