Page 1 of 1

Arduino – All LEDStrip effects in one (NeoPixel and FastLED)

Arduino – All LEDStrip effects in one (NeoPixel and FastLED)
   558

If you’ve read the article I wrote a while ago “LEDStrip effects for NeoPixel and FastLED“, then you might have noticed quite a few requests to combine all these effects in one single sketch.

I have seen some users come up with some nice examples, but the challenge remained (for me): how do I instantly toggle from effect to another?

Well, today I’ll have such a sketch available for you; it allows you toggle between effects with a simple switch.




Overview

Framework – NeoPixel or FastLED

Well, I have to admit that I have become a FastLED fan – it’s become much more mature and advanced than NeoPixel. However, as with the original article, I wanted this to work for both. FastLED might be more advanced, but NeoPixel takes up less memory. This way you have a choice – it’s up to you. With the Arduino Uno R3 though, this works great with FastLED.

I do recommend reading the original article “LEDStrip effects for NeoPixel and FastLED“, but it is not required since I will be posting the full code for both libraries.

Installing FastLED or NeoPixel

The Arduino IDE has come a long way since I’ve written the original article, and installing a library has become much easier.

The Arduino IDE can be dowloaded from their website for free – I have never used their online IDE, so please stick with the regular one that you install on your computer.

After starting the Arduino IDE, which may take a bit, go to the menu and choose “SketchInclude LibraryManage Libraries“.
In the window that pops up, enter either “neopixel” or “fastled” in the filter field, and press ENTER for the library you’d like to use. I prefer FastLED, but I leave that choice up to you.

Your selected library will be listed, where you can select a version (I used v3.1.0 of FastLED and v1.1.3 of NeoPixel) and click “Install“.

And that’s all there is to it …

Arduino IDE - Install a Library

Arduino IDE – Install a Library

Download LEDEffect Sketches

At the end I’ll list the full code, but you can save yourself the typing or copy and paste efforts by just downlading them here.

Settings … make sure you set them right! 

Obviously, there are a few settings in the source code you will have to match to your setup.

#define PIN 5
Make sure this number (5) matches the PIN on your Arduino that you’re used for Din of your LED strip – this could for example by 6.

#define NUM_LEDS 60
Make sure this number (60) matches the LED count of your LED strip(s).

For FastLED, make sure the “FastLED.addLeds” function is set correctly for your LED strip – I’ve used a WS2811/WS218 LED stip – and the correct color order (RGB vs GRB)!
For NeoPixel, make sure the “Adafruit_NeoPixel strip” line matches your hardware – again: I used a WS2811/WS2812 – and the correct colors (NEO_RGB in this case).

Note :
The use of PIN 2 for the button is a requirement since it allows the button to interrupt your code. Pin 3 will work as well – just remember to chaneg the #define BUTTON 2 to #define BUTTON 3. This is all set for the Arduino UNO R3. Other Arduino models this might be a different pin.

Download - AllEffects LEDStrip Effect (FastLED) 

Filename:  AllEffects-FastLED.ino.zip
Platform:  Undefined
Version:  1.1
File size:  4.7 kB
Date:  2019-10-21
 Download Now  Send me a cup of Coffee    

Download - AllEffects LEDStrip Effect (NeoPixel) 

Filename:  AllEffects-NeoPixel.ino.zip
Platform:  Undefined
Version:  1.1
File size:  4.7 kB
Date:  2019-10-21
 Download Now  Send me a cup of Coffee    

LED Hardware Setup

Since we want to be able to toggle effects, we will need to change the hardware a little bit by adding a button.

Note: I’ve used PIN 6 in the drawing but PIN 5 in the code. So please either use PIN 6 (modify the #define PIN 5 line to #define PIN 6) or read the drawing below as PIN 5 (instead of PIN 6) – apologies for the confusion here.

The setup is the same as the original article, I’ve just added a push switch.
This push switch is of the type that makes contact when you push it, but breaks contact once you let it go.

Arduino, LED strip, Switch and Power Supply setup

Arduino, LED strip, Switch and Power Supply setup

Challenges Explained

Most users that tried to combine effects have ran into the same issues. I’ll briefly explain how I resolved them so it may be of use to someone – if you don’t care about the challenges, then feel free to ignore it and test the sketch right away.

Challenge 1 – Endless effects

Some of the effects last for ever – for example the bouncing balls. One of the visitors here, Daniel, pointed me in the right direction on how to address this. I made some improvements so it accommodates multiple bouncing balls.

In short, the bouncing balls kept going forever because of an endless while loop:


...
  while(true) {
  ...
  }
...

For one bouncing ball this could be caught in the if ( ImpactVelocity[i] < 0.01 ) { ... } part, but for multiple balls this became a little more challenging.

The basic solution was to keep track of all balls, to see if they are still finishing their bounce session. If all stopped bouncing then we exit the procedure.

Below you can see the final bouncingBalls() procedure.
I’ve added a parameter to this function so one can choose to let a ball bounce until it’s done, or have a ball restart bouncing over and over again.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
void BouncingColoredBalls(int BallCount, byte colors[][3], boolean continuous) {
  float Gravity = -9.81;
  int StartHeight = 1;
 
  float Height[BallCount];
  float ImpactVelocityStart = sqrt( -2 * Gravity * StartHeight );
  float ImpactVelocity[BallCount];
  float TimeSinceLastBounce[BallCount];
  int   Position[BallCount];
  long  ClockTimeSinceLastBounce[BallCount];
  float Dampening[BallCount];
  boolean ballBouncing[BallCount];
  boolean ballsStillBouncing = true;
 
  for (int i = 0 ; i < BallCount ; i++) {  
    ClockTimeSinceLastBounce[i] = millis();
    Height[i] = StartHeight;
    Position[i] = 0;
    ImpactVelocity[i] = ImpactVelocityStart;
    TimeSinceLastBounce[i] = 0;
    Dampening[i] = 0.90 - float(i)/pow(BallCount,2);
    ballBouncing[i]=true;
  }

  while (ballsStillBouncing) {
    for (int i = 0 ; i < BallCount ; i++) {
      TimeSinceLastBounce[i] =  millis() - ClockTimeSinceLastBounce[i];
      Height[i] = 0.5 * Gravity * pow( TimeSinceLastBounce[i]/1000 , 2.0 ) + ImpactVelocity[i] * TimeSinceLastBounce[i]/1000;
 
      if ( Height[i] < 0 ) {                      
        Height[i] = 0;
        ImpactVelocity[i] = Dampening[i] * ImpactVelocity[i];
        ClockTimeSinceLastBounce[i] = millis();
 
        if ( ImpactVelocity[i] < 0.01 ) {
          if (continuous) {
            ImpactVelocity[i] = ImpactVelocityStart;
          } else {
            ballBouncing[i]=false;
          }
        }
      }
      Position[i] = round( Height[i] * (NUM_LEDS - 1) / StartHeight);
    }

    ballsStillBouncing = false; // assume no balls bouncing
    for (int i = 0 ; i < BallCount ; i++) {
      setPixel(Position[i],colors[i][0],colors[i][1],colors[i][2]);
      if ( ballBouncing[i] ) {
        ballsStillBouncing = true;
      }
    }
   
    showStrip();
    setAll(0,0,0);
  }
}

Challenge 2 – Catching that button

Next challenge was adding a button to toggle the effects.

Initially I started with following the good Button tutorial on the Arduino website, until I found a slightly easier method. As you can see in the Arduino tutorial, they use a resistor. Now it seems (took me a while before I bumped into that one by accident) there is an internal resistor for this as well – so I decided to use that to keep the hardware setup easier.

Of course we need to define what PIN we want to use for our button. Here we have to pay attention (you’ll see more about that in the next challenge).
We want the button to basically “interrupt” an effect so we can switch right away to another effect.
If we would do it the “usual” way, then we’d find ourselves adding lots and lots of code to try to catch the button status – something I’d like to avoid.

To have a button “interrupt” the flow of the code, we must use either PIN 2 and PIN 3 (on an Arduino UNO). Per the guide of the Arduino website:

Pins for Interrupt Button
 Uno, Nano, Mini, other 328-based  2, 3
 Mega, Mega2560, MegaADK  2, 3, 18, 19, 20, 21
 Micro, Leonardo, other 32u4-based  0, 1, 2, 3, 7
 Zero  All digital pins, except pin 4
 MKR1000 Rev.1  0, 1, 4, 5, 6, 7, 8, 9, A1, A2
 Due  all digital pins
 101  2, 5, 7, 8, 10, 11, 12, 13

To make a button work with the internal pull-up resistor, we will have to add a line to the “setup()” function:


pinMode(2,INPUT_PULLUP);  // internal pull-up resistor

Later we can test if a button was pressed with:


if (digitalRead (BUTTON) == HIGH) {
  ...
}

 

Challenge 3 – Interrupt an effect and catch that button

This method is what worked best for me, and I’m sure there are better options out there.

I used a so called interrupt, that’s why we choose pin 2 for the switch. We want to catch the button press at any given time and we want to attach a function to an interrupt caused by pressing the button and for this we can use the “attachInterrupt()” function. If you’d like to dig deeper in this topic, please read the Arduino attachInterrupt Documentation.

In essence: When the state of the button (BUTTON) changes (CHANGE), we’d like to call for our own function (changeEffect()).

Which in code would look something like this:


attachInterrupt (digitalPinToInterrupt(BUTTON), changeEffect, CHANGE); // pressed

When reading the documentation you might wonder why I used the “CHANGE” mode instead of the “LOW” or “HIGH” mode. The reason is that both produced unexpected effects, like I pressed the button multiple times. So instead I used “CHANGE” and in our own function “changeEffect()” I then determine what the button state is and react accordingly. This is super fast!

This works surprisingly well!


void changeEffect() {
  if (digitalRead (BUTTON) == HIGH) {
    selectedEffect++;
  }
}

Once a button is pressed, our function will increase the value of “selectedEffect” by one.

Challenge 4 – Initiate the start of a new effect

So now we can catch the button being pressed at any time. Great!
But how do we go back to the beginning of the “loop()” function?

Since we have different levels of nested loops and functions, simply using “break” or “return” is not going to cut it.
So I had to come up with something better. How do I restart the loop?

Well, again there is no simple straight forward method for that it seems, and where ever you look on the Internet; questions like these will simply not be answered since folks think they need to explain that we need to program things differently. What’s up with that?

Eventually I found a sweet little piece of assembler code (unlike the C language Arduino uses) that resets the Arduino and starts over again – we basically let the Arduino jump back to address 0 (zero) so it starts over again. This works great:


asm volatile ("  jmp 0");

This line can be added anywhere in your code and your Arduino WILL reset.

Combined with the previous challenge, our button press will call:


1
2
3
4
5
6
void changeEffect() {
  if (digitalRead (BUTTON) == HIGH) {
    selectedEffect++;
    asm volatile ("  jmp 0");
  }
}

Note: this is more complicated than it sounds and comes with consequences – none of them harm your Arduino – which more experienced developers will tell you to pay attention to.

There is a ginormous downside to resetting your Arduino though: you’ll loose all your variables!
Or better said: the value the variables had, since they will be reinitiated blank …

So … that’s a problem, since we now no longer know what the selected effect was supposed to be.

Challenge 5 – Variable surviving a reset

You can imagine I had a good day trying to figure all this out – it was fun though,… now that it works.

So how do we store a value (the selected effect) without losing it? It’s not like the Arduino has a harddrive or SD card on which we can store the value …
Ehm … that’s not entirely true. The Arduino has an EEPROM – a piece of memory that does not loose it’s content after power is dropped, or a reset is being done.

Your Arduino actually has some functions for that! See the EEPROM documentation for more details.

One side note: you should not use the EEPROM for excessive read/write operations, as it has a limited live span (they say that I may fail after 100,000 read/write operations). Considering that this would take an awful lot of clicks, I’m not very worried with this application of the EEPROM.

Back to our last challenge: we just store the selected effect number (byte) in the EEPROM.

For this to work we will need to include the EEPROM library:


#include <EEPROM.h>

Writing and reading an EEPROM address is surprisingly easy:


// read EEPORM address 0 (1 byte)
EEPROM.get(0,selectedEffect);

// write EEPROM address 0 (also 1 byte)
EEPROM.put(0, selectedEffect);

As you can see in the code, the variable “selectedEffect” is of the type byte – which I did intentionally to keep things easy.
Address “0” of the EEPROM seems to be commonly used, so I didn’t see a reason to divert from that. Not all Arduino’s have the same amount of EEPROM space.

We cannot “set” the EEPROM in the “setup()” function with an initial value. After all, after a reset, the same “setup()” function would be called and … reset that value as well.

So instead I decided to read whatever is there. If the returning value is larger than the number of effects (18), then we set it to zero so it starts with the first effect again. Perfect to catch an odd value that was not initialized, and perfect for us cycling through effects.


EEPROM.get(0,selectedEffect);
 
if(selectedEffect>18) {
  selectedEffect=0;
  EEPROM.put(0,0);
}

Our button press function will now look like this:


void changeEffect() {
  if (digitalRead (BUTTON) == HIGH) {
    selectedEffect++;
    EEPROM.put(0, selectedEffect); // store the chose effect
    asm volatile ("  jmp 0");      // reset the Arduino
  }
}

Sources

You can download the sources in the beginning of this article.
If you’d like to review, then take a look here;

FastLED


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
#include "FastLED.h"
#include <EEPROM.h>
#define NUM_LEDS 60
CRGB leds[NUM_LEDS];
#define PIN 5

#define BUTTON 2
byte selectedEffect=0;

void setup()
{
  FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  pinMode(2,INPUT_PULLUP); // internal pull-up resistor
  attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, CHANGE); // pressed
}

// *** REPLACE FROM HERE ***
void loop() {
  EEPROM.get(0,selectedEffect);
 
  if(selectedEffect>18) {
    selectedEffect=0;
    EEPROM.put(0,0);
  }
 
  switch(selectedEffect) {
   
    case 0  : {
                // RGBLoop - no parameters
                RGBLoop();
                break;
              }

    case 1  : {
                // FadeInOut - Color (red, green. blue)
                FadeInOut(0xff, 0x00, 0x00); // red
                FadeInOut(0xff, 0xff, 0xff); // white
                FadeInOut(0x00, 0x00, 0xff); // blue
                break;
              }
             
    case 2  : {
                // Strobe - Color (red, green, blue), number of flashes, flash speed, end pause
                Strobe(0xff, 0xff, 0xff, 10, 50, 1000);
                break;
              }

    case 3  : {
                // HalloweenEyes - Color (red, green, blue), Size of eye, space between eyes, fade (true/false), steps, fade delay, end pause
                HalloweenEyes(0xff, 0x00, 0x00,
                              1, 4,
                              true, random(5,50), random(50,150),
                              random(1000, 10000));
                HalloweenEyes(0xff, 0x00, 0x00,
                              1, 4,
                              true, random(5,50), random(50,150),
                              random(1000, 10000));
                break;
              }
             
    case 4  : {
                // CylonBounce - Color (red, green, blue), eye size, speed delay, end pause
                CylonBounce(0xff, 0x00, 0x00, 4, 10, 50);
                break;
              }
             
    case 5  : {
                // NewKITT - Color (red, green, blue), eye size, speed delay, end pause
                NewKITT(0xff, 0x00, 0x00, 8, 10, 50);
                break;
              }
             
    case 6  : {
                // Twinkle - Color (red, green, blue), count, speed delay, only one twinkle (true/false)
                Twinkle(0xff, 0x00, 0x00, 10, 100, false);
                break;
              }
             
    case 7  : {
                // TwinkleRandom - twinkle count, speed delay, only one (true/false)
                TwinkleRandom(20, 100, false);
                break;
              }
             
    case 8  : {
                // Sparkle - Color (red, green, blue), speed delay
                Sparkle(0xff, 0xff, 0xff, 0);
                break;
              }
               
    case 9  : {
                // SnowSparkle - Color (red, green, blue), sparkle delay, speed delay
                SnowSparkle(0x10, 0x10, 0x10, 20, random(100,1000));
                break;
              }
             
    case 10 : {
                // Running Lights - Color (red, green, blue), wave dealy
                RunningLights(0xff,0x00,0x00, 50);  // red
                RunningLights(0xff,0xff,0xff, 50);  // white
                RunningLights(0x00,0x00,0xff, 50);  // blue
                break;
              }
             
    case 11 : {
                // colorWipe - Color (red, green, blue), speed delay
                colorWipe(0x00,0xff,0x00, 50);
                colorWipe(0x00,0x00,0x00, 50);
                break;
              }

    case 12 : {
                // rainbowCycle - speed delay
                rainbowCycle(20);
                break;
              }

    case 13 : {
                // theatherChase - Color (red, green, blue), speed delay
                theaterChase(0xff,0,0,50);
                break;
              }

    case 14 : {
                // theaterChaseRainbow - Speed delay
                theaterChaseRainbow(50);
                break;
              }

    case 15 : {
                // Fire - Cooling rate, Sparking rate, speed delay
                Fire(55,120,15);
                break;
              }


              // simple bouncingBalls not included, since BouncingColoredBalls can perform this as well as shown below
              // BouncingColoredBalls - Number of balls, color (red, green, blue) array, continuous
              // CAUTION: If set to continuous then this effect will never stop!!!
             
    case 16 : {
                // mimic BouncingBalls
                byte onecolor[1][3] = { {0xff, 0x00, 0x00} };
                BouncingColoredBalls(1, onecolor, false);
                break;
              }

    case 17 : {
                // multiple colored balls
                byte colors[3][3] = { {0xff, 0x00, 0x00},
                                      {0xff, 0xff, 0xff},
                                      {0x00, 0x00, 0xff} };
                BouncingColoredBalls(3, colors, false);
                break;
              }

    case 18 : {
                // meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay
                meteorRain(0xff,0xff,0xff,10, 64, true, 30);
                break;
              }
  }
}

void changeEffect() {
  if (digitalRead (BUTTON) == HIGH) {
    selectedEffect++;
    EEPROM.put(0, selectedEffect);
    asm volatile ("  jmp 0");
  }
}


// *************************
// ** LEDEffect Functions **
// *************************

void RGBLoop(){
  for(int j = 0; j < 3; j++ ) {
    // Fade IN
    for(int k = 0; k < 256; k++) {
      switch(j) {
        case 0: setAll(k,0,0); break;
        case 1: setAll(0,k,0); break;
        case 2: setAll(0,0,k); break;
      }
      showStrip();
      delay(3);
    }
    // Fade OUT
    for(int k = 255; k >= 0; k--) {
      switch(j) {
        case 0: setAll(k,0,0); break;
        case 1: setAll(0,k,0); break;
        case 2: setAll(0,0,k); break;
      }
      showStrip();
      delay(3);
    }
  }
}

void FadeInOut(byte red, byte green, byte blue){
  float r, g, b;
     
  for(int k = 0; k < 256; k=k+1) {
    r = (k/256.0)*red;
    g = (k/256.0)*green;
    b = (k/256.0)*blue;
    setAll(r,g,b);
    showStrip();
  }
     
  for(int k = 255; k >= 0; k=k-2) {
    r = (k/256.0)*red;
    g = (k/256.0)*green;
    b = (k/256.0)*blue;
    setAll(r,g,b);
    showStrip();
  }
}

void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause){
  for(int j = 0; j < StrobeCount; j++) {
    setAll(red,green,blue);
    showStrip();
    delay(FlashDelay);
    setAll(0,0,0);
    showStrip();
    delay(FlashDelay);
  }
 
 delay(EndPause);
}

void HalloweenEyes(byte red, byte green, byte blue,
                   int EyeWidth, int EyeSpace,
                   boolean Fade, int Steps, int FadeDelay,
                   int EndPause){
  randomSeed(analogRead(0));
 
  int i;
  int StartPoint  = random( 0, NUM_LEDS - (2*EyeWidth) - EyeSpace );
  int Start2ndEye = StartPoint + EyeWidth + EyeSpace;
 
  for(i = 0; i < EyeWidth; i++) {
    setPixel(StartPoint + i, red, green, blue);
    setPixel(Start2ndEye + i, red, green, blue);
  }
 
  showStrip();
 
  if(Fade==true) {
    float r, g, b;
 
    for(int j = Steps; j >= 0; j--) {
      r = j*(red/Steps);
      g = j*(green/Steps);
      b = j*(blue/Steps);
     
      for(i = 0; i < EyeWidth; i++) {
        setPixel(StartPoint + i, r, g, b);
        setPixel(Start2ndEye + i, r, g, b);
      }
     
      showStrip();
      delay(FadeDelay);
    }
  }
 
  setAll(0,0,0); // Set all black
 
  delay(EndPause);
}

void CylonBounce(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay){

  for(int i = 0; i < NUM_LEDS-EyeSize-2; i++) {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();
    delay(SpeedDelay);
  }

  delay(ReturnDelay);

  for(int i = NUM_LEDS-EyeSize-2; i > 0; i--) {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();
    delay(SpeedDelay);
  }
 
  delay(ReturnDelay);
}

void NewKITT(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay){
  RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
}

// used by NewKITT
void CenterToOutside(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for(int i =((NUM_LEDS-EyeSize)/2); i>=0; i--) {
    setAll(0,0,0);
   
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
   
    setPixel(NUM_LEDS-i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(NUM_LEDS-i-j, red, green, blue);
    }
    setPixel(NUM_LEDS-i-EyeSize-1, red/10, green/10, blue/10);
   
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}

// used by NewKITT
void OutsideToCenter(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for(int i = 0; i<=((NUM_LEDS-EyeSize)/2); i++) {
    setAll(0,0,0);
   
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
   
    setPixel(NUM_LEDS-i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(NUM_LEDS-i-j, red, green, blue);
    }
    setPixel(NUM_LEDS-i-EyeSize-1, red/10, green/10, blue/10);
   
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}

// used by NewKITT
void LeftToRight(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for(int i = 0; i < NUM_LEDS-EyeSize-2; i++) {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}

// used by NewKITT
void RightToLeft(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for(int i = NUM_LEDS-EyeSize-2; i > 0; i--) {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}

void Twinkle(byte red, byte green, byte blue, int Count, int SpeedDelay, boolean OnlyOne) {
  setAll(0,0,0);
 
  for (int i=0; i<Count; i++) {
     setPixel(random(NUM_LEDS),red,green,blue);
     showStrip();
     delay(SpeedDelay);
     if(OnlyOne) {
       setAll(0,0,0);
     }
   }
 
  delay(SpeedDelay);
}

void TwinkleRandom(int Count, int SpeedDelay, boolean OnlyOne) {
  setAll(0,0,0);
 
  for (int i=0; i<Count; i++) {
     setPixel(random(NUM_LEDS),random(0,255),random(0,255),random(0,255));
     showStrip();
     delay(SpeedDelay);
     if(OnlyOne) {
       setAll(0,0,0);
     }
   }
 
  delay(SpeedDelay);
}

void Sparkle(byte red, byte green, byte blue, int SpeedDelay) {
  int Pixel = random(NUM_LEDS);
  setPixel(Pixel,red,green,blue);
  showStrip();
  delay(SpeedDelay);
  setPixel(Pixel,0,0,0);
}

void SnowSparkle(byte red, byte green, byte blue, int SparkleDelay, int SpeedDelay) {
  setAll(red,green,blue);
 
  int Pixel = random(NUM_LEDS);
  setPixel(Pixel,0xff,0xff,0xff);
  showStrip();
  delay(SparkleDelay);
  setPixel(Pixel,red,green,blue);
  showStrip();
  delay(SpeedDelay);
}

void RunningLights(byte red, byte green, byte blue, int WaveDelay) {
  int Position=0;
 
  for(int i=0; i<NUM_LEDS*2; i++)
  {
      Position++; // = 0; //Position + Rate;
      for(int i=0; i<NUM_LEDS; i++) {
        // sine wave, 3 offset waves make a rainbow!
        //float level = sin(i+Position) * 127 + 128;
        //setPixel(i,level,0,0);
        //float level = sin(i+Position) * 127 + 128;
        setPixel(i,((sin(i+Position) * 127 + 128)/255)*red,
                   ((sin(i+Position) * 127 + 128)/255)*green,
                   ((sin(i+Position) * 127 + 128)/255)*blue);
      }
     
      showStrip();
      delay(WaveDelay);
  }
}

void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {
  for(uint16_t i=0; i<NUM_LEDS; i++) {
      setPixel(i, red, green, blue);
      showStrip();
      delay(SpeedDelay);
  }
}

void rainbowCycle(int SpeedDelay) {
  byte *c;
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< NUM_LEDS; i++) {
      c=Wheel(((i * 256 / NUM_LEDS) + j) & 255);
      setPixel(i, *c, *(c+1), *(c+2));
    }
    showStrip();
    delay(SpeedDelay);
  }
}

// used by rainbowCycle and theaterChaseRainbow
byte * Wheel(byte WheelPos) {
  static byte c[3];
 
  if(WheelPos < 85) {
   c[0]=WheelPos * 3;
   c[1]=255 - WheelPos * 3;
   c[2]=0;
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   c[0]=255 - WheelPos * 3;
   c[1]=0;
   c[2]=WheelPos * 3;
  } else {
   WheelPos -= 170;
   c[0]=0;
   c[1]=WheelPos * 3;
   c[2]=255 - WheelPos * 3;
  }

  return c;
}

void theaterChase(byte red, byte green, byte blue, int SpeedDelay) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (int i=0; i < NUM_LEDS; i=i+3) {
        setPixel(i+q, red, green, blue);    //turn every third pixel on
      }
      showStrip();
     
      delay(SpeedDelay);
     
      for (int i=0; i < NUM_LEDS; i=i+3) {
        setPixel(i+q, 0,0,0);        //turn every third pixel off
      }
    }
  }
}

void theaterChaseRainbow(int SpeedDelay) {
  byte *c;
 
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
        for (int i=0; i < NUM_LEDS; i=i+3) {
          c = Wheel( (i+j) % 255);
          setPixel(i+q, *c, *(c+1), *(c+2));    //turn every third pixel on
        }
        showStrip();
       
        delay(SpeedDelay);
       
        for (int i=0; i < NUM_LEDS; i=i+3) {
          setPixel(i+q, 0,0,0);        //turn every third pixel off
        }
    }
  }
}

void Fire(int Cooling, int Sparking, int SpeedDelay) {
  static byte heat[NUM_LEDS];
  int cooldown;
 
  // Step 1.  Cool down every cell a little
  for( int i = 0; i < NUM_LEDS; i++) {
    cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
   
    if(cooldown>heat[i]) {
      heat[i]=0;
    } else {
      heat[i]=heat[i]-cooldown;
    }
  }
 
  // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  for( int k= NUM_LEDS - 1; k >= 2; k--) {
    heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
  }
   
  // Step 3.  Randomly ignite new 'sparks' near the bottom
  if( random(255) < Sparking ) {
    int y = random(7);
    heat[y] = heat[y] + random(160,255);
    //heat[y] = random(160,255);
  }

  // Step 4.  Convert heat to LED colors
  for( int j = 0; j < NUM_LEDS; j++) {
    setPixelHeatColor(j, heat[j] );
  }

  showStrip();
  delay(SpeedDelay);
}

void setPixelHeatColor (int Pixel, byte temperature) {
  // Scale 'heat' down from 0-255 to 0-191
  byte t192 = round((temperature/255.0)*191);
 
  // calculate ramp up from
  byte heatramp = t192 & 0x3F; // 0..63
  heatramp <<= 2; // scale up to 0..252
 
  // figure out which third of the spectrum we're in:
  if( t192 > 0x80) {                     // hottest
    setPixel(Pixel, 255, 255, heatramp);
  } else if( t192 > 0x40 ) {             // middle
    setPixel(Pixel, 255, heatramp, 0);
  } else {                               // coolest
    setPixel(Pixel, heatramp, 0, 0);
  }
}

void BouncingColoredBalls(int BallCount, byte colors[][3], boolean continuous) {
  float Gravity = -9.81;
  int StartHeight = 1;
 
  float Height[BallCount];
  float ImpactVelocityStart = sqrt( -2 * Gravity * StartHeight );
  float ImpactVelocity[BallCount];
  float TimeSinceLastBounce[BallCount];
  int   Position[BallCount];
  long  ClockTimeSinceLastBounce[BallCount];
  float Dampening[BallCount];
  boolean ballBouncing[BallCount];
  boolean ballsStillBouncing = true;
 
  for (int i = 0 ; i < BallCount ; i++) {  
    ClockTimeSinceLastBounce[i] = millis();
    Height[i] = StartHeight;
    Position[i] = 0;
    ImpactVelocity[i] = ImpactVelocityStart;
    TimeSinceLastBounce[i] = 0;
    Dampening[i] = 0.90 - float(i)/pow(BallCount,2);
    ballBouncing[i]=true;
  }

  while (ballsStillBouncing) {
    for (int i = 0 ; i < BallCount ; i++) {
      TimeSinceLastBounce[i] =  millis() - ClockTimeSinceLastBounce[i];
      Height[i] = 0.5 * Gravity * pow( TimeSinceLastBounce[i]/1000 , 2.0 ) + ImpactVelocity[i] * TimeSinceLastBounce[i]/1000;
 
      if ( Height[i] < 0 ) {                      
        Height[i] = 0;
        ImpactVelocity[i] = Dampening[i] * ImpactVelocity[i];
        ClockTimeSinceLastBounce[i] = millis();
 
        if ( ImpactVelocity[i] < 0.01 ) {
          if (continuous) {
            ImpactVelocity[i] = ImpactVelocityStart;
          } else {
            ballBouncing[i]=false;
          }
        }
      }
      Position[i] = round( Height[i] * (NUM_LEDS - 1) / StartHeight);
    }

    ballsStillBouncing = false; // assume no balls bouncing
    for (int i = 0 ; i < BallCount ; i++) {
      setPixel(Position[i],colors[i][0],colors[i][1],colors[i][2]);
      if ( ballBouncing[i] ) {
        ballsStillBouncing = true;
      }
    }
   
    showStrip();
    setAll(0,0,0);
  }
}

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {  
  setAll(0,0,0);
 
  for(int i = 0; i < NUM_LEDS+NUM_LEDS; i++) {
   
   
    // fade brightness all LEDs one step
    for(int j=0; j<NUM_LEDS; j++) {
      if( (!meteorRandomDecay) || (random(10)>5) ) {
        fadeToBlack(j, meteorTrailDecay );        
      }
    }
   
    // draw meteor
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j <NUM_LEDS) && (i-j>=0) ) {
        setPixel(i-j, red, green, blue);
      }
    }
   
    showStrip();
    delay(SpeedDelay);
  }
}

