yes a very simple code should get you going
The code will wait for a button (on pin 10) to be pressed to actually start the animation
constexpr uint8_t light1 = 2;
constexpr uint8_t light2 = 3;
constexpr uint8_t light3 = 4;
constexpr uint8_t light4 = 5;
constexpr uint8_t light5 = 6;
constexpr uint8_t light6 = 7;
constexpr uint8_t light7 = 8;
constexpr uint8_t smoke = 9;
constexpr uint8_t button = 10;
void setup() {
pinMode(light1, OUTPUT);
pinMode(light2, OUTPUT);
pinMode(light3, OUTPUT);
pinMode(light4, OUTPUT);
pinMode(light5, OUTPUT);
pinMode(light6, OUTPUT);
pinMode(light7, OUTPUT);
pinMode(smoke, OUTPUT);
pinMode(button, INPUT_PULLUP);
while (digitalRead(button) != LOW) yield(); // wait for button press
// animation example
digitalWrite(smoke, HIGH);
digitalWrite(light1, HIGH);
delay(5000);
digitalWrite(light2, HIGH);
delay(3000);
digitalWrite(light1, LOW);
digitalWrite(light3, HIGH);
delay(4000);
digitalWrite(smoke, LOW);
digitalWrite(light4, HIGH);
delay(2000);
digitalWrite(light2, LOW);
digitalWrite(light5, HIGH);
delay(3000);
digitalWrite(light3, LOW);
digitalWrite(light6, HIGH);
delay(3000);
digitalWrite(light4, LOW);
digitalWrite(light7, HIGH);
delay(5000);
digitalWrite(light5, LOW);
digitalWrite(light6, LOW);
digitalWrite(light7, LOW);
}
Note that this is a lot of repetition and boring to maintain
since you have only 8 elements to manage and that a byte is 8 bits, you could represent the status of your 8 devices as a byte and then add how long it should be in that state in a structure. A sequence would be an array of that structure and then a simple for loop could call a function going through the sequence and setting the states.
constexpr uint8_t relays[8] = {
2, // light0 → bit 0
3, // light1 → bit 1
4, // light2 → bit 2
5, // light3 → bit 3
6, // light4 → bit 4
7, // light5 → bit 5
8, // light6 → bit 6
9 // smoke → bit 7
};
constexpr uint8_t button = 10;
struct State {
byte status;
uint16_t duration;
};
constexpr State sequence[] = {
{0b10000001, 5000}, // smoke + light0 on
{0b10000011, 3000}, // add light1
{0b10000110, 4000}, // light0 off, light2 on
{0b00001100, 2000}, // smoke off, light3 on
{0b00010000, 3000}, // light1 off, light4 on
{0b00100000, 3000}, // light2 off, light5 on
{0b01000000, 5000}, // light3 off, light6 on
{0b00000000, 1}, // all off
};
void setOutputsAndWait(byte status, uint16_t duration) {
for (uint8_t i = 0; i < 8; ++i)
digitalWrite(relays[i], bitRead(status, i) ? HIGH : LOW); // or LOW : HIGH depending on how your relay works
delay(duration);
}
void setup() {
for (uint8_t pin : relays) pinMode(pin, OUTPUT);
pinMode(button, INPUT_PULLUP);
while (digitalRead(button) != LOW);
for (const auto &state : sequence)
setOutputsAndWait(state.status, state.duration);
}
void loop() {}
if you are on a UNO or NANO and you map the relays to a PORT, instead of the for loop with the digitalWrite() in the function, you could directly write the port to instantly set the status of the 8 devices.
Modifying the sequence now is just a matter of editing the array.
Side note:
If the last step is always shutting everything off, you could hardwire that at the end of the setup so that you don't have to add a last entry in the array that says
{0b00000000, 1}, // all off