using uint = unsigned int;
using ulong = unsigned long;
constexpr byte LED_PINS[5] {3, 4, 5, 6, 7};
// Time im milliseconds (ms)
constexpr ulong LIGHT_DELAY_MS {500}; // Time between two LDR measurements
// Class / struct Definition(s)
//////////////////////////////////////////////////////////////////////////////
/// @brief Helper class for non-blocking execution of
/// code sections at certain intervals.
///
//////////////////////////////////////////////////////////////////////////////
class Interval {
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief Determine whether the specified interval has expired.
///
/// @param duration Interval duration
/// @return true when the interval has elapsed
/// @return false interval not elapsed yet
//////////////////////////////////////////////////////////////////////////////
bool operator()(const ulong duration) {
if (false == isStarted) { return start(false); }
return (millis() - timeStamp >= duration) ? start(true) : retFalse();
}
private:
bool start(bool state = false) {
isStarted = !state; // Set the value to true on the first call
timeStamp = millis();
return state;
}
bool retFalse() { return false; }
private:
bool isStarted {false}; // Flag = true if the first Operator() call has been made.
ulong timeStamp {0};
};
// Class / struct Definition(s) end
//
// Global variables/objects
//
Interval timer;
//
// Functions
//
template <size_t N> void setLeds(const byte (&pins)[N], byte &lastIdx ){
byte idx;
do { // Prevents the same (random)number from being used twice in a row.
idx = random(0, N);
} while (idx == lastIdx);
digitalWrite(pins[lastIdx], LOW);
lastIdx = idx;
digitalWrite(pins[idx], HIGH);
}
//
// Main
//
void setup() {
Serial.begin(115200);
for (auto pin : LED_PINS) { pinMode(pin, OUTPUT); }
randomSeed(A0);
}
void loop() {
static byte currentLedIndex {0};
if (true == timer(LIGHT_DELAY_MS)) { setLeds(LED_PINS, currentLedIndex); }
}