/*
Solution For:
Topics: Combine multiple millis() to control relais and neopixel simultanious
Category: Programming Questions
Link: https://forum.arduino.cc/t/combine-multiple-millis-to-control-relais-and-neopixel-simultanious/1099091
Sketch: AuCP_RandomPipes.ino
Created: 11-Mar-2023 (GMT+7)
MicroBeaut (μB)
*/
/*
===========================================================================
Class: TimerOn
The rising edge of input "input" starts a timer of duration "timeDelay".
When the elapsed time is greater than or equal to "timeDelay",
the timer stops and output changes from FALSE to TRUE.
The next falling edge of input "input" initializes the timer
===========================================================================
*/
class TimerOn {
private:
bool prevInput = false;
bool state = false;
unsigned long startTime;
unsigned long timeDelay;
public:
TimerOn() {
prevInput = false;
state = false;
timeDelay = 500000UL;
}
// Convert milliseconds to microseconds
void setTimeDelay(long msTimeDelay) {
timeDelay = msTimeDelay * 1000UL;
}
// Timer ON Condition
bool timerOn(bool input = true) {
if (input) {
if (!prevInput) {
startTime = micros();
} else if (!state) {
unsigned long elapsedTime = micros() - startTime;
if (elapsedTime >= timeDelay) {
elapsedTime = timeDelay;
state = true;
}
}
} else {
state = false;
}
prevInput = input;
return state;
}
bool done() {
return state;
}
};
#define RANDOM_MIN 100L // Random Min x milliseconds
#define RANDOM_MAX 1000L // Random Max y milliseconds
const uint8_t numberOfPipes = 8; // Number of Pipes
TimerOn pipeTimerOns[numberOfPipes]; // Timer On objects
void setup() {
Serial.begin(115200);
for (uint8_t index = 0; index < numberOfPipes; index++) {
randomSeed(analogRead(0)); // Use an unconnected pin for randomSeed()
long newDelay = random(RANDOM_MIN, RANDOM_MAX); // Initial Random Time n milliseconds
pipeTimerOns[index].setTimeDelay(newDelay); // Set delay time to object
}
}
void loop() {
RunGame();
}
void RunGame() {
for (uint8_t index = 0; index < numberOfPipes; index++) {
pipeTimerOns[index].timerOn(true); // True = Enable, Start, False = Disable or Stop or Reset
if (pipeTimerOns[index].done()) { // Timer On Done?
pipeTimerOns[index].timerOn(false); // Reset Timer On
randomSeed(analogRead(0)); // Use an unconnected pin for randomSeed()
long newDelay = random(RANDOM_MIN, RANDOM_MAX); // New Random Time n milliseconds
pipeTimerOns[index].setTimeDelay(newDelay); // Set delay time to object
// START PRINT - NEW PIPE AND TIMER INFO.
char charArray[10];
unsigned long currTime = micros();
sprintf(charArray, "T%06lu", currTime / 1000UL);
Serial.print(charArray);
Serial.print(" - New Pipe ");
Serial.print(index + 1);
Serial.print(", Next Time: ≈");
sprintf(charArray, "T%06lu", (currTime + newDelay * 1000UL) / 1000UL + 1UL);
Serial.println(charArray);
// END PRINT - NEW PIPE AND TIMER INFO.
}
}
}