// used by meteorrain
void fadeToBlack(int ledNo, byte fadeValue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
    // NeoPixel
    uint32_t oldColor;
    uint8_t r, g, b;
    int value;
   
    oldColor = strip.getPixelColor(ledNo);
    r = (oldColor & 0x00ff0000UL) >> 16;
    g = (oldColor & 0x0000ff00UL) >> 8;
    b = (oldColor & 0x000000ffUL);

    r=(r<=10)? 0 : (int) r-(r*fadeValue/256);
    g=(g<=10)? 0 : (int) g-(g*fadeValue/256);
    b=(b<=10)? 0 : (int) b-(b*fadeValue/256);
   
    strip.setPixelColor(ledNo, r,g,b);
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds[ledNo].fadeToBlackBy( fadeValue );
 #endif  
}

// *** REPLACE TO HERE ***



// ***************************************
// ** FastLed/NeoPixel Common Functions **
// ***************************************

// Apply LED color changes
void showStrip() {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.show();
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   FastLED.show();
 #endif
}

// Set a LED color (not yet visible)
void setPixel(int Pixel, byte red, byte green, byte blue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
 #endif
}

// Set all LEDs to a given color and apply it (visible)
void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}

NeoPixel


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
#include <Adafruit_NeoPixel.h>
#include <EEPROM.h>

#define NUM_LEDS 60
#define PIN 5
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

#define BUTTON 2
byte selectedEffect=0;

void setup()
{
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  pinMode(2,INPUT_PULLUP);  // internal pull-up resistor
  attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, CHANGE); // pressed
}

// *** REPLACE FROM HERE ***
void loop() {
  EEPROM.get(0,selectedEffect);
 
  if(selectedEffect>18) {
    selectedEffect=0;
    EEPROM.put(0,0);
  }
 
  switch(selectedEffect) {
   
    case 0  : {
                // RGBLoop - no parameters
                RGBLoop();
                break;
              }

    case 1  : {
                // FadeInOut - Color (red, green. blue)
                FadeInOut(0xff, 0x00, 0x00); // red
                FadeInOut(0xff, 0xff, 0xff); // white
                FadeInOut(0x00, 0x00, 0xff); // blue
                break;
              }
             
    case 2  : {
                // Strobe - Color (red, green, blue), number of flashes, flash speed, end pause
                Strobe(0xff, 0xff, 0xff, 10, 50, 1000);
                break;
              }

    case 3  : {
                // HalloweenEyes - Color (red, green, blue), Size of eye, space between eyes, fade (true/false), steps, fade delay, end pause
                HalloweenEyes(0xff, 0x00, 0x00,
                              1, 4,
                              true, random(5,50), random(50,150),
                              random(1000, 10000));
                HalloweenEyes(0xff, 0x00, 0x00,
                              1, 4,
                              true, random(5,50), random(50,150),
                              random(1000, 10000));
                break;
              }
             
    case 4  : {
                // CylonBounce - Color (red, green, blue), eye size, speed delay, end pause
                CylonBounce(0xff, 0x00, 0x00, 4, 10, 50);
                break;
              }
             
    case 5  : {
                // NewKITT - Color (red, green, blue), eye size, speed delay, end pause
                NewKITT(0xff, 0x00, 0x00, 8, 10, 50);
                break;
              }
             
    case 6  : {
                // Twinkle - Color (red, green, blue), count, speed delay, only one twinkle (true/false)
                Twinkle(0xff, 0x00, 0x00, 10, 100, false);
                break;
              }
             
    case 7  : {
                // TwinkleRandom - twinkle count, speed delay, only one (true/false)
                TwinkleRandom(20, 100, false);
                break;
              }
             
    case 8  : {
                // Sparkle - Color (red, green, blue), speed delay
                Sparkle(0xff, 0xff, 0xff, 0);
                break;
              }
               
    case 9  : {
                // SnowSparkle - Color (red, green, blue), sparkle delay, speed delay
                SnowSparkle(0x10, 0x10, 0x10, 20, random(100,1000));
                break;
              }
             
    case 10 : {
                // Running Lights - Color (red, green, blue), wave dealy
                RunningLights(0xff,0x00,0x00, 50);  // red
                RunningLights(0xff,0xff,0xff, 50);  // white
                RunningLights(0x00,0x00,0xff, 50);  // blue
                break;
              }
             
    case 11 : {
                // colorWipe - Color (red, green, blue), speed delay
                colorWipe(0x00,0xff,0x00, 50);
                colorWipe(0x00,0x00,0x00, 50);
                break;
              }

    case 12 : {
                // rainbowCycle - speed delay
                rainbowCycle(20);
                break;
              }

    case 13 : {
                // theatherChase - Color (red, green, blue), speed delay
                theaterChase(0xff,0,0,50);
                break;
              }

    case 14 : {
                // theaterChaseRainbow - Speed delay
                theaterChaseRainbow(50);
                break;
              }

    case 15 : {
                // Fire - Cooling rate, Sparking rate, speed delay
                Fire(55,120,15);
                break;
              }


              // simple bouncingBalls not included, since BouncingColoredBalls can perform this as well as shown below
              // BouncingColoredBalls - Number of balls, color (red, green, blue) array, continuous
              // CAUTION: If set to continuous then this effect will never stop!!!
             
    case 16 : {
                // mimic BouncingBalls
                byte onecolor[1][3] = { {0xff, 0x00, 0x00} };
                BouncingColoredBalls(1, onecolor, false);
                break;
              }

    case 17 : {
                // multiple colored balls
                byte colors[3][3] = { {0xff, 0x00, 0x00},
                                      {0xff, 0xff, 0xff},
                                      {0x00, 0x00, 0xff} };
                BouncingColoredBalls(3, colors, false);
                break;
              }

    case 18 : {
                // meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay
                meteorRain(0xff,0xff,0xff,10, 64, true, 30);
                break;
              }
  }
}

void changeEffect() {
  if (digitalRead (BUTTON) == HIGH) {
    selectedEffect++;
    EEPROM.put(0, selectedEffect);
    asm volatile ("  jmp 0");
  }
}


// *************************
// ** LEDEffect Functions **
// *************************

void RGBLoop(){
  for(int j = 0; j < 3; j++ ) {
    // Fade IN
    for(int k = 0; k < 256; k++) {
      switch(j) {
        case 0: setAll(k,0,0); break;
        case 1: setAll(0,k,0); break;
        case 2: setAll(0,0,k); break;
      }
      showStrip();
      delay(3);
    }
    // Fade OUT
    for(int k = 255; k >= 0; k--) {
      switch(j) {
        case 0: setAll(k,0,0); break;
        case 1: setAll(0,k,0); break;
        case 2: setAll(0,0,k); break;
      }
      showStrip();
      delay(3);
    }
  }
}

void FadeInOut(byte red, byte green, byte blue){
  float r, g, b;
     
  for(int k = 0; k < 256; k=k+1) {
    r = (k/256.0)*red;
    g = (k/256.0)*green;
    b = (k/256.0)*blue;
    setAll(r,g,b);
    showStrip();
  }
     
  for(int k = 255; k >= 0; k=k-2) {
    r = (k/256.0)*red;
    g = (k/256.0)*green;
    b = (k/256.0)*blue;
    setAll(r,g,b);
    showStrip();
  }
}

void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause){
  for(int j = 0; j < StrobeCount; j++) {
    setAll(red,green,blue);
    showStrip();
    delay(FlashDelay);
    setAll(0,0,0);
    showStrip();
    delay(FlashDelay);
  }
 
 delay(EndPause);
}

void HalloweenEyes(byte red, byte green, byte blue,
                   int EyeWidth, int EyeSpace,
                   boolean Fade, int Steps, int FadeDelay,
                   int EndPause){
  randomSeed(analogRead(0));
 
  int i;
  int StartPoint  = random( 0, NUM_LEDS - (2*EyeWidth) - EyeSpace );
  int Start2ndEye = StartPoint + EyeWidth + EyeSpace;
 
  for(i = 0; i < EyeWidth; i++) {
    setPixel(StartPoint + i, red, green, blue);
    setPixel(Start2ndEye + i, red, green, blue);
  }
 
  showStrip();
 
  if(Fade==true) {
    float r, g, b;
 
    for(int j = Steps; j >= 0; j--) {
      r = j*(red/Steps);
      g = j*(green/Steps);
      b = j*(blue/Steps);
     
      for(i = 0; i < EyeWidth; i++) {
        setPixel(StartPoint + i, r, g, b);
        setPixel(Start2ndEye + i, r, g, b);
      }
     
      showStrip();
      delay(FadeDelay);
    }
  }
 
  setAll(0,0,0); // Set all black
 
  delay(EndPause);
}

void CylonBounce(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay){

  for(int i = 0; i < NUM_LEDS-EyeSize-2; i++) {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();
    delay(SpeedDelay);
  }

  delay(ReturnDelay);

  for(int i = NUM_LEDS-EyeSize-2; i > 0; i--) {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();
    delay(SpeedDelay);
  }
 
  delay(ReturnDelay);
}

void NewKITT(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay){
  RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
  CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
}

// used by NewKITT
void CenterToOutside(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for(int i =((NUM_LEDS-EyeSize)/2); i>=0; i--) {
    setAll(0,0,0);
   
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
   
    setPixel(NUM_LEDS-i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(NUM_LEDS-i-j, red, green, blue);
    }
    setPixel(NUM_LEDS-i-EyeSize-1, red/10, green/10, blue/10);
   
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}

// used by NewKITT
void OutsideToCenter(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for(int i = 0; i<=((NUM_LEDS-EyeSize)/2); i++) {
    setAll(0,0,0);
   
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
   
    setPixel(NUM_LEDS-i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(NUM_LEDS-i-j, red, green, blue);
    }
    setPixel(NUM_LEDS-i-EyeSize-1, red/10, green/10, blue/10);
   
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}

// used by NewKITT
void LeftToRight(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for(int i = 0; i < NUM_LEDS-EyeSize-2; i++) {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}

// used by NewKITT
void RightToLeft(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
  for(int i = NUM_LEDS-EyeSize-2; i > 0; i--) {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();
    delay(SpeedDelay);
  }
  delay(ReturnDelay);
}

void Twinkle(byte red, byte green, byte blue, int Count, int SpeedDelay, boolean OnlyOne) {
  setAll(0,0,0);
 
  for (int i=0; i<Count; i++) {
     setPixel(random(NUM_LEDS),red,green,blue);
     showStrip();
     delay(SpeedDelay);
     if(OnlyOne) {
       setAll(0,0,0);
     }
   }
 
  delay(SpeedDelay);
}

void TwinkleRandom(int Count, int SpeedDelay, boolean OnlyOne) {
  setAll(0,0,0);
 
  for (int i=0; i<Count; i++) {
     setPixel(random(NUM_LEDS),random(0,255),random(0,255),random(0,255));
     showStrip();
     delay(SpeedDelay);
     if(OnlyOne) {
       setAll(0,0,0);
     }
   }
 
  delay(SpeedDelay);
}

void Sparkle(byte red, byte green, byte blue, int SpeedDelay) {
  int Pixel = random(NUM_LEDS);
  setPixel(Pixel,red,green,blue);
  showStrip();
  delay(SpeedDelay);
  setPixel(Pixel,0,0,0);
}

void SnowSparkle(byte red, byte green, byte blue, int SparkleDelay, int SpeedDelay) {
  setAll(red,green,blue);
 
  int Pixel = random(NUM_LEDS);
  setPixel(Pixel,0xff,0xff,0xff);
  showStrip();
  delay(SparkleDelay);
  setPixel(Pixel,red,green,blue);
  showStrip();
  delay(SpeedDelay);
}

void RunningLights(byte red, byte green, byte blue, int WaveDelay) {
  int Position=0;
 
  for(int i=0; i<NUM_LEDS*2; i++)
  {
      Position++; // = 0; //Position + Rate;
      for(int i=0; i<NUM_LEDS; i++) {
        // sine wave, 3 offset waves make a rainbow!
        //float level = sin(i+Position) * 127 + 128;
        //setPixel(i,level,0,0);
        //float level = sin(i+Position) * 127 + 128;
        setPixel(i,((sin(i+Position) * 127 + 128)/255)*red,
                   ((sin(i+Position) * 127 + 128)/255)*green,
                   ((sin(i+Position) * 127 + 128)/255)*blue);
      }
     
      showStrip();
      delay(WaveDelay);
  }
}

void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {
  for(uint16_t i=0; i<NUM_LEDS; i++) {
      setPixel(i, red, green, blue);
      showStrip();
      delay(SpeedDelay);
  }
}

void rainbowCycle(int SpeedDelay) {
  byte *c;
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< NUM_LEDS; i++) {
      c=Wheel(((i * 256 / NUM_LEDS) + j) & 255);
      setPixel(i, *c, *(c+1), *(c+2));
    }
    showStrip();
    delay(SpeedDelay);
  }
}

// used by rainbowCycle and theaterChaseRainbow
byte * Wheel(byte WheelPos) {
  static byte c[3];
 
  if(WheelPos < 85) {
   c[0]=WheelPos * 3;
   c[1]=255 - WheelPos * 3;
   c[2]=0;
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   c[0]=255 - WheelPos * 3;
   c[1]=0;
   c[2]=WheelPos * 3;
  } else {
   WheelPos -= 170;
   c[0]=0;
   c[1]=WheelPos * 3;
   c[2]=255 - WheelPos * 3;
  }

  return c;
}

void theaterChase(byte red, byte green, byte blue, int SpeedDelay) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (int i=0; i < NUM_LEDS; i=i+3) {
        setPixel(i+q, red, green, blue);    //turn every third pixel on
      }
      showStrip();
     
      delay(SpeedDelay);
     
      for (int i=0; i < NUM_LEDS; i=i+3) {
        setPixel(i+q, 0,0,0);        //turn every third pixel off
      }
    }
  }
}

void theaterChaseRainbow(int SpeedDelay) {
  byte *c;
 
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
        for (int i=0; i < NUM_LEDS; i=i+3) {
          c = Wheel( (i+j) % 255);
          setPixel(i+q, *c, *(c+1), *(c+2));    //turn every third pixel on
        }
        showStrip();
       
        delay(SpeedDelay);
       
        for (int i=0; i < NUM_LEDS; i=i+3) {
          setPixel(i+q, 0,0,0);        //turn every third pixel off
        }
    }
  }
}

void Fire(int Cooling, int Sparking, int SpeedDelay) {
  static byte heat[NUM_LEDS];
  int cooldown;
 
  // Step 1.  Cool down every cell a little
  for( int i = 0; i < NUM_LEDS; i++) {
    cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
   
    if(cooldown>heat[i]) {
      heat[i]=0;
    } else {
      heat[i]=heat[i]-cooldown;
    }
  }
 
  // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  for( int k= NUM_LEDS - 1; k >= 2; k--) {
    heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
  }
   
  // Step 3.  Randomly ignite new 'sparks' near the bottom
  if( random(255) < Sparking ) {
    int y = random(7);
    heat[y] = heat[y] + random(160,255);
    //heat[y] = random(160,255);
  }

  // Step 4.  Convert heat to LED colors
  for( int j = 0; j < NUM_LEDS; j++) {
    setPixelHeatColor(j, heat[j] );
  }

  showStrip();
  delay(SpeedDelay);
}

void setPixelHeatColor (int Pixel, byte temperature) {
  // Scale 'heat' down from 0-255 to 0-191
  byte t192 = round((temperature/255.0)*191);
 
  // calculate ramp up from
  byte heatramp = t192 & 0x3F; // 0..63
  heatramp <<= 2; // scale up to 0..252
 
  // figure out which third of the spectrum we're in:
  if( t192 > 0x80) {                     // hottest
    setPixel(Pixel, 255, 255, heatramp);
  } else if( t192 > 0x40 ) {             // middle
    setPixel(Pixel, 255, heatramp, 0);
  } else {                               // coolest
    setPixel(Pixel, heatramp, 0, 0);
  }
}

void BouncingColoredBalls(int BallCount, byte colors[][3], boolean continuous) {
  float Gravity = -9.81;
  int StartHeight = 1;
 
  float Height[BallCount];
  float ImpactVelocityStart = sqrt( -2 * Gravity * StartHeight );
  float ImpactVelocity[BallCount];
  float TimeSinceLastBounce[BallCount];
  int   Position[BallCount];
  long  ClockTimeSinceLastBounce[BallCount];
  float Dampening[BallCount];
  boolean ballBouncing[BallCount];
  boolean ballsStillBouncing = true;
 
  for (int i = 0 ; i < BallCount ; i++) {  
    ClockTimeSinceLastBounce[i] = millis();
    Height[i] = StartHeight;
    Position[i] = 0;
    ImpactVelocity[i] = ImpactVelocityStart;
    TimeSinceLastBounce[i] = 0;
    Dampening[i] = 0.90 - float(i)/pow(BallCount,2);
    ballBouncing[i]=true;
  }

  while (ballsStillBouncing) {
    for (int i = 0 ; i < BallCount ; i++) {
      TimeSinceLastBounce[i] =  millis() - ClockTimeSinceLastBounce[i];
      Height[i] = 0.5 * Gravity * pow( TimeSinceLastBounce[i]/1000 , 2.0 ) + ImpactVelocity[i] * TimeSinceLastBounce[i]/1000;
 
      if ( Height[i] < 0 ) {                      
        Height[i] = 0;
        ImpactVelocity[i] = Dampening[i] * ImpactVelocity[i];
        ClockTimeSinceLastBounce[i] = millis();
 
        if ( ImpactVelocity[i] < 0.01 ) {
          if (continuous) {
            ImpactVelocity[i] = ImpactVelocityStart;
          } else {
            ballBouncing[i]=false;
          }
        }
      }
      Position[i] = round( Height[i] * (NUM_LEDS - 1) / StartHeight);
    }

    ballsStillBouncing = false; // assume no balls bouncing
    for (int i = 0 ; i < BallCount ; i++) {
      setPixel(Position[i],colors[i][0],colors[i][1],colors[i][2]);
      if ( ballBouncing[i] ) {
        ballsStillBouncing = true;
      }
    }
   
    showStrip();
    setAll(0,0,0);
  }
}

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {  
  setAll(0,0,0);
 
  for(int i = 0; i < NUM_LEDS+NUM_LEDS; i++) {
   
   
    // fade brightness all LEDs one step
    for(int j=0; j<NUM_LEDS; j++) {
      if( (!meteorRandomDecay) || (random(10)>5) ) {
        fadeToBlack(j, meteorTrailDecay );        
      }
    }
   
    // draw meteor
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j <NUM_LEDS) && (i-j>=0) ) {
        setPixel(i-j, red, green, blue);
      }
    }
   
    showStrip();
    delay(SpeedDelay);
  }
}

// used by meteorrain
void fadeToBlack(int ledNo, byte fadeValue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
    // NeoPixel
    uint32_t oldColor;
    uint8_t r, g, b;
    int value;
   
    oldColor = strip.getPixelColor(ledNo);
    r = (oldColor & 0x00ff0000UL) >> 16;
    g = (oldColor & 0x0000ff00UL) >> 8;
    b = (oldColor & 0x000000ffUL);

    r=(r<=10)? 0 : (int) r-(r*fadeValue/256);
    g=(g<=10)? 0 : (int) g-(g*fadeValue/256);
    b=(b<=10)? 0 : (int) b-(b*fadeValue/256);
   
    strip.setPixelColor(ledNo, r,g,b);
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds[ledNo].fadeToBlackBy( fadeValue );
 #endif  
}

// *** REPLACE TO HERE ***



// ***************************************
// ** FastLed/NeoPixel Common Functions **
// ***************************************

// Apply LED color changes
void showStrip() {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.show();
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   FastLED.show();
 #endif
}

// Set a LED color (not yet visible)
void setPixel(int Pixel, byte red, byte green, byte blue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
 #endif
}

// Set all LEDs to a given color and apply it (visible)
void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}

 

Support Us ...


Your support is very much appreciated, and can be as easy as sharing a link to my website with others, or on social media.

Support can also be done by sponsoring me, and even that can be free (e.g. shop at Amazon).
Any funds received from your support will be used for web-hosting expenses, project hardware and software, coffee, etc.

Thank you very much for those that have shown support already!
It's truly amazing to see that folks like my articles and small applications.

Please note that clicking affiliate links, like the ones from Amazon, may result in a small commission for us - which we highly appreciate as well.

Comments


