#include <FastLED.h>
//////////////////////////////////////////////////
// Global default constants
//////////////////////////////////////////////////
namespace gdc {
constexpr uint8_t dataPin {16};
constexpr unsigned int numLeds {32};
constexpr unsigned long delay_ms {250};
constexpr unsigned long printDelay_ms {1500};
} // namespace gdc
//////////////////////////////////////////////////
// Class and structure definitions
//////////////////////////////////////////////////
class Timer {
public:
void start() { timeStamp = millis(); }
bool operator()(const ulong duration) const { return (millis() - timeStamp >= duration) ? true : false; }
private:
ulong timeStamp {0};
};
struct ColorBlocksData {
unsigned from;
unsigned to;
unsigned color;
};
//////////////////////////////////////////////////
// Global variables
//////////////////////////////////////////////////
constexpr ColorBlocksData blockFour[] {
{0, 3, CRGB::Blue },
{4, 7, CRGB::Red },
{8, 11, CRGB::Green },
{12, 15, CRGB::Yellow},
{16, 19, CRGB::Blue },
{20, 23, CRGB::Red },
{24, 27, CRGB::Green },
{28, 31, CRGB::Yellow}
};
constexpr ColorBlocksData blockTwo[] {
{0, 1, CRGB::Blue },
{2, 3, CRGB::Red },
{4, 5, CRGB::Green },
{6, 7, CRGB::Yellow},
{8, 9, CRGB::Blue },
{10, 11, CRGB::Red },
{12, 13, CRGB::Green },
{14, 15, CRGB::Yellow},
{16, 17, CRGB::Blue },
{18, 19, CRGB::Red },
{20, 21, CRGB::Green },
{22, 23, CRGB::Yellow},
{24, 25, CRGB::Blue },
{26, 27, CRGB::Red },
{28, 29, CRGB::Green },
{30, 31, CRGB::Yellow}
};
CRGB leds[gdc::numLeds];
//////////////////////////////////////////////////
// Global size constants
//////////////////////////////////////////////////
namespace gsc {
constexpr size_t numColorBlocks {sizeof(blockFour) / sizeof(blockFour[0])};
} // namespace gsc
//////////////////////////////////////////////////
// Functions
//////////////////////////////////////////////////
template <size_t N> unsigned setColorBlock(CRGB (&led)[N], unsigned from, unsigned to, unsigned color) {
if (to < N && from < N) {
for (size_t i {from}; i <= to; ++i) { led[i] = color; }
}
return to;
}
template <size_t N, size_t M>
size_t cbFullLoop(CRGB (&leds)[N], const ColorBlocksData (&cbd)[M], unsigned long delay_ms) {
static Timer wait;
static size_t idx {0};
static bool setColor {true};
if (!wait(delay_ms)) {
return idx;
} else {
wait.start();
}
// --idx is UNSIGEND !!!!
if (setColor && !(idx < M)) {
idx = M - 1;
setColor = false;
} else if (!setColor && !(idx < M)) {
idx = 0;
setColor = true;
}
switch (setColor) {
case true:
setColorBlock(leds, cbd[idx].from, cbd[idx].to, cbd[idx].color);
++idx;
break;
case false:
setColorBlock(leds, cbd[idx].from, cbd[idx].to, CRGB::Black);
--idx;
break;
}
return idx;
}
//////////////////////////////////////////////////
// Main Program
//////////////////////////////////////////////////
void setup() {
Serial.begin(115200);
FastLED.addLeds<WS2812, gdc::dataPin, GRB>(leds, gdc::numLeds);
FastLED.setBrightness(255);
FastLED.clear();
while (cbFullLoop(leds, blockFour, gdc::delay_ms) < gsc::numColorBlocks + 1) { FastLED.show(); }
Serial.println(F("Verlasse Setup\n"));
}
void loop() {
static Timer printTimer;
static unsigned long counter {0};
cbFullLoop(leds, blockTwo, gdc::delay_ms);
FastLED.show();
if (printTimer(gdc::printDelay_ms)) {
counter++;
Serial.print(counter);
Serial.println(F(" Neben dem Steuern der LEDs, kann ich auch noch andere Dinge tun..."));
printTimer.start();
}
}