Components and supplies
2
5mm Yellow LED
9
1k Resistor
1
Push Button de 4 pines
2
5mm Green LED
1
Jumper wires (generic)
3
3mm red LED
1
10k Resistor
2
10 Blue Led 5mm
1
Mini breadboard - White
1
Arduino Uno Rev3
Apps and platforms
1
Arduino IDE 2.0
Project description
Code
GlowCycle9
c
1// ============================================= 2// 9-LED Non-Blocking Sequencer with 30 Effects 3// Pins: LEDs D2-D10, Button D11 (INPUT_PULLUP) 4// ============================================= 5const int ledPins[9] = {2,3,4,5,6,7,8,9,10}; 6const char* effectNames[30] = { 7 "Chaser", "Bounce", "Opposites", "Sparkle", "Fill Up/Down", 8 "Snake", "Pulse Bar", "Ping Pong Double", "Random Single", "Ripple", 9 "Knight Rider PWM", "Breathing PWM", "Trail", "Wave Brightness", "Binary Counter", 10 "Circular Rotation", "Meteor", "Spark Flash", "Chase Triplet", "Expand/Contract", 11 "Running Fill", "Alternating Blink", "Fire Simulation", "Random Walk", "Scanner Fade", 12 "Sparkler", "Sweep Erase", "Bounce Pair", "Accelerating Chaser", "Decelerating Chaser" 13}; 14const int buttonPin = 11; 15const int totalEffects = 30; 16 17// Button debounce variables 18int buttonState; // current stable state 19int lastButtonReading = HIGH; // previous reading 20unsigned long lastDebounceTime = 0; 21const unsigned long debounceDelay = 50; 22 23// Effect engine variables 24int effect = 0; 25unsigned long previousMillis = 0; 26int indexA = 0; // generic index 27int indexB = 0; // second index for dual effects 28int direction = 1; 29int speed = 50; 30 31void setup() { 32 Serial.begin(9600); 33 34 for(int i=0;i<9;i++){ 35 pinMode(ledPins[i], OUTPUT); 36 digitalWrite(ledPins[i], LOW); 37 } 38 39 pinMode(buttonPin, INPUT); 40 Serial.println("Non-blocking 30-effect LED sequencer ready!"); 41} 42 43void loop() { 44 updateButton(); 45 runEffect(); 46} 47 48void updateButton(){ 49 int reading = digitalRead(buttonPin); 50 51 // check if reading changed 52 if(reading != lastButtonReading){ 53 lastDebounceTime = millis(); 54 } 55 56 // if stable for debounce period, accept the change 57 if(millis() - lastDebounceTime > debounceDelay){ 58 if(reading != buttonState){ // state changed 59 buttonState = reading; 60 61 // check for pressed (falling edge) 62 if(buttonState == LOW){ 63 effect = (effect + 1) % totalEffects; 64 resetEffect(); 65 Serial.print("Effect changed to: "); 66 Serial.println(effectNames[effect]); 67 } 68 } 69 } 70 71 lastButtonReading = reading; 72} 73 74void resetEffect(){ 75 indexA = 0; 76 indexB = 0; 77 direction = 1; 78 previousMillis = millis(); 79 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 80} 81 82void runEffect(){ 83 switch(effect){ 84 case 0: effectChaser(120); break; 85 case 1: effectBounce(80); break; 86 case 2: effectOpposites(150); break; 87 case 3: effectSparkle(70); break; 88 case 4: effectFill(100); break; 89 case 5: effectSnake(120); break; 90 case 6: effectPulseBar(100); break; 91 case 7: effectPingPong(90); break; 92 case 8: effectRandomSingle(60); break; 93 case 9: effectRipple(100); break; 94 case 10: effectKnightRiderPWM(50); break; 95 case 11: effectBreathingPWM(20); break; 96 case 12: effectTrail(80); break; 97 case 13: effectWaveBrightness(60); break; 98 case 14: effectBinaryCounter(80); break; 99 case 15: effectCircularRotation(100); break; 100 case 16: effectMeteor(50); break; 101 case 17: effectSparkFlash(70); break; 102 case 18: effectChaseTriplet(100); break; 103 case 19: effectExpandContract(120); break; 104 case 20: effectRunningFill(90); break; 105 case 21: effectAlternatingBlink(200); break; 106 case 22: effectFireSimulation(60); break; 107 case 23: effectRandomWalk(100); break; 108 case 24: effectScannerFade(80); break; 109 case 25: effectSparkler(60); break; 110 case 26: effectSweepErase(90); break; 111 case 27: effectBouncePair(100); break; 112 case 28: effectAcceleratingChaser(70); break; 113 case 29: effectDeceleratingChaser(120); break; 114 } 115} 116 117// ------------------ EFFECT IMPLEMENTATIONS ------------------ 118 119// 0: Chaser 120void effectChaser(unsigned long interval){ 121 if(millis()-previousMillis>=interval){ 122 previousMillis=millis(); 123 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 124 digitalWrite(ledPins[indexA], HIGH); 125 indexA=(indexA+1)%9; 126 } 127} 128 129// 1: Bounce 130void effectBounce(unsigned long interval){ 131 if(millis()-previousMillis>=interval){ 132 previousMillis=millis(); 133 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 134 digitalWrite(ledPins[indexA], HIGH); 135 indexA+=direction; 136 if(indexA==0||indexA==8) direction*=-1; 137 } 138} 139 140// 2: Opposites 141void effectOpposites(unsigned long interval){ 142 if(millis()-previousMillis>=interval){ 143 previousMillis=millis(); 144 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 145 int left=indexA; 146 int right=8-indexA; 147 digitalWrite(ledPins[left], HIGH); 148 digitalWrite(ledPins[right], HIGH); 149 indexA=(indexA+1)%5; 150 } 151} 152 153// 3: Sparkle 154void effectSparkle(unsigned long interval){ 155 if(millis()-previousMillis>=interval){ 156 previousMillis=millis(); 157 for(int i=0;i<9;i++) digitalWrite(ledPins[i], random(0,2)); 158 } 159} 160 161// 4: Fill Up/Down 162void effectFill(unsigned long interval){ 163 if(millis()-previousMillis>=interval){ 164 previousMillis=millis(); 165 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 166 for(int i=0;i<=indexA;i++) digitalWrite(ledPins[i], HIGH); 167 indexA+=direction; 168 if(indexA==0||indexA==8) direction*=-1; 169 } 170} 171 172// 5: Snake 173void effectSnake(unsigned long interval){ 174 if(millis()-previousMillis>=interval){ 175 previousMillis=millis(); 176 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 177 for(int i=indexA-2;i<=indexA;i++){ 178 if(i>=0) digitalWrite(ledPins[i], HIGH); 179 } 180 indexA=(indexA+1)%9; 181 } 182} 183 184// 6: Pulse Bar 185void effectPulseBar(unsigned long interval){ 186 if(millis()-previousMillis>=interval){ 187 previousMillis=millis(); 188 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 189 for(int i=0;i<=indexA;i++) digitalWrite(ledPins[i], HIGH); 190 indexA+=direction; 191 if(indexA==0||indexA==8) direction*=-1; 192 } 193} 194 195// 7: Ping Pong Double 196void effectPingPong(unsigned long interval){ 197 if(millis()-previousMillis>=interval){ 198 previousMillis=millis(); 199 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 200 digitalWrite(ledPins[indexA], HIGH); 201 if(indexA<8) digitalWrite(ledPins[indexA+1], HIGH); 202 indexA+=direction; 203 if(indexA==0||indexA==7) direction*=-1; 204 } 205} 206 207// 8: Random Single 208void effectRandomSingle(unsigned long interval){ 209 if(millis()-previousMillis>=interval){ 210 previousMillis=millis(); 211 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 212 int r=random(0,9); 213 digitalWrite(ledPins[r], HIGH); 214 } 215} 216 217// 9: Ripple (Center Out) 218void effectRipple(unsigned long interval){ 219 if(millis()-previousMillis>=interval){ 220 previousMillis=millis(); 221 int order[]={4,3,5,2,6,1,7,0,8}; 222 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 223 digitalWrite(ledPins[order[indexA]], HIGH); 224 indexA=(indexA+1)%9; 225 } 226} 227 228// 10: Knight Rider PWM 229void effectKnightRiderPWM(unsigned long interval){ 230 if(millis()-previousMillis>=interval){ 231 previousMillis=millis(); 232 for(int i=0;i<9;i++) analogWrite(ledPins[i],0); 233 analogWrite(ledPins[indexA],255); 234 indexA+=direction; 235 if(indexA==0||indexA==8) direction*=-1; 236 } 237} 238 239// 11: Breathing PWM 240void effectBreathingPWM(unsigned long interval){ 241 if(millis()-previousMillis>=interval){ 242 previousMillis=millis(); 243 int brightness = (sin(indexA * 0.2) * 127) + 128; 244 for(int i=0;i<9;i++) analogWrite(ledPins[i],brightness); 245 indexA++; 246 } 247} 248 249// 12: Trail 250void effectTrail(unsigned long interval){ 251 if(millis()-previousMillis>=interval){ 252 previousMillis=millis(); 253 for(int i=0;i<9;i++) analogWrite(ledPins[i],0); 254 for(int i=indexA-2;i<=indexA;i++) if(i>=0) analogWrite(ledPins[i],255-(indexA-i)*80); 255 indexA=(indexA+1)%9; 256 } 257} 258 259// 13: Wave Brightness 260void effectWaveBrightness(unsigned long interval){ 261 if(millis()-previousMillis>=interval){ 262 previousMillis=millis(); 263 for(int i=0;i<9;i++){ 264 int val = (sin((indexA+i)*0.5)*127)+128; 265 analogWrite(ledPins[i],val); 266 } 267 indexA++; 268 } 269} 270 271// 14: Binary Counter 272void effectBinaryCounter(unsigned long interval){ 273 if(millis()-previousMillis>=interval){ 274 previousMillis=millis(); 275 for(int i=0;i<9;i++){ 276 digitalWrite(ledPins[i], (indexA>>i)&1); 277 } 278 indexA=(indexA+1)%512; 279 } 280} 281 282// 15: Circular Rotation 283void effectCircularRotation(unsigned long interval){ 284 if(millis()-previousMillis>=interval){ 285 previousMillis=millis(); 286 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 287 digitalWrite(ledPins[indexA], HIGH); 288 indexA=(indexA+1)%9; 289 } 290} 291 292// 16: Meteor 293void effectMeteor(unsigned long interval){ 294 if(millis()-previousMillis>=interval){ 295 previousMillis=millis(); 296 for(int i=0;i<9;i++) analogWrite(ledPins[i],0); 297 for(int i=0;i<3;i++) if(indexA-i>=0) analogWrite(ledPins[indexA-i], 255-i*80); 298 indexA=(indexA+1)%9; 299 } 300} 301 302// 17: Spark Flash 303void effectSparkFlash(unsigned long interval){ 304 if(millis()-previousMillis>=interval){ 305 previousMillis=millis(); 306 for(int i=0;i<9;i++) digitalWrite(ledPins[i], random(0,2)); 307 } 308} 309 310// 18: Chase Triplet 311void effectChaseTriplet(unsigned long interval){ 312 if(millis()-previousMillis>=interval){ 313 previousMillis=millis(); 314 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 315 for(int i=0;i<3;i++) digitalWrite(ledPins[(indexA+i)%9], HIGH); 316 indexA=(indexA+1)%9; 317 } 318} 319 320// 19: Expand/Contract 321void effectExpandContract(unsigned long interval){ 322 if(millis()-previousMillis>=interval){ 323 previousMillis=millis(); 324 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 325 int center=4; 326 int left=center-indexA; 327 int right=center+indexA; 328 if(left>=0) digitalWrite(ledPins[left], HIGH); 329 if(right<=8) digitalWrite(ledPins[right], HIGH); 330 indexA+=direction; 331 if(indexA==0||indexA==4) direction*=-1; 332 } 333} 334 335// 20: Running Fill 336void effectRunningFill(unsigned long interval){ 337 if(millis()-previousMillis>=interval){ 338 previousMillis=millis(); 339 for(int i=0;i<9;i++) digitalWrite(ledPins[i], i<=indexA?HIGH:LOW); 340 indexA=(indexA+1)%9; 341 } 342} 343 344// 21: Alternating Blink 345void effectAlternatingBlink(unsigned long interval){ 346 if(millis()-previousMillis>=interval){ 347 previousMillis=millis(); 348 for(int i=0;i<9;i++) digitalWrite(ledPins[i], i%2==indexA%2?HIGH:LOW); 349 indexA++; 350 } 351} 352 353// 22: Fire Simulation 354void effectFireSimulation(unsigned long interval){ 355 if(millis()-previousMillis>=interval){ 356 previousMillis=millis(); 357 for(int i=0;i<9;i++) analogWrite(ledPins[i], random(50,255)); 358 } 359} 360 361// 23: Random Walk 362void effectRandomWalk(unsigned long interval){ 363 if(millis()-previousMillis>=interval){ 364 previousMillis=millis(); 365 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 366 digitalWrite(ledPins[indexA], HIGH); 367 int step = random(-1,2); 368 indexA=(indexA+step+9)%9; 369 } 370} 371 372// 24: Scanner Fade 373void effectScannerFade(unsigned long interval){ 374 if(millis()-previousMillis>=interval){ 375 previousMillis=millis(); 376 for(int i=0;i<9;i++) analogWrite(ledPins[i],0); 377 analogWrite(ledPins[indexA],255); 378 indexA+=direction; 379 if(indexA==0||indexA==8) direction*=-1; 380 } 381} 382 383// 25: Sparkler 384void effectSparkler(unsigned long interval){ 385 if(millis()-previousMillis>=interval){ 386 previousMillis=millis(); 387 for(int i=0;i<9;i++) analogWrite(ledPins[i], random(50,255)); 388 } 389} 390 391// 26: Sweep Erase 392void effectSweepErase(unsigned long interval){ 393 if(millis()-previousMillis>=interval){ 394 previousMillis=millis(); 395 for(int i=0;i<9;i++) digitalWrite(ledPins[i], i<=indexA?LOW:HIGH); 396 indexA=(indexA+1)%9; 397 } 398} 399 400// 27: Bounce Pair 401void effectBouncePair(unsigned long interval){ 402 if(millis()-previousMillis>=interval){ 403 previousMillis=millis(); 404 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 405 digitalWrite(ledPins[indexA], HIGH); 406 digitalWrite(ledPins[indexA+1<9?indexA+1:8], HIGH); 407 indexA+=direction; 408 if(indexA==0||indexA==7) direction*=-1; 409 } 410} 411 412// 28: Accelerating Chaser 413void effectAcceleratingChaser(unsigned long interval){ 414 if(millis()-previousMillis>=speed){ 415 previousMillis=millis(); 416 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 417 digitalWrite(ledPins[indexA], HIGH); 418 indexA=(indexA+1)%9; 419 speed=max(10,speed-1); // accelerate 420 } 421} 422 423// 29: Decelerating Chaser 424void effectDeceleratingChaser(unsigned long interval){ 425 if(millis()-previousMillis>=speed){ 426 previousMillis=millis(); 427 for(int i=0;i<9;i++) digitalWrite(ledPins[i], LOW); 428 digitalWrite(ledPins[indexA], HIGH); 429 indexA=(indexA+1)%9; 430 speed=min(200,speed+1); // decelerate 431 } 432}
Documentation
Multiple RGB Led Chaser Using Arduino Uno
project as a starting point for LED sequencing
https://projecthub.arduino.cc/Sparkbuzzer/multiple-rgb-led-chaser-using-arduino-uno-1ff98c?_gl=1*qxhatk*_up*MQ..*_ga*MTgwNzY5NDEyOC4xNzY1MTkzMTMz*_ga_NEXN8H46L5*czE3NjUxOTMxMzMkbzEkZzAkdDE3NjUxOTMxMzMkajYwJGwwJGgxMDQ0MDIyOTU.
Comments
Only logged in users can leave comments