There are 558 comments. You can read them below.
You can post your own comments by using the form below, or reply to existing comments by using the "Reply" button.

  • Jan 7, 2018 - 5:43 PM - Spike Comment Link

    Hi Hans,

    Thank you so much for working all this out and sharing it with us.

    It is all way above my ability, which explains why I never managed to get it to work :-)

    I’m looking forward to getting the time to try this out.

    All the best

    Spike

    Reply

    Spike

    • Jan 8, 2018 - 3:14 PM - hans - Author: Comment Link

      Thanks Spike!

      And you’re most welcome – wish I could do these kind of articles all day long 
      But … keep in mind that I had to do my share of research as well, since some of these challenges are exactly that: challenges.

      Enjoy! 

      Reply

      hans

      • Jul 21, 2020 - 12:53 PM - Junior Comment Link

        Hi guys! I use led strip ws2812 with 60 leds on my quad copter, flying like a UFO at night… But using one effect each time when return tô ground. Please have The way to changes effects automatics? 

        Sorry my poor english. 

        Reply

        Junior

        • Jul 22, 2020 - 5:38 AM - Hans - Author: Comment Link

          Hi Junior,

          Yes you can modify the code, without too much work, to rotate through the effects automatically.
          Instead of using an interrupt for a button press, you could create an time based interrupt that increases the value for “selectedEffect” by one, and resets it to zero when the maximum has been reached.

          Having said that: There could be a better way to do this without the need for a timer.

          You may have to tweak the individual “case” statements, since some of the effects depend on being repeated over and over again.
          For example calling “RGBLoop()” in the “case 0:” block: you may want to call the function “RGBLoop()” several times, or create a loop around it that checks the time so it runs for at least a second (if needed).

          The basics: Change this

          #include "FastLED.h"
          #include <EEPROM.h>
          #define NUM_LEDS 60
          CRGB leds[NUM_LEDS];
          #define PIN 5
          #define BUTTON 2
          byte selectedEffect=0;
          void setup()
          {
            FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
            pinMode(2,INPUT_PULLUP); // internal pull-up resistor
            attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, CHANGE); // pressed
          }
          void loop() {
            EEPROM.get(0,selectedEffect);
           
            if(selectedEffect>18) {
              selectedEffect=0;
              EEPROM.put(0,0);
            }
            switch(selectedEffect) {
            case 0 : { ...

          to this (basically remove the EEPROM and interrupt related code, and modify the effect selection):

          #include "FastLED.h"
          #define NUM_LEDS 60
          CRGB leds[NUM_LEDS];
          #define PIN 5
          #define BUTTON 2
          byte selectedEffect=-1; // start with "-1" since the "loop" will right away increase it by 1
          void setup()
          {
            FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
          }
          void loop() {
            selectedEffect++; // increase effect to the next one
           
            if(selectedEffect>18) {
              selectedEffect=0;
            }
            switch(selectedEffect) {
            case 0: { ...

          This is untested code, but I’m pretty confident this will work.
          Hope this helps. 

          NOTE: If you want to discuss this more in depth: please start a forum topic to avoid us posting code here.

          Reply

          Hans

          • Jul 22, 2020 - 7:29 AM - Junior Comment Link

            Thanks my friend, I Will try change The code to make automatic, thanks só much Hans. 

            Junior

          • Jul 23, 2020 - 5:17 AM - Hans - Author: Comment Link

            You’re welcome Junior! 

            Hans

          • Oct 6, 2020 - 6:21 AM - Lukas Comment Link

            Could You advice how to change it also for Adafruit_NeoPixel?

            Lukas

          • Oct 7, 2020 - 3:43 AM - Hans - Author: Comment Link

            Hi Lukas,

            The code for AdaFruit NeoPixel is listed below the FastLED code (here).

            Hans

          • Oct 7, 2020 - 4:03 AM - Lukas Comment Link

            Hi thanks, but this is the full code I need without the button 2. Automatically change.

            Lukas

          • Oct 7, 2020 - 4:45 AM - Hans - Author: Comment Link

            Removing a button is the same for FastLED and NeoPixel.
            Say you want to remove effect #2 (Strobe, which is the 3rd effect – effects start counting at zero, so from zero to 17 for 18 effects):

            Change (around line #23):

              if(selectedEffect>18) {
                selectedEffect=0;
                EEPROM.put(0,0);
              }

            to (reduce the number 18 by one):

              if(selectedEffect>17) { // <--- 18 minus 1
                selectedEffect=0;
                EEPROM.put(0,0);
              }

            Remove:

                case 2  : {
                            // Strobe - Color (red, green, blue), number of flashes, flash speed, end pause
                            Strobe(0xff, 0xff, 0xff, 10, 50, 1000);
                            break;
                          }

            Update:

            All “case” lines after where “case 2” used to be, and reduce the numbers by one.
            Eg “case 3:” -> “case 2:“,
                 “case 4:” -> “case 3:
                 etc.

            And you should be good to go. (I assume this is what you meant).

            Hans

  • Jan 9, 2018 - 9:57 PM - Daniel Comment Link

    Hello Hans, thanks for the nice “All-in-One” Wonder!
    I test it and all seams to work ok.

    I smole problem that i have is the debouncing problem of
    the button, i use a Nano 328 and the latest Arduino IDE.

    When pushing the button, it jumps from selectedEffect 0
    to lets say 3 or 5, so i must click very fast the button to jump to
    nr. 2 and 3…

    In your setup()
    you use: digitalWrite (BUTTON, HIGH);  // internal pull-up resistor
    for buttons i use this line: pinMode(2,INPUT_PULLUP);
    …this sets the D2 as input and also activates the internal 40 kOhm
    in one wash.

    The new “meteorRain” is the coolest effect :-)
    With “FastLED”-Library i have some colored points in the String,
    behind this Effect, but only white color in “Adafruit_NeoPixel”.
    Is that the same in your string? Is “Adafruit_NeoPixel”
    not able to handle this colors?

    Reply

    Daniel

    • Jan 12, 2018 - 10:27 AM - hans - Author: Comment Link

      Hi Daniel,

      So using 

      pinMode(2,INPUT_PULLUP);

      instead of

      digitalWrite (BUTTON, HIGH); 

      works better? If you confirm that, then I will modify the code accordingly.
      (can’t test right now, since I stowed my stuff away again – argh – I need a workshop!)

      I did not experience the debouncing problem though – maybe the nature of the switch I’m using?

      FastLED is much more advanced when it comes to colors, ADAFruit NeoPixel is pretty limited. On my strand the meteor rain works correct with both, however the effect is much more refined with FastLED. A refinement of the fadeToBlack function might be helpful – as you can see, for FastLED I use a build in function, and for neoPixel I have to glue something together.

      Reply

      hans

      • Jan 13, 2018 - 3:04 PM - Daniel Comment Link

        Hello Hans, yes i allways use

        pinMode(Button,INPUT_PULLUP); //Activate internal 40k resistor to +5V

        because it is all done in one line, set digitalport to input and also set this input to +5v

        so i dont need any aditional 10k resistors from input-pin to ground and a button from

        input to +5v.

        This is allway better with PULUP because all ports are FET Inputs and so they have a very

        hi impedance witch is good …but a high impedance input, always pick up some noise or

        static loads…so the pins driving slowly to HIGH or at least 2-3V from ground away.

        I made a VU-Meter with Neopixels and i have the problem…in the pause (no sound)…

        the A= port starts climbing up and my Pixel starts one after another…so i put

        a 1 Megaohm from A0 to ground, then the port can not start growibg up because the 1M

        resistor descharge the port. 1M is very high, i use it to not influence the A0 port.

        Here in this case i can not PULLUP because the Pixels will light all full from the +5V.

        But for Buttons i’m allways using PULLUP, no need of 10kohm and port is not rising up

        because he is allready at +5v :-)

        You don’t have to change the code for this, i hope other readers understand what i mean.

        Ok i hade no problems till now with the NeoPixel -lIbrary, but i also try the FastLED, it use

        around 1kb more memory but else no relevant changes.

        Ok Hans have a nice weekend, cheers de Daniel 72

        Reply

        Daniel

        • Jan 21, 2018 - 1:38 PM - hans - Author: Comment Link

          Thanks Daniel!

          Thanks for the great explanation – I can (and like to) learn something every day as well! 

          I’ll play with your suggestion once I get time to play again. 

          Reply

          hans

      • Oct 20, 2019 - 9:06 AM - leigh Comment Link

        I know I am resurrecting this from the dead, but I had the same issue of the push button being random on my Metro Mini. Changing the code to this fixed my problem as mentioned above :

        pinMode(BUTTON,INPUT_PULLUP);
        Reply

        leigh

    • Jul 7, 2019 - 10:49 AM - Scott Comment Link

      With the issue of the code jumping past certain effects, if you add a 50ms delay in the setup section. I had the same problem and this fixed it. 

      Reply

      Scott

      • Jul 12, 2019 - 3:29 AM - hans - Author: Comment Link

        Reply

        hans

      • Jul 31, 2020 - 2:49 PM - Junior Comment Link

        Please, how can i add 50ms on setup code to eliminate boucing on button? 

        Thanks for all. 

        Reply

        Junior

        • Aug 1, 2020 - 4:39 AM - Hans - Author: Comment Link

          Hi Junior,

          you could try something like this (derived from Arduino – Debounce):

          Add to the beginning of the code (before “void setup()”):

          unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
          unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers

          And change the changeEffect function to this:

          void changeEffect() {
            if ((millis() - lastDebounceTime) > debounceDelay) 
            {

              if (digitalRead (BUTTON) == HIGH) {
                selectedEffect++;
                EEPROM.put(0, selectedEffect);
                asm volatile (" jmp 0");
              }
            }
          }

          The value for lastDebounceTime does not need to be reset, since we reset the Arduino and lastDebounceTime will become zero again.

          Note: I have not tested this code.

          Reply

          Hans

          • Aug 1, 2020 - 4:40 AM - Hans - Author: Comment Link

            Please let me know if this works – then I’ll add it to the main article.
            (i have not been able to reproduce the bouncing issue with my gear, so I cannot test)

            Hans

          • Aug 1, 2020 - 4:51 AM - Junior Comment Link

            Hi Hans! I solve my boucing issues using in a place of button one optocoupler 817!. Magnifc results and a use with my controler RC. Thanks, late Will send YouTube link demostraining in use! 

            Junior

          • Aug 1, 2020 - 4:52 AM - Hans - Author: Comment Link

            Cool! Interesting approach! But that would do the trick I suppose!
            Curious how you hooked it up!

            Hans

          • Aug 1, 2020 - 4:57 AM - Junior Comment Link

            In time.. 

            In the rádio i have option in milliseconds The switching in put in on position ex. 10secs close position tô release a key… Do you understand my f*** poor english?

            Thanks Hans! 

            Junior

          • Aug 1, 2020 - 5:02 AM - Hans - Author: Comment Link

            Haha, I’ll admit that it takes some decoding hahah 😜 

            Hans

          • Aug 1, 2020 - 5:34 AM - Junior Comment Link

            Hahaha, sorry Hans. On vídeo i Will explain more easily… I hope hahahahahahahah if write is a terror, imagine speaking…. Hahaha

            Do you have some other way to contact? Instagram? The imagens and vídeos of my Project is there. 

            Thanks for all Hans. 

            Junior

          • Aug 1, 2020 - 6:39 AM - Hans - Author: Comment Link

            I do have Instagram (but rarely use it). You can also use the forum, or even email me (webmaster at tweaking4all dot com). 

            Hans

          • Aug 1, 2020 - 7:26 AM - Junior Comment Link

            I found your Instagram! When you have a little time, follow me to see my project with ws2812b strip led based in your work! Thanks one more time!

            Junior

          • Aug 1, 2020 - 11:03 AM - Hans - Author: Comment Link

            Cool, I’ve requested to follow you as well 

            I’ll be traveling tomorrow, so apologies up front if I do not respond right away. 

            Hans

          • Aug 3, 2020 - 5:31 AM - Junior Comment Link

            Here is the brain of the lights project, arduino pro mini With 18 lighting effects controlled via the ch7 key on my radio control! I was trying to use a button on the arduino itself, but without success, there were several defects … But now everything is perfect, added to a coupler that was perfect without the effect of boucing. Use an L817! ..thanks Hans to make it happens! 

            https://www.instagram.com/p/CDbAQmMnrIEfhzptmueFo_kEBrUtDVp50o-YPY0/?igshid=1uuinq3t6zca6

            Junior

          • Aug 4, 2020 - 10:40 AM - Hans - Author: Comment Link

            Hi Junior!

            That looks great!
            Awesome that you got it resolved and thanks for the pictures! 

            Thanks for posting the fix as well. 

            Hans

          • Aug 4, 2020 - 10:49 AM - Junior Comment Link

            Thanks for all Hans, next week i will post vídeo on my Instagram with my RC working and demostrating all effects on my quad copter! Bye and thanks so much Hans! 

            Junior

          • Aug 4, 2020 - 11:00 AM - Hans - Author: Comment Link

            Thank you as well – I’ll be looking forward to your video 😊 

            Hans

          • Aug 6, 2020 - 7:03 AM - Junior Comment Link

            Hello Hans, there is the link with project working perfect 

            https://www.instagram.com/tv/CDfLLQ_nEdKD0qfSUTv-9CtNWyxzHyV6F3CgY00/?igshid=mceirp0vvqa8

            Junior

          • Aug 6, 2020 - 10:32 AM - Hans - Author: Comment Link

            That looks awesome! Haha!
            Please try to record the faces of the neighbors when you hover over their house at night 

            Hans

          • Aug 6, 2020 - 10:49 AM - Junior Comment Link

            Hahaha, good idea Hans, I do if possible…. 

            I will be forever grateful for the tips you taught me! Thank you very much for your help, Hans you have a great friend here in Brazil. God bless you. 

            Junior

          • Aug 7, 2020 - 9:54 AM - Hans - Author: Comment Link

            Thanks Junior – that’s really nice to hear! Have fun! Hope to see you here again! 

            Hans

          • Aug 7, 2020 - 10:24 AM - Junior Comment Link

            I’m sure I’ll be here, even if I don’t need anything, I’m always reading your posts in search of more knowledge in the area of ​​general electronics. My next step is to assemble a strobe unit, to put on the belly of my drone, a similar strobe used in old cameras … The circuit is not very difficult, but I still have to study a little more! Thank you Hans.

            Junior

          • Aug 7, 2020 - 10:28 AM - Hans - Author: Comment Link

            Awesome! Thanks Junior! 
            Have a good weekend! 

            Hans

    • Oct 21, 2019 - 7:49 AM - hans - Author: Comment Link

      Apologies to all for somehow totally forgetting to update the code with Daniels brilliant modification. 

      I’ve updated the code and the download! Thanks again Daniel! 
      And thanks Leigh for reminding me! 

      Reply

      hans

  • Jan 17, 2018 - 8:41 AM - Bob Comment Link

    I want to thank you for this awesome articular on LEDS strips.   It gave me some great ideas for my latest Jukebox project using these Neo-pixal strips.  Your welcome to  check out my latest LED effects using some of your coding at  https://youtu.be/ZWGdVXJNOww.&nbsp; I am using a Arduino Mega to control three strips of 180 leds per strip plus additional  59 leds that I am using in a keyboard/index display which is controlled by a Arduino Micro. The complete Jukebox build can be viewed here if you are interested. https://youtu.be/mNt3cUORvak

    Thanks 

    Reply

    Bob

    • Jan 21, 2018 - 2:05 PM - hans - Author: Comment Link

      Hi Bob!

      Thanks you for taking the time to post a thank you note.
      I’ve just looked at your jukebox project – that’s awesome!!! (the first YouTube link didn’t work)

      Wow, you’ve given me an idea for a project – amazingly well build! 

      Reply

      hans

  • Jan 19, 2018 - 9:36 AM - Marco Weinkauf Comment Link

    Hi Hans,

    thank you so much for this nice work! 

    What changes in setup and define section do I have to make for SPI (APA102) LEDs working for that demo? 

    Reply

    Marco Weinkauf

    • Jan 21, 2018 - 2:15 PM - hans - Author: Comment Link

      Hi Marco!

      Thank you for the compliment! It’s much appreciated! 

      I’ve never worked with the APA102, so I’m afraid I will have to point you to the reference of (for example) FastLED: Setting up LEDs.
      I did see an example there:

      FastLED.addLeds<APA102>(leds, NUM_LEDS);

      And I did find more info here: SPI Hardware or Bit banging:

      FastLED.addLeds<APA102,7,11>(leds,NUM_LEDS);

      There is even the option to change the frequency:

      FastLED.addLeds<APA102,7,11,RGB,DATA_RATE_MHZ(10)>(leds,NUM_LEDS);

      There is more info, especially on that second link.

      I hope this is helpful.

      Reply

      hans

  • Jan 23, 2018 - 10:48 PM - Alan Comment Link

    Hans–

    Great stuff.  Readily tweakable to all the color palettes I like.  Using it on two diff 5M neopixel strips to pep up my house’s entrance way for a party.

    My one question:   Would there be an easy way to insert an analog potentiometer input into the wiring and code that could control brightness universally through all the cases?

    Reply

    Alan

    • Jan 25, 2018 - 12:34 PM - hans - Author: Comment Link

      Hi Alan,

      Awesome! 

      Yes, I would assume so. I have not tried this yet, but with the use of one of the Analog pins of the Arduino, and some code to set the overall brightness (FastLED is really good at that) should do the trick.

      The only issue I’d see is that turning a potentiometer would have to be read, kind-a like the push of the button, to make sure it works right away. This then makes it a challenge since triggering this works for buttons, but not (as far as I know) for potentiometers. 

      Reply

      hans

  • Jan 30, 2018 - 8:17 AM - Jimmie M Comment Link

    Thank you for this awesome write-up!! I am trying to do exactly this but instead of a button I need to trigger by serial input, when a particular character is read it would trigger a particular effect. This is all new to me so I’m a bit in over my head. 

    Reply

    Jimmie M

    • Feb 16, 2018 - 10:50 AM - hans - Author: Comment Link

      Hi Jimmie,

      your approach would come with a challenge. Unless you add some electronics and/or a second Arduino.
      The switch is connected to a pin that allows interruption of your program. I don’t think this will work with serial data though.

      Reply

      hans

  • Mar 3, 2018 - 3:23 AM - Samim SK Comment Link

    Dear Sir, My interesting subject and most helpful. Thanks lot

    Reply

    Samim SK

    • Mar 3, 2018 - 5:42 AM - hans - Author: Comment Link

      Hi Samim!

      thank you very much for the complement and for taking the time to post a thank-you – it’s very much appreciated! 

      Reply

      hans

  • Mar 3, 2018 - 7:29 PM - kabodos Comment Link

    great proyect, im new on arduino programing, but is any way or guide to control  with a bluetooth instead of a push button?

    Reply

    kabodos

    • Mar 7, 2018 - 3:00 AM - hans - Author: Comment Link

      Hi Kabodos,

      I have yet to play with Bluetooth, but I’m sure there must be a way to do this.
      There will be 2 challenges; get Bluetooth to work of course and make sure that a response from Bluetooth can actually interrupt the code. The latter might be a little challenging, as I have zero experience with Bluetooth and Arduino.

      Reply

      hans

  • Mar 8, 2018 - 10:05 AM - Jerry Campbell Comment Link

    I would like to run a continuous light show using all the different patterns without using a button to switch between them. 

    Reply

    Jerry Campbell

    • Mar 11, 2018 - 3:20 AM - hans - Author: Comment Link

      Hi Jerry,

      You can, by modifying the “loop()”, something like this:

      void loop() { 
                      // RGBLoop - no parameters
                      RGBLoop();
                      // FadeInOut - Color (red, green. blue)
                      FadeInOut(0xff, 0x00, 0x00); // red
                      FadeInOut(0xff, 0xff, 0xff); // white 
                      FadeInOut(0x00, 0x00, 0xff); // blue
                      // Strobe - Color (red, green, blue), number of flashes, flash speed, end pause
                      Strobe(0xff, 0xff, 0xff, 10, 50, 1000);
                      // HalloweenEyes - Color (red, green, blue), Size of eye, space between eyes, fade (true/false), steps, fade delay, end pause
                      HalloweenEyes(0xff, 0x00, 0x00, 
                                    1, 4, 
                                    true, random(5,50), random(50,150), 
                                    random(1000, 10000));
                      HalloweenEyes(0xff, 0x00, 0x00, 
                                    1, 4, 
                                    true, random(5,50), random(50,150), 
                                    random(1000, 10000));
                      // CylonBounce - Color (red, green, blue), eye size, speed delay, end pause
                      CylonBounce(0xff, 0x00, 0x00, 4, 10, 50);
                      // NewKITT - Color (red, green, blue), eye size, speed delay, end pause
                      NewKITT(0xff, 0x00, 0x00, 8, 10, 50);
                      // Twinkle - Color (red, green, blue), count, speed delay, only one twinkle (true/false) 
                      Twinkle(0xff, 0x00, 0x00, 10, 100, false);
                      // TwinkleRandom - twinkle count, speed delay, only one (true/false)
                      TwinkleRandom(20, 100, false);
                      // Sparkle - Color (red, green, blue), speed delay
                      Sparkle(0xff, 0xff, 0xff, 0);
                      // SnowSparkle - Color (red, green, blue), sparkle delay, speed delay
                      SnowSparkle(0x10, 0x10, 0x10, 20, random(100,1000));
                      // Running Lights - Color (red, green, blue), wave dealy
                      RunningLights(0xff,0x00,0x00, 50); // red
                      RunningLights(0xff,0xff,0xff, 50); // white
                      RunningLights(0x00,0x00,0xff, 50); // blue
                      // colorWipe - Color (red, green, blue), speed delay
                      colorWipe(0x00,0xff,0x00, 50);
                      colorWipe(0x00,0x00,0x00, 50);
                      // rainbowCycle - speed delay
                      rainbowCycle(20);
                      // theatherChase - Color (red, green, blue), speed delay
                      theaterChase(0xff,0,0,50);
                      // theaterChaseRainbow - Speed delay
                      theaterChaseRainbow(50);
                      // Fire - Cooling rate, Sparking rate, speed delay
                      Fire(55,120,15);

                    // simple bouncingBalls not included, since BouncingColoredBalls can perform this as well as shown below
                    // BouncingColoredBalls - Number of balls, color (red, green, blue) array, continuous
                    // CAUTION: If set to continuous then this effect will never stop!!! 
                      // mimic BouncingBalls
                      byte onecolor[1][3] = { {0xff, 0x00, 0x00} };
                      BouncingColoredBalls(1, onecolor, false);
                      // multiple colored balls
                      byte colors[3][3] = { {0xff, 0x00, 0x00}, 
                                            {0xff, 0xff, 0xff}, 
                                            {0x00, 0x00, 0xff} };
                      BouncingColoredBalls(3, colors, false);
                      // meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay 
                      meteorRain(0xff,0xff,0xff,10, 64, true, 30);
      }

      I have not been able to test this, and it’s still early in the morning here (I need one more coffee I think haha).
      If one of the effects is endless then it will get “stuck” with that effect and we’d need to tweak the effect to not be endless.
      Each effect is ran only once, so you may want to to a “for-loop” around an effect to make it appear multiple times.

      Hope this helps!

      Reply

      hans

      • Mar 12, 2018 - 8:18 AM - Jerry Campbell Comment Link

        Thanks Hans,

        I’ll give it a try this evening.

        Reply

        Jerry Campbell

      • Mar 12, 2018 - 8:20 AM - hans - Author: Comment Link

        Keep us posted! 

        Reply

        hans

        • Mar 12, 2018 - 7:50 PM - Jerry Campbell Comment Link

          Big Thank You, Hans

          Worked perfectly, just what I was wanting. 

          Reply

          Jerry Campbell

          • May 7, 2018 - 11:58 AM - Daniel Fernandes Comment Link

            Hi Jerry, post a link to your modified code… Thanks

            Daniel Fernandes

        • Mar 14, 2018 - 4:39 AM - hans - Author: Comment Link

          Thanks Jerry!

          That’s good news 

          Reply

          hans

      • Apr 24, 2020 - 7:41 AM - Marunthol Comment Link

        I tried it but I did not find the effect (Fire) working or being missed,
        Did I make a mistake?
        Sorry I am a beginner who just wants to learn Arduino 🙏

        Reply

        Marunthol

        • Apr 26, 2020 - 5:19 AM - Hans - Author: Comment Link

          Assuming you’re referring to the code in the threat, you’ll have to add this line:

          Fire(55,120,15); 

          The values passed to the Fire function (more details here) are : 

          Fire(int Cooling, int Sparking, int SpeedDelay)

          You could, for example place it right after the meteor rain line:

          meteorRain(0xff,0xff,0xff,10, 64, true, 30);

          Reply

          Hans

          • Apr 28, 2020 - 8:24 AM - Marunthol Comment Link

            I have done your advice but not get results

            can you add the code so that I can see the difference?

            Marunthol

          • Apr 29, 2020 - 6:36 AM - Hans - Author: Comment Link

            From your code:

                            BouncingColoredBalls(3, colors, false);
                            // meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay 
                            meteorRain(0xff,0xff,0xff,10, 64, true, 30);
            }

            change it to:

                            BouncingColoredBalls(3, colors, false);
                            // meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay 
                            meteorRain(0xff,0xff,0xff,10, 64, true, 30);
                            // Fire effect
                           Fire(55,120,15); 
            }

            (assuming your code gets to the MeteorRain, it will fire the Fire effect right after that)

            Hans

      • Apr 29, 2020 - 12:20 PM - Kevin Comment Link

        Great stuff! Although I have not been able to get the ‘Meteor Rain’ effect to work with Fast LED.

        Reply

        Kevin

        • Apr 30, 2020 - 4:48 AM - Hans - Author: Comment Link

          Hi Kevin!

          Glad you like it!
          Please start a new forum topic in the Arduino Forum, so you can post your code and I can maybe see what it is failing.
          (please do not post code in here the comment section)

          Also; please list the model Arduino you’re using.

          Reply

          Hans

  • Mar 23, 2018 - 2:12 AM - Emiel Comment Link

    Hi.

    On the sample video you can see the led flicker when they get dimmed. 

    I quess this is to do with the PWM dimming. Can this be set to a higher frequency or is this preset in the led chips.

    I would to use in video recordings 

    Reply

    Emiel

    • Mar 24, 2018 - 2:57 AM - hans - Author: Comment Link

      Hi Emiel,

      not sure what video you’re referring to, but I did notice that FastLED is much better at this than NeoPixel – so I’d start by using FastLED.
      Another reason could be the method dimming is calculated. If the steps to the next level are too much, flickering may occur. I know FastLED has much better dimming techniques/functions available (NeoPixel not so much) which you may want to experiment with.

      Hope this helps 

      Reply

      hans

  • Mar 27, 2018 - 3:34 AM - Aaron Comment Link

    Thank you for all your work, it proves we all can do it as long as as we just give it a go.

    You inspired me to do some Christmas lights.

    I will try it out for my Christmas lights and add BLE or a button.,

    I don’t mind  if the script/sketch resets, I probably would prefer it.

    Regards

    Reply

    Aaron

    • Mar 28, 2018 - 8:27 AM - hans - Author: Comment Link

      Thanks Aaron!

      I very much appreciate your thank-you note! It’s much appreciated and it’s fun to hear that others get enthusiastic with this stuff as well! 

      Reply

      hans

  • Mar 30, 2018 - 4:10 PM - Mike Garber Comment Link

    Tip:      Your use of     asm volatile (” jmp 0″);   wont fly on a ESP8266  (Error:  “unknown opcode or format name jmp”)

    Reply

    Mike Garber

    • Mar 31, 2018 - 4:11 AM - hans - Author: Comment Link

      Thanks Mike for the tip!

      I read in a bug report that the ESP library has a reset/restart function.

      ESP.restart();

      and 

      ESP.reset();

      There seems to be a bug with the first reset call, and I’m not sure if this still is the case (since I have done nothing with ESP yet).
      One user suggest using this to reset:

      WiFi.forceSleepBegin(); wdt_reset(); ESP.restart(); while(1) wdt_reset();

      I cannot (yet) test this though, but it would be cool if it would work.

      Reply

      hans

      • Jan 3, 2021 - 10:37 PM - Peter Thompson Comment Link

        That doesn’t seem to work for me.  At least not for the M5Stick-C.  The IDE doesn’t know where to find wdt_reset, nor do I. I did try some various headers, such as “esp_system.h” but no joy.  Any  what ESP32 library I should be using?

        Cheers, Peter

        Reply

        Peter Thompson

      • Jan 4, 2021 - 6:31 AM - Hans - Author: Comment Link

        Hi Peter!

        Happy New Year!

        I do not have an ESP32 (yet) and haven’t been able to test the code.
        I did find this article attempting to implement WDT for the ESP32 using the “esp_task_wdt.h” library.
        I have not tried this code, but maybe it is helpful for you.

        Reply

        Hans

        • Jan 4, 2021 - 11:06 AM - Peter Thompson Comment Link

          Thanks Hans,

          I’ll check that out.  I was able to get the neoPixel version working without the button – merely cycles through the various patterns. 

          If you want a fun device to play with that is ESP32, check out the M5Stick-C.  

          Cheers!

          Reply

          Peter Thompson

        • Jan 5, 2021 - 4:42 AM - Hans - Author: Comment Link

          Hi Peter!

          Thanks for the tip on the M5Stick-C – is it M5Stick-C or M5Stack-C? (tried Googling it)

          Cheers 

          Reply

          Hans

  • Apr 13, 2018 - 7:38 AM - Arnaud Comment Link

    Hello,

    I don’t speack English so it’s difficult for me to understand all your explications.
    I try to use AllEffects LEDStrip Effect (NeoPixel) downloaded on this page.
    But I have some problem when I check the code.
    Could you help me please?

    1. AllEffects_NeoPixel.ino: In function ‘void setup()’:
    2. AllEffects_NeoPixel.ino:16:49: error: ‘digitalPinToInterrupt’ was not declared in this scope
    3. AllEffects_NeoPixel.ino: In function ‘void loop()’:
    4. AllEffects_NeoPixel.ino:21:10: error: ‘class EEPROMClass’ has no member named ‘get’
    5. AllEffects_NeoPixel.ino:25:12: error: ‘class EEPROMClass’ has no member named ‘put’
    6. AllEffects_NeoPixel.ino: In function ‘void changeEffect()’:
    7. AllEffects_NeoPixel.ino:170:12: error: ‘class EEPROMClass’ has no member named ‘put’
    Reply

    Arnaud

    • Apr 16, 2018 - 7:31 AM - hans - Author: Comment Link

      Hi Arnaud,

      What hardware are you using? (Arduino Uno R3?)
      If you’re using an Arduino Uno, then by the looks of the error messages you have a typo somewhere …

      Reply

      hans

      • Apr 16, 2018 - 12:10 PM - Arnaud Comment Link

        Hello Hans,

        Thank you for your answer.
        I use an Arduino Uno R3.
        I just found a solution. Not why it didn’t work but how to use your sketch.
        The problem was not typo but software.
        On my laptop I use Ubuntu and Arduino 2:1.0.5+dfsg2-4. Your sketch doesn’t work.
        I tried with my Android smartphone, ArduinoDroid, the same sketch and the same libraries. Your sketch works perfectly.

        Thank you Hans for your very good sketches and tutorials.

        Reply

        Arnaud

        • Apr 17, 2018 - 3:20 AM - hans - Author: Comment Link

          Hi Arnaud,

          what you could try, if you use copy and paste: copy the sketch text to a plain text editor (you could try Atom – freely available for Windows, Mac and Linux). After having it copied there, select all and copy again, and now paste it into the Arduino IDE. I have seen a few users with goofy effects of characters being copied from their browser. So maybe this is the case in your situation as well. 

          Reply

          hans

          • Apr 21, 2018 - 11:17 AM - Arnaud Comment Link

            Hello Hans,

            Thank you for your help.
            I installed Atom, copied-pasted our code inside, just changed “PIN 5” to “PIN 6” and copied-pasted all from Atom into the Arduino IDE.
            There is the same compilation error.

            Perhaps there is a problem with my EEPROM library on Linux. I will try to remove it and install it at new.
            But our code works fine when I use it from my phone with an Android OS. And for that I’m very happy.

            Arnaud

          • Apr 22, 2018 - 3:20 PM - hans - Author: Comment Link

            Thanks for the feedback – there must be an issue with the Arduino IDE you’re using. 
            Your version number seems a little odd, maybe you’d want to try to download the latest version from the Arduino website: https://www.arduino.cc/en/Main/Software – which at this time would be version 1.8.5.

            Would be nice to figure that one out, right? 

            hans

          • Apr 24, 2018 - 1:32 PM - Arnaud Comment Link

            Hello Hans,

            You’re right. I had a too old version.
            I installed the latest version as you advised me and there no check problem.
            The uploading is OK and your code works wonderfully.

            Many thanks for all.

            Arnaud

          • Apr 27, 2018 - 2:29 AM - hans - Author: Comment Link

            You’re most welcome!
            Glad it got resolved and thanks for posting the confirmation! 

            hans

  • May 6, 2018 - 9:15 PM - Daniel Fernandes Comment Link

    Hi Hans! First, thank you and congratulations for the “CHALLENGE!”
    I
    do not know if anyone here in the forum commented on it (I did not read
    everything because my language is Portuguese) but, instead of using a
    Button, like you did, I would not be able to sequence these codes with a
    kind of “Delay”, or
    either, each time one code ends, the other starts, and so on?
    See that they are words of a practically “layman” in the subject; hug from Brazil

    Reply

    Daniel Fernandes

    • May 9, 2018 - 3:23 AM - hans - Author: Comment Link

      Hi Daniel,

      yes you most certainly can put them in sequence so it rotates automatically.

      Probably the easiest to do this is by making a small change to the loop();

      replace this:

      void loop() { 
        EEPROM.get(0,selectedEffect); 
        
        if(selectedEffect>18) { 
          selectedEffect=0;
          EEPROM.put(0,0); 
        } 

      with this:

      void loop() { 
        selectedEffec++;  
        if(selectedEffect>18) { 
          selectedEffect=0;
          delay(1000); // 1 second delay
        } 
        ... // the effects

      Hope this helps. 

      Reply

      hans

      • May 9, 2018 - 11:55 AM - Daniel Fernandes Comment Link

        Hi Hans!

        I did so, as you said:

        void loop() {
          selectedEffec++;
         
          if(selectedEffect>18) {
            selectedEffect=0;
            delay(1000); // 1 second delay
          }
           
          switch(selectedEffect) {

        case 0,  1,  2 …

        And showed the following error:

        ‘selectedEffec’ was not declared in this scope


        Hugs

        Reply

        Daniel Fernandes

        • May 9, 2018 - 2:20 PM - hans - Author: Comment Link

          Hi Daniel!

          I see, typo on my end … it should have been selectedEffect – forgot the “t” at the end 

          Corrected:

          void loop() { 
            selectedEffect++; // <--- I forgot the "t" in selectedEffect
           
            if(selectedEffect>18) { 
              selectedEffect=0;
              delay(1000); // 1 second delay
            } 
          Reply

          hans

          • May 13, 2018 - 11:06 AM - Daniel Fernandes Comment Link

            Hi Hans! One more time, it did not work!
            He performs some four sequences and stops at a set of red lights;

            Daniel Fernandes

          • May 14, 2018 - 5:20 AM - hans - Author: Comment Link

            Hi Daniel,

            oh man, we keep running into small problems 

            Can you verify that the numbers in the “case” statement are sequential (ie. there is no gap in the numbers).

              switch(selectedEffect) {
                
                case 0 : {
                            // RGBLoop - no parameters
                            RGBLoop();
                            break;
                          }
                case 1 : {
                            // FadeInOut - Color (red, green. blue)
                            FadeInOut(0xff, 0x00, 0x00); // red
                            FadeInOut(0xff, 0xff, 0xff); // white 
                            FadeInOut(0x00, 0x00, 0xff); // blue
                            break;
                          }
                ...

            You should see: case 0, case 1, case 2, …, case 18.

            Are you using FastLED (better) or NeoPixel?

            And is your powersupply powerful enough to have all LEDs powered?

            So the 4th or 5th sequence fails? You could comment out an effect and see which one is failing, for example like so, see effect “case 4- CylonBounce” where I added “//” before the effect.

                case 3  : {
                            // HalloweenEyes - Color (red, green, blue), Size of eye, space between eyes, fade (true/false), steps, fade delay, end pause
                            HalloweenEyes(0xff, 0x00, 0x00, 
                                          1, 4, 
                                          true, random(5,50), random(50,150), 
                                          random(1000, 10000));
                            HalloweenEyes(0xff, 0x00, 0x00, 
                                          1, 4, 
                                          true, random(5,50), random(50,150), 
                                          random(1000, 10000));
                            break;
                          }
                          
                case 4 : {
                            // CylonBounce - Color (red, green, blue), eye size, speed delay, end pause
                            // CylonBounce(0xff, 0x00, 0x00, 4, 10, 50);  // <--- here, added "//" to comment out the effect
                            break;
                          }
                          
                case 5 : {
                            // NewKITT - Color (red, green, blue), eye size, speed delay, end pause
                            NewKITT(0xff, 0x00, 0x00, 8, 10, 50);
                            break;
                          }

            hans

  • May 14, 2018 - 2:41 PM - Daniel Fernandes Comment Link

    Hi Hans, It worked! Very cool!
    I think it was not enough to connect the Source Negative to Arduino’s GND;
    I’ll always be looking on your site for a few more effects additions.
    Now I have a few more questions:
    1) Is there a Delay between each effect or is it a Delay for all?
    2) Is this code supported by an ATtiny85 8MHz (by size and versatility)?
    3) To cancel an effect, for example “HalloweenEyes”, do I only comment on the effect with “//” or exclude all “case 3”?
    Once again, thank you very much and congratulations for the feat!

    Reply

    Daniel Fernandes

    • May 15, 2018 - 2:51 AM - hans - Author: Comment Link

      Hi Daniel,

      Glad to hear it works! 

      Ill try to answer your questions:

      1) Delay between effects can be accomplished by adding a delay at the end of loop(), like so (watch out for the accolade):

          case 18 : {
                      // meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay 
                      meteorRain(0xff,0xff,0xff,10, 64, true, 30);
                      break;
                    }
        }
        delay(1000); // <-- added a 1 second delay after an effect has been executed
      }

      2) I have no idea if the ATtiny can handle this – if it would be limited then it would be because of the size of the code. You could also consider an ESP8266, which I haven’t tested yet. They are very cheap and very capable.

      3) Cancelling an effect;
      The best way would be to remove the code and change the numbers of the “case x:” lines, for example:

          ...
          case 2 : {
                      // Strobe - Color (red, green, blue), number of flashes, flash speed, end pause
                      Strobe(0xff, 0xff, 0xff, 10, 50, 1000);
                      break;
                    }
          case 3 : {
                      // HalloweenEyes - Color (red, green, blue), Size of eye, space between eyes, fade (true/false), steps, fade delay, end pause
                      HalloweenEyes(0xff, 0x00, 0x00, 
                                    1, 4, 
                                    true, random(5,50), random(50,150), 
                                    random(1000, 10000));
                      HalloweenEyes(0xff, 0x00, 0x00, 
                                    1, 4, 
                                    true, random(5,50), random(50,150), 
                                    random(1000, 10000));
                      break;
                    }
                    
          case 4 : {
                      // CylonBounce - Color (red, green, blue), eye size, speed delay, end pause
                      CylonBounce(0xff, 0x00, 0x00, 4, 10, 50);
                      break;
                    }
         ...

      becomes:

          case 2  : {
                      // Strobe - Color (red, green, blue), number of flashes, flash speed, end pause
                      Strobe(0xff, 0xff, 0xff, 10, 50, 1000);
                      break;
                    }
          // case 3 removed
          case 3 : { // case 4 has been renumbered to case 3, ditto for the following "case" numbers (ie. case 5 becomes case4 etc)
                      // CylonBounce - Color (red, green, blue), eye size, speed delay, end pause
                      CylonBounce(0xff, 0x00, 0x00, 4, 10, 50);
                      break;
                    }

      Hope this helps. 

      Reply

      hans

  • May 18, 2018 - 12:54 PM - Jim Comment Link

    Hi

    Thank you so much for your article and your explanation. I’m new to arduino and programming. I’ve by looking quite a long time for an answer to that problem of interrupt with Neopixel but didn’t fnd anything until I found your webpage.

    I took your code structure (Neopixel) and replaced your animations by mine (I kept some of your animations…). It works quite well. But there are 2 minor problems.

    1) Starting Case:

    When I switch on the arduino (or reset), it starts at case 1 instead of case 0. I could fix this by changing the code at line 9:  byte selectedEffect=0; to byte selectedEffect=18. If I choose selectedEffect= Max Nr of cases, then it starts at case 0. I don’t understand why but it works, so it’s fine for me. I’m just curious to know why it happens…

    2) Switch debounce:

    While toggling through the cases, it often starts again at case 0 before having reached the last case. I don’t know what the reason is but I guess it has something to do with switch bouncing. I don’t know how to fix this with an interrupt. Can somebody help me with this? I would prefer a software solution than a hardware solution but any solution is welcome.

    Thanks a lot!

    Jim

    Reply

    Jim

    • May 20, 2018 - 9:57 AM - hans - Author: Comment Link

      Hi Jim,

      welcome at Tweaking4All and thank you very much for the very nice and motivating compliments! 

      1) Starting point

      Theoretically the EEPROM should hold the value where you left off last time the Arduino ran – but I have found that not to be reliable, which makes me wonder a little about the EEPROM. I guess it needs to remain power to actually hold that value (and that’s why it survives a reset).

      To force it to start at zero you could make this modification (untested);

      void setup()
      {
        strip.begin();
        strip.show(); // Initialize all pixels to 'off'
        digitalWrite (BUTTON, HIGH); // internal pull-up resistor
        attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, CHANGE); // pressed
        EEPROM.put(0,0);  // <-- add this
      }

      2) Debouncing the switch

      I do not have access to my gear at the moment (I’m on vacation for the next 4 weeks). Maybe try another switch (I did some testing with just 2 wires, which worked very well). Keep us in the loop for what you see or find on this topic – anything to improve the sketch is naturally very welcome.
      When I get back home, I’ll try to make some time and look at this, but I can understand that 4 weeks is a rather long time to wait 

      Reply

      hans

  • May 18, 2018 - 10:48 PM - Brent Roberson Comment Link

    Hello Hans,

    I wanted to say thank you for this awesome information and also ask a couple questions. I am a beginner with arduino but I am working on a project where I use a potentiometer to smoothly change the colors in the spectrum. My code ends up not working in the end and I think it is just because I don’t really know what I am doing. Do you have any ideas or know any websites that can show me how to do this? I also wanted to make it dimmer and brighter as it reacts to music so if you have any ideas on how I should go about that please let me know. I also have one more question about your code. The function setAll is not being recognized the arduino and it says it was not declared in this scope even though I have downloaded and included the fast led and adafruit library. Do you have any idea why this would not work? Thanks so much and if you don’t have the time to spend on this long question or part of the question I understand. 

    Reply

    Brent Roberson

    • May 20, 2018 - 10:03 AM - hans - Author: Comment Link

      Hi Brent,

      welcome to Tweaking4all and thank you very much for the kind compliments – it’s very much appreciated. 

      As for playing with potentiometers (watch the different kinds – linear vs non-linear) and reacting to music; I’ve not played much with potentiometers, but I have done some playing with a microphone and a line-in setup to “read” music volume and found that it’s not as straight forward as one would hope. With a microphone you will need to add a tiny amp (single chip, real cheap) and even then things are not as consistent as I wanted it to be (I wanted the fire effect to respond to music – like VU meters from back in the day). I’m on vacation right now, so I do not have all my stuff near me, you may end up consulting Google. Sorry … 

      As for the setAll() function; that’s kind a hard to determine without seeing the code, and posting the full code here is not desirable either (since comments then become huge over time). You could post you sketch in the forum and I can look at it and see what the issue may be.

      Reply

      hans

      • May 21, 2018 - 9:08 PM - Brent Roberson Comment Link

        Okay, thanks for the suggestions I’ll try that out. And somehow the setAll function worked the next day I tried it lol

        Reply

        Brent Roberson

      • May 22, 2018 - 8:09 AM - hans - Author: Comment Link

        Awesome – glad it is working now 

        Reply

        hans

  • Jun 13, 2018 - 10:08 PM - Blake Comment Link

    Sorry if this comment already posted. Does anyone have the code for all the effects without a button function? Would be greatly appreciated.

    Thanks!

    Reply

    Blake

    • Jun 16, 2018 - 9:16 AM - hans - Author: Comment Link

      Hi Blake,

      yes this was posted before. To save you the search:

      Change this piece of the code:

      void loop() { 
        EEPROM.get(0,selectedEffect); 
        
        if(selectedEffect>18) { 
          selectedEffect=0;
          EEPROM.put(0,0); 
        } 

      to:

      void loop() { 
        selectedEffect++;  
       
        if(selectedEffect>18) { 
          selectedEffect=0;
          delay(1000); // 1 second delay
        } 

      (this is the quick an dirty method)

      Reply

      hans

  • Jul 3, 2018 - 11:06 AM - Nathan Comment Link

    Hey Hans,

    You do amazing work. A question I have is that I want to power 1200 leds for a costume so I use an M0 board. Do you know what needs to be tweeked in your code? Right now its coming up with a fault about EEPROM. Ive read that you need to emulate EEPROM for M0 boards. Do you know how to do that?

    Thank you for all your hard efforts

    Reply

    Nathan

    • Jul 4, 2018 - 6:16 AM - hans - Author: Comment Link

      Hi Nathan,

      I’m not familiar with the MO board you’re referring to.
      Having said that: 1200 LEDs is a lot … but that sounds pretty awesome to play with 

      To power 1200 LEDs, you’ll need a pretty good power-supply. Not just that, but you’d want to connect +5V and GND of the strips, in multiple places so power distribution works OK. I have seen with 300 LEDs that the last LEDs seem to be getting less power. For 300 LEDs, the trick is to connect +5V and GND to both ends of the strand(s). I’d carefully assume the same goes for 1200 LEDs. Maybe power each strip separately?

      Since I’m not familiar with the board you’re using; I cannot help you with how to access EEPROM.
      I did find these posts that may be helpful though:

      Hope this is helpful … 

      Reply

      hans

      • Jul 13, 2018 - 10:03 PM - Nathan Comment Link

        I’m talking about the Trinket MO or the itsy bitsy MO. They are just like Arduino boards but smaller and can power way more LEDs. But they do not have eeprom. I have all the power and wiring done and figured out. Online I’ve read that you need to replace the eeprom part of the code with an emulated eeprom instead. I don’t know how to code though. It seems like it wouldn’t be too hard if I had a little more knowledge. This guide from you is the closest thing I’ve seen so far to finding a code with a button to change effects. You’re very talented

        Reply

        Nathan

      • Jul 14, 2018 - 4:06 AM - hans - Author: Comment Link

        Hi Nathan,

        I have no experience with either MO (even though they do sound interesting!).

        As for working with the eeprom on either of these boards, from what I can see is that there is some sorts of nonvolatile memory, but working with it seems to need one of the AVR (low level) libraries. 

        This code at Github (eeprom-blink) may be useful, but it’s definitely not as easy looking as the functions that come with the standard EEPROM libraries for other Arduino models. AdaFruits shows there are two working functions, but I have to say that the explanation/documentation is pretty poor.

        This flashstorage library may be helpful as well. I did see in a forum that a user confirmed this to work with the trinket.

        Something like this:

        #include <FlashStorage.h>
        ... // Reserve a portion of flash memory to store an "int" variable and call it "my_flash_store".
        FlashStorage(my_flash_store, int);
        ...
        void setup() { ...   int number;
          // Read the content of "my_flash_store" and assign it to "number"
          number = my_flash_store.read();
        ...
          // Save into "my_flash_store" the number increased by 1 for the
          // next run of the sketch
          my_flash_store.write(number + 1); ...
        }
        ...

        Not sure how helpful this info is, since I cannot test any of it.

        Reply

        hans

        • Jul 14, 2018 - 4:15 PM - Nathan Comment Link

          Thank you for your research. I’ll attempt trying that. I’m going to enroll in a class for this soon. I hate that I don’t know how to write my own code. I have to rely on finding it at the moment. Seeing your work is very motivating too. You should be very proud of your skills. If you learn any more about this in the future I’m always interested to learn more about it. Thanks again

          Reply

          Nathan

          • Jul 15, 2018 - 3:39 AM - hans - Author: Comment Link

            Hi Nathan,

            You’re most welcome and thank you very much for your compliments – it’s appreciated and motivating for myself as wel! 

            As for programming, I did write some articles for beginners but I’m not sure if this is what you’re looking for: Arduino Programming for Beginners. It starts with the basics, so it may or may not be what you’re looking for. 

            hans

  • Jul 28, 2018 - 7:53 AM - Christophe Gonthier-Georges Comment Link

    Bonjour, votre code fonctionne très bien, c’est exactement ce que je cherchais.

    Pourriez-vous juste me dire comment ajouter tous les led au début du programme s’il vous plaît?

    Reply

    Christophe Gonthier-Georges

    • Jul 29, 2018 - 7:37 AM - Christophe Gonthier-Georges Comment Link

      Sorry, but he did not translate the French text.

      I was saying:

        “Hello, your code works fine, that’s exactly what I was looking for.

      Could you just tell me how to add all the led off in the first sequence of the program please? “

      Thank you in advance

      Reply

      Christophe Gonthier-Georges

    • Jul 30, 2018 - 5:06 AM - hans - Author: Comment Link

      Hi Christophe!

      No worries…

      You can add an effect in the case statements.

      Something like:

          case 19 : {
                      // all off 
                      setAll(0,0,0);
                      break;
                    }

      You’ll need to modify line 23:

        if(selectedEffect>19) {  // increase the number 18 to 19
          selectedEffect=0;
          EEPROM.put(0,0); 
        } 

      I can imagine that you’d like to start with this effect, in that case, swap it with the effect at “case 0:”.

      Hope this helps 

      Reply

      hans

      • Jul 30, 2018 - 2:29 PM - Christophe Gonthier-Georges Comment Link

        I set up your code I have the effect in 19 but impossible to start on even putting it in box 0

        J’ai mis en place votre code j’ai bien l’effet en 19 mais impossible à démarrer dessus même en le mettant en case 0

        Reply

        Christophe Gonthier-Georges

      • Aug 8, 2018 - 6:31 AM - hans - Author: Comment Link

        Easiest way to do it:

        Add 

            case 0 : {
                        // all off 
                        setAll(0,0,0);
                        break;
                      }

        before line 30 (where “case 0: {” currently is).

        For all following case numbers, increase by one, so:

        –  the old “case 0: {” becomes, “case 1: {“,
        –  the old “case 1: {” becomes “case 2: {“,
        … etc until your reach “case 18: {” which becomes “case 19: {“.

        Make sure to modify the code at line 23 as well:

         if(selectedEffect>19) {  // increase the number 18 to 19
            selectedEffect=0;
            EEPROM.put(0,0); 
          } 
        Reply

        hans

        • Aug 8, 2018 - 5:02 PM - Christophe Gonthier-Georges Comment Link

          J’ai fait ce que tu as mis mais ça commence toujours sur le premier effet et non sur la LED.

          Je ne comprends pas :(

          J’ai fait ce que vous avez mis mais ça commence toujours sur le premier effet et non les LED éteintes.

          Je ne comprend pas :(

          Reply

          Christophe Gonthier-Georges

        • Aug 11, 2018 - 5:33 AM - hans - Author: Comment Link

          Hi Christophe,

          pretty please post in English only … my French is very bad, and this may be the case for other visitors as well.

          Your message (per Google Translate):

          I did what you put but it always starts on the first effect and not on the LED.

          I do not understand :(

          I did what you put but it always starts on the first effect and not the LEDs off.

          I do not understand :(

          Always starting with a given effect will be tricky. We use the EEPROM to store the value of the selected effect to survive a reset and powering the Arduino down would result the same effect. The only thing I could find (Arduino forum post) is this:

          void setup() {
           Serial.begin(38400);
           Serial.print("MCUSR: ");
           Serial.println(MCUSR);
           
           if (MCUSR & _BV(EXTRF)){
               // Reset button or otherwise some software reset
               Serial.println("Reset button was pressed.");
           }
           if (MCUSR & (_BV(BORF) | _BV(PORF))){
                // Brownout or Power On
                Serial.println("Power loss occured!");
           }
           if (MCUSR & _BV(WDRF)){
                //Watchdog Reset
                Serial.println("Watchdog Reset");
           }
           // Clear all MCUSR registers immediately for 'next use'
           MCUSR = 0;
          }

          So this would mean that we could change the “void setup()” code a little … (untested!!!!)

          void setup()
          {
            // Read the appropriate register to detect power on/off/brownout vs reset button press
            if (MCUSR & (_BV(BORF) | _BV(PORF))){
              selectedEffect=0;
              EEPROM.put(0, selectedEffect); // store the chose effect
            }
            FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
            digitalWrite (BUTTON, HIGH); // internal pull-up resistor
            attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, CHANGE); // pressed
          }

          If this work appropriately, then please let us know, so I can update the code to accommodate for this.

          Reply

          hans

          • Sep 2, 2018 - 4:27 AM - Christophe Gonthier-Georges Comment Link

            Hi Hans, I found the solution to my problem.

            I deleted case 0 by case 1 and changed all the others and I can boot on any LED off.

            Here is my code for those interested:

            #include <Adafruit_NeoPixel.h>
            #include <EEPROM.h>

            #define NUM_LEDS 35 
            #define PIN 4 
            Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

            #define BUTTON 2
            byte selectedEffect=0;

            void setup()
            {
              strip.begin();
              strip.show(); // Initialize all pixels to 'off'
              digitalWrite (BUTTON, HIGH); // internal pull-up resistor
              attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, CHANGE); // pressed
            }

            void loop() { 
              EEPROM.get(0,selectedEffect); 
              
              if(selectedEffect>20) { // increase the number 18 to 19
                selectedEffect=0;
                EEPROM.put(0,0); 
              } 
              
              switch(selectedEffect) {
               

                case 1 : {
                           // all off 
                            setAll(0,0,0);
                            break;
                           }
                case 2 : {
                            // Strobe - Color (red, green, blue), number of flashes, flash speed, end pause
                            Strobe(0xff, 0xff, 0xff, 10, 50, 1000);
                            break;
                          }

                ...

            thank you very much

            Christophe Gonthier-Georges

          • Sep 3, 2018 - 2:50 AM - hans - Author: Comment Link

            Hi Christophe!

            Good to hear you’ve got it to work! 
            I did shorten your code a little, since it is quite long for the comment section. I left the case section in tacts so folks can see what you are referring to.

            Thanks for posting! 

            hans

  • Aug 20, 2018 - 11:48 AM - JLPicard Comment Link

    New to this, should I purchase a UNO for this sketch?  Ebay ok?

    Reply

    JLPicard

    • Aug 20, 2018 - 12:16 PM - hans - Author: Comment Link

      Hi Star Trek Fan! 

      Yeah I’d start with an Uno, and preferably a genuine one from Arduino. You can find them at eBay and Amazon. Most clones work well, but it will remain a gamble since some have issue with their USB chip, where as the original does not. I always find a challenging to determine which one is genuine and which one is not, so at Amazon you can at least select the brand “Arduino”. I know it’s a little more than most clones … but when starting, it may be worth it. Also: there are some great started kits at Amazon (and I’m sure at eBay as well).

      Hope this helps …

      p.s. The Arduino Uno is also called the “Arduino Uno R3” – those are the same boards.

      Reply

      hans

  • Aug 28, 2018 - 6:20 PM - tratzum Comment Link

    I am impressed. I want to ask how I could slow some of these animations down. I know the basics of how it all works but everything after line 175 ish LEDEFFECT FUNCTIONS is mostly black magic to me.

    Reply

    tratzum

    • Aug 29, 2018 - 3:25 AM - hans - Author: Comment Link

      Hi Tratzum,

      thank you very much for the compliment, it’s very much appreciated.

      To delay effects, for most of the effects anyway, you can tinker a little with the “delay()” statement right before or after the “showStrip()” function calls in an effect. For example:

      void RGBLoop(){
        for(int j = 0; j < 3; j++ ) { 
          // Fade IN
          for(int k = 0; k < 256; k++) { 
            switch(j) { 
              case 0: setAll(k,0,0); break;
              case 1: setAll(0,k,0); break;
              case 2: setAll(0,0,k); break;
            }
            showStrip();
            delay(3); // <--- increase this value will slow down the effect
          }
          // Fade OUT
          for(int k = 255; k >= 0; k--) { 
            switch(j) { 
              case 0: setAll(k,0,0); break;
              case 1: setAll(0,k,0); break;
              case 2: setAll(0,0,k); break;
            }
            showStrip();
            delay(3); // <--- increase this value will slow down the effect
          }
        }
      }

      In some functions you may have to add a delay, for example:

      void FadeInOut(byte red, byte green, byte blue){
        float r, g, b;
            
        for(int k = 0; k < 256; k=k+1) { 
          r = (k/256.0)*red;
          g = (k/256.0)*green;
          b = (k/256.0)*blue;
          setAll(r,g,b);
          showStrip(); delay(10); // <--- added a delay here
        }
           
        for(int k = 255; k >= 0; k=k-2) {
          r = (k/256.0)*red;
          g = (k/256.0)*green;
          b = (k/256.0)*blue;
          setAll(r,g,b);
          showStrip(); delay(10); // <--- added a delay here
        }
      }

      You may have to experiment a little with the delay values (values in milliseconds, so 1000 = 1 second).
      Some of the effects already have a delay option build in; like

      Strobe();
      HalloweenEyes()
      CylonBounce();
      NewKITT();
      Twinkle();
      TwinkleRandom();
      Sparkle();
      SnowSparkle();
      RunningLights();
      colorWipe();
      theaterChase();
      Fire();
      meteorRain();

      Look for any delay or speed-delay parameters.

      Maybe one of these days I’ll convert all of them to include a speed/delay option. Unfortunately, I’m still trying to get settled after moving to a new home, so I do not have my gear readily available.

      Hope this helps … 

      Reply

      hans

  • Sep 1, 2018 - 2:32 PM - Philip King Comment Link

    Hi Hans,

    Brilliant sequence and explanation and I’m really impressed. Its also answered a future problem (for me), as I needed to add a button to 2 x 2.5m strips of 2812b to both my kids bedrooms (one per child) and wanted them to be able to switch between patterns. Thank you!

    I took the plunge about 8 months ago and have installed strips round the outside of my house ready for Christmas (took it slow as the leds are cheap but the infrastructure to run the 500 leds I have installed is substantial. (PSUs, buck converters, conduit, cable etc)), I’ll definitely be looking to add a few of your sequences to my (ever extending) list .

    I’ve tried to write a few (very unsuccessful)  sequences myself but just don’t seem to be mathematically capable YET!  

    I have a question though. I really want to modify the code so that the fire and bouncing ball sequences will run within my 500led outside lights. Try as I might I cannot get the sequences to work as I need the first 75 leds to work then miss out the next 142 then run again (but upside down) in the next 75 leds (I do hope you can follow). Can you see a way of doing it as I’ve been scratching my head so much its starting to bleed. LOL 

    The leds are arranged (outside) in one continuous loop. A vertical strip (going up) up the side of the house (75leds), a horizonal strip under the guttering (142 leds), another 75leds going down the opposite side, then a final horizontal set (208) linking back around a porch.

    I’ve set used the #define NUM_LEDS 500 and both look very silly when you try to run them round the house….

    Hope you can help.

    Philip

    Reply

    Philip King

    • Sep 2, 2018 - 2:53 AM - hans - Author: Comment Link

      Hi Philip!

      Thank you very much for the compliments! It’s very much appreciated!
      Wow you really are using LED strips a lot haha – I’m jealous! One of these days, when I own my own house, I’ll follow your approach! 

      I’ve started a forum topic, if you don’t mind, because I can see us talking about this for a bit to get things working …

      Here is the link to the forum topic.

      Reply

      hans

  • Sep 16, 2018 - 12:23 PM - Jakob Comment Link

    Hey,

    Great job on the code! I made a project with the led strip on a portable wooden stick and i use it for my photography. Quick question though: 

    I changed the code so that I could use a keypad matrix to switch between effects. But there’s a problem. The error comes up for every effect saying: 

    “‘theaterChaseRainbow’ was not declared in this scope” or “‘Fire’ was not declared in this scope”

    Is there anyway you can help?

    Reply

    Jakob

  • Oct 12, 2018 - 4:09 PM - DropDatabase Comment Link

    Hey nice work, but i keep getting the error:
    Have i done something wrong?

    C:/Users/user/Documents/PlatformIO/Projects/ESPFASTLED/src/main.ino: In function ‘void rainbowCycle(int)’:C:/Users/user/Documents/PlatformIO/Projects/ESPFASTLED/src/main.ino:955:47: error: ‘Wheel’ was not declared in this scope*** [.pioenvs\nodemcuv2\src\main.ino.cpp.o] Error 1

    Reply

    DropDatabase

    • Oct 14, 2018 - 3:24 AM - hans - Author: Comment Link

      Hi DropDatabase,

      In the function “rainbowCycle”, a call is made to the function “wheel”.
      You may want to verify if the function is there, and that there are no types.

      void rainbowCycle(int SpeedDelay) {
        byte *c;
        uint16_t i, j;
        for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
          for(i=0; i< NUM_LEDS; i++) {
            c=Wheel(((i * 256 / NUM_LEDS) + j) & 255);
            setPixel(i, *c, *(c+1), *(c+2));
          }
          showStrip();
          delay(SpeedDelay);
        }
      }
      // used by rainbowCycle and theaterChaseRainbow
      byte * Wheel(byte WheelPos) {
        static byte c[3];
        
        if(WheelPos < 85) {
         c[0]=WheelPos * 3;
         c[1]=255 - WheelPos * 3;
         c[2]=0;
        } else if(WheelPos < 170) {
         WheelPos -= 85;
         c[0]=255 - WheelPos * 3;
         c[1]=0;
         c[2]=WheelPos * 3;
        } else {
         WheelPos -= 170;
         c[0]=0;
         c[1]=WheelPos * 3;
         c[2]=255 - WheelPos * 3;
        }
        return c;
      }

      Reply

      hans

  • Oct 14, 2018 - 2:38 AM - deezee111 Comment Link

    Hello Hans,

    thanks for the great project! I’m a complete newbie to arduino and your beautifully-explained setup got me running my ledstrip from zero on a Saturday morning :-)

    I am now trying to get each pattern to run for a set period of time AND jump to the next pattern when the pushbutton is pressed but so far without success.  

    Would you have any tips on how to go about it?

    Dieter

    Reply

    deezee111

    • Oct 14, 2018 - 3:28 AM - hans - Author: Comment Link

      Hi Dieter!

      Thank you for the compliments! It’s very much appreciated 

      I’m not entirely clear what you’d want the Arduino to do.
      So when a button is pressed, the next effect is ran and ran only for a fixed time?

      Reply

      hans

      • Oct 14, 2018 - 8:06 AM - deezee111 Comment Link

        yes, basically I want each effect to run (for 5 minutes) before calling the next effect. 

        BUT if the button is pressed, to start the next effect immediately.

        Reply

        deezee111

      • Oct 16, 2018 - 4:00 AM - hans - Author: Comment Link

        Hi Dieter,

        that may be a little tricky on the timing part, but it’s not impossible. We’d have to adjust the “switch … case ..” loop a little (this would be my first attempt).

        Define an interval;

        DEFINE Interval 5000     // 5000 = 5 sec

        Define a few global variables;

        unsigned long startTime;
        unsigned long currentTime;

        and then in each case statement (just one example, but it should be applied to all):

        case 1  : {
                        // FadeInOut - Color (red, green. blue)
                        startTime = millis();  // store start time   
                        do {
                           FadeInOut(0xff, 0x00, 0x00); // red
                           FadeInOut(0xff, 0xff, 0xff); // white 
                           FadeInOut(0x00, 0x00, 0xff); // blue currentTime=millis();
                        while (startTime+Interval>currentTime); // repeat this until we are at, or passed, 5 seconds
                        selectedEffect++; // select the next effect EEPROM.put(0, selectedEffect); // store in EEPROM
                        break;
                      }

        Now a few things with this approach;

        1) I haven’t tested this, but I’m sure it will work, or is at least very close to something that works
        2) There may be a more elegant way of doing this
        3) Repeatedly writing to the EEPROM may not be the best thing to do as it will limit the lifespan of the EEPROM

        To improve this, you may want to try moving

        EEPROM.get(0,selectedEffect); 

        to the “setup()”, and remove the line 

        EEPROM.put(0, selectedEffect); // store in EEPROM

        Again, not tested … and when the Arduino resets it will most likely not continue where you left off.

        Hope this helps. 

        Reply

        hans

        • Oct 16, 2018 - 11:46 AM - deezee111 Comment Link

          thanks so much Hans, I’ll give it a try & let you know…

          Reply

          deezee111

  • Oct 25, 2018 - 11:49 AM - Sean Comment Link

    Hey Hans, thank you for sharing this project with us, I am using it to build a led display for our restaurant. When we were looking at options for our display, I tested it out and got it running well on my Uno with a 144led/1m led strip, but then switched to a 5m led strip with 600 leds using a Arduino Mega, and haven’t been able to get it working properly. The leds light up but don’t run the patterns, they just flicker randomly. The 5 pin on the Uno seems to be the same as the 5 pin on the Mega, do you have any advice on where I should start tweaking the code to get it to work properly? Thank you for your help.

    Reply

    Sean

    • Oct 25, 2018 - 5:01 PM - hans - Author: Comment Link

      Hi Sean,

      my advise would be to test it on the Arduino Uno first – since you had a shorter strip already working on that one.

      Second item to look at: your power supply. The flickering of the lights may indicate that you’re not having enough power.
      You’ll need a pretty good power supply to power 600 LEDs. With an effect I’d ballpark it at at least 15A/5V. Not sure if you did accommodate for that as well. Having said that; I’d recommend connecting +5V and GND of the power supply to both ends of the 600 LEDs. I know it sounds funny, but it will counter power loss at the end of the 600 LEDs (which would dim the LEDs more and more as you get closer to the end of the strand).
      You could also get 2x a 10A/5V power supply, each feeding half of the LEDs (they will all need to share GND).

      If you get all this working on the Uno, then I’d start playing with the Mega.
      As for the pins; have not played with the Mega either (never had a need for it).
      I did find a few diagrams showing the pinout of Uno and Mega, but it sure can be confusing.

      Reply

      hans

  • Oct 29, 2018 - 8:17 AM - dim Comment Link

    Hi Hans,

    Thank you so much for working all this out and sharing it with us.

    I have a problem. Why when checking the code this error appears:

    /

    C:\Arduino\AllEffects_FastLED\AllEffects_FastLED.ino: In function ‘CenterToOutside.constprop’:

    C:\Arduino\AllEffects_FastLED\AllEffects_FastLED.ino:735:23: warning: iteration 26 invokes undefined behavior [-Waggressive-loop-optimizations]

        leds[Pixel].r = red;

                           ^

    C:\Arduino\AllEffects_FastLED\AllEffects_FastLED.ino:318:3: note: containing loop

       for(int i =((NUM_LEDS-EyeSize)/2); i>=0; i–) {

       ^

    Thank you for your help.

    p.s. https://i.gyazo.com/101ec12922ecf66baa9aa6656861e223.png

    Reply

    dim

    • Oct 29, 2018 - 9:01 AM - hans - Author: Comment Link

      Hi Dim!

      As far as I can see these are not errors, just notes and warnings – so not real problems.
      While looking at the code, I cannot see why there even would be a warning, except that it’s related to the compiler directive “-Waggressive-loop-optimizations”.
      You can disable this in the Preferences of the Arduino IDE; uncheck the option “Aggressively cache compiled core“.

      One message may remain, but this is intended to be there (pragma message “FastLED version …”).

      Hope this helps 

      Reply

      hans

      • Oct 29, 2018 - 10:38 AM - dim Comment Link

        uncheck the option “Aggressively cache compiled core“

        Thanks, Hans! Works!!!!

        Reply

        dim

      • Oct 29, 2018 - 4:17 PM - hans - Author: Comment Link

        Awesome! 

        For the record; I had never noticed that option before either … so I would have been wondering as well 

        Reply

        hans

  • Nov 2, 2018 - 3:12 AM - Roy Comment Link

    I’m new to this, I need both more practice and study, so I could be completely overlooking an obvious answer but considering the limited eeprom flash cycles why not EEPROM.write instead of EEPROM.put ?  From what I have read, again limited, ‘write’ only writes data that differs from what is already there.  I’m unsure if writing the same data counts as a cycle or how many unnecessary cycles this might prevent if any, but it does seem to work.

    Reply

    Roy

    • Nov 2, 2018 - 4:29 AM - hans - Author: Comment Link

      Hi Roy,

      well, that’s actually a very good and important question. 

      As far as I know, the write function writes each and every time. Per the documentation at Arduino:

      An EEPROM write takes 3.3 ms to complete. The EEPROM memory has a specified life of 100,000 write/erase cycles, so you may need to be careful about how often you write to it.

      The put function on the other hand only writes when the value is different. Per documentation:

      This function uses EEPROM.update() to perform the write, so does not rewrites the value if it didn’t change.

      I’ll admit that I had to look it up myself as well, it’s been a while that I wrote this code. I even had to check my own code twice to make sure I had done it right 

      So; a very very good question! Put will less burden your EEPROM with wear and tear than write. (opposite of what you thought)

      Reply

      hans

      • Nov 2, 2018 - 4:37 AM - campfool Comment Link

        Thanks!  I’ll go back and reread it after I get rest, I know I’m getting tired when I start reading things backwards!  

        Reply

        campfool

      • Nov 2, 2018 - 4:39 AM - hans - Author: Comment Link

        Haha, totally get that! 

        Reply

        hans

  • Nov 20, 2018 - 7:35 AM - farizno Comment Link

    Fantastic job with this tutorial and all this information included. I came across your page while looking for info on the WS2812B code for Arduino. I have created a small PCB and installed it in my car to control the LED strips under my dash and seats. I currently have only solid colors and chasers available, with an LCD screen and rotary encoder. I was looking to add more animations and have struck the motherlode with this site. Thank you so much for sharing! Great work!

    Reply

    farizno

    • Nov 21, 2018 - 4:18 AM - hans - Author: Comment Link

      Hi Farizno!

      thank you very much for the compliments! It’s very much appreciated.
      I think you’re the first one I know of that uses this in their car – never thought of it myself, but now I’m curious 

      Reply

      hans

  • Dec 11, 2018 - 2:27 AM - beau Comment Link

    Can some one mod this to have no button and to change every 120 seconds plz.

    (lengthy code removed)

    Reply

    beau

    • Dec 11, 2018 - 8:23 AM - hans - Author: Comment Link

      Hi Beau,

      apologies that I had to remove the code – It would have taken up way too much space here.
      For future reference; when posting large chunks of code, please start a topic in the Arduino Forum.

      As for your question; I do not have an example ready for you, but the main loop() could be taken apart and place it in a loop using timer triggers. Here is some explanation on how timer triggers can be used. Unfortunately, I have no code available to demonstrate, or Arduino (at the moment – I’m traveling) at my disposal to test this.

      Reply

      hans

  • Jan 21, 2019 - 5:42 PM - dai trying Comment Link

    Hi Hans, I have modified this so that it doesn’t use the EEPROM for storage and it seems to work well, I have posted the code in the forum as it was quite long, hope this might be useful to someone.

    Forum post

    Reply

    dai trying

    • Jan 22, 2019 - 5:21 AM - hans - Author: Comment Link

      Hi Dai!

      Awesome! Thanks for doing this the right way! 

      I’ll go have a look – a solution without using the EEPROM would indeed be better.

      Reply

      hans

    • Jan 22, 2019 - 5:30 AM - hans - Author: Comment Link

      Just checked it out (I’m unable to test at the moment), and it looks really good!
      Great (if not better) alternative to using the EEPROM. 

      Reply

      hans

      • Jan 22, 2019 - 5:42 AM - Dai Trying - Author: Comment Link

        Thanks Hans, I’m going to edit the Forum post to include the check in the Fire routine, I’d like to say I was using programming etiquette and leaving a deliberate error but I just missed it

        Reply

        Dai Trying

        • Jan 22, 2019 - 5:51 AM - dai trying Comment Link

          I couldn’t edit the Forum post but users should see your comment and be able to add it, I am working on the IR capability which was another reason not to use EEPROM and will make sure I double check it before posting (If I find a viable solution that is).

          Reply

          dai trying

          • Jan 22, 2019 - 6:26 AM - hans - Author: Comment Link

            I’ve uploaded the corrected code. 

            Yeah I’ve disabled the editing in the forum, since it usually screws up the markup. Hopefully I’ll find a good alternative for this forum in the near future. Sorry about that 

            hans

      • Jan 22, 2019 - 5:49 AM - hans - Author: Comment Link

        No worries, I goof up every now and then as well 

        I was looking to see if we could glue that in the showStrip() function, but that would be a no-go (bad idea to break the loop from another function).

        Reply

        hans

        • Jan 22, 2019 - 5:53 AM - dai trying Comment Link

          I did think about that but thought it might just break out of that function but didn’t test it, I will try later and see if it works (just for kicks).

          Reply

          dai trying

        • Jan 22, 2019 - 6:26 AM - hans - Author: Comment Link

          Let me know if you run into a cool fix! 

          Reply

          hans

  • Feb 1, 2019 - 8:23 AM - dai trying Comment Link

    I have finally managed an IR solution and have posted it (and source code) in the forum, it does require two arduino modules though, I tested it with two pro-minis (cheapest on ebay)

    Forum Post

    Any thoughts or suggestions would be most welcome.

    Reply

    dai trying

    • Feb 3, 2019 - 5:37 AM - hans - Author: Comment Link

      Thanks Dai for posting the code in the forum and sharing your solution – awesome! 

      Reply

      hans

  • Mar 3, 2019 - 6:47 AM - dai trying Comment Link

    I have posted a sketch that creates a web interface (very basic) to control LED string effects in the forum, it was created for (and tested with) a Wemos D1R1 but should work with any ESP8266 variant, I hope it will be of use to others.

    Reply

    dai trying

    • Mar 3, 2019 - 7:10 AM - hans - Author: Comment Link

      Hi Dai Trying!

      Awesome, very well done and thank you so much for posting the code! 

      Reply

      hans

  • Mar 3, 2019 - 10:58 AM - Dancopy Comment Link

    Sorry but I did not understand how I can change the effects and also adjust the colors / speed / fade speed, etc.
    Do I have to use a Browser?
    Thank you

    Reply

    Dancopy

    • Mar 3, 2019 - 11:18 AM - hans - Author: Comment Link

      Hi Dancopy,

      are you referring to this article? In that case; press the button to toggle effects.
      If you’re referring to Dai Trying’s Arduino Sketch: then yes you’ll need a browser to connect to the Arduino – for this particular topic, it would be best to comment in the forum, below Dai Trying’s code.

      Reply

      hans

  • Mar 6, 2019 - 3:40 AM - Manfred Comment Link

    Hi Hans,

    just for entertainment: I used your effects and ported them to Mongoose-OS, used then a folded stripe of APA102 LEDs, controlled them via ESP32 over SPI and “pimped” the effects a little. So I created a “Versatile LED (Andon)Light” – see the video here. The video unfortunately is of poor color quality, as LEDs are hard to fiilm with digital sensors, but it gives an idea. The lamp has 320 LEDs, all separately addressable, so it’s really very versatile. I have a “serious” use case (first part of the video) as Andonlight and a “entertaining” part with the effects. If there are questions about this little project, feel free to ask. Enjoy!

    Reply

    Manfred

    • Mar 6, 2019 - 5:26 AM - hans - Author: Comment Link

      Hi Manfred,

      that looks awesome!! Did you make a write up on how you’ve build this?
      I love it, thanks for sharing! 

      p.s. would you mind posting a link to this page under your YouTube video? Not required of course, but it would help my website’s Google position a little 

      Reply

      hans

  • Mar 6, 2019 - 5:47 AM - Manfred Comment Link

    Hi Hans,

    … done! A description might follow (it’s easy to build – only the soldering of the dense stripes is tricky (I used stripes with 144 leds/m …), but for the moment it has to wait because of lack of time.

    Reply

    Manfred

    • Mar 6, 2019 - 5:51 AM - hans - Author: Comment Link

      Thanks Manfred!

      You rock! 

      Reply

      hans

    • May 10, 2019 - 3:49 PM - crewsing Comment Link

      Hi Manfred,

      I’m higly interested in the effects you’ve shown in the video.

      Is there there no way to post your code? Without commenting an wasting time for you?

      I’d appreciate your code!

      Reply

      crewsing

      • May 11, 2019 - 11:27 AM - Manfred Comment Link

        Hi crewsing,

        the code is found on Github, but unfortunately I broke the code doen to a master app and every effect as a single lib. And it’s based on Mongoose-OS – so you may not use the Arduino IDE. It’s completely timer driven and written in C. It works with APA102 LEDs in the first place, but should also work with WS2812, but I made no big tests. I improved my lamp as well and have now a column of 8×40 pixels in a frosted glas cylinder, every single LEDs is addressable. Not to mention that I have even added audio triggering … So give me some days and I will clear the repos and post the link here.

        Reply

        Manfred

  • Mar 14, 2019 - 12:44 PM Comment Link
  • Mar 15, 2019 - 6:31 PM - johnny - Author: Comment Link

    I’m trying to compile this on an adafruit trinket but it keeps erroring out on an include of nrf.h which library is that from, does anyone know?

    Reply

    johnny

    • Mar 16, 2019 - 5:13 AM - hans - Author: Comment Link

      Ho Johnny,

      I actually had to Google what that nrf.h library might be.
      Since you do not mention what Operating System, Arduino model, or Arduino IDE version you’re using, or what the error message actually is, I can only do a few guesses since this library is not used with regular Arduinos (as far as I know);

      1) I have seen that users of the Web version of the Arduino IDE see this message. Fix: use the application of the Arduino IDE application instead of the web version (in browser).

      2) You’re using an Arduino clone, seems there is are Nordic Semiconductor nRF5 based boards, which require nrf.h (link) and you’ll need to install that library because of that. The error message will be something like “fatal error: nrf.h: No such file or directory”. In the Arduino IDE go to “Sketch” – “Include Library” – “Manage Libraries”. In the filter type “nrf.h” and a few options will be listed. Since I do not know what Arduino board you’re using, you’ll have to run through the list and see which ones applies to your setup.

      Hope this helps,

      Reply

      hans

  • Apr 3, 2019 - 5:26 AM - Richard Comment Link

    Hello Hans, being new to Arduino this code has been a god send and also allowed me to analyse it to understand how it works.

    What I want to do is have an option for sound activated patterns, I have already wired up the microphone, would you be able to advise at all what additional code I would need and how to apply it as one of the button options if that is possible?

    Currently it is up and running using the button method.

    Thanks for your great work, time and patience in replying to all the questions you get asked, a refreshing change.

    Richard

    Reply

    Richard

    • Apr 3, 2019 - 8:52 AM - hans - Author: Comment Link

      Hi Richard,

      Thank you for the compliments and I’m happy to hear you’re having fun with the it! 

      As for sound activation … well, the code that I use here depends on an interrupt to toggle effects – which probably cannot be triggered with a microphone. Maybe this forum topic can help in finding a fix for that – it may be a little complicated and you have to keep in mind that it’s based on an ESP8266.

      As an alternative, since Arduino’s are cheap, you could use a second Arduino that responds to sound and then briefly flips a switch (for example a relay or transistor) connected to the Arduino that controls the LED effects.

      Reply

      hans

  • Apr 5, 2019 - 5:49 AM - Richard Comment Link

    Hi Hans,

    I’m trying to register on the website but unable too, it tells me it has sent me an email containing the password but I never receive it, I have tried this now with 3 different emails, nothin in Junk email. If I then go to forgotten password and ask request it I get a message saying that the host may have disabled emails?

    Are you able to help with this

    Richard

    Reply

    Richard

    • Apr 6, 2019 - 3:44 AM - hans - Author: Comment Link

      My apologies for the inconvenience.
      please check your email – I’ve sent you an email a few seconds ago. 

      Reply

      hans

  • Apr 5, 2019 - 2:32 PM - Richard Comment Link

    Hi, I’m trying to compile the code for the web interface but am hitting errors, all libraries are installed but when compiling I get 

    missing terminating ” character

    I can’t see an issue, there doesn’t appear to be a missing terminator

    Any ideas welcome

    Reply

    Richard

    • Apr 6, 2019 - 3:50 AM - hans - Author: Comment Link

      Hi Richard,

      I’d recommend pasting the code in a simple text editor first – for example Notepad (Windows) or BBEdit (macOS) – and then copy it from the text editor to the Arduino IDE. I suspect you’re working under Windows though, since I’ve had one report in the past (different article) – occasionally (may depend on the browser) “extra” characters come along, confusing the Arduino IDE.

      Alternatively, there is indeed a double quote missing somewhere in the code. I have not yet tested it.
      In that case (once you can login of course) you can ask the original programmer in the forum topic as well.

      p.s. did it mention a line number or anything? This may help finding the issue.

      Reply

      hans

  • May 13, 2019 - 9:30 PM - Troy Comment Link

    Thank you so much for posting this! This is extremely helpful on my current project. My question though is how do I go about changing the colors to these functions? I’m new to programming and i’m not sure I understand. For example  FadeInOut(0xff, 0x00, 0x00); // red 

    Do you know where I could find a reference sheet for these values to change them as I see fit? Thanks again and sorry for the n00b question!

    Reply

    Troy

    • May 13, 2019 - 10:55 PM - Troy Comment Link

      I’ve found out a little about the color, but I have another question. My current project has three buttons, one for modes/effects, one for color, and one for brightness. I’m currently using internal pin interrupts to stop the loop functions but this is proving difficult. Since internal pin interrupts do the same thing as external pin interrupts, would it be possible to change the code to accommodate these other two buttons?

      If not I think I can continue down my current path and just incorporate some of these cool functions into my code. Although i’m at a loss for how to handle the color. For example, in my current code I’m define an array of colors like: 

      uint32_t LEDColor[] = {CRGB::Green, CRGB::Blue, CRGB::Purple, CRGB::Red, CRGB::Yellow, CRGB::White};

      int NUM_COLOR = 0;

      and then i’m calling it within functions in the following way: 

      case 8:

            NUM_COLOR = 3; //red

            fill_solid(leds, NUM_LEDS, LEDColor[NUM_COLOR]);

      is it possible to do something similar using this hex color convention? 

      Reply

      Troy

    • May 14, 2019 - 2:40 AM - hans - Author: Comment Link

      Hi Troy!

      I’ll try to answer both your posts;

      Colors

      Colors, as you may already have figured out, are build up out of 3 base colors: red, green and blue.
      Each color has a value 0…255, which means the values are a single byte.
      Often these 3 numbers are combined in a single number notation (0xFF0000) or in separate numbers (0xff, 0x00, 0x00).
      The “0x” in front of the number, means the number is in hexadecimal, which has historical background but also can be less confusing to read (once you know how to read it).
      A byte has a value 0…255, which in hexadecimal (often abbreviated as “hex”) is 0x00 … 0xFF.
      There are a lot of color tables and converters out there that help you select a color. In my previous article I have posted one as well (link).
      This color picker/chart and this one both look very good as well.

      Buttons and interrupts

      The problem with interrupts, depending on your Arduino model, is that an Arduino typically has very few of these.
      If I recall correctly, the Uno has only 2 pins that can be used for interrupts (Pin 2 and 3). See the Arduino documentation.
      What you could do, is a potentiometer for brightness – which may not even need a pin, see this article.
      Doing brightness in code would require interruption of an effect, which in turn would need an interrupt.
      If you do it without code, then you’d have 2 pins available to toggle effects, and to toggle colors.

      Color Toggling

      Yes you can do this with the hex RGB codes as well. There is a function called “CRGB()” for FastLED (I’m assuming you;re using FastLED).

      uint32_t LEDColor[] = {0xFF0000, 0x0000FF, 0xFF00FF, 0xFF0000, 0xFFFF00, 0x000000};
      int NUM_COLOR = 0;
      ...
      case 8:
            NUM_COLOR = 3; //red
            fill_solid(leds, NUM_LEDS, CRGB(LEDColor[NUM_COLOR]) );

      Hope this helps 

      Reply

      hans

      • May 15, 2019 - 12:12 AM - Troy Comment Link

        Thank you so much for the information. The color article explains it perfectly! Right now though I’m still stuck on the color issue. So now that I understand how its structured I’m trying to figure out how I could setup a color array like in the previous code I posted, but to pass the values in the hex format like this code uses. I’m unsure of the best way to do this though. Using the example in your other article an array could look like:

        uint32_t MainColorArray[] = {0xB7, 0x00, 0xFE}; //purple color in array
        int SELECTED_COLOR; //global var to call the color

        So each sequence of 3 values in the array is a different color, but i’m totally lost on what would be the best way to call those values. In my code I’d like have a switch setup for different color choices based on button presses and depending on the case, it would determine which array is set the global var SELECTED_COLOR however I don’t know if this will work. 

        SELECTED_COLOR = MainColorArray[0,1,2]; 

        So for example your strobe case:

               Strobe(0xff, 0xff, 0xff, 10, 50, 1000);

        Would I be able to set the color by changing the code to:

                Strobe(SELECTED_COLOR, 10, 50, 1000);

        My other concern is the functions at the bottom of your code. I was wondering if you could shed some light on how they work exactly? At the moment I’m rather confused by them, I’m referring to the “** FastLed/NeoPixel Common Functions **” section of the code. Would this code have any effect on what I’m trying to do?

        Thanks again for your time, I greatly appreciate the help you’ve given me!

        Reply

        Troy

      • May 15, 2019 - 4:43 AM - hans - Author: Comment Link

        Hi Troy!

        Good to here the info was helpful.

        There are a few options concerning your color problem.

        If I’m not mistake, you can access the individual color elements of a CRGB like so:

        uint32_t LEDColor[] = {0xFF0000, 0x0000FF, 0xFF00FF, 0xFF0000, 0xFFFF00, 0x000000};

        You could use a multidimensional array like so

        uint32_t MainColorArray[3,3] = { {0xFF, 0x00, 0xFE},
                                         {0xFF, 0xFF, 0xFE},
                                         {0xB7, 0x00, 0xFE} };
        ...
        Strobe(MainColorArray[0][0], MainColorArray[0][1], MainColorArray[0][2], 10, 50, 1000);
        ...

        There are more advanced techniques to do this, for example by shifting bits, using pointers, using union, or even define you own type.
        But all these alternatives will take a little work on understanding the concepts they use.

        Hope this helps! 

        Reply

        hans

        • May 15, 2019 - 4:51 AM - Troy Comment Link

          I’ve actually made a lot of progress tonight, and I’ve almost finished with my project. Here is the code below. I’m using internal interrupts which doesn’t limit the pins you can use. This code also allows you to change the color of any function as its running without any issues, other then the theaterChaseRainbow function. I think it has something to do with the setPixel function. For whatever reason it seems to get stuck in the loop. I’ll probably just remove it. 

          My only issue at the moment is how to use fill_solid with the hex system.  fill_solid(leds, NUM_LEDS, Red, Green, Blue); doesn’t work, do you have any idea how to make this work by calling the byte variables?

          The only thing I have left to do is to add a third button for the brightness.

          Here is the working code at this moment:

          Code moved to Forum: Troy’s Project Code

          Reply

          Troy

          • May 15, 2019 - 5:02 AM - hans - Author: Comment Link

            Awesome Troy!

            Since we like to avoid long sections of code in the comments, I’ve moved your code to the forum.
            See this forum post.

            From what I’m reading in the FastLED documentation, this should do the trick:

            fill_solid( leds, NUM_LEDS, CRGB(Red,Green,Blue) );

            hans

          • May 15, 2019 - 5:05 AM - Troy Comment Link

            Sorry about that! I actually tried registering for the forum but it kept saying my username had invalid characters. Any idea how I can sign up to post there? I’d love to share the final project code in case anyone else could benefit from it.

            I’d like to thank you again for all the help, I couldn’t have done this without this site and your help, i’m extremely grateful! 

            Troy

          • May 15, 2019 - 5:12 AM - hans - Author: Comment Link

            No worries, and you’re most welcome 

            I love it when folks share their work derived from my projects! 

            The username needs to be all lowercase characters and numbers. A limitation of WordPress.
            Good that you reminded me of this – so I can update the form.

            Shameless plug: share the link to this article on social media 

            hans

  • Jun 4, 2019 - 1:50 PM - NICOLAS Comment Link

    HELLO HANS, HOW CAN I MAKE THE EFFECTS APPEAR RANDOMLY? THANKS

    Reply

    NICOLAS

    • Jun 4, 2019 - 2:36 PM - hans - Author: Comment Link

      Hi Nicolas,

      The random function in the Arduino isn’t the best random generator, but you can start by changing this code in the beginning of void loop():

        EEPROM.get(0,selectedEffect); 
        
        if(selectedEffect>18) { 
          selectedEffect=0;
          EEPROM.put(0,0); 
        } 

      to something like this:

        selectedEffect= random(18); // select a random number

      and add this line to the void setup() function – it is said that it provides a more random seed, so random will not always be the same (theoretically);

      randomSeed(analogRead(0));
      Reply

      hans

    • Jun 4, 2019 - 2:37 PM - hans - Author: Comment Link

      p.s. 

      Please do not write in all capital letters – it’s considered yelling/screaming, and not seen as polite.
      I’m sure you just forgot your caps-lock. 

      Reply

      hans

  • Jun 6, 2019 - 6:38 AM - Mike Comment Link

    Hey Hans, great write ups. I, like many on here, am new to neo pixels and arduino as well, but have a background in electronics.  I was hoping you might get me pointed in the right direction on a project I am working on.  I have read all of the write-ups you have on fastled but haven’t really been able to pinpoint the method for what I want.  What I am working on involves three separate WS2812b strips (2 of equal length that should display the same effect, the 3rd is a 60 LED ring).  I think I know how to run the three different (at least I have an idea from the research I have been doing) strips off of one arduino. What I was hoping you could assist me with is how I might go about using to separate N.O. momentary switches (technically one is a vibration sensor, and the other is a lever switch) to change the effect. I would have meteor running on the 2 strips, and fade running on the ring, one switch would trigger all three to strobe for 2 sec, then go back to the meteor and fade.  The other would change the meteor to strobe, but set the ring to chase.  I thought I was onto something with the way you triggered and reset to using “ASM volatile”, but I was wrong.  I cant seem to find a great tutorial set that can walk me through fully understanding the code, but I wont give up.  Thanks for any help you can provide. 

    Reply

    Mike

    • Jun 8, 2019 - 7:12 AM - hans - Author: Comment Link

      Hi Mike,

      sorry for the late reply – I’m traveling at the moment.

      Your project is not impossible haha, but it will come with a few challenges.
      The 2 strips that should be doing the same, can be connected in parallel, no extra code needed.

      Concerning 2 switches, you can actually setup 2 interrupts, so that would not impossible.
      For the lever I’d consider triggering a simple push switch, since an interrupt would need a brief signal and not a constant signal (goes for both switches).

      It will take some tinkering in the code as well.

      Reply

      hans

      • Jun 8, 2019 - 8:14 AM - Mike Comment Link

        The lever switch is actually a momentary and 1 of the 2, not a constant. Some times they are referred to as a Reed switch. So I would only need to set both up as interrupts?

         I will spend some time working on my code, and then repost when I hit a hiccup. I was assuming I could wire the two identical strips in parallel, but wasnt sure due to lack of experience with arduino and digi LEDs  thanks for the reply Hans.

        Reply

        Mike

      • Jun 9, 2019 - 8:45 AM - hans - Author: Comment Link

        Oh cool, reed switches, I haven’t used those in a while, but that would definitely work!
        You can indeed add something like this for the 2nd button

        attachInterrupt (digitalPinToInterrupt(BUTTON), changeEffectSecondButton, CHANGE); // pressed

        Where “changeEffectSecondButton” should be a new function of course, to handle that button being “pressed”.

        Per Arduino model, the pins you can used for that will be slightly different. Worse case scenario, your Arduino can handle only 2 of these interrupts, so it should always work for what you’re planning.

        Reply

        hans

        • Jun 10, 2019 - 7:05 PM - Mike Comment Link

          Well, I have been at it for some time now, googling, researching, learning (attempting anyway), and here is where I am at.  Hoping you can help me out.  I am in wayyyyy over my head, but I am trying.  I am having a hard time understanding how to write in those interrupts, what color bytes I need to change and how, and how to go about switching effects per pin as well as defining what pin runs what effect.  I think I am doing ok. what do you think.  this is way harder than what I am used to.  Thanks HAN, Really.
          if you are wondering why RunningLight and TheaterChase are both in there, its because I am not sure which one I want to use yet.  I will remove the one I don’t want later and adjust as needed. 

          #include "FastLED.h"

          // How many leds in your strips? (code removed)
          Reply

          Mike

          • Jun 11, 2019 - 8:50 AM - hans - Author: Comment Link

            Hi Mike,

            apologies that I had to remove the code. 
            Long code like yours should be placed in the forum – otherwise other people cannot oversee what’s going on here anymore.
            Would you mind starting a forum topic (Arduino forum)?

            hans

          • Jun 11, 2019 - 9:22 AM - Mike Comment Link

            Sorry about that Hans, I was hoping it would add it into a condensed box.  I will make a forum for it.  Thanks again.

            Mike

          • Jun 11, 2019 - 9:37 AM - hans - Author: Comment Link

            No worries – all good 

            hans

          • Jun 11, 2019 - 10:04 AM - Mike Comment Link

            I cant start a forum at the moment because I cant access my email, but I was hoping you could help with something a little simpler. Im using a a Switch, case, Default loop to command the strings. Thats the idea anyway, the default is the main loop and case 1 and 2 are triggered with the 2 separate “attachInterrupt” command lines.

            attachInterrupt (digitalPinToInterrupt (BUTTON_Vibrate), case 0, CHANGE); // pressed
            attachInterrupt (digitalPinToInterrupt (BUTTON_Lever), case 1, CHANGE); // pressed

            . that makes sense to me, but how do I command what effect goes to which pin. If I wanted the meteor effect to write to my defined 

            CRGB ledsStrips[NUM_LEDS_Strips]

            , and Fade in and out effect to write to my defined

             CRGB ledsRing[NUM_LEDS_Ring]

             I may be able to work it out from there.  I cant see how to do that, but I’ll keep scouring the forums.

            Mike

          • Jun 11, 2019 - 7:06 PM - supramp Comment Link
  • Jun 6, 2019 - 8:44 PM - Zen Comment Link

    ALL working is nice color change push button better enjoy… thank you

    Reply

    Zen

  • Jun 7, 2019 - 5:30 PM - Fred Comment Link

    Hi, thanks for the great work!

    I noticed there is an index out of bounds crash in NewKITT line 327 and 350, “setPixel(NUM_LEDS-i, red/10, green/10, blue/10);” before the second loop in the OutsideToCenter and CenterToOutside functions.

    When i==0, the index will be NUM_LEDS which is one after the end of the array.

    I tried the sketch and it worked without the error trigging anything originally, but when I pulled in more libraries and code, it started crashing at the above statement until I changed it to “setPixel(NUM_LEDS-i-1, red/10, green/10, blue/10);”. I also subtracted 1 from the indices to the setPixel call inside and after the loop to keep the eye size.

    Reply

    Fred

    • Jun 8, 2019 - 7:14 AM - hans - Author: Comment Link

      Thanks Fred for catching that! 

      Since I’m traveling, I won’t be able to update the code just yet.
      But once I get back, I most certainly will! 

      Reply

      hans

  • Jun 18, 2019 - 12:23 PM - manu Comment Link

    Hi,

    Thanks for providing such a thorough information and great collection showing possibilities with WS2812B etc.
    I ran into issue, where animation would just stop just after a few minutes.

    I was wondering if its possible to let it switch to next effect automatically after few minutes, this would certainly be very eye-catching for most.

    Reply

    manu

    • Jun 19, 2019 - 9:28 AM - hans - Author: Comment Link

      Hi manu,

      Thank you for the compliment! 

      I’m not sure why the effects would stop – that doesn’t sound normal.

      Having said that, if you want to automatically rotate through all effects, look at lines 19-24 in the source code;

        EEPROM.get(0,selectedEffect); 
        
        if(selectedEffect>18) { 
          selectedEffect=0;
          EEPROM.put(0,0); 
        } 

      This part, in the beginning of the loop(), will select the active effect.

      A simplified way to rotate effects (you may want to fine tine this) could be done by replacing it with this:

        selectedEffect++;
        if(selectedEffect>18) { 
          selectedEffect=0;
        } 

      This will go through one cycle of each effect, so you may want to do something there with a second counter, but this will get you started.

      You’ll also need to add this to the “void setup()”, so the effect selection starts with zero:

      selectedEffect=0;

      so the setup will look something like this:

      void setup()
      {
        FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
        selectedEffect=0;
      }

      Note: this will disable the button.

      Hope this helps getting you started. 

      Reply

      hans

  • Jun 21, 2019 - 5:35 AM - wahyu Comment Link

    hi, it awesome..

    i exactly looking like this,it for my home front yard n my front shop light decoration....  thank a lot n it work done and great..but i use 2 nano,  1 for home n another for shop.

    i have question but iam sorry maybe is already asked in comments, i have amount 50 led (for my home) and 30 led (my shop), what code skecth in 1 nano with 2 output pin (i have 2 strip with different amount leds) but with effect moving on at same time with different amount of leds n different strip.

    thank you very muchhhh

    Reply

    wahyu

  • Jun 21, 2019 - 8:13 AM - wahyu Comment Link

    hi ..

    great. . and thanks for informaton.. this is i looking n its all work for me…

    but what code to make 2 output because i will use 2 strip with different  amount of leds.. example strip A 50 leds n strip B 30 leds n while power on will moving the your all effect at same time..

    thank you

    Reply

    wahyu

    • Jun 22, 2019 - 9:36 AM - hans - Author: Comment Link

      Hi Wahyu!

      Thanks for the compliment 

      Controlling 2 LED strands of a different length may be more tricky than you’d may expect, especially when both need to run simultaneously.

      The first option is to place the strands in parallel on the same pin, the downside would be that either one strand misses some LEDs (the 30 LED strand), or may not use all LEDs (the 50 LED strand) – depending on what you set NUM_LEDS to (30 or 50). I assume you already considered this. Although a little sloppy, this is your best and easiest option.

      The second option, what you may be looking for, is indeed using 2 separate pins. This however will be more difficult.
      First you’ll need to define both strips, which would change the beginning of the code.

      For example (untested):

      #include "FastLED.h"
      #include <EEPROM.h>
      #define NUM_LEDS_SHORT 30 
      #define NUM_LEDS_LONG 50
      CRGB leds_short[NUM_LEDS_SHORT];
      CRGB leds_long[NUM_LEDS_LONG];
      #define PIN_SHORT 5 
      #define PIN_LONG 4
      #define BUTTON 2
      byte selectedEffect=0;
      void setup()
      {
        FastLED.addLeds<WS2811, PIN_SHORT, GRB>(leds_short, NUM_LEDS_SHORT).setCorrection( TypicalLEDStrip );
        FastLED.addLeds<WS2811, PIN_LONG, GRB>(leds, NUM_LEDS_LONG).setCorrection( TypicalLEDStrip );
        digitalWrite (BUTTON, HIGH); // internal pull-up resistor
        attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, CHANGE); // pressed
      }
      ... // the switch-case loop etc

      Second, you’ll have to make the generic functions (showStrip, etc) to be able to work with 2 strips (typically: pass the strip variable).

      And finally you’ll need to update all effects to accommodate 2 strips as well. You can’t just call the function for each strip. You’ll need to adapt (for example) the for-loop where the colors for each LED are being set. For each effect this will be a different challenge. On top of that; obviously setting both strips will slow down the effect, so with some effects this may work great, with others you’ll need to select a different delay, and with other effects they may become just too slow.

      As you can see; not impossible, but a lot of work. 

      Reply

      hans

      • Jun 24, 2019 - 1:09 PM - wahyu Comment Link

        thank you hans.. 

        after read your answer it make my head full of stars haha.. still much lerning about codes..so i choose easy way.. use 1 hardware 1 strip.. haha.. but thanks a lot bro. you really help me. thank you.. 

        Reply

        wahyu

        • Jun 25, 2019 - 8:38 AM - hans - Author: Comment Link

          You’re welcome Wahyu 

          Reply

          hans

          • Jun 26, 2019 - 2:15 PM - wahyu Comment Link

            halo again hans..

            please help me make code effect like this video on minute 0.18 start from left then from right too..

            https://youtu.be/b4pwLFa2EDU

            and one more please create boinching balls effect from other side too.. i mean start bounching from left then from right too.. 

            thank you.. iam sorry if i ask to much.. 

            wahyu

          • Jun 27, 2019 - 10:17 AM - hans - Author: Comment Link

            Hi Wahyu,

            that effect shouldn’t be too hard to implement.
            However, at the moment I’m on vacation. Next week I’ll be back and hope to find some time to implement that.

            hans

  • Jun 22, 2019 - 5:12 PM - David Comment Link

    Hi,

      Hope you can help I am using 4 rings 96 LEDs the odd thing I am getting is the 4th ring will normally be green for some of the code I.E the fire code will happy spin thew the red yellow orange on ring 123 but ring 4 it will show green as the affect. I was thinking a power issue but I am now running off a PC PSU and it is still doing it for some of the codes.
    Bouncing ball red ball will spin on ring 123 and then go green on 4
    Multi Bouncing ball is OK!
    Meteor is OK on all 4 rings
    RGB – when red is on rings 123 but on 4 it is green for  Green rings 123 ok but ring 4 is red and blue rings 1234 all ok! “Odd”
    Knight rider — 123 red 4 green
    Random red dots 123 but 4 is green
    Random dots of colours all OK
    sparkles all ok
    Twinkles all ok
    Rainbow all ok.

    Do you have any clue why this is happening for some of the code?

    Thanks in advice.
    David

    Reply

    David

    • Jun 23, 2019 - 11:48 AM - hans - Author: Comment Link

      Hi David,

      First thing I’d try, is doing a LED test by setting ALL LEDs to WHITE, and then RED, GREEN and finally BLUE. Or follow the example in this article.

      This will tell you if your PSU is keeping up, with that many LEDs, you’ll theoretically need 23A at 5V. Which is a lot.
      From experience; quite often you can get away with a smaller PSU, say 15A or maybe even 10A.
      With those kind of loads, you may need to watch the thickness of your power and GND cables (don’t use thin cables).

      The test will also tell you if there is something wrong with one (or more) of the LEDs (see this article again).

      Each LED block contains 3 LEDs (red,green,blue) and a simple controller (to read the data, pass on the rest of the data and control the individual LED colors).
      Such a controller may be defective. But since you’re saying that bouncingballs and meteorrain work fine, I’m not quite sure if this would be the case.

      Reply

      hans

      • Jun 24, 2019 - 5:25 AM - David Comment Link

        Hi Hans,

              Thank you for the reply if I do white all is ok but colours the last ring will flip the colour I am using a PC power supply 5v 20A it says on the box.  The wire is thin will try thicker wire. 
        Is it best to power off two PSU’s… I am looking to use this in a car so trying to keep it as small as possible. 
        In-fact can I power each ring of its own small PSU without issues?    

        Reply

        David

        • Jun 24, 2019 - 7:01 AM - David Comment Link

          Forgot to add when I power on the rings without Arduino powered up rings 1,2,3 will flash and go off and the 4th will stay lit up not go out..  

          Reply

          David

          • Jun 24, 2019 - 4:26 PM - David Comment Link

            Hello Me again,

                    Right it looks like the LEDs are the issue  if I power up one led on all 4 rings RGB on low power I can see 123 rings are all are Blue Red Green on ring 4 the led it is B G R so the signal is getting sent to the incorrect colour I think. very odd. I will get some replacements and see what happens

            David

          • Jun 25, 2019 - 8:35 AM - hans - Author: Comment Link

            The LEDs of Ring 4 could indeed be a problem. You could test swapping (for example) ring 1 and ring 4 and see what happens.
            If the “new” ring 1 now works, then those LEDs are (seemingly) OK.

            You can power the LEDs with more than 1 PSU, you’d just have to make sure they all share the same GND (Ground).
            However, this may not be needed. You can run the +5V separate for each ring from the same PSU.
            (disconnect the +5V from the end of each ring, but keep GND in tact)

            Also note: Computer PSU’s can have some separate rails for each +5V connection. So look on the PSU, and it “should” list the Amps per +5V connection (typically less than what the entire PSU is suppose to provide).

            hans

  • Jun 28, 2019 - 8:52 PM - jayanath Comment Link

    sir how do i remove button function? i want run these patterns automatically one after another. how i can do that? please explain?

    Reply

    jayanath

  • Jul 11, 2019 - 12:10 PM - budd Comment Link

    hi.. 

    it awesome hans.. thank n its work fine..

    i want add more patters/effects for my led strip,i use demoreel in IDE before, so i want combine/adding your code with demoreel that already in IDE..  can you help me create (combined) the code.. thanks.. 

    Reply

    budd

    • Jul 12, 2019 - 4:00 AM - hans - Author: Comment Link

      Hi Budd,

      adding effects is not too hard, it requires only minor changes to the code.
      If you look at the “loop()”;

      void loop() { 
        EEPROM.get(0,selectedEffect); 
        
        if(selectedEffect>19) { // 19 reflects the number of effects
          selectedEffect=0;
          EEPROM.put(0,0); 
        } 
        
        switch(selectedEffect) {
          
          case 0 : {
                      // RGBLoop - no parameters
                      RGBLoop();
                      break;
                    }
          case 1 : {
                      // FadeInOut - Color (red, green. blue)
                      FadeInOut(0xff, 0x00, 0x00); // red
                      FadeInOut(0xff, 0xff, 0xff); // white 
                      FadeInOut(0x00, 0x00, 0xff); // blue
                      break;
                    }
                    
          ...
          case 18 : {
                      // meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay 
                      meteorRain(0xff,0xff,0xff,10, 64, true, 30);
                      break;
                    } case 19 : { // call your effect here }
        }
      }

      You’ll see the last one being “case 18 : {“. 

      If you’d like to add an effect, simply add

      case 19 : {
         // call your effect here
      }

      after “case 18”. 

      Do not forget to update “18” in the line “if(selectedEffect>18) {“.
      This number should now become 19.

      Reply

      hans

      • Jul 19, 2019 - 12:39 PM - budd Comment Link

        i already add n do like your advice.. but when it run/on that your effects n demoreel100 effects run on at same time.. its like colours crash each other.. please create me sketch that already combined the effects.. its will great for chrismast light.. thanks a lot n sorry if i asking too much.. 

        Reply

        budd

        • Jul 21, 2020 - 11:12 AM - homer Comment Link

          Hi Budd, culd you add Demoreel effects to his code??

          Could you explain to me how you did. Thank you

          Reply

          homer

      • Jul 20, 2019 - 4:15 AM - hans - Author: Comment Link

        Hi Budd,

        in all fairness; I’m not sure what you’re asking … 

        Reply

        hans

  • Jul 18, 2019 - 2:19 PM - mircea Comment Link

    with Bluetooth it works

    Reply

    mircea

    • Jan 21, 2020 - 5:44 PM - Matt Comment Link

      Can I ask how you got this to work with bluetooth?

      Were you only sending a toggle signal via bluetooth or were you able to select which “case” you wanted by sending different ASCII characters from serial bluetooth?

      I attempted below but am stuck. Any assistance would be greatly appreciated

      [CODE DELETED]

      Reply

      Matt

      • Jan 22, 2020 - 8:48 AM - Hans - Author: Comment Link

        I’d recommend looking in the forum. Some users have been tinkering with IR and Bluetooth for this as well.
        For example this post may help you in the right direction.
        I do not have a Bluetooth module available, so it will not be possible to provide assistance. 

        Reply

        Hans

        • Jan 22, 2020 - 11:09 AM - mlimbrick Comment Link

          Hello Hans,

          Thank you for pointing me in the right direction. I will work with it and see what I can come up with!

          Reply

          mlimbrick

    • Jan 21, 2020 - 5:46 PM - Matt Comment Link

      My apologies, 

      I dont know why it didnt condense the code

      Reply

      Matt

      • Jan 22, 2020 - 8:46 AM - Hans - Author: Comment Link

        No worries – I have removed the entire code, even condensed it would have been way too long to post here.

        Reply

        Hans

  • Jul 24, 2019 - 4:18 PM - Leslie Comment Link

    I love your work and the effects demo…it is helping me learn! Thanks! I tried adding an effect that I like and for some reason it screws up the others…it creates random problems, dimmed effects, getting “hung” and not advancing, or simply stopping two or three effects later after the new one is called! The new one I added works, it just screws up some of the others and I cannot pinpoint why.

    I replaced my new effect for case 3 as follows…

        case 3 : {

                    rainbow_march(200, 10);

                    break;

                  }

    Here is the code for it…

    void rainbow_march(uint8_t thisdelay, uint8_t deltahue) { // The fill_rainbow call doesn’t support brightness levels.

      uint8_t thishue = millis()*(255-thisdelay)/255; // To change the rate, add a beat or something to the result. ‘thisdelay’ must be a fixed value.

     thishue = beat8(50); // This uses a FastLED sawtooth generator. Again, the ’50’ should not change on the fly.

    // thishue = beatsin8(50,0,255); // This can change speeds on the fly. You can also add these to each other.

      fill_rainbow(leds, NUM_LEDS, thishue, deltahue); // Use FastLED’s fill_rainbow routine

       showStrip();

    } // rainbow_march()

    Any thoughts or ideas how to make this work?

    Thanks

    Leslie

    Reply

    Leslie

    • Aug 1, 2019 - 6:43 AM - hans - Author: Comment Link

      Hi Leslie,

      apologies for the late response – it’s been a crazy 2 weeks.

      I suspect that the “beat8()” function may be triggering this issue. It may be using an interrupt.
      As far as I could see in the FastLED documentation, you can disable the interrupt, by adding this at the beginning of your sketch:

      #define FASTLED_ALLOW_INTERRUPTS 0

      Not sure if this will fix the issue, but worth a try. 

      Reply

      hans

  • Aug 1, 2019 - 2:56 AM - herenchao Comment Link

    3 questions:

    1.use fastLED.h , can set brightness,but can not run rainbow effect, other effects are running great, why is that?

    2. use NEOPixle, can run rainbow, but can not set brightness. 

    3. how can i do both?

    Reply

    herenchao

    • Aug 1, 2019 - 7:17 AM - hans - Author: Comment Link

      Hi Herenchao!

      I’d stick with FastLED, since NeoPixel is a little bit more limited.
      I have not work with the SetBrightness function yet, but from what I understand from the documentation, it’s called like so:

      FastLED.setBrightness(MAX_BRIGHTNESS);

      I’m not sure how you implemented this.

      Reply

      hans

  • Aug 3, 2019 - 12:50 PM - wahyu Comment Link

    hi again hans..

    please need help.. i want adding more effect, example with 10 led..i use from newkitt code left to right and right to left, i want the effect move like fill empty cup with water, so the effect is led blue/red/green color move from left to right but after reach led 10 it will stop and still lit up and move from start again and stop in led9 and start again and stop in led8 etc, until led lit up all led from right to left.

     void LeftToRight(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
      for(int i = 0; i < NUM_LEDS-EyeSize-2; i++) {
        setAll(0,0,0);
        setPixel(i, red/10, green/10, blue/10);
        for(int j = 1; j <= EyeSize; j++) {
          setPixel(i+j, red, green, blue); 
        }
        setPixel(i+EyeSize+1, red/10, green/10, blue/10);
        showStrip();
        delay(SpeedDelay);
      }
      delay(ReturnDelay);
    }

    thanks you.. and i am sorry if i always ask your help.. but thanks alot..

    Reply

    wahyu

    • Aug 4, 2019 - 3:00 AM - hans - Author: Comment Link

      Hi Wahyu,

      it is never a problem to ask for help! 
      I’m however not quite sure if I understand what effect you’re looking for.
      Do you mean like a stacking effect?
      A sequence like this:

      1. move a LED from left to right, only one led on during the move (the LeftToRight effect), and when reaching the end (led 10), leave led 10 on.
      2. Do the same thing, and at the end leave led 9 and 10 on.
      3. And again, leaving led 8, 9 and 10 on.
      4. And again, leaving led 7, 8, 9, 10 on.

      We could do something like that with a modified LeftToRight function, by adding a “lastled” parameter.
      An additional minor modification is needed now, since SetAll(0,0,0) would turn off ALL LEDs, which is something we don’t want (code below: the bold text was added/changed).

      void NewLeftToRight(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay, int LastLED) {
        for(int i = 0; i < LastLED-EyeSize-2; i++) { // this for loop replaces SetAll()
          for(int ClearLeds; ClearLeds<=LastLED, ClearLeds++){
             setPixel(ClearLeds,0,0,0);
           }
          showStrip();

          setPixel(i, red/10, green/10, blue/10);
          for(int j = 1; j <= EyeSize; j++) {
            setPixel(i+j, red, green, blue); 
          }
          setPixel(i+EyeSize+1, red/10, green/10, blue/10);
          showStrip();
          delay(SpeedDelay);
        }
        delay(ReturnDelay);
      }

      Now this function can be called indicating where to stop.
      For example:

      NewLeftToRight(0xff,0,0, 3, 100, 0, 10);
      NewLeftToRight(0xff,0,0, 3, 100, 0, 9);
      NewLeftToRight(0xff,0,0, 3, 100, 0, 8);
      ...

      As you can see; this of course invites to use a “for-loop” like so:

      for(int EndPosition=NUM_LEDS; EndPosition>=0; EndPosition--) {
        NewLeftToRight(0xff,0,0, 3, 100, 0, EndPosition);
      }

      I have not tested this code, so you may need to play with it a little, especially timing is something you may want to tweak a little.
      Hope this is getting you started.

      Reply

      hans

      • Aug 4, 2019 - 4:43 AM - wahyu Comment Link

        [code]

        for(int ClearLeds; ClearLeds<=LastLED, ClearLeds++){ 
               setPixel(ClearLeds,0,0,0);

        [/code]

        it show “expected ‘;’ before ‘)’ token”.

        and if i edit “Clearleds;” with “Clearleds = 0;” or “Clearleds = NUM_LEDS;” or “Clearleds = LastLED” the effect run like you say “move a LED from left to right, only one led on during the move (the LeftToRight effect), but when reaching the end (led 10, 9, 8, 7)” the led not on.

        Reply

        wahyu

      • Aug 4, 2019 - 5:14 AM - hans - Author: Comment Link

        This is the code for that loop, corrected;

            // this for loop replaces SetAll()
            for(int ClearLeds=0; ClearLeds<=LastLED; ClearLeds++){ 
               setPixel(ClearLeds,0,0,0);
             }
            showStrip();

        and I forgot the “=0” and typed a “,” instead of a “;” —  sorry. 

        Reply

        hans

        • Aug 4, 2019 - 5:29 AM - wahyu Comment Link

          it work great.. thank you alot hans…

          Reply

          wahyu

        • Aug 4, 2019 - 6:11 AM - hans - Author: Comment Link

          Awesome! 

          Reply

          hans

        • Aug 4, 2019 - 8:56 AM - wahyu Comment Link

          hi again,

          for this code :

          [code]

          NewLeftToRight(0xff,0,0, 3, 100, 0, 10);
          NewLeftToRight(0xff,0,0, 3, 100, 0, 9);
          NewLeftToRight(0xff,0,0, 3, 100, 0, 8);
          ...

          [/code]

          But hans, how if i use 50 or 100 led, how to get automate random color but without write very lots code like above..

          example  1. slide red,

                          2. slide blue,

                          3. slide green ….. 4. yellow, 5. purple ……………………….

                          until all led light on..

          Reply

          wahyu

          • Aug 4, 2019 - 9:31 AM - hans - Author: Comment Link

            You can make a for-loop around the for-loop while having predefined colors (you’d probably want to define an array for that).
            This would of course be a lot of work if you want to define 50 to 100 colors.
            For loop see this article, and for arrays see this article.

            Easier would be if the colors should really be random, you could try this:

            for(int EndPosition=NUM_LEDS; EndPosition>=0; EndPosition--) {
              NewLeftToRight(random(255),random(255),random(255), 3, 100, 0, EndPosition);
            }

            random(255) will generate a random number between 0 and 255.
            If you require a minimum value, then random(10,255) picks a random color between 10 and 255.

            Since the Arduino is not that great with it’s randomness, you could add

            randomSeed(analogRead(0));

            to the void setup() function – this way it tries to be more random.

            Now you could predefine a handful of colors in an array, for example defining 5 colors (each color has 3 values one for red, green and blue):

            define colorCount 5
            
            byte MyColors[colorCount,3] = { {255,0,0}, {0,255,0}, {0,0,255}, {0,255,255}, {255,255,255} };

            and in your code you could call those like so

            int ChosenColor;
            
            for(int EndPosition=NUM_LEDS; EndPosition>=0; EndPosition--) {
              ChosenColor := random(colorCount);
              NewLeftToRight(MyColors[ChosenColor,0], MyColors[ChosenColor,1], MyColors[ChosenColor,2], 3, 100, 0, EndPosition);
            }

            Hope I didn’t screw up the array indexes, but I hope you get the idea.

            hans

  • Aug 19, 2019 - 2:04 PM - De Wodzu Comment Link

    Dziekuje za Twoją cięzką pracą.

    Efekt niesamowity. Wszystko w jednym i możesz sobie wybrać do tego, co aktualnie jest potrzebne.

    Zrobiłem lampkę z 20LED i kilka działań już przenoszę i delkiatnie modyfikuje.

    Super opisy i wszytko działa od pierszewo startu.

    Translated

    Thank you for your hard work.

    The effect is amazing. All in one and you can choose for what is currently needed.
    I made a lamp with 20LED and a few actions I am moving and delicately modifying.
    Super descriptions and everything works from the first start.

    Reply

    De Wodzu

  • Aug 29, 2019 - 4:57 AM - 3D-Gurke Comment Link

    Dear Hans,

    this project is incredible and it is the perfect basis for one my own Halloween 2019 project’s problems.

    My Halloween project will be three animatronic skulls singing the “Ghostbusters” song.

    The last major step was the “disco lighting” illuminating the three skulls in the darkness of Haloween night.

    A test setup is shown here: https://www.youtube.com/watch?v=9FpQztl9sac&t

    Your work is very nicely documented and therefore easy to adapt for own projects. Thanks so much for sharing!

    The full implementation of your work into my own project will be ready at Halloween, as I am still working on the project.

    See my project on Thingiverse: https://www.thingiverse.com/thing:3658843

    But, I have one less problem, thanks to you!

    Cheers,

    3D-Gurke 

    Reply

    3D-Gurke

    • Aug 29, 2019 - 5:08 AM - hans - Author: Comment Link

      Hi 3D-Gruke,

      that’s an awesome project! Very nicely done! 
      And thanks for sharing your project, I mean really very cool animatronic skulls.
      This make me wish I still had my 3D printer (still looking for a good replacement).

      Would you mind posting a link to the page on Thingiverse/Github/Youtube?
      Absolutely not required of course, just trying to promote my website a little 

      Reply

      hans

  • Aug 31, 2019 - 10:10 AM - jayanath Comment Link

    Dear sir i want to combine following A and B routines for more patterns. so request instructions from you. (B routine is yours pattern combination)

    Source removed

    Reply

    jayanath

    • Sep 1, 2019 - 3:58 AM - hans - Author: Comment Link

      Hi Jayanath.

      Per comments rules, I have removed you very logn source codes (see a few lines above the text edit field: Friendly request to not post large files here).
      Long source codes like this really should be posted in the Forum

      On that note; combining the two sources does not seem impossible – if you do not run out memory on your Arduino.
      For adding new effects, please look at earlier posts (for example this one).

      Reply

      hans

      • Sep 1, 2019 - 9:26 PM - jayanath Comment Link

        extremely very sorry sir, i will never do that again. i have combined these two codes and Arduino is also done complying but when plays it will repeat only one code not both codes sir. i have tried several times 

        Reply

        jayanath

      • Sep 2, 2019 - 2:42 AM - hans - Author: Comment Link

        No problem, just start a forum topic, and I’ll see where I can help. 

        Reply

        hans

  • Sep 3, 2019 - 4:28 PM - chinh Comment Link

    hi, thank you for this.
    im new to arduino, i try to upload this code for my Aduino pro mini but it say
     “exit status 1

    Error compiling for board Arduino Pro or Pro Mini.”
    i don’t know why. please help me. thank you!

    Reply

    chinh

    • Sep 4, 2019 - 3:30 AM - hans - Author: Comment Link

      Hi Chinh,

      “Exit status 1” does not say much. It means that there was a problem compiling, linking, or uploading the code.
      If you’re using the Arduino IDE, try setting “Show verbose output during:” on for “compilation” and “upload”. You may get more information on what is going wrong.

      Reply

      hans

  • Sep 17, 2019 - 1:51 AM - Gert Comment Link

    Hi Hans,

    Discovered this project a few weeks ago and it’s great, so thanks for that.

    I was wondering if you experienced the same problem that I have here in my setup.

    The problem I’m confronted with is that when a certain effect is selected and I plug in an electrical device near my arduino, the selectedEffect changes without pushing the button.

    I think that plugging in an electrical device might give a spike in the power supply of the arduino which causes the change in effect. I’m using an older pc power supply for this project.

    Don’t know if you could think of a good solution to prevent the unwanted effect switch?

    Thanks in advance.

    Reply

    Gert

    • Sep 17, 2019 - 7:14 AM - Gert Comment Link

      Hi Hans,

      Well I experimented this morning with a combination of a rotary switch and the pushbutton and this seems to solve my problem. Now I first set the rotary switch to a certain selection and then I push the button. The rotary switch is connected to analog input A0. Now if there is some kind of disturbance on the power the selected effect doesn”t change as long as the rotary switch is in the same position.

      The rotary switch is a 12 position switch, so ofcourse I’ll loose some options, but 12 is enough for me, so no problem.

      The code that I use now to select the desired effect is:

      void changeEffect(){
        if (digitalRead (BUTTON) == HIGH) {
          analog0 = analogRead(analogPin);
          AnalogSelect();
          EEPROM.put(0, selectedEffect);
          asm volatile (" jmp 0");
      }
        delay(500);
      }
      void AnalogSelect(){
         if (analog0 < 30) {
          selectedEffect = 0;
        }
          else if (analog0 > 50 && analog0 < 140) {
            selectedEffect = 1;
          }
          else if (analog0 > 155 && analog0 < 220) {
            selectedEffect = 2;
          }
          else if (analog0 > 240 && analog0 < 310) {
            selectedEffect = 3;
          }
          else if (analog0 > 330 && analog0 < 410) {
            selectedEffect = 4;
          }
          else if (analog0 > 420 && analog0 < 510) {
            selectedEffect = 5;
          }
          else if (analog0 > 520 && analog0 < 610) {
            selectedEffect = 6;
          }
          else if (analog0 > 620 && analog0 < 700) {
            selectedEffect = 7;
          }
          else if (analog0 > 710 && analog0 < 790) {
            selectedEffect = 8;
          }
          else if (analog0 > 800 && analog0 < 890) {
            selectedEffect = 9;
          }
          else if (analog0 > 900 && analog0 < 970) {
            selectedEffect = 10;
          }
          else if (analog0 > 980) {
            selectedEffect = 11;
          }
          else {
              
          }
      }
      Reply

      Gert

    • Sep 19, 2019 - 6:13 AM - hans - Author: Comment Link

      Hi Gert,

      apologies for the late response.

      Yes, a spike in power usage may cause a brief drop in power fed to your power supply – resulting in a possible reset of the Arduino.
      I would assume you have a lot of other devices on the same power outlet, or the device you’re switching on pulls a lot of power to start up (eg. a device with a motor in it, since they potentially throw a power big spike when turning on).

      The only thing I can think of to fix this is trying another outlet. Getting some sorts of backup power for the Arduino may be an option as well. For example a battery with a trickle charger. But that seems an expensive/complicated exercise for a project like this?

      If the power drop is not the cause, then I’d try placing the Arduino further away from the other device – assuming the device is in no way connected to the Arduino (like the USB of your PC, while powering on the PC). 

      As for your rotary switch code: nicely done and very elegant – and thanks for posting the solution and code! 
      Just a thought to prevent the need to push a button after setting the rotary switch; try if a timer interrupt (another good article) could do the trick. Every second (or which every time works best) have it check the rotary value and apply the change then.
      This way you would not need the push button (and it’s interrupt) anymore. Granted, it will be a little bit more work to implement.

      Reply

      hans

  • Sep 19, 2019 - 12:53 PM - Daniel Fernandes Comment Link

    Hi Hans,
    I was reading the comment and got interested because I’m having the same problem.

    I have a Clock + Text Scroll project with 2 Led Array Modules (2x 8×32 = 8×64) with esp8266 Nodemcu + DS3231 and, I connected between the power terminals (+5 and Ground), a 1000uf 16V Capacitor;

    Since this circuit is plugged into an outlet on the same wiring as another outlet, a Blender or other household appliance is sometimes connected.

    And sometimes the characters on the clock show ghostly, and even some displays turn off completely or greatly reduce the intensity of the LEDs, but it doesn’t get to the Arduino reset.

    Maybe the cause is different and not the use of appliances!

    So I ask you: is there anything that can be done to solve this problem?

    Thanks

    Reply

    Daniel Fernandes

    • Sep 20, 2019 - 6:31 AM - hans - Author: Comment Link

      Hi Daniel,

      Well, there are a few tricks one could consider.

      1) The obvious one: connect those appliances on a different power group in your house (different fuse in the fuse box for your household power).

      2) Use a UPS unit, but that can be rather expensive for just this.

      3) Use a surge protector – but as I understand, most of these only catch a peak in power instead of a drop in power.

      4) Use a capacitor – but you’ve already done that, and a capacitor can catch a super short power drop, but that may not be enough.

      5) Have the Arduino powered by a rechargeable battery, where the battery is hooked up to a charger. This may take some research to see how it’s done the right way.

      Naturally, there could be other reasons for the power drops.
      For example, if the power supply is not the best, not very stable, or not “strong” enough to keep up. From my own experience; some cheap Chinese power supplies may list a certain capacity (A), but in reality they can’t keep up with what they claim. I’ve had a few cheap 5V PSU’s claiming they could do 2A, to find out that even 1A was pushing it.

      Reply

      hans

  • Sep 20, 2019 - 3:21 PM - Daniel Fernandes Comment Link

    Hi Hans,
    It seems to be the Chinese power supply I’m using. I will try others; Thank you for your help!

    Reply

    Daniel Fernandes

    • Sep 23, 2019 - 4:34 AM - hans - Author: Comment Link

      Hi Daniel,

      You’re welcome, and this could indeed be the source of your problems.
      If you’d like; please keep us posted on your progress! I’m sure others will benefit from it as well 

      Reply

      hans

  • Oct 8, 2019 - 10:32 PM - David Jordan Comment Link

    Hello! Awesome codes. I discovered these while looking for a fire pattern, and yours is sweet! I’ve stumbled my way through creating a dozen variations (different colors, speeds, added  more random sparks, etc.), but what I’m trying to do now is stumping me. Basically I want to use this code here, switching between patterns with a button press-but instead of your 17 patterns here, I want every pattern to be a variation of Fire.  I run into issues when I try to add a second Fire effect to the code. I think I need to somehow differentiate a line in each Fire variation, so the arduino knows exactly which “Fire” to use? I notice that the “Fire” text appears as orange, but if I add a number to it (ie Fire1) it goes back to regular text. I am a noob so any help guidance is greatly appreciated!

    Thanks!

    Reply

    David Jordan

    • Oct 10, 2019 - 4:13 AM - hans - Author: Comment Link

      Hi David,

      Good to hear you like the code 

      As for switching between Fire variants,…

      Cycling through the desired effect is done in the switch-loop;

      switch(selectedEffect) {   
      case 0 : {
          // do effect 1 here
          break; // break is needed, otherwise it will potentially execute the next "case" statement
        }
      case 1 : {
          // do effect 2 here
          break; // break is needed, otherwise it will potentially execute the next "case" statement
        }
      ... rinse and repeat ... 
      case n : {
          // do effect n+1 here (where "n"=the number of the last effect)
          break; // break is needed, otherwise it will potentially execute the next "case" statement
        }
      }

      In line 21

        if(selectedEffect>18) {

      the number 18 represents the max effect number, so if you have more or less effects, change this number.

      As for you color variations; you could add an extra parameter to the Fire() function, which then in the Fire() function calls the variant you’re using.
      I personally would add the parameters red, green and blue, and then use these color values in the Fire and/or the setPixelHeatColor() functions.
      Since I’m not sure what lines you specifically modified, I can’t give you an example.

      Or you could make variations in the sende by creating multiple Fire() functions (Fire1, Fire2, Fire3, ect) – which will work as well, even though it’s not a very clean or efficient (memory) way.

      Reply

      hans

      • Oct 12, 2019 - 1:13 AM - David Jordan Comment Link

        Hi Hans, thanks for the reply. I was able to make some progress after your comment!  I like the idea of having just one Fire function with certain parameters being changed with each button press. It’d be a hassle to have several copies of the fire code pasted in my master code. I realize that I don’t actually need all the other LED patterns for this current project, so I’ll be taking those out to save some memory/be more organized…anyways…

        Below is a piece of your code that I changed to make the strip mostly blue with flickering white bits.  We’ll just call it flamecolor BLUE for this example…

         // figure out which third of the spectrum we're in:

        if( t192 > 0x80) {  // hottest
          setPixel(Pixel, 255, 255, 255);
          } else if( t192 > 0xFF ) {  // middle
          setPixel(Pixel, 0, 255, 255);
          } else {  // coolest
          setPixel(Pixel, 0, 0, 15);
          }

        How would you recommend I go about naming each of those variations? Could I do something like listing all of my flame color codes, like-  if flamecolor = BLUE  then {code pasted above}  , followed by flamecolor PINK = {pink flame code} , followed by the next color, etc etc, and then adding a parameter to the first line of the fire code like :

        //cooling rate, sparking rate, speed delay, flamecolor
        Fire(30,120,3, BLUE);

        Then I could make each case of your all ledstrip code a different variant of fire.

        case 0: {
        // fire blue
          Fire(30,120,3, BLUE);
          break;
          }

        case 1  : {
          // fire green
          Fire(30,120,3, GREEN);
         
          break;
          }

        and on and on. It that kinda what you meant in your suggestion?

        Thanks a lot, I’m learning a lot every day!

        Reply

        David Jordan

        • Oct 12, 2019 - 4:40 AM - hans - Author: Comment Link

          Hi David,

          Great to hear you’re making progress! 

          Yeah getting your code organized and clean up is recommended, even if it’s just for fixing issues, and reading the code in the future.

          Yes, something like that is what I had in mind. However instead of passing “BLUE”, I’d rather pass color codes (RGB) so you can modify the colors to anything you want without having to redo the “if BLUE then” sequence.

          I don’t have LEDs and Arduino handy, so I can’t test it, but I was thinking something like this (assuming you’re using FastLED):

          void Fire(int Cooling, int Sparking, int SpeedDelay, uint16_t Color1, uint16_t Color2) { // Added Color1 and Color2
            static byte heat[NUM_LEDS];
            int cooldown;
           
            // Step 1. Cool down every cell a little
            for( int i = 0; i < NUM_LEDS; i++) {
              cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
             
              if(cooldown>heat[i]) {
                heat[i]=0;
              } else {
                heat[i]=heat[i]-cooldown;
              }
            }
           
            // Step 2. Heat from each cell drifts 'up' and diffuses a little
            for( int k= NUM_LEDS - 1; k >= 2; k--) {
              heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
            }
             
            // Step 3. Randomly ignite new 'sparks' near the bottom
            if( random(255) < Sparking ) {
              int y = random(7);
              heat[y] = heat[y] + random(160,255);
              //heat[y] = random(160,255);
            }
            // Step 4. Convert heat to LED colors
            for( int j = 0; j < NUM_LEDS; j++) {
              setPixelHeatColor(j, heat[j], Color1, Color2 ); // Added Color1 and Color2
            }
            showStrip();
            delay(SpeedDelay);
          }
          void setPixelHeatColor (int Pixel, byte temperature, uint16_t Color1, uint16_t Color2) { // Added Color1 and Color2
            // Scale 'heat' down from 0-255 to 0-191
            byte t192 = round((temperature/255.0)*191);
           
            // calculate ramp up from
            byte heatramp = t192 & 0x3F; // 0..63
            heatramp <<= 2; // scale up to 0..252
           
            // figure out which third of the spectrum we're in:
            if( t192 > 0x80) { // hottest setPixel(Pixel, 255, 255, heatramp);
            } else if( t192 > 0x40 ) { // middle leds[Pixel] = Color1;
              // was: setPixel(Pixel, 255, heatramp, 0);

            } else { // coolest leds[Pixel] = Color2;
              // was: setPixel(Pixel, heatramp, 0, 0);

            }
          }

          All this based on your example:

          if( t192 > 0x80) { // hottest
            setPixel(Pixel, 255, 255, 255);
            } else if( t192 > 0xFF ) { // middle
            setPixel(Pixel, 0, 255, 255);
            } else { // coolest
            setPixel(Pixel, 0, 0, 15);
            } 

          Calling Fire would then be (if I didn’t make any mistakes – using your 2 color values):

          Fire( 30,120,3, CRGB(0,255,255), CRGB(0,0,15) );

          So the basic format would be:

          Fire( Cooling, Sparking, SpeedDelay, CRGB( red, green, blue ), CRGB( red, green, blue ) );

          Note:
          CRGB( red, green, blue ) returns a uint16_t (I had to look that up as well haha), which we can assign straight to a led (leds[Pixel]=Color) – note that this is FastLED specific, so for NeoPixel this will work a little different.

          Also note that with 2 fixed colors color you will lose the color ramping – but if the effect works as you like: who cares, right? 

          Reply

          hans

          • Oct 15, 2019 - 12:09 AM - David Jordan Comment Link

            Nice Hans, that’s definitely looking like closer to the solution! I do use the FastLED library so I was able to implement your code. The code compiles just fine, but for some reason I couldn’t get the Color1 and Color2 to influence the LEDS at all. The LEDs were only be triggered by the “hottest” led section, and the rest of the pixels would be dark.

             if( t192 > 0x80) {                     // hottest
                setPixel(Pixel, 255, 255, heatramp);

            I tried fiddling around with the line

             leds[Pixel] = Color1;

            and changed it to a setPixel function that includes Color1, and heatramp parameters, but it was pretty hard to get it to do what I wanted. Do you have any ideas as to why the Color1 and Color2 aren’t working for me?

            Thanks friend!

            David Jordan

          • Oct 15, 2019 - 4:58 AM - hans - Author: Comment Link

            The challenge will be to use the heatramp in the “setPixelHeatColor()” function.
            As I said: with 2 fixed colors color you will lose the color ramping, and since I cannot test the code, I do not have a good idea how this works best. You could try passing the colors as RGB values, which makes it a little less efficient but easier to read.

            I’ve used the values again, that you had used before:

            ...
              Fire( 30,120,3, 0,255,255, 0,0,15 );
            ...
            void Fire(int Cooling, int Sparking, int SpeedDelay, byte red1,byte green1,byte blue1, byte red2,byte green2,byte blue2) { 
            ... 
              // Step 3. Randomly ignite new 'sparks' near the bottom
              if( random(255) < Sparking ) {
                int y = random(7);
                heat[y] = heat[y] + random(160,255);
                //heat[y] = random(160,255);
              }
              // Step 4. Convert heat to LED colors
              for( int j = 0; j < NUM_LEDS; j++) {
                setPixelHeatColor(j, heat[j], red1,green1,blue1, red2,green2,blue2); 
              }
              ...
            }
            void setPixelHeatColor (int Pixel, byte temperature, byte red1,byte green1,byte blue1, byte red2,byte green2,byte blue2) { 
            ...
              if( t192 > 0x80) { // hottest
                setPixel(Pixel, 255, 255, heatramp);
              } else if( t192 > 0x40 ) { // middle
                setPixel(Pixel, red1,green1,blue1);
              } else { // coolest
                was: setPixel(Pixel, red2,green2,blue2);
              }
            ...

            Since I cannot test right now, I’m kind-a stuck with the colors you found 

            hans

          • Oct 16, 2019 - 1:20 AM - David Jordan Comment Link

            Hans! Awesome!!!! One last question, what’s your paypal?

            David Jordan

          • Oct 16, 2019 - 2:59 AM - hans - Author: Comment Link

            I assume it worked out? 😁 

            My PayPal is hans at luijten dot net. Donations are very much appreciated, but you can also donate by sharing the link on other websites, or shopping at Amazon (use this link – I get a small commission each time you shop there).  

            hans

  • Oct 21, 2019 - 7:51 AM - hans - Author: Comment Link

    UDPATE:

    Source code has been updated to include Daniel’s suggestion to use

    pinMode(2,INPUT_PULLUP);

    instead of

    digitalWrite (BUTTON, HIGH); 
    Reply

    hans

  • Oct 21, 2019 - 12:08 PM - Daniel Fernandes Comment Link

    Hi Hans,
    About the comment I made (Sep 19, 2019 – 12:53 PM), oddly enough, but the whole point was that I installed the LED display just above a microwave, so when it was turned on, it produced the big energy field and affected the display, so I moved the microwave and everything is now normal. Thanks for your attention and tips.

    Reply

    Daniel Fernandes

    • Oct 22, 2019 - 9:12 AM - hans - Author: Comment Link

      Haha, that is actually quite funny!
      Glad to hear everything now works as hoped for! 

      Reply

      hans

  • Oct 24, 2019 - 12:37 AM - Azroliak Comment Link

    Hi Hans,

    I’m wondering why didn’t you use the goto function instead of the assembly jmp.

    I’m not sure if this could save the eeprom use. 

    And btw, you did an awesome job, i’ll be able to save a lot of time thank you :)

    Reply

    Azroliak

    • Oct 25, 2019 - 4:20 AM - hans - Author: Comment Link

      Thanks Azroliak 

      Great question; well, the “goto” function is something most programmers frown upon and should never have to use.
      Just my opinion, but I’m sure a lot of programmers will agree with me.
      The description of the link says it all:

      The use of goto is discouraged in C programming, and some authors of C programming books claim that the goto statement is never necessary …

      The biggest issue is that the program flow can become unpredictable (not in this case though) and would make debugging an issue hell.
      This is why it’s ingrained in me to not use “goto”, but in this case you’re bringing up a valid point, and it may be a better choice.

      So this doesn’t mean “goto” is evil. Theoretically you could do this:

      void loop() {
        jumphere:
        // EEPROM.get(0,selectedEffect);
       
        if(selectedEffect>18) {
          selectedEffect=0;
          EEPROM.put(0,0);
        }
       ...
      void changeEffect() {
        if (digitalRead (BUTTON) == HIGH) {
          selectedEffect++;
          // EEPROM.put(0, selectedEffect);
          // asm volatile (" jmp 0");
         goto jumphere;
        }
      }

      I haven’t tried it, so I do not know if it is OK to have the label located in a different function.
      If this works, then the use of the EEPROM could be eliminated (a good argument to use “goto” in this case).

      Unfortunately, I do not have an Arduino or LED strip handy to test this.
      If you decide to test this; please let us know your findings!

      Reply

      hans

      • Nov 2, 2019 - 5:11 AM - Azroliak Comment Link

        So I’m back after some experimentations 
        We can’t use the goto function since we’re not in the same function but, we can use the setjmp/longjmp couple. That way, I can comment the eeprom functions and that work pretty well. 

        #include "FastLED.h"
        //#include <EEPROM.h>
        #include <setjmp.h>
        #define NUM_LEDS 142 
        CRGB leds[NUM_LEDS];
        #define PIN 5 
        #define BUTTON 2
        byte selectedEffect=0;
        jmp_buf envBuffer;
        void setup()
        {
          FastLED.addLeds<NEOPIXEL, PIN>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
          pinMode(2,INPUT_PULLUP); // internal pull-up resistor
          attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, RISING); // pressed
        }
        void loop() {
          int val;
          val = setjmp(envBuffer);
          //EEPROM.get(0,selectedEffect); 
          
          if(selectedEffect>18) { 
            selectedEffect=0;
            //EEPROM.put(0,0); 
          } 
        ... } void changeEffect() { if (digitalRead (BUTTON) == HIGH) { selectedEffect++; longjmp(envBuffer, selectedEffect); //EEPROM.put(0, selectedEffect); //asm volatile (" jmp 0"); } } ...

        I’ve also added a capacitor (100nF) in parallel with the button to avoid boucing effect which allow me to put the interruption on rising edge.

        Reply

        Azroliak

        • Nov 2, 2019 - 6:04 AM - hans - Author: Comment Link

          Awesome Azroliak!

          What a great find – I would not have found that one, never heard of the setjmp.h.
          Once I get my Arduino stuff handy, I’ll go play with that – it is a great way to avoid using the EEPROM! 

          Reply

          hans

  • Nov 7, 2019 - 12:39 PM - Tapomoy Comment Link

    Anyway to add random colours instead of the usual RGB?

    Reply

    Tapomoy

    • Nov 8, 2019 - 4:11 AM - hans - Author: Comment Link

      Did you have a particular function in mind?

      For example:

      FadeInOut(0xff, 0x00, 0x00);

      could be replaced with this, by using the random function:

      FadeInOut(random(255), random(255), random(255)); // random number between 0 and 255

      or (if you want to have a certain minim brightness:

      FadeInOut(random(64,255), random(64,255), random(64,255)); // random number between 64 and 255

      Add this line to the “setup()” for better random numbers:

      randomSeed(analogRead(0)); // set a random seed for random numbers

      You can apply this to any function calls that takes RGB numbers.

      Some other examples:

      HalloweenEyes(random(255), random(255), random(255),
      CylonBounce(random(255), random(255), random(255), 4, 10, 50);
      NewKITT(random(255), random(255), random(255), 8, 10, 50);
      Twinkle(random(255), random(255), random(255), 10, 100, false);

      Hope this helps 

      Reply

      hans

      • Nov 8, 2019 - 10:11 AM - Tapomoy Comment Link

        First of all, many many thanks for replying me.

         I actually googled the code for random colour option yesterday and applied it. I guess I made some mistake in it as I am completely new to this and got errors (random is not a type, red was not declared in this scope). Will try accordingly and let you know about the results.

        Reply

        Tapomoy

        • Nov 9, 2019 - 3:12 AM - hans - Author: Comment Link

          Trying to figure it out yourself is commendable – quite a lot of people do not even try that. Excellent! 
          …. but never shy away from asking 

          Reply

          hans

      • Nov 8, 2019 - 1:08 PM - Tapomoy Comment Link

        Hans, thanks a lot for solving my problem. I got exactly what I wanted. There’s one problem though. All effects are showing random colours except for SnowSparkle. There’s a problem in it if I make the colours random. What happens is, the colours become random and change don’t sparkle. And after a few seconds the arduino restarts by itself. I can hear disconnected sound in my computer and the effects restart from fade out. Apart from this, the later effects like bouncing balls, meteor showers also become absent.

        If I keep the code of sparkle as it was before the  everything works fine except that the sparkle colour is only white.

        Reply

        Tapomoy

        • Nov 9, 2019 - 3:01 AM - hans - Author: Comment Link

          Hi Tapomoy,

          glad to hear you’ve made progress.

          I see there is a little boo-boo in the SnowSparkle() code.
          Replace it with this:

          void SnowSparkle(byte red, byte green, byte blue, int SparkleDelay, int SpeedDelay) {
            setAll(0,0,0); // was set to the color passed to the function
           
            int Pixel = random(NUM_LEDS);
            setPixel(Pixel,red,green,blue); // was set to white
            showStrip();
            delay(SparkleDelay);
            setPixel(Pixel,red,green,blue);
            showStrip();
            delay(SpeedDelay);
          }

          Not sure why the Arduino would reset though … 

          Reply

          hans

          • Nov 9, 2019 - 6:09 AM - Tapomoy Comment Link

            Thanks a lot for helping me out Hans. It is working the way I want it now. But there is a strange bug now. Previously when I pressed the button, all effects changed according to the sequence in the sketch. But now something like this is happening:

            Fadeinout, strobe, halloween eyes
            back to fade

            after repeated presses the effects later in the sequences appear. the sequence previously is kind of broken now.

            Tapomoy

          • Nov 10, 2019 - 4:21 AM - hans - Author: Comment Link

            Hi Tapomoy,

            you’re welcome 

            Maybe it’s an idea to move this to the Arduino forum, so you can post your code and I can review what you have.
            I’d start with adding some Serial.println calls to see how the “selectedEffect” variable changes (or not).

            hans

  • Nov 13, 2019 - 1:16 PM - David Comment Link

    Hello Hans!

    First of all, I want to thank you for your amazing articles.

    I recently bought my first Arduino, along with a string of LEDs, and your earlier article on using FastLED was a great reference for me!
    I really enjoy your style of presentation, the level of detail that you explain for both the hardware and accompanying code, and the amazing engagement that you have with others that read and ask questions.

    However, I have a couple of clarifications for some of your descriptions here.

    For dealing with the button, you mentioned using the following code:

     pinMode(2,INPUT_PULLUP);  // internal pull-up resistor

    And noted:

    Later we can test if a button was pressed with:

    if (digitalRead (BUTTON) == HIGH) {
      ...
    }

    But actually, that’s not correct.

    The pull-up resistor “pulls” the signal to the high voltage state, so the normal, non-pushed state of this signal is HIGH. Pressing the button connects the pin to GND through the switch, and so to detect when the button is pushed, you should really be checking to see if the signal is LOW. It works for you in your code, because you are not directly checking the signal’s state, but instead are checking when it changes state, which is subtly different.

    That leads me to the next section, which discusses the interrupt handling.
    You mentioned:

    attachInterrupt (digitalPinToInterrupt(BUTTON), changeEffect, CHANGE); // pressed

    When reading the documentation you might wonder why I used the “CHANGE” mode instead of the “LOW” or “HIGH” mode. The reason is that both produced unexpected effects, like I pressed the button multiple times. So instead I used “CHANGE” and in our own function “changeEffect()” I then determine what the button state is and react accordingly. This is super fast!

    I believe that the reason that you were having problems when using the mode set to LOW or HIGH mode, rather than CHANGE, is that you were causing the interrupt routine to be triggered continually when the button was pushed. As explained in the documentation for attachInterrupt, setting Mode to LOW will “trigger the interrupt whenever the pin is low”. With your configuration, pressing the button causes the pin’s signal to go low, and thus, for as long as you hold the button down, the interrupt routine would continue to get re-triggered! This is why you experienced the effect that was like you “pressed the button multiple times”.

    With the changes that you made to get this to work, you are changing the logic to only increment selectedEffect when the signal CHANGEs state, AND the ending signal state is HIGH. As I mentioned above, because you are checking the HIGH state, you are actually incrementing selectedEffect on the button release, and not when the button is pushed (it doesn’t really make much difference for this application, but for some applications it might be critical to trigger on the correct event).

    However, there is a more direct method of doing this exact same thing, which is slightly more efficient (only calls the interrupt routine when needed), and makes the code more explicit (and thus easier to read). The mode parameter to attachInterrupt also supports values of RISING (triggers when the pin changes state from low to high), or FALLING (triggers when the pin changes state from high to low).
    If you changed your code to use RISING, it is essentially using the same logic of “signal CHANGEd state, and ended HIGH”, but you could do that without using the additional “if” statement inside the changeEffect function. Likewise, you could also choose FALLING, and have the effect change on the button press, rather than the release.

    Thanks again for a wonderful article!
    David

    Reply

    David

    • Nov 14, 2019 - 4:38 AM - hans - Author: Comment Link

      Hi David,

      thank you very much for this insightful info, and your kind words.
      I think it’s great that other users, like yourself, contribute to the article! 

      I see your point – very well explained! I may have moved a little too quick bringing in the PULLUP. 
      With your info in mind, I’ll go do some playing with my Arduino and LED strips.

      Thanks again and pretty please, always feel free to post info like this – it truly is very much appreciated! 

      Reply

      hans

      • Nov 14, 2019 - 11:58 AM - David Comment Link

        Hi Hans,

        Using a pull-up resistor (either internal, or external) is absolutely the correct thing to do. 
        If you don’t use a pull-up resistor, the input pin is essentially “floating” when the button is not pressed, and its state will be uncontrolled – it may read HIGH, or it may read LOW. Using a pull-up resistor is the widely accepted method of addressing that problem.

        I’m sure that your code, as currently written, works correctly, but my point was that I think that it is working slightly differently than you may believe, and had described. Again, for this particular application, those differences probably don’t matter (it really doesn’t matter if the effect changes when you push the button, or release it).

        I really like the way that you broke the article up into the individual challenges, with detailed descriptions of how you solved them. These same challenges could be faced in other applications, so it is really nice to break them out like this. However, for other applications, it may be more critical that the correct event is monitored, and so it would be helpful to understand the detail of what is happening.

        I’d suggest playing around without changing your current code, and try and validate my statements around the “change on button press” or “change on button release”.
        Of course, none of this considers switch-bounce, which could make the results harder to interpret if it is occurring. 

        David

        Reply

        David

        • Nov 15, 2019 - 3:48 AM - hans - Author: Comment Link

          Thanks again David! 

          You’re right, and that’s why I wanted to play with it so I can make a better description.
          Now that PULLUP has been introduced, which is something I originally did not use, I should also describe the debounce schematics and how it works, and your info will be very helpful with that.

          Thank you that you like the way I broke things down. 
          I will never claim to know everything (and I like to learn some new things as well), but when writing an article, I literally go through every step to make sure I provide useful info and an explanation on how I got there. This way folks can learn something from it, or (like you) provide corrections (which are most welcome).

          As with all these articles, finding time to write, edit, test and respond, can be a challenge. I’m still looking for that billionaire that is willing to sponsor me so I do not need a daytime job .

          So in short; I’ll go through your info, and play with it, and finally will revamp the article to reflect this info.

          Thanks again! And by all means; keep the info coming 

          Reply

          hans

  • Nov 20, 2019 - 12:04 PM - cprelot Comment Link

    Hi Hans

    I making a lamp with 49 fastled for my Little daughter and I use the gradient palettes sketch by Mark Kriegsman
    here:https://gist.github.com/kriegsman/8281905786e8b2632aeb
    his sketch use a time delay to go one to another…from Playlist of color palettes

    void setup() {
    delay(3000); // 3 second delay for recovery

    // tell FastLED about the LED strip configuration
    FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS)
    //.setCorrection(TypicalLEDStrip) // cpt-city palettes have different color balance
    .setDither(BRIGHTNESS < 255);


    // set master brightness control
    FastLED.setBrightness(BRIGHTNESS);
    }


    // Forward declarations of an array of cpt-city gradient palettes, and
    // a count of how many there are. The actual color palette definitions
    // are at the bottom of this file.
    extern const TProgmemRGBGradientPalettePtr gGradientPalettes[];
    extern const uint8_t gGradientPaletteCount;


    // Current palette number from the 'playlist' of color palettes
    uint8_t gCurrentPaletteNumber = 0;


    CRGBPalette16 gCurrentPalette( CRGB::Black);
    CRGBPalette16 gTargetPalette( gGradientPalettes[0] );

    But I want to use a button to call the gradient palette color from the playlist instead like:

    //********************************************************
    DEFINE_GRADIENT_PALETTE( BlacK_Red_Magenta_Yellow_gp ) {

    0, 0, 0, 0,

    42, 42, 0, 0,

    84, 255, 0, 0,

    127, 255, 0, 45,

    170, 255, 0,255,

    212, 255, 55, 45,

    255, 255,255, 0}; // This list of color palettes acts as a "playlist"; you can

    // add or delete, or re-arrange as you wish.

    const TProgmemRGBGradientPalettePtr gGradientPalettes[] = { BlacK_Red_Magenta_Yellow_gp, //***********************************************************

    I need help to setup the void loop()
    can you help me please thank you

    Chris

    Reply

    cprelot

    • Nov 21, 2019 - 4:20 AM - hans - Author: Comment Link

      Hi Chris,

      I’m not familiar with the code, and it is a little off-topic.
      So this should really be in the forum

      Having said that, and not knowing anything about Mark’s code, you could try using my code (remove my effects), merging it with Mark’s and replace all the “case” statements with a color palette change. Something like this:

      void loop() {
        EEPROM.get(0,selectedEffect);
       
        if(selectedEffect>18) { // where "18" is the number of gradients you want to use
          selectedEffect=0;
          EEPROM.put(0,0);
        }
       
        switch(selectedEffect) {
         
          case 0 : {
                      gCurrentPaletteNumber = addmod8( gCurrentPaletteNumber, 1, gGradientPaletteCount);
                      gTargetPalette = gGradientPalettes[ gCurrentPaletteNumber ];
                      break;
                    }
       ... (for all palettes)
        EVERY_N_MILLISECONDS(40) {
          nblendPaletteTowardPalette( gCurrentPalette, gTargetPalette, 16);
        }
        
        colorwaves( leds, NUM_LEDS, gCurrentPalette);
        FastLED.show();
        FastLED.delay(20);
      }

      Hope this helps you go into the right direction. If not: please place a post in the forum.

      Reply

      hans

  • Dec 14, 2019 - 11:46 PM - beau Comment Link

    Multiple libraries were found for “Adafruit_NeoPixel.h”

     Used: C:\Users\beauh\OneDrive\Documents\Arduino\libraries\Adafruit_NeoPixel

    Multiple libraries were found for “EEPROM.h”

     Used: C:\Users\beauh\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\libraries\EEPROM

    exit status 1

    Error compiling for board WeMos D1 R1.

    whats the problem?

    Reply

    beau

    • Dec 15, 2019 - 6:09 AM - hans - Author: Comment Link

      Hi Beau,

      You seem to have multiple versions of the AdaFruit library on your system.

      For example, I suspect you have one here:

      C:\Users\beauh\OneDrive\Documents\Arduino\libraries\

      and one here:

      C:\Users\beauh\AppData\Local\Arduino15\packages\

      (I could be wrong about that second path, it was just an educated guess, I do not use Windows).
      And probably something similar for the EEPROM library, and maybe even more than just these 2.

      Ideally you maintain only one, in the default location the Arduino uses, otherwise the Arduino IDE doesn’t know which one to use.

      Probably the easiest way to fix this is by closing the Arduino IDE, moving both versions to a temporary different location (just so you can restore in case things go haywire), opening the Arduino IDE again, and using the “Tools” – “Manage Libraries” to re-install the FastLED library.

      Note: If you’d like to keep the library with your sketch (the one you have on OneDrive), which is never a bad idea, then may you should keep that one as a zipped file in some sub-directory, just for reference in the future, not for the IDE to be used.

      Reply

      hans

  • Dec 19, 2019 - 3:36 PM - mattx38 Comment Link

    Hello, 

    How can I mkae the patterns alternate without having to push the button on pin 2 ?

    Thnak you !

    Reply

    mattx38

    • Dec 19, 2019 - 4:13 PM - mattx38 Comment Link

      Well, I used the random number function to make it done.

      selectedEffect = random(0, 18);

      Is it the right way to do it ?

      It makes the job.

      Reply

      mattx38

    • Dec 20, 2019 - 5:47 AM - hans - Author: Comment Link

      That would most certainly work.
      However, since the random function on the Arduino is not the best random generator, add this to the loop() function:

      void setup() {
      ...
        // if analog input pin 0 is unconnected, random analog
        // noise will cause the call to randomSeed() to generate
        // different seed numbers each time the sketch runs.
        // randomSeed() will then shuffle the random function.
        randomSeed(analogRead(0));
      }

      Your random function should replace this

      void loop() {
        EEPROM.get(0,selectedEffect);
       
        if(selectedEffect>18) {
          selectedEffect=0;
          EEPROM.put(0,0);
        } ...

      and make it something like this:

      void loop() {
        selectedEffect = random(0, 18);
        ...
      Reply

      hans

  • Dec 28, 2019 - 10:03 PM - Veijo Ryhanen Comment Link

    Hi, Hans!

    Thank You for sharing this wonderfule application! :)

    When running “FastLED” -code, I was wondering: “What effect is currently running ?”

    So I added this row to “setup()” -function:

        Serial.begin(9600); 

    And these rows to “loop()” -function:

        Serial.print(selectedEffect);

        Serial.print(” “);

       …

        Serial.println(“RGBLoop”);

        …

        Serial.println(“NewKITT”);

        …

    Everything works well in my serial monitor (Arduino IDE: Ctrl+Shift+M) from “case 0” to “case 4”, I was able to see name of the effect currently running.

    Strangely, after “case 5” ie. “NewKITT” -function was executed, it prevented to execute all methods from “case 6” to “case 18”. I found that there was two “indexOutOfBoundsException” (as we say in java world) happening in Your code. In both of these cases, “setPixel” led index reached prohibited value 60, even though 59 is maximum allowed value:

        // CenterToOutside -function, row 327, original: 

        //setPixel(NUM_LEDS-i, red/10, green/10, blue/10);

        //Fixed:

        setPixel(NUM_LEDS-(i+1), red/10, green/10, blue/10);

        // OutsideToCenter -function, row 350, original:

        // originalsetPixel(NUM_LEDS-i, red/10, green/10, blue/10);

        setPixel(NUM_LEDS-i-1, red/10, green/10, blue/10);

    It seems that “Neopixel” -code contains these two bugs, too.

    Reply

    Veijo Ryhanen

    • Dec 29, 2019 - 5:17 AM - hans - Author: Comment Link

      Hi Veijo!

      Thanks for catching that! I think it may be my code (so not Library related).
      Under different circumstances I’d include a check ro make sure it doesn’t go below zero or beyond NUM_LEDS.
      Silly me, since it just worked, assumed that the Libraries would take care of that and I didn’t want to slow down the effects by repeatedly checking the values.
      Maybe in this particular function it may not be a bad idea to include such a check.

      I’ll have to dig up my Arduino hardware and do some testing – which I hope to be able to do in the next weeks (working on another big project and the holidays tend to consume a lot of time as well).

      Nice catch! 

      Reply

      hans

  • Jan 26, 2020 - 12:20 AM - Geuther Comment Link

    Hello everybody,

    The sketch is great. Thanks a lot! I want to add a new effect. Where do I have to insert it to be able to switch with the button?

    Reply

    Geuther

    • Jan 26, 2020 - 4:54 AM - Hans - Author: Comment Link

      Hi Geuther,

      Thanks for the compliment! 

      Adding an affect isn’t too complicated. Please read this earlier comment for some of the details. 

      Reply

      Hans

      • Jan 26, 2020 - 5:40 AM - Geuther Comment Link

        Hello Hans, thanks for the quick reply. unfortunately i am new with arduino. I would like to have a color white on case 19. please give me an example. thank you and best regards from Dresden.

        Reply

        Geuther

      • Jan 26, 2020 - 5:51 AM - Hans - Author: Comment Link

        If you want all LEDs to be white at max brightness, you could try this (not displaying all the other code – changes are displayed BOLD)

        We have to make a few changes in the “void loop()”:

        void loop() { 
          EEPROM.get(0,selectedEffect); 
          
          if(selectedEffect>19) { // <--- we have added an effect, so "19" reflects the number of effects
            selectedEffect=0;
            EEPROM.put(0,0); 
          } 

         We also need to change the “switch” section by adding our new effect at the end with a “case” statement and the code to set the LEDs to white: 

          switch(selectedEffect) {
            
            case 0 : {
                        // RGBLoop - no parameters
                        RGBLoop();
                        break;
                      }
            case 1 : {
                        // FadeInOut - Color (red, green. blue)
                        FadeInOut(0xff, 0x00, 0x00); // red
                        FadeInOut(0xff, 0xff, 0xff); // white 
                        FadeInOut(0x00, 0x00, 0xff); // blue
                        break;
                      }
                      
            ... // all the other "case" statements (removed to save space here)
            case 18 : {
                        // meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay 
                        meteorRain(0xff,0xff,0xff,10, 64, true, 30);
                        break;
                      } // new effect starts here
            case 19 : {
                        // setting all LEDs to white setAll(255,255,255); // all LEDs to white showStrip(); // Show the changes in the LED colors.
            }

        // new effect ends here   }
        }

        Hope this will get you started. 

        Reply

        Hans

  • Jan 27, 2020 - 10:08 AM - Ronald Comment Link

    Hi, Hans!

    Thank You for sharing this wonderfule application!

    I have extended the application with an optical Led display in binary format. Plug a LED with pre-resistor into pins 8 to 12 of the ARDUINO and add the following code:

    void setup()
    ….
    // declare LED pins as output pins  
      pinMode(8,OUTPUT);     
      pinMode(9,OUTPUT);  
      pinMode(10,OUTPUT);  
      pinMode(11,OUTPUT);
      pinMode(12,OUTPUT);
    
    void loop()
    …
    case2LED();
    …
    void case2LED() {
      k = selectedEffect; 
      int a=k%2;            // calculate LSB  entspricht high für ungerade Zahlen 
      int b=k/2 %2;        //                  	entspricht high für ein vielfaches von 2 oder 3
      int c=k/4 %2;        //                  	entspricht high für ein vielfaches von 4,5,6 oder 7     
      int d=k/8 %2;       //                  	entspricht high für ein vielfaches von 8,9,10 .. 15  
      int e=k/16 %2;     // calculate MSB    	entspricht high für ein vielfaches von 16 ...
      
      digitalWrite(12,e);       //  write MSB
      digitalWrite(11,d);   
      digitalWrite(10,c);   
      digitalWrite(9,b);   
      digitalWrite(8,a);        // write LSB 
    }
    

    Greetings Ronald.

    Reply

    Ronald

    • Jan 28, 2020 - 4:44 AM - Hans - Author: Comment Link

      Awesome! Thanks for sharing Ronald! 

      Do you have a little video showing what this will look like?

      Reply

      Hans

      • Jan 31, 2020 - 4:40 AM - Ronald Comment Link

        Here is a short video. You can see the Arduino with power supply and the connectors for the LED strip. The potentiometers are for an additional step 19, which is for normal lighting and you can adjust the brightness and colors. 

        https://youtu.be/9vcvrNZCMVY

        Greetings Ronald.

        Reply

        Ronald

      • Jan 31, 2020 - 5:13 AM - Hans - Author: Comment Link

        Awesome! And thank for posting a video! 

        Reply

        Hans

  • Feb 3, 2020 - 8:12 AM - Nikunj Comment Link

    asm volatile (” jmp 0″)  not working with any  ESP8266 model

    so i changed ESP.reset() and  ESP.restart() but every time eeprom is not stored data and give same pattern.

    is that any solution then help me.

    Reply

    Nikunj

    • Feb 4, 2020 - 4:31 AM - Hans - Author: Comment Link

      The ESP8266 is still on my list of “things to play with” (I have 2 laying around, new in box).

      From what I found:
      In this StackExchange post I read that the EEPROM implementation in the ESP8266 is not the same as for a normal Arduino, and the post suggests using this particular EEPROM.h library (not the same as the one that comes with the Arduino software).

      Of course, I haven’t tested this, and I have zero experience with the ESP8266 (if you don’t count “holding the box” as an experience ).

      Hope this helps.

      Reply

      Hans

  • Mar 16, 2020 - 7:06 PM - Altiparmak Comment Link

    Hello,

    nice code!!!

    I played a little bit with it – meanwhile i can use a infrared-remote to change the different effects on an arduino nano and a ws2812b-strip

    I use it together with the lego ISS as a wall-lamp.

    If anybody is interested, i can provide the code here – the a.m. link https://www.tweaking4all.com/forums/ doesnt work….

    Reply

    Altiparmak

    • Mar 17, 2020 - 6:13 AM - Hans - Author: Comment Link

      Hi Altiparmak!

      Thanks for the nice compliment – it’s much appreciated! 

      I recently swapped the old forum for a better working forum.
      The new link is https://www.tweaking4all.com/forum (minus the “s”).
      I’d love to see the code! 

      Reply

      Hans

      • Apr 12, 2020 - 3:44 PM - normen Comment Link

        Hello Hans,

        i have to clean up the code a bit before posting :-)

        The comments are in german right now – i don’t think that its helpful.

        I put 466 Leds on the Lego ISS – 16*16 on the front and 16*13 on the back + 2 in the base = 466 in total
        Controller: arduino mega 2560 – with two different control channels for the strips (back/front)

        Features so far:

        • modus switchable with a normal ir-remote
        • selectable effects on the back / front
        • adjustable brightness (back/front seperated)

        Features coming:

        • adjustable color when no effect is displayed
        • storing the settings in the eeprom for the next startup

        Unfortunately i can’t get the bouncingball to work
        properly – it works with one strip – but not with fastled support for
        separated strips :-(Because of the ugly timing-constraints of the ir-lib (without using IRQs) i changed the delay-function of the effects to receive ir-commands.Works quite well for short ir-values (4 Byte) and long delays :-)
        Here is a video for the first half of the LEDs (the rest is stucked in china-post)
        http://www.altiparmak.de/temp/20200412_041937.mp4
        Kimd regardsNormen

        Reply

        normen

      • Apr 13, 2020 - 3:31 AM - Hans - Author: Comment Link

        Hi Normen!

        That looks awesome! 
        Yeah, I can imagine that finding an “interrupt” to catch IR (this goes for Bluetooth as well) can be quite tricky.

        I’m not sure how helpful this will be, but I did find some code for handling IR and using interrupts.
        Reading the code carefully will also show you how to connect the IR receiver.

        Connections:

        IR Receiver     ->  Arduino
           V+ -> +5v
           GND -> GND
           Signal Out -> Digital Pin 2

        Seemingly allowing the use of a interrupt:

        attachInterrupt(digitalPinToInterrupt(PIN), InterruptHandlerFunction, CHANGE); 

        It’s a based on a different application, but I’m sure you’ll get the idea. The original article can be found here.

        I haven’t tested any of this, and you may have to tinker a little with it to fit it into the code here.

        Reply

        Hans

  • Mar 30, 2020 - 10:45 PM - Jensen Comment Link

    Good morning My Idol.
    instead of using buttons, why do not you use Processing to set effect and set RGB color?

    Reply

    Jensen

    • Mar 31, 2020 - 3:50 AM - Hans - Author: Comment Link

      Hi Jensen,

      I honestly have no idea what you’re trying to ask?
      Could you elaborate?

      Reply

      Hans

      • Apr 1, 2020 - 2:04 AM - Jensen Comment Link

        Hi Hans.
        My mean is we will control the Color and  Effect of LED by “Processing” on PC.
        We can select the effect and pick color easy than. 

        Reply

        Jensen

      • Apr 1, 2020 - 3:00 AM - Hans - Author: Comment Link

        Ah now I see what you mean, controlling the LEDs via a PC.
        Well, this is not impossible of course, but the idea of this project is to create LED effects with an Arduino (it is afterall an Arduino project), so we can run the LED effects without the need for PC. This way, the entire setup can easily placed and used anywhere the user would like.

        You could of course still use the Arduino to receive info from the PC to control the effects, or you could use (for example, I’m sure there are more out there) this Python library to run LED effects straight from a PC.

        Hope this helps.

        Reply

        Hans

      • Apr 1, 2020 - 6:49 AM - Jensen Comment Link

        Thank you so much Hans.
        because i’m not pro. So with your link I can control led with Windows PC?

        Reply

        Jensen

        • Apr 2, 2020 - 5:53 AM - Hans - Author: Comment Link

          You’re welcome.

          As for controlling the LED through your PC, you’ll have to do some reading up on the topic I’m afraid. I haven’t experimented with this at all and I’m not a Python user either.

          Most use an Arduino though, even when they control the LEDs from their PC (for example this project).

          The main reason for this is that the good old serial ports (RS232) and parallel ports used to be used for projects like this, but most PC’s no longer have these ports.

          So in short: you’ll have to do a lot of homework – sorry 

          Reply

          Hans

  • Apr 16, 2020 - 1:03 PM - Bartek Comment Link

    Hi Hans

    I admire your work, best article for learning about FastLED.

    I want to modify you code for party light system, it will be controler with 10 button (more or less) and each button needs to trigger only one effect, of course interupting previous one.

    I`ve tried to make something like below. one buton makes effect goes up and second down, but down function didnt work :/

    #include <FastLED.h>
    #include <EEPROM.h>
    #define NUM_LEDS 8
    CRGB leds[NUM_LEDS];
    #define PIN 5
    #define BUTTON 2
    #define BUTTONDUO 3
    byte selectedEffect=0;
    void setup()
    {
     FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
     pinMode(2,INPUT_PULLUP);
     pinMode(3,INPUT_PULLUP);// internal pull-up resistor
     attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, HIGH);
     attachInterrupt (digitalPinToInterrupt (BUTTONDUO), changeEffectDown, HIGH);// pressed
    }
    // *** REPLACE FROM HERE ***
    void loop() {
     EEPROM.get(0,selectedEffect);
     
     if(selectedEffect>18) {
     selectedEffect=0;
     EEPROM.put(0,0);
     }
     
     switch(selectedEffect) {
     
     case 0 : {
     // RGBLoop - no parameters
     RGBLoop();
     break;
     }
    Cases ...
    void changeEffect() {
     if (digitalRead (BUTTON) == HIGH) {
     selectedEffect++;
     EEPROM.put(0, selectedEffect);
     asm volatile (" jmp 0");
     }
    }
     void changeEffectDown() {
     if (digitalRead (BUTTONDUO) == HIGH) {
     selectedEffect--;
     EEPROM.put(0, selectedEffect);
     asm volatile (" jmp 0");
     }
    }

    I hope theres a solution for this problem.

    Thanks,

    Reply

    Bartek

    • Apr 18, 2020 - 6:42 AM - Hans - Author: Comment Link

      Hi Bartek!

      Thank you for the compliments! 

      This would have probably been better in the forum, … using 10 (or any different number) of buttons, will come with a few challenges.
      The first option could be (untested) to use a separate PIN per button (like you started in your code), but would require a minor change:

      void changeEffect() {
       if (digitalRead (BUTTON) == HIGH) {
       selectedEffect = 1;
       EEPROM.put(0, selectedEffect);
       asm volatile (" jmp 0");
       }
      }
      void changeEffectDown() {
        if (digitalRead (BUTTONDUO) == HIGH) {
        selectedEffect = 2;
        EEPROM.put(0, selectedEffect);
        asm volatile (" jmp 0");
        }
      }

      So when BUTTON is pressed, the selected effect will be effect number 1.
      If BUTTONDUO is pressed, the selected effect will be effect number 2.
      And so on. 

      Note: you could also combine both functions into one function (also: untested):

      void changeEffect() {
        int newEffect = -1; 
        if (digitalRead (BUTTON) == HIGH) {
         newEffect = 1; }
       else if (digitalRead (BUTTON) == HIGH) {
         newEffect = 2; }
       if( (newEffect!=selectedEffect) && (newEffect!=-1) ) { EEPROM.put(0, newEffect);
         asm volatile (" jmp 0");
        }
      }

      But …. with 10 buttons, you’ll run out of pins pretty quickly, and you’d need to resort to another solution. Something like a key matrix (often seen with keyboards, or numeric keypads). This will be a little bit more of a challenge though.

      Reply

      Hans

  • Apr 29, 2020 - 3:49 PM - Marunthol Comment Link

    I’m sorry Hans
    That’s the code from yesterday which I tried and didn’t work

    I tried only using two effects
    void loop () {
    meteorRain (0xff, 0xff, 0xff, 10, 64, true, 30);

    Fire (55, 120, 15);
    }

    also not getting good results

    Reply

    Marunthol

    • Apr 30, 2020 - 4:46 AM - Hans - Author: Comment Link

      Hi Marunthol,

      Maybe it is better to start a forum topic in the Arduino Forum section.
      Your messages unfortunately are all over the place and without seeing the entire code, solving this becomes a challenge.
      Please do NOT post the full code here, use the forum instead.

      Reply

      Hans

  • May 17, 2020 - 1:55 PM - Stephen John Hysick Comment Link

    I am attempting to use your code for a community group theater production of Cinderella on stage. The framework of her carriage would have six states.
    1. Off. While the prop is waiting in the wings.
    2. A very slow ramping from off, to green, and eventually orange over 10 minutes. So slow that the audience barely notices.
    3. Twinkle random. While the fairy godmother applies her magic.
    4 Snow Sparkle. After the transformation is complete.
    5 Meteor Rain. As the spell wears off.
    6. Static Orange. Back to being a pumpkin.
    Ideally, (and for simplicity) I would like to use a 6 position rotary switch to change modes – as it would be easy and logical for the actors to operate and giving them control over how long each lighting effect lasts.

    We have always had a hard time staging a realistic campfire or shooting star and your code is (almost) perfect as-is! I really like this approach because the hardware could be used in other productions as well simply by choosing which effect is assigned to each position of the switch. Try as I might, I just can’t seem to come up with code that works. Can you possibly assist?

    One other idea (or switch mode) I had would be to use the theater chase effect (just on the wheels) to convey they are rolling while in the woods – but I don’t think it’s possible to have the coach with one lighting effect (snow) and the wheels another (chase) without using a second Arduino just for the wheels.

    Any support would be appreciated via support donation and due credit in the playbill! This project would really make the show special.

    Reply

    Stephen John Hysick

    • May 18, 2020 - 4:23 AM - Hans - Author: Comment Link

      Hi Stephen!

      This sounds like an exciting project, but maybe it is a little to big to talk about this in the comments here (maybe better to start a forum topic as it may involve a lot of code and such).

      The use of a rotary switch is most certainly an option and in your situation probably more logical.
      Mixing 2 effects (running them at the same time) is probably not the best idea, the use of 2 Arduino’s is probably better. Mostly because each effect “eats” some of the of the other effect away, which results in a slower effect (and more complex code). You can combine them though, it is not impossible. I recommend using 2 Arduinos though.

      Reply

      Hans

  • May 21, 2020 - 12:29 AM - Xavier Comment Link

    Hi, thanks for the program, it is awesome :)

    I got an Issue with the button. When I press it, it will randomly send the program back to case 1 instead of going forward to the next case. i tought at first it was my button that was causing the issue but It behaved the same way using the wires directly. I also switched wires and breadboard to make sure. Anything you think that might help me with this issue^

    Thank you!

    Xavier

    Reply

    Xavier

    • May 21, 2020 - 4:26 AM - Hans - Author: Comment Link

      Hi Xavier,

      this could be caused by the so called “bounce” effect.
      I have not experienced this issue myself, but it could be what you’re looking at.

      On the official Arduino page I found this article that may be helpful.
      2 other users reported the same issue, but I just haven’t had time yet to work on a solution (not being able to reproduce this in my setup makes it even harder to see if a potential solution actually works).

      Reply

      Hans

      • May 21, 2020 - 9:48 AM - Xavier Comment Link

        Thank you, I did some research this morning!
        found this piece of code that I included in the Setup

        void my_interrupt_handler()
        {
        static unsigned long last_interrupt_time = 0;
        unsigned long interrupt_time = millis();
        // If interrupts come faster than 200ms, assume it’s a bounce and ignore
        if (interrupt_time – last_interrupt_time > 200)
        {
        }
        last_interrupt_time = interrupt_time;
        }

        For a unknown reason, I had to increase the timing to 3000 ms to make reliable. But still the interrupt is working without any delay… Dont know exactly why but it is working.

        I also implemented a second interrupt button on pin 3 to go backward in the reading of the cases. Thanks to all the informations you already responded to other users :)
        There is still one thing I would like to add that I cant manage by myself…!

        Going backwards, I would like the button to go from the first case to the last one (case 2, 1, 0, 18, 17, 16…) Right know it stops on case 0.

        What do you think^

        Xavier

        Reply

        Xavier

        • May 22, 2020 - 5:11 AM - Hans - Author: Comment Link

          Hi Xavier,

          Cool that this works, but a little weird as well 

          Both variables are local variables (last_interrupt_time and interrupt_time).
          You set the first one to zero, and the second one to millis. Where millis = “Returns the number of milliseconds passed since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 50 days.”

          The if block (if (interrupt_time – last_interrupt_time > 200) { } ) executes “nothing” when the Arduino has been running for more than 200 ms. There is nothing between the accolades, so it won’t be doing anything.

          After that it sets the (local) variable last_interrupt_time to the current interrupt_time, but once this function is done, both variable will no longer exist.
          Even if they would exist, the would be reset when the function”my_interrupt_handler” is being called.

          You’d probably want something like this (assuming the original code, and leaving the “back” button out of it for now):

          void changeEffect() {
            if ( (digitalRead (BUTTON) == HIGH) and (millis() > 200) {
              selectedEffect++;
              EEPROM.put(0, selectedEffect);
              asm volatile (" jmp 0");
            }
          }

          I haven’t tested this, but the button press will only do something if the Arduino has been reset more than 200 ms ago.

          Now your second question, the “back” button, would need a little rewriting:

          ...
          #define FORWARDBUTTON 2
          #define BACKBUTTON 3

          ...
          void setup()
          {
            FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
            pinMode(2,INPUT_PULLUP); // internal pull-up resistor
            attachInterrupt (digitalPinToInterrupt (FORWARDBUTTON), changeEffect_forward, CHANGE); // pressed
            attachInterrupt (digitalPinToInterrupt (BACKBUTTON), changeEffect_back, CHANGE); // pressed

          }
          ...
          void changeEffect_forward() {
            if ( (digitalRead (BUTTON) == HIGH) and (millis() > 200) {
              selectedEffect++;
              if (selectedEffect>18) { selectedEffect = 0; }
              EEPROM.put(0, selectedEffect);
              asm volatile (" jmp 0");
            }
          }

          ...
          void changeEffect_back() {
            if ( (digitalRead (BUTTON) == HIGH) and (millis() > 200) {
              selectedEffect--;
              if (selectedEffect<0) { selectedEffect = 18; }
              EEPROM.put(0, selectedEffect);
              asm volatile (" jmp 0");
            }
          }

          ...
          void loop() {
            EEPROM.get(0,selectedEffect);
           
            // if(selectedEffect>18) {
            //   selectedEffect=0;
            //   EEPROM.put(0,0);
            // }

          ...

          You’ll have to disable the code as indicated in the loop().

          I hope this is helpful, and please keep in mind that I have not tested the code.

          Reply

          Hans

          • May 22, 2020 - 5:46 PM - Xavier Comment Link

            Hey thank you so much for your help.
            I corrected the firs part as you explained to me, its working!

            For the second button It was already pretty much my code, but it wouldnt go backward from case 0 to case 32 ( my last case)

            if ((digitalRead (BUTTONdown) == HIGH) and (millis() > 200)) {
            selectedEffect–;
            if (selectedEffect 200)) {
            selectedEffect–;
            if (selectedEffect < 1) { selectedEffect = 32; }
            EEPROM.put(0,selectedEffect );
            asm volatile (" jmp 0");
            }

            I just switched all the numbers and the other related lines.

            Its my first arduino/programming project and Ive been learning so much, thanks to you!.

            Xavier

            Xavier

          • May 23, 2020 - 5:51 AM - Hans - Author: Comment Link

            Hi Xavier,

            You’re most welcome, and awesome to hear it is working.
            I am however a little confused about your code …

            if ((digitalRead (BUTTONdown) == HIGH) and (millis() > 200)) {
            selectedEffect–;
            if (selectedEffect 200)) {
            selectedEffect–;
            if (selectedEffect < 1) { selectedEffect = 32; }
            EEPROM.put(0,selectedEffect );
            asm volatile (" jmp 0");
            }

            It seems incomplete and I honestly would not know what “if (selectedEffect 200))” would do (I’d expect an error message when trying to compile this).

            Hans

  • Jun 12, 2020 - 8:13 AM - Alex Comment Link

    Thank you for the nice code! I first tested some individual effects. Now with this code I could not use the button.
    It seemed to restart without saving to EEPROM.I guessed the saving is interupted by the hard reset. A delay(200); after saving to EEPROM solved the problem (in the function “changeEffect”).

    Reply

    Alex

    • Jun 12, 2020 - 8:57 AM - Hans - Author: Comment Link

      Interesting, thanks for the delay tip. What kind of Arduino are you using?

      Reply

      Hans

  • Jun 27, 2020 - 11:06 AM - Ken Comment Link

    Hello Hans,

    Your dedication to this thread is amazing!  I have used your code as my largest tool to learn FastLED.  Going through the functions one by one and making changes to see what is effected has been invaluable to me, and I am sure hundreds more.  You have a tremendous amount of patience while responding and helping everyone that posts in these comments.  Keep up the great work.

    Reply

    Ken

    • Jun 28, 2020 - 2:38 AM - David Vernon Comment Link

      True words. Keep up the good work 👍

      Reply

      David Vernon

    • Jun 28, 2020 - 4:51 AM - Hans - Author: Comment Link

      Thanks Ken and David! 

      I very much appreciate your kind words, and it’s my pleasure to help 

      Reply

      Hans

  • Jul 1, 2020 - 9:27 PM - German Comment Link

    Hola Hans!!!

    Muchas gracias por tu explicación y lo mejor, seguir en el tiempo respondiendo muchas preguntas.

    Voy a comenzar a estudiar los códigos. Seguramente alguno se adapta a lo que necesito con alguna modificación. Primero trataré de modificarlo sino volvere para consultas.

    El mejor blog de Arduino es este.

    Gracias otra vez!!!!!!

    Reply

    German

    • Jul 2, 2020 - 4:58 AM - Hans - Author: Comment Link

      Hi German,

      I do not speak Spanish, so I had to use Google Translate;

      Hello Hans !!!

      Thank you very much for your explanation and the best, continue in time answering many questions.

      I’m going to start studying the codes. Surely one adapts to what I need with some modification. I’ll try to modify it first, but I’ll come back for consultation.

      The best Arduino blog is this.

      Thank you very much for the compliments 

      Reply

      Hans

  • Jul 5, 2020 - 4:34 AM - Pritam Comment Link

    Hello,    Without button candition this code is work…. ?
    Means – one by one change of effects automatic,Without button push..  Thank you..

    Reply

    Pritam

    • Jul 5, 2020 - 5:49 AM - Hans - Author: Comment Link

      Hi Pritam,

      yes this is possible. As mentioned in other comments, you could try changing this part of the code:

      void setup()
      {
        FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
        pinMode(2,INPUT_PULLUP); // internal pull-up resistor
        attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, CHANGE); // pressed
      }
      // *** REPLACE FROM HERE ***
      void loop() {
        EEPROM.get(0,selectedEffect);
       
        if(selectedEffect>18) {
          selectedEffect=0;
          EEPROM.put(0,0);
        }

      to this:

      void setup()
      {
        FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
        // No longer needed: pinMode(2,INPUT_PULLUP); // internal pull-up resistor
        // No longer needed: attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, CHANGE); // pressed
      selectedEffect = -1; // add this
      }
      // *** REPLACE FROM HERE ***
      void loop() {
        // No longer needed: EEPROM.get(0,selectedEffect);
        selectedEffect++; // add this
        if(selectedEffect>18) {
          selectedEffect=0;
          // No longer needed: EEPROM.put(0,0);
        }

      This should start the effect with “0” and each time it goes through the loop it will increase the selected Effect by one, until it reaches the max value and then starts over at 0 again. 

      You can also remove the “#include <EEPROM.h>” line in the beginning as it is no longer needed either.

      Keep in mind though that the effects have been written to do individual steps for each loop() run.
      So with some effects you may want to call the effect more than once in a “case” block.

      Reply

      Hans

  • Jul 10, 2020 - 8:40 PM - Aimar Romeo Comment Link

    Hi, 

    First of all, congratulations about this project. It’s very well done, but I’va a question. Is it possible to add a bluetooth module? To control the effects by using a smartphone. Thanks! 

    From Spain ;) 

    Reply

    Aimar Romeo

    • Jul 12, 2020 - 6:30 AM - Hans - Author: Comment Link

      Hi Aimar!

      Thank you for the compliments 

      As for Bluetooth support: I do not (yet) have a Bluetooth module available, but I do know that several users here have done it.
      You may have to look at (for example) this forum post, or look in the comments here.
      They may help you get started.

      I’m in the middle of working on a new project where all effects (and more) are done on an ESP8266 (super cheap, more capable than an Arduino, and WiFi included). I already have code where it works great with WiFi (use a simple “webpage” for the buttons).

      Maybe in the near future I’ll be able to write an article on how to use the example here with Bluetooth.
      I’d need some more info and some more testing though.

      Reply

      Hans

      • Jul 22, 2020 - 4:45 PM - Aimar Romeo Comment Link

        Thanks Hans!

        Reply

        Aimar Romeo

      • Nov 28, 2022 - 6:17 PM - jlpicard Comment Link

        Hello Hans and I am interested in knowing what became of the ESP8266 conversion of this great sketch?

        Reply

        jlpicard

        • Nov 29, 2022 - 11:37 AM - Hans - Author: Comment Link

          Cool to hear someone ask about it! 

          Unfortunately, due to all kinds of issues these days, this project went in a dormant state (just like a few other projects).
          I do have code though with a lot of effects and the option to control it through a webbrowser – it does need some refinement though.

          Taking not of it though, and moved it a little higher on my to-do list.

          Reply

          Hans

          • Nov 29, 2022 - 4:45 PM - jlpicard Comment Link

            Sweet, I am going to purchase some those ESP8266.  I had a couple ESP32’s left from a different project, but the WIFI capable ESP8266 sounded interesting.  Thanks!

            jlpicard

          • Nov 30, 2022 - 4:07 AM - Hans - Author: Comment Link

            In case it takes too long, I’d be happy to share the current code – just cannot do that in the comments here.

            Hans

          • Nov 30, 2022 - 4:17 AM - Hans - Author: Comment Link

            Almost forgot to mention: This sketch can be copied pretty much 1:1 on an ESP8266. Naturally, it wouldn’t use extra capabilities like WiFi. 

            Hans

          • Nov 30, 2022 - 4:37 PM - Charles Comment Link

            Hans, you are everyones hero for working on these codes. Since I posted a while ago about this topic I have been using WLED on a few ESP8266 boards and it works ok. I like your effects MUCH better than what WLED has to offer. I would be willing to give your current version of the ESP8266 code a try.

            I tried to load the AllEffects_FastLED code to one of my ESP8266 boards and it gave me some errors, 

            In file included from /Users/charles/Documents/Arduino/libraries/FastLED/src/FastLED.h:67,

                             from /Users/charles/Downloads/AllEffects_FastLED/AllEffects_FastLED.ino:1:

            /Users/charles/Documents/Arduino/libraries/FastLED/src/fastspi.h:145:23: note: ‘#pragma message: No hardware SPI pins defined. All SPI access will default to bitbanged output’

              145 | # pragma message “No hardware SPI pins defined. All SPI access will default to bitbanged output”

                  | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            /Users/charles/Downloads/AllEffects_FastLED/AllEffects_FastLED.ino: Assembler messages:

            /Users/charles/Downloads/AllEffects_FastLED/AllEffects_FastLED.ino:169: Error: unknown opcode or format name ‘jmp’

            exit status 1

            Error compiling for board NodeMCU 1.0 (ESP-12E Module).

            I am able to load other code to the board fine that is basic (just changes led colors and brightness with buttons).

            Also to combine topics from an earlier post when I asked about controlling lots of leds. You suggested that I test the strips to make sure they were in working order and they were. I am currently using 3 different ESP8266 boards running WLED to control a total of 1407 leds (558 leds one one strip, 558 on another , and 291 on the last strip). So I know the led strips themselves do work.

            If you would like I could create a new forum post about this.

            Charles

          • Dec 1, 2022 - 7:18 AM - Hans - Author: Comment Link

            I’ve sent you an email 😉 

            Hans

  • Jul 21, 2020 - 11:25 AM - homer Comment Link

    Hello, I would like to add effects of demoreel100 to this code, how could I do it, thanks.

    void rainbowWithGlitter()
    {
     // built-in FastLED rainbow, plus some random sparkly glitter
     rainbow();
     addGlitter(80);
     }
    
    void addGlitter( fract8 chanceOfGlitter) { if( random8() < chanceOfGlitter) { leds[ random16(NUM_LEDS) ] += CRGB::White; } }
    void confetti() { // random colored speckles that blink in and fade smoothly fadeToBlackBy( leds, NUM_LEDS, 10); int pos = random16(NUM_LEDS); leds[pos] += CHSV( gHue + random8(64), 200, 255); } .....
    Reply

    homer

    • Jul 22, 2020 - 5:24 AM - Hans - Author: Comment Link

      Hi Homer,

      easiest way to do this would be by changing just a few lines (assuming you pasted the functions somewhere at the end of your code, and assuming you’re using FastLED since these functions will not work with neoPixel);

      1) Since we add an effect, we will need to update the effect counter:

      void loop() { 
        EEPROM.get(0,selectedEffect); 
        
        if(selectedEffect>19) { // this was "18"
          selectedEffect=0;
          EEPROM.put(0,0); 
        } 

      2) We will need to catch this new function in the case statement, by adding a new case block.

          case 18 : {
                      // meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay
                      meteorRain(0xff,0xff,0xff,10, 64, true, 30);
                      break;
                    }

      to this (adding “case 19”):

          case 18 : {
                      // meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay
                      meteorRain(0xff,0xff,0xff,10, 64, true, 30);
                      break;
                    }
          case 19 : {
                      rainbowWithGlitter;
                      break;
                    }

      Now you’re not quite done yet, since you may have to fine tune a few things.
      As explained in this article, one of the challenges are the “endless” functions that never return to “void loop()” – and I’m not sure if this would affect your code (specifically the “rainbow” function).
      The way it looks right now: rainbow is called (I assume it creates a rainbow) and only one (or zero) LEDs will be used for the glitter effect and I’d assume you’d probably want more “glitter”.

      If you want to dive deeper in this, please start a forum topic, to avoid that we are posting large chunks of code here. 

      Reply

      Hans

  • Jul 22, 2020 - 10:39 AM - Aimar Romeo Comment Link

    Hi, can anyone do a version to controll by using a smartphone? I’ve been doing one, but it didn’t work very well

    Reply

    Aimar Romeo

    • Jul 23, 2020 - 5:19 AM - Hans - Author: Comment Link

      There are a few folks here (you’ll have to search the comments and/or the forum) who did a setup with cellphone using Bluetooth.

      One of my next projects will be based on an ESP8266 which can be controlled through cellphone/tablet/PC/Mac based on a web interface.
      (the ESP8266 can run a tiny webserver and so far my experiments are working great)

      Reply

      Hans

  • Jul 23, 2020 - 1:23 PM - Daniel Fernandes Comment Link

    For those interested, I have the code that works with the Effects (17 cases), automatically one after the other, as Hans taught me!
    In fact, I would like to use the Blynk program (not Blink) to turn the strip On/Off but I still can’t.

    Reply

    Daniel Fernandes

    • Jul 26, 2020 - 7:19 AM - Hans - Author: Comment Link

      Awesome Daniel! 

      Feel free to post it in the Arduino forum (you can email it to me as well, if you’d prefer not to sign up for the forum)!
      I’m sure others would love to see that 

      I haven’t played with Blynk yet, but I presume it will not provide the option to trigger the interrupt to change effects.
      I am however working on a new project where I use an ESP8266 as a replacement for the Arduino, allowing you to switch effects with a simple web interface.
      That code should be relatively easy to adapt to Blynk or Bluetooth use as well.
      Since it is a lot of work, it may take a few weeks before I post it though (sorry).

      Reply

      Hans

      • Jul 28, 2020 - 9:30 PM - Daniel Fernandes Comment Link

        Thank you very much friend!
        I admire your intelligence for the excellent project and your kindness in putting all your work here for free!
        How can I send the file to you by email?

        Reply

        Daniel Fernandes

      • Jul 29, 2020 - 5:06 AM - Hans - Author: Comment Link

        Hi Daniel,

        ideally the best way would be in the forum (so others can learn something from it as well).
        If you still prefer email, then you can email me at webmaster at tweaking4all dot com. 

        Reply

        Hans

  • Jul 23, 2020 - 8:43 PM - Aimar Romeomeo Comment Link

    Good evening Hans,

    First of all, sorry to bother again and thank you very much for the help you have offered us all and thank you for teaching us. I’ve been looking through a social network called TikTok effects for ws2812 strips. I have come across these 3 effects and I would like to know if you could do the programming. I’ve been trying for a couple of days but I don’t know how to do it. Any help is welcome. I have also asked the author of the video and he replied that since he puts the led strips up for sale with these effects, he cannot give or sell the programming. Thanks for everything!

    Videos:

    Storm effect: https://youtu.be/2GlTI3MUjJk

    Twinkle effect: https://youtu.be/Jh7DD9XYIcc

    Explosion effect: https://youtu.be/uyv2EnIU_m0

    Reply

    Aimar Romeomeo

    • Jul 26, 2020 - 7:31 AM - Hans - Author: Comment Link

      No worries 

      By the looks of it, the 3rd effect may not even be his own. 

      Anyhoo … 

      The Storm effect

      I like this effect and I may include something like this in my new ESP8266 projecy.
      This one reminds me of the Strobe() effect, which can be adjusted something like this (untested) by breaking it up in two pieces (the flashing pattern can even be randomized).

      void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause){
        for(int j = 0; j < StrobeCount; j++) {
          // setAll(red,green,blue);
          for(int counter=0; counter<NUM_LEDS/2; counter++) {
            setPixel(counter, red, green, blue);
          }
        showStrip();
        delay(FlashDelay);
        setAll(0,0,0);
        showStrip();
        for(int counter=NUM_LEDS/2; counter<NUM_LEDS; counter++) {
            setPixel(counter, red, green, blue);
          }
          showStrip();
          delay(FlashDelay);
          setAll(0,0,0);
          showStrip();
          delay(FlashDelay);
        }
       
       delay(EndPause);
      }

      You probably have to play a little with this to find the right settings (timings, number of LEDs, number of sections, sections with or without overlap).

      The Twinkle effect

      It looks like this one relies heavily on the FastLED library and I do not (yet) have a quick code for this. Maybe this effect may do the trick even though it does not seem to be exactly the same? 

      Explosion Effect

      It looks like he may have taken the code from this project.
      Note that this is not the simplest effect … you may run into some issues or challenges.

      Hope this helps – I’ll try to make similar effect for my upcoming ESP8266 pro