#include <FastLED.h>
// #include <DS3232RTC.h> // for normal Arduino project
#include "DS3232RTC.h" // for Wokwi simulation
#define NUM_LEDS 288
#define DATA_PIN 6
#define BRIGHTNESS 255 // more brightness is better for wokwi, was 50
CRGB leds[NUM_LEDS];
#define columns 24
#define rows 12
DS3232RTC myRTC(false);
tmElements_t tm;
uint8_t col;
uint8_t row;
int r;
uint8_t number = 0;
uint8_t xpos = 1; //x=column
uint8_t ypos = 1; //y=row
uint8_t hr10;
uint8_t hr1;
uint8_t min10;
uint8_t min1;
const uint8_t digits[10][35] = {
{ 14, 26, 38, 50, 3, 15, 51, 63, 4, 40, 64, 5, 29, 41, 65, 6, 42, 66, 7, 31, 67, 8, 32, 44, 68, 9, 33, 69, 10, 70, 23, 35, 47, 59 },
{ 26, 38, 50, 15, 51, 4, 52, 5, 17, 29, 53, 18, 54, 19, 55, 20, 56, 9, 21, 57, 69, 10, 70, 11, 23, 35, 47, 59, 71 },
{ 14, 26, 38, 50, 3, 63, 4, 16, 28, 64, 29, 65, 18, 54, 7, 43, 8, 32, 44, 56, 68, 9, 69, 10, 70, 11, 23, 35, 47, 59 },
{ 14, 26, 38, 50, 3, 63, 4, 16, 28, 64, 29, 65, 18, 54, 19, 55, 8, 20, 32, 68, 9, 69, 10, 70, 23, 35, 47, 59 },
{ 26, 38, 50, 27, 51, 16, 52, 17, 53, 6, 42, 66, 7, 67, 8, 20, 32, 44, 68, 45, 69, 46, 70, 47, 59, 71 },
{ 2, 14, 26, 38, 50, 62, 3, 63, 4, 64, 5, 29, 41, 53, 6, 42, 19, 55, 32, 68, 9, 21, 33, 69, 10, 70, 23, 35, 47, 59 },
{ 26, 38, 50, 62, 15, 63, 16, 52, 64, 5, 41, 6, 42, 54, 7, 67, 8, 32, 68, 9, 33, 45, 69, 10, 70, 23, 35, 47, 59 },
{ 2, 14, 26, 38, 50, 62, 3, 63, 4, 16, 28, 40, 64, 41, 65, 42, 66, 31, 67, 32, 56, 21, 57, 22, 46, 23, 35, 47 },
{ 14, 26, 38, 50, 3, 63, 4, 28, 40, 64, 5, 41, 65, 18, 54, 7, 67, 8, 32, 44, 68, 9, 45, 69, 10, 70, 23, 35, 47, 59 },
{ 14, 26, 38, 50, 3, 63, 4, 28, 40, 64, 5, 41, 65, 6, 66, 19, 31, 67, 32, 68, 9, 21, 57, 10, 58, 11, 23, 35, 47 }
};
void setup() {
Serial.begin(9600);
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
FastLED.clear();
delay(500);
}
void loop() {
delay(100);
FastLED.show();
FastLED.clear();
RTC.read(tm);
displaytime();
flashborder();
}
void displaytime() {
hr10 = tm.Hour / 10;
hr1 = tm.Hour % 10;
min10 = tm.Minute / 10;
min1 = tm.Minute % 10;
Displaynumber(hr10, 1, 1);
Displaynumber(hr1, 7, 1);
Displaynumber(min10, 13, 1);
Displaynumber(min1, 19, 1);
if (xpos >= columns)
xpos = 0;
if (ypos > rows)
ypos = 0;
}
void Displaynumber(uint8_t number, uint8_t xpos, uint8_t ypos) {
for (uint8_t i = 0; i < 35; i++) {
uint8_t pixelnumber = digits[number][i];
if (pixelnumber == 0)
return 32767;
uint8_t x = (pixelnumber / 12) + xpos;
uint8_t y = ((pixelnumber - 1) % 12) + ypos;
if (x > columns)
x = x - columns;
if (y > rows)
y = y - rows;
r = { calcLEDposition(x, y) };
leds[r] += CHSV(number * 25 + xpos * 5, 255, 255);
}
}
void flashborder() {
if (tm.Second % 2 == 0) {
leds[276] = CRGB::White;
leds[287] = CRGB::White;
leds[11] = CRGB::White;
leds[0] = CRGB::White;
}
}
int calcLEDposition(uint8_t col, uint8_t row) { //Calculate the position of the LED to light up. column & row 0 are not displayed, 'overscan'areas! This is used to hide away artefacts at position 0,0 which I got otherwise
if (row == 0 || col == 0) {
return 32767;
}
if (col % 2 == 0) {
int r = (300 - ((col * 12) + row));
return r;
} else {
int r = (300 - ((col * 12) + (13 - row)));
return r;
}
}