From ef87855b78df81164500d6190bfa7e701054aa5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Ha=C3=9Fel?= Date: Wed, 12 Mar 2025 21:52:18 +0100 Subject: [PATCH] countdown running (not resettable) --- src/Color.cpp | 17 ++++++++++ src/Color.h | 31 ++++++++++++++++++ src/display.cpp | 85 +++++++++++++++++++++++++++++++++++++++++++++++++ src/display.h | 14 ++++++++ src/main.cpp | 78 ++++++++++++++++++++++++--------------------- 5 files changed, 189 insertions(+), 36 deletions(-) create mode 100644 src/Color.cpp create mode 100644 src/Color.h create mode 100644 src/display.cpp create mode 100644 src/display.h diff --git a/src/Color.cpp b/src/Color.cpp new file mode 100644 index 0000000..c1c1add --- /dev/null +++ b/src/Color.cpp @@ -0,0 +1,17 @@ +#include "Color.h" + +#define ___ 0 +#define TTT 85 +#define HHH 127 +#define XXX 255 + +// @formatter:off +Color RED (XXX, ___, ___); +Color YELLOW (HHH, HHH, ___); +Color GREEN (___, XXX, ___); +Color TURQUOISE (___, HHH, HHH); +Color BLUE (___, ___, XXX); +Color MAGENTA (HHH, ___, HHH); +Color WHITE (TTT, TTT, TTT); +Color BLACK (___, ___, ___); +// @formatter:on diff --git a/src/Color.h b/src/Color.h new file mode 100644 index 0000000..5963caa --- /dev/null +++ b/src/Color.h @@ -0,0 +1,31 @@ +#ifndef WS2812B_COLOR_H +#define WS2812B_COLOR_H + +#include + +struct Color { + uint8_t r, g, b; + + Color(uint8_t r, uint8_t g, uint8_t b) : r(r), g(g), b(b) { + // + } + +}; + +extern Color RED; + +extern Color YELLOW; + +extern Color GREEN; + +extern Color TURQUOISE; + +extern Color BLUE; + +extern Color MAGENTA; + +extern Color WHITE; + +extern Color BLACK; + +#endif diff --git a/src/display.cpp b/src/display.cpp new file mode 100644 index 0000000..77a9d26 --- /dev/null +++ b/src/display.cpp @@ -0,0 +1,85 @@ +#include "display.h" + +#define SEGMENTS_PER_DIGIT 7 +#define LEDS_PER_SEGMENT 6 +#define LEDS_PER_DOT 2 +#define DOT_COUNT 4 +#define DOTS_AFTER_DIGIT 1 + +uint8_t CHARS[] = { + 0b11111100, // 0 + 0b00110000, // 1 + 0b01101110, // 2 + 0b01111010, // 3 + 0b10110010, // 4 + 0b11011010, // 5, S + 0b11011110, // 6 + 0b01110000, // 7 + 0b11111110, // 8 + 0b11111010, // 9 + 0b11100110, // P + 0b11110110, // A + 0b10111100, // U +}; + +int toIndex(char c) { + if (c >= '0' && c <= '9') { + return c - '0'; + } + switch (c) { + case 'P': + return 10; + } + return -1; +} + +uint8_t mapChar(char c) { + const int index = toIndex(c); + if (index >= 0) { + return CHARS[index]; + } + return 0; +} + +void drawChar(Adafruit_NeoPixel& pixels, int digit, char c, bool showIfZero, Color& color) { + if (c == '0' && !showIfZero) { + return; + } + auto pixel = digit * SEGMENTS_PER_DIGIT * LEDS_PER_SEGMENT + (digit > DOTS_AFTER_DIGIT ? DOT_COUNT * LEDS_PER_DOT : 0); + const auto symbol = mapChar(c); + Serial.printf(" character '%c'\n", c); + uint8_t symbolMask = 128; + for (int segment = 0; segment < SEGMENTS_PER_DIGIT; ++segment) { + const auto on = (symbol & symbolMask) != 0; + Serial.printf(" segment %d = %s\n", segment, on ? "ON" : "__"); + if (on) { + for (int led = 0; led < LEDS_PER_SEGMENT; ++led) { + pixels.setPixelColor(pixel, color.r, color.g, color.b); + pixel++; + } + } else { + pixel += LEDS_PER_SEGMENT; + } + symbolMask >>= 1; + } +} + +void drawNumber(Adafruit_NeoPixel& pixels, int digit, int number, bool zero, Color& color) { + const char ten = '0' + (number / 10 % 10); + const char one = '0' + (number % 10); + drawChar(pixels, digit + 0, ten, zero, color); + drawChar(pixels, digit + 1, one, true, color); +} + +void drawDot(Adafruit_NeoPixel& pixels, int dot, const Color& c) { + int index = 2 * SEGMENTS_PER_DIGIT * LEDS_PER_SEGMENT + dot * LEDS_PER_DOT; + pixels.setPixelColor(index++, c.r, c.g, c.b); + pixels.setPixelColor(index++, c.r, c.g, c.b); +} + +void drawDots(Adafruit_NeoPixel& pixels, Color& bottom, Color& middleBottom, Color& middleTop, Color& top) { + drawDot(pixels, 0, bottom); + drawDot(pixels, 1, middleBottom); + drawDot(pixels, 2, middleTop); + drawDot(pixels, 3, top); +} diff --git a/src/display.h b/src/display.h new file mode 100644 index 0000000..e300baf --- /dev/null +++ b/src/display.h @@ -0,0 +1,14 @@ +#ifndef WS2812B_DISPLAY_H +#define WS2812B_DISPLAY_H + +#include + +#include "Color.h" + +void drawChar(Adafruit_NeoPixel& pixels, int digit, char c, bool showIfZero, Color& color); + +void drawNumber(Adafruit_NeoPixel& pixels, int digit, int number, bool zero, Color& color); + +void drawDots(Adafruit_NeoPixel& pixels, Color& bottom, Color& middleBottom, Color& middleTop, Color& top); + +#endif diff --git a/src/main.cpp b/src/main.cpp index f147a32..6155788 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,4 @@ -#include - -#define countof(a) (sizeof(a) / sizeof((a)[0])) - -#define ___ 0 -#define TTT 85 -#define HHH 127 -#define XXX 255 +#include "display.h" #define GPIO 26 #define PIXELS (4 * 7 * 6 + 4 * 4) @@ -13,26 +6,6 @@ Adafruit_NeoPixel pixels(PIXELS, GPIO, NEO_GRB + NEO_KHZ800); -struct color { - uint8_t r, g, b; -}; - -color colors[] = { - {XXX, ___, ___}, - {HHH, HHH, ___}, - {___, XXX, ___}, - {___, HHH, HHH}, - {___, ___, XXX}, - {HHH, ___, HHH}, - {TTT, TTT, TTT}, -}; - -color *c = colors; - -int step = 0; - -int dir = 1; - void setup() { delay(500); Serial.begin(115200); @@ -40,15 +13,48 @@ void setup() { pixels.begin(); pixels.setBrightness(BRIGHTNESS); pixels.clear(); + pixels.show(); +} + +long configCountdownSeconds = 65; + +long countdownRestMillis = configCountdownSeconds * 1000; + +unsigned long last = 0; + +void updateTime() { + const auto now = max(1UL, millis()); + if (last != 0) { + const auto diff = now - last; + countdownRestMillis -= (long) diff; + if (countdownRestMillis < 0) { + countdownRestMillis = 0; + } + } + last = now; +} + +void showTime() { + const auto secondsTotal = (unsigned long) ceil(countdownRestMillis / 1000.0); + const auto minutes = (int) secondsTotal / 60; + const auto seconds = (int) secondsTotal % 60; + + static auto lastSeconds = -1; + if (lastSeconds == seconds) { + return; + } + lastSeconds = seconds; + + Serial.printf("%2d:%02d\n", minutes, seconds); + + pixels.clear(); + drawNumber(pixels, 0, minutes, false, WHITE); + drawDots(pixels, BLACK, WHITE, WHITE, BLACK); + drawNumber(pixels, 2, seconds, true, WHITE); + pixels.show(); } void loop() { - pixels.setPixelColor(step, c->r, c->g, c->b); - pixels.show(); - - step += dir; - if (step < 0 || step > PIXELS - 1) { - dir = -dir; - c = (c + 1 - colors) % countof(colors) + colors; - } + updateTime(); + showTime(); }