/*
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
MicroBeaut (μB)
changed for changes 10-Mar-2023?! @alto777
https://wokwi.com/projects/358876197860297729
*/
# include <Adafruit_NeoPixel.h>
# define PIN 8 //Neopixel pin with PWM
# define NUMPIXELS 12 // number of LEDs on strip
Adafruit_NeoPixel strip(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); // Declare our NeoPixel strip object
class TimerOn {
private:
bool prevInput;
bool state;
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 1000L // Random Min x milliseconds
#define RANDOM_MAX 7000L // Random Mzx y milliseconds
const uint8_t numberOfPipes = 8; // Number of Pipes
TimerOn pipeTimerOns[numberOfPipes]; // Timer On objects
TimerOn myTO;
void setup() {
Serial.begin(115200);
Serial.println(" timer focus \n");
randomSeed(analogRead(0));
strip.begin();
// strip check - are we talking or what?
if (1) {
strip.setPixelColor(7, 0xffffff);
strip.show();
delay(777);
}
for (uint8_t index = 0; index < numberOfPipes; index++) {
long newDelay = random(RANDOM_MIN, RANDOM_MAX); //Initial Random Time n milliseconds
pipeTimerOns[index].setTimeDelay(newDelay); // Set delay time to object
}
}
unsigned long now;
void loop() {
now = millis();
RunGame();
rainbow();
}
void RunGame() {
for (uint8_t index = 0; index < numberOfPipes; index++) {
pipeTimerOns[index].timerOn(true); // True = Enable or 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
Serial.print(millis()); Serial.print(" dropping ");
Serial.print(index); Serial.print(" delay ");
Serial.print(newDelay); Serial.print(" to next");
Serial.println("");
}
}
}
// modified from Adafruit example to make it a state machine
void rainbow()
{
static uint16_t j = 0;
static unsigned long lastUpdate;
if (now - lastUpdate < 40)
return;
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i + j) & 255));
}
strip.show();
j++;
if (j >= 256) j = 0;
lastUpdate = now; // time for next change to the display
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}