Skip to content

Instantly share code, notes, and snippets.

@lean8086
Last active December 23, 2023 22:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lean8086/87455e205271c8d83e8e30e5d04b24d4 to your computer and use it in GitHub Desktop.
Save lean8086/87455e205271c8d83e8e30e5d04b24d4 to your computer and use it in GitHub Desktop.
#include "FastLED.h"
#define BTN_PIN 3
#define LED_PIN A3
#define LED_TYPE WS2812B
#define LED_COLOR 0x7aff0b
#define TOTAL_LEDS 110
#define BRIGHTNESS 123 /* 0 to 255 */
#define LOWEST_BRIGHTNESS 5 /* 0 to 255 */
#define CHUNK_SIZE_MS 300000 /* 5 minute chunks (1 sentence per chunk) */
#define INTERVAL_MS 250
#define HOUR_MAX_LEN 6 /* Maximum amount of letters an hour can have */
#define SENTENCE_MAX_LEN 24 /* Maximum amount of letters a sentence can have */
#define POWERUP_SAFETY_DELAY 3000 /* Avoid to fry the LEDs on startup */
CRGB leds[TOTAL_LEDS];
/* Clock starts at 9am (o'clock) */
int HOUR_LETTERS[12][HOUR_MAX_LEN] = {
{51,52,53,54}, /* N I N E */
{109,108,107}, /* T E N */
{82,81,80,79,78,77}, /* E L E V E N */
{93,94,95,96,97,98}, /* T W E L V E */
{65,64,63}, /* O N E */
{74,75,76}, /* T W O */
{59,58,57,56,55}, /* T H R E E */
{66,67,68,69}, /* F O U R */
{70,71,72,73}, /* F I V E */
{62,61,60}, /* S I X */
{88,89,90,91,92}, /* S E V E N */
{87,86,85,84,83} /* E I G H T */
};
/* Replaceable numbers is the fastest solution I found for variable hours */
/* e.g.: 888 = {hours}, 999 = {next hours} */
int SENTENCE_LETTERS[12][SENTENCE_MAX_LEN] = {
{0,1, 3,4, 104,103,102,101,100,99, 888}, /* IT IS {hs} O'CLOCK */
{0,1, 3,4, 28,29,30,31, 44,45,46,47, 888}, /* IT IS FIVE PAST {hs} */
{0,1, 3,4, 38,37,36, 44,45,46,47, 888}, /* IT IS TEN PAST {hs} */
{0,1, 3,4, 19,18,17,16,15,14,13, 44,45,46,47, 888}, /* IT IS QUARTER PAST {hs} */
{0,1, 3,4, 22,23,24,25,26,27, 44,45,46,47, 888}, /* IT IS TWENTY PAST {hs} */
{0,1, 3,4, 22,23,24,25,26,27, 28,29,30,31, 44,45,46,47, 888}, /* IT IS TWENTYFIVE PAST {hs} */
{0,1, 3,4, 43,42,41,40, 44,45,46,47, 888}, /* IT IS half PAST {hs} */
{0,1, 3,4, 22,23,24,25,26,27, 28,29,30,31, 34,33, 999}, /* IT IS TWENTYFIVE TO {next-hs} */
{0,1, 3,4, 22,23,24,25,26,27, 34,33, 999}, /* IT IS TWENTY TO {next-hs} */
{0,1, 3,4, 19,18,17,16,15,14,13, 34,33, 999}, /* IT IS QUARTER TO {next-hs} */
{0,1, 3,4, 38,37,36, 34,33, 999}, /* IT IS TEN TO {next-hs} */
{0,1, 3,4, 28,29,30,31, 34,33, 999} /* IT IS FIVE TO {next-hs} */
};
int manuallyEnteredChunk = 0; /* Updated with the button */
int currentSentenceOrder = 42; /* Answer to the ultimate question of life, the universe, and everything */
int prevHourOrder = 0;
void setup() {
delay(POWERUP_SAFETY_DELAY);
FastLED.addLeds<LED_TYPE, LED_PIN>(leds, TOTAL_LEDS);
FastLED.setBrightness(BRIGHTNESS);
/* Initialize button pin as a pull-up input. */
pinMode(BTN_PIN, INPUT_PULLUP);
}
void loop() {
int buttonState = digitalRead(BTN_PIN);
if (buttonState == LOW) {
manuallyEnteredChunk = manuallyEnteredChunk + 1;
}
int chunk = floor(millis() / CHUNK_SIZE_MS) + manuallyEnteredChunk;
int sentenceOrder = chunk % 12;
/* Avoid to change anything if there was no change in the sentence */
if (sentenceOrder != currentSentenceOrder) {
currentSentenceOrder = sentenceOrder;
int hourChunk = floor(chunk / 12);
int hourOrder24 = hourChunk % 24; /* 0 to 24 on HOUR_LETTERS */
cleanDisplay();
/* Only paint LEDs between 9am and 11pm */
if (hourOrder24 <= 13) {
/* Lower the brightness between 9pm and 9am */
FastLED.setBrightness(hourOrder24 >= 12 ? LOWEST_BRIGHTNESS : BRIGHTNESS);
for (int i = 0; i < SENTENCE_MAX_LEN; i++) {
int letter = SENTENCE_LETTERS[sentenceOrder][i];
if (letter < TOTAL_LEDS) {
paintLED(letter);
} else if (letter == 888) {
int hourOrder = hourChunk % 12; /* 0 to 12 */
for (int j = 0; j < HOUR_MAX_LEN; j++) {
paintLED(HOUR_LETTERS[hourOrder][j]);
}
} else if (letter == 999) {
int nextHourChunk = hourChunk + 1;
int nextHourOrder = nextHourChunk % 12; /* 0 to 12 */
for (int j = 0; j < HOUR_MAX_LEN; j++) {
paintLED(HOUR_LETTERS[nextHourOrder][j]);
}
}
}
}
FastLED.show();
}
delay(INTERVAL_MS);
}
void cleanDisplay() {
for (int i = 0; i < TOTAL_LEDS; i++) {
leds[i] = CRGB::Black;
}
}
void paintLED(int i) {
leds[i].setColorCode(LED_COLOR);
}
@lean8086
Copy link
Author

Connected pins

Top

  • GND: Negative (-) wire for the LED strip
  • VCC: Positive (+5V) wire for the LED strip
  • A3: Data for the LED strip (defined as LED_PIN in the code)

Bottom

  • GND: Negative (-) leg of the push button
  • 3: Positive (+) leg of the push button (defined as BTN_PIN in the code)

diagram

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment