/*
Run LED Pattern on several LEDs
based on https://werner.rothschopf.net/microcontroller/202109_millis_led_sequence_en.htm
POC for https://forum.arduino.cc/t/2x-esp32-synchronising-led-effect-code/1236019/11
2024-03-17 by noiasca
*/
constexpr uint8_t t = 20;
constexpr uint8_t t1 = 40;
constexpr uint8_t t2 = 60;
constexpr uint8_t t3 = 80;
constexpr uint8_t t4 = 200;
constexpr uint16_t t5 = 500;
constexpr uint16_t t6 = 800;
constexpr uint16_t t7 = 1000;
struct Pattern {
uint16_t interval; // the milliseconds for the current LED pattern
uint16_t led; // the LEDs to be activated
};
/* ***************************
Configuration/Konfiguraton
* ************************* */
// 5432109876543210 // the LED pattern to be displayed, each bit defines one LED state, "paint" your pattern/sequence
const Pattern pattern[] = {
// 5432109876543210
{t4, 0b0000000000000000}, // all off
{t4, 0b0000100000000000}, // LED is on
{t3, 0b0000010000000000},
{t3, 0b0000001000000000},
{t3, 0b0000000100000000},
{t3, 0b0000000010000000},
{t3, 0b0000000001000000},
{t3, 0b0000000000100000},
{t3, 0b0000000000010000},
{t3, 0b0000000000001000},
{t3, 0b0000000000000100},
{t3, 0b0000000000000010},
{t3, 0b0000000000000001},
{t4, 0b0000100000000001},
{t3, 0b0000010000000001},
{t3, 0b0000001000000001},
{t3, 0b0000000100000001},
{t3, 0b0000000010000001},
{t3, 0b0000000001000001},
{t3, 0b0000000000100001},
{t3, 0b0000000000010001},
{t3, 0b0000000000001001},
{t3, 0b0000000000000101},
{t3, 0b0000000000000011},
{t4, 0b0000100000000111},
{t3, 0b0000010000000111},
{t3, 0b0000001000000111},
{t3, 0b0000000100000111},
{t3, 0b0000000010000111},
{t3, 0b0000000001000111},
{t3, 0b0000000000100111},
{t3, 0b0000000000010111},
{t3, 0b0000000000001111},
{t4, 0b0000100000001111},
{t3, 0b0000010000001111},
{t3, 0b0000001000001111},
{t3, 0b0000000100001111},
{t3, 0b0000000010001111},
{t3, 0b0000000001001111},
{t3, 0b0000000000101111},
{t3, 0b0000000000011111},
{t4, 0b0000100000011111},
{t3, 0b0000010000011111},
{t3, 0b0000001000011111},
{t3, 0b0000000100011111},
{t3, 0b0000000010011111},
{t3, 0b0000000001011111},
{t3, 0b0000000000101111},
{t4, 0b0000100000111111},
{t3, 0b0000010000111111},
{t3, 0b0000001000111111},
{t3, 0b0000000100111111},
{t3, 0b0000000010111111},
{t3, 0b0000000001111111},
{t4, 0b0000100001111111},
{t3, 0b0000010001111111},
{t3, 0b0000001001111111},
{t3, 0b0000000101111111},
{t3, 0b0000000011111111},
{t4, 0b0000100011111111},
{t3, 0b0000010011111111},
{t3, 0b0000001011111111},
{t3, 0b0000000111111111},
{t3, 0b0000100111111111},
{t3, 0b0000010111111111},
{t3, 0b0000001111111111},
{t4, 0b0000101111111111},
{t3, 0b0000011111111111},
{t4, 0b0000111111111111},
{t4, 0b0000000000000000},
{t4, 0b0000111111111111},
};
const uint8_t ledPin[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; // currently maximum are 16 pins - first pin is index 0 -> the LSB (the right most) bit in the pattern
/* ***************************
Globals / Variablen für den Sketch
* ************************* */
uint32_t lastMillis = 0; // last update of the LED pattern
uint16_t actualPattern = 0; // actual active pattern
uint16_t actualInterval = 0; // actual interval
const size_t totalNoPattern = sizeof(pattern) / sizeof(pattern[0]); // how many patterns are defined
const size_t totalNoPins = sizeof(ledPin) / sizeof(ledPin[0]); // how many pins are defined
/* ***************************
set LEDs of a specific index position
* ************************* */
void set(uint16_t index) {
for (uint8_t i = 0; i < totalNoPins; i++) {
if (pattern[actualPattern].led & (1 << i)) {
digitalWrite(ledPin[i], HIGH);
}
else {
digitalWrite(ledPin[i], LOW);
}
}
}
/* ***************************
run animation
* ************************* */
void runPattern() {
if (millis() - lastMillis >= actualInterval) {
actualPattern++;
if (actualPattern >= totalNoPattern) actualPattern = 0;
// tbd: on sender side (client): trigger partner on - optional: only each 10th iteration
set(actualPattern);
actualInterval = pattern[actualPattern].interval;
lastMillis = millis();
}
}
/* ***************************
simulate an incoming message an set to a specific position
* ************************* */
void readButton() {
if (digitalRead(A0) == LOW) {
actualPattern = 11; // here just any position. In reality the received index from the other device
set(actualPattern);
actualInterval = pattern[actualPattern].interval;
lastMillis = millis(); // optional minus some milliseconds for the transmission latency
}
}
/* ***************************
Setup
* ************************* */
void setup() {
Serial.begin(115200);
Serial.println(F("\nLED Pattern"));
for (uint8_t i = 0; i < totalNoPins; i++) {
pinMode(ledPin[i], OUTPUT);
}
pinMode(A0, INPUT_PULLUP);
}
/* ***************************
Main - Loop
* ************************* */
void loop() {
runPattern();
readButton();
// tbd: handle incoming message on receiver side (server)
}