Multitasking example clock
Instead of using the delay()
function we use the millis()
to find the right point in time to trigger the next steps.
The idea is to have four thing to display:
- a display for the 1/100s of a second
we use a filling circle, which alternates between light and dark mode - seconds
we use a green dot - minutes
we use a red dot - hours
we use a blue dot
If the dots are overlaying each other we use different colors, eg. red + green = yellow. As the arduino does not have an onboard real time clock, we always start at 00h 00m 00s 000hs.
The code:
/* Clock with a 16 LED NeoPixel ring (C) 2016 -mat- filid brandy, brandy@linuxpinguin.de */ // Settings for the NeoPixel #include <Adafruit_NeoPixel.h> #define stripSize 16 Adafruit_NeoPixel strip = Adafruit_NeoPixel( stripSize, 6, NEO_GRB + NEO_KHZ800 ); // Time keeping #define hs 0 #define s 1 #define m 2 #define h 3 unsigned long Diff[4]; unsigned long Max[4]; unsigned long Tick[4]; unsigned long Uhr[4]; unsigned int Pixel[4]; float Ratio[4]; bool reverse = LOW; bool toggle = LOW; // Colors uint32_t colors[9]; #define black 0 #define white 1 #define red 2 #define green 3 #define blue 4 #define purple 5 #define cyan 6 #define yellow 7 #define all 8 #define light 8 void setup() { // Initialize the strip strip.begin(); strip.show(); Max[hs] = 100; Max[s] = 60; Max[m] = 60; Max[h] = 12; Diff[hs] = 10; Diff[s] = 1000; Diff[m] = 60000; Diff[h] = 3600000; for (int i = 0; i < 4; i++) { Tick[i] = 0; Uhr[i] = 0; Pixel[i] = 0; Ratio[i] = (float)Max[i] / (float)stripSize; } // fill in the wanted colors colors[black] = strip.Color(0, 0, 0); colors[white] = strip.Color(light / 4, light / 4, light / 4); colors[red] = strip.Color(light, 0, 0); colors[green] = strip.Color(0, light, 0); colors[blue] = strip.Color(0, 0, light); colors[purple] = strip.Color(light, 0, light); colors[cyan] = strip.Color(0, light, light); colors[yellow] = strip.Color(light, light, 0); colors[all] = strip.Color(light * 2, light * 2, light * 2); } void loop() { // This is based on the internal Ticker unsigned long cTick = millis(); // Find the trigger points in Tick for (int i = 0; i < 4; i++) { if ( (cTick - Tick[i]) >= Diff[i] ) { Tick[i] = cTick; Uhr[i] = ( ++Uhr[i] < Max[i] ) ? Uhr[i] : 0; } } if ( 0 == Uhr[hs] && !toggle) { reverse = !reverse; toggle = HIGH; } if ( 1 == Uhr[hs] ) { toggle = LOW; } // Calculate the display of for (int16_t p = 0; p < stripSize; p++) { strip.setPixelColor(p, colors[black]); // Find the points for the hs, s, m, h for (int j = 0; j < 4; j++) { if ( ( (float)(p) * Ratio[j] <= Uhr[j] ) && ( Uhr[j] < (float)(p + 1) * Ratio[j] ) ) { Pixel[j] = stripSize - p - 1; } } } // 1/100s animation for (int16_t p = 0; p < stripSize; p++ ) { if (Pixel[hs] < p) { if (reverse) strip.setPixelColor(p, colors[white]); else strip.setPixelColor(p, colors[black]); } else { if (reverse) strip.setPixelColor(p, colors[black]); else strip.setPixelColor(p, colors[white]); } } // Paint the points strip.setPixelColor(Pixel[hs], colors[white]); strip.setPixelColor(Pixel[s], colors[green]); strip.setPixelColor(Pixel[m], colors[red]); strip.setPixelColor(Pixel[h], colors[blue]); // Handle overlaying points // double if ( Pixel[s] == Pixel[m] ) strip.setPixelColor(Pixel[m], colors[yellow]); if ( Pixel[s] == Pixel[h] ) strip.setPixelColor(Pixel[h], colors[cyan]); if ( Pixel[m] == Pixel[h] ) strip.setPixelColor(Pixel[h], colors[purple]); // triple if ( ( Pixel[m] == Pixel[h] ) && ( Pixel[s] == Pixel[m]) ) strip.setPixelColor(Pixel[h], colors[all]); // Tada! strip.show(); }
Recent Comments