NeoPixel Code Generator

I was wondering how much people like the Arduino together with the WS2812 led strips, as you can create a lot of nice effects and items (3d print) with less than 10$.

Once you have to program the Arduino, it begins to be more complicated if you don't find the code ready to use.

So I begun to write a simple led strip effect generator, where you can set how many strips you want and give an effect for each strip.

It is still in development, but if this can help someone, I can put it on github (so everyone can create new effects).

You can test it here:

How use it:

  • Click on "Add Led Strip"
  • Select Arduino Pin and leds quantity.
  • Press "Add Effect"
  • Choose "Rainbow"
  • Press "generate Arduino code" to get a copy-paste code

Transitions between effects would be a nice feature for the future. I am still trying to see if it could be something helpful or not.

Adriano

Well done job!

Github would be nice as other people can co-develop it.

Nice, just used it for my clock. Save a bunch of time from having to code it myself. I think it is a great tool!

Thank you for the feedbacks.
It is now on GitHub :slight_smile:

I need to add a save/load button to save it as XML, add other 2 important effects and add transitions between the effects.

The link is:

Webpage:

Bonjour, c'est un super boulot, pensez vous qu'il serais possible de rajouter des fonctions ?
Ex : bouton, accéléromètre etc... ?

Une interaction sur les néopixel pour modifier les effets en temps réel et non juste par les boucles du programme ?

Hello, this is a great job, do you think it would be possible to add functions?
Ex: button, accelerometer etc ...?

Interaction on neopixel to modify the effects in real time and not just by the loops of the program?

Yes it would be possible. But not in this page. Maybe on a fork or on another page since this was wrote to loop.

I wrote it thinking at that. So you have only 1 function in your loop. If you add some sensors or buttons, you can easely add a switch to your loop and execute the wanted loop depending on the button or sensor you activate.

But would not be difficult to integrate it on this project :slight_smile:

The outputted sketch code causes compile errors if you use the rainbow effect and adjust the parameter sliders, and/or specified a different number of LEDs in the strip to the default setting.

The problem appears to be because the mathematic equation you're passing those parameters to, does not always produce a whole number (integer), but the NeoPixel library is expecting an integer - it does not know how to address LED number 19.888!.

I think the solution is to simply round up the numbers to integer values before using them as parameters to call the NeoPixel library. You can do this by either rounding up the variable after it is output from the equation:
NewVar = Int(OldVar); (Where OldVar is your resulting variable from the equation,
OR
By declaring the variable as an unsigned integer type from the outset:

Unsigned Int x = 1;

This is a great tool, very usefull, is it possible to be able to select individual LED's so they can be assigned individual effects? I am making a Nanoleaf clone and want to be able to configure diferent panels different effects

Is there anyway you can explain this coding? I'm trying to do research to understand how to code neopixels and don't want to just copy and paste. Want to understand what I'm trying to code.

What do you mean with coding?
How to use the library?

There are just 3 steps:
1- set up the strip: led quantity, led type
2- set the LEDS (index + color)
3 - send the data to the led strip

This project just write the code for the step 2.

Hello,

very nice tool!!

I would like to loop a rainbow for 3 seconds. I set the loop options to time and 3 seconds, but the rainbow still keeps showing after 3 seconds.

Who can I do this? Rainbow runs for 3 seconds and then stops.

This code was created:

#include <Adafruit_NeoPixel.h>

class Strip
{
public:
  uint8_t   effect;
  uint8_t   effects;
  uint16_t  effStep;
  unsigned long effStart;
  Adafruit_NeoPixel strip;
  Strip(uint16_t leds, uint8_t pin, uint8_t toteffects) : strip(leds, pin, NEO_GRB + NEO_KHZ800) {
    effect = -1;
    effects = toteffects;
    Reset();
  }
  void Reset(){
    effStep = 0;
    effect = (effect + 1) % effects;
    effStart = millis();
  }
};

struct Loop
{
  uint8_t currentChild;
  uint8_t childs;
  bool timeBased;
  uint16_t cycles;
  uint16_t currentTime;
  Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;}
};

Strip strip_0(32, 3, 32 );
struct Loop strip0loop0(1, true, 3);

//[GLOBAL_VARIABLES]

void setup() {

  //Your setup here:

  strip_0.strip.begin();
}

void loop() {

  //Your code here:

  strips_loop();
}

void strips_loop() {
  if(strip0_loop0() & 0x01)
    strip_0.strip.show();
}

uint8_t strip0_loop0() {
  uint8_t ret = 0x00;
  switch(strip0loop0.currentChild) {
    case 0: 
           ret = strip0_loop0_eff0();break;
  }
  if(ret & 0x02) {
    ret &= 0xfd;
    if(strip0loop0.currentChild + 1 >= strip0loop0.childs) {
      strip0loop0.currentChild = 0;
      if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;}
    }
    else {
      strip0loop0.currentChild++;
    }
  };
  return ret;
}

uint8_t strip0_loop0_eff0() {
    // Strip ID: 0 - Effect: Rainbow - LEDS: 32
    // Steps: 32 - Delay: 20
    // Colors: 3 (255.0.0, 0.255.0, 0.0.255, )
    // Options: toLeft=true, 
  if(millis() - strip_0.effStart < 20 * (strip_0.effStep)) return 0x00;
  float factor1, factor2;
  uint16_t ind;
  for(uint16_t j=0;j<32;j++) {
    ind = strip_0.effStep + j * 1;
    switch((int)((ind % 32) / 10.666666666666666)) {
      case 0: factor1 = 1.0 - ((float)(ind % 32 - 0 * 10.666666666666666) / 10.666666666666666);
              factor2 = (float)((int)(ind - 0) % 32) / 10.666666666666666;
              strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2);
              break;
      case 1: factor1 = 1.0 - ((float)(ind % 32 - 1 * 10.666666666666666) / 10.666666666666666);
              factor2 = (float)((int)(ind - 10.666666666666666) % 32) / 10.666666666666666;
              strip_0.strip.setPixelColor(j, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2);
              break;
      case 2: factor1 = 1.0 - ((float)(ind % 32 - 2 * 10.666666666666666) / 10.666666666666666);
              factor2 = (float)((int)(ind - 21.333333333333332) % 32) / 10.666666666666666;
              strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2);
              break;
    }
  }
  if(strip_0.effStep >= 32) {strip_0.Reset(); return 0x03; }
  else strip_0.effStep++;
  return 0x01;
}

mille81:
Hello,

very nice tool!!

I would like to loop a rainbow for 3 seconds. I set the loop options to time and 3 seconds, but the rainbow still keeps showing after 3 seconds.

Who can I do this? Rainbow runs for 3 seconds and then stops.

Yes, this is because the Arduino code is executed inside a loop. You can add different effects, but at the end it will repeat anything. You can add a sleep of many seconds, but one time it will restart...

This is awesome! Would it be a abundance of work to adapt it to RGBW (red, green, blue, white) LED strips that use the SK6812 version of WS2812B chip?

thegr8revealing:
This is awesome! Would it be a abundance of work to adapt it to RGBW (red, green, blue, white) LED strips that use the SK6812 version of WS2812B chip?

Thanks :slight_smile:
The project was made to see the effects in the Webbrowser, so a JavaScript and an Arduino code are created.
It should not be a big problem to implement also a white component, as the Neopixel-library already has this feature, but how should I show the white component in the browser?

That's a good question. Maybe you can use the 'warm' 3k color to differentiate it from the bright white that can be generated from the combination the RGB set.

That or maybe a small 'w' above the led to indicate the pure white illuminating?

To be honest I'm not sure.

Well, this is a very useful tool. thanks OP.

I cannot seem to get the fade effect to work. The rainbow works fine, but the fade just snaps to the different colors. Can anyone tell me what's wrong? Here's what it output (please note that for power constraints I cannot take the colors higher than 50):

Here's the code for the effects portion:

uint8_t strip0_loop0_eff1() {
// Strip ID: 0 - Effect: Fade - LEDS: 32
// Steps: 100 - Delay: 10
// Colors: 2 (50.0.0, 0.50.0, )
// Options: duration=1000, every=1,
if(millis() - strip_0.effStart < 10 * (strip_0.effStep)) return 0x00;
uint8_t r,g,b;
double e;
e = (strip_0.effStep * 10) / 1000;
r = 0 * ( e ) + 50 * ( 1.0 - e );
g = 50 * ( e ) + 0 * ( 1.0 - e );
b = 0 * ( e ) + 0 * ( 1.0 - e );
for(uint16_t j=0;j<32;j++) {
if((j % 1) == 0)
strip_0.strip.setPixelColor(j, 50, 0, 0);
else
strip_0.strip.setPixelColor(j, 0, 0, 0);
}
if(strip_0.effStep >= 100) {strip_0.Reset(); return 0x03; }
else strip_0.effStep++;
return 0x01;
}

uint8_t strip0_loop0_eff2() {
// Strip ID: 0 - Effect: Fade - LEDS: 32
// Steps: 100 - Delay: 10
// Colors: 2 (0.50.0, 0.0.50, )
// Options: duration=1000, every=1,
if(millis() - strip_0.effStart < 10 * (strip_0.effStep)) return 0x00;
uint8_t r,g,b;
double e;
e = (strip_0.effStep * 10) / 1000;
r = 0 * ( e ) + 0 * ( 1.0 - e );
g = 0 * ( e ) + 50 * ( 1.0 - e );
b = 50 * ( e ) + 0 * ( 1.0 - e );
for(uint16_t j=0;j<32;j++) {
if((j % 1) == 0)
strip_0.strip.setPixelColor(j, 0, 50, 0);
else
strip_0.strip.setPixelColor(j, 0, 0, 0);
}
if(strip_0.effStep >= 100) {strip_0.Reset(); return 0x03; }
else strip_0.effStep++;
return 0x01;
}

uint8_t strip0_loop0_eff3() {
// Strip ID: 0 - Effect: Fade - LEDS: 32
// Steps: 100 - Delay: 10
// Colors: 2 (0.0.50, 25.25.0, )
// Options: duration=1000, every=1,
if(millis() - strip_0.effStart < 10 * (strip_0.effStep)) return 0x00;
uint8_t r,g,b;
double e;
e = (strip_0.effStep * 10) / 1000;
r = 25 * ( e ) + 0 * ( 1.0 - e );
g = 25 * ( e ) + 0 * ( 1.0 - e );
b = 0 * ( e ) + 50 * ( 1.0 - e );
for(uint16_t j=0;j<32;j++) {
if((j % 1) == 0)
strip_0.strip.setPixelColor(j, 0, 0, 50);
else
strip_0.strip.setPixelColor(j, 0, 0, 0);
}
if(strip_0.effStep >= 100) {strip_0.Reset(); return 0x03; }
else strip_0.effStep++;
return 0x01;
}

uint8_t strip0_loop0_eff4() {
// Strip ID: 0 - Effect: Fade - LEDS: 32
// Steps: 100 - Delay: 10
// Colors: 2 (25.25.0, 50.0.0, )
// Options: duration=1000, every=1,
if(millis() - strip_0.effStart < 10 * (strip_0.effStep)) return 0x00;
uint8_t r,g,b;
double e;
e = (strip_0.effStep * 10) / 1000;
r = 50 * ( e ) + 25 * ( 1.0 - e );
g = 0 * ( e ) + 25 * ( 1.0 - e );
b = 0 * ( e ) + 0 * ( 1.0 - e );
for(uint16_t j=0;j<32;j++) {
if((j % 1) == 0)
strip_0.strip.setPixelColor(j, 25, 25, 0);
else
strip_0.strip.setPixelColor(j, 0, 0, 0);
}
if(strip_0.effStep >= 100) {strip_0.Reset(); return 0x03; }
else strip_0.effStep++;
return 0x01;
}

Hi MuscleNerd,
Did you changed something in the code? It is completely wrong... It will never fade but only jump from one color to the other.
Tomorrow I will check it and update the code.

An export and import function would also be a nice feature, I think...

musclenerdzllc:
I cannot seem to get the fade effect to work. The rainbow works fine, but the fade just snaps to the different colors. Can anyone tell me what's wrong? Here's what it output (please note that for power constraints I cannot take the colors higher than 50):

I updated the code. Can you try the new version?

I will add the possibility to export and import the script as json in future and to measure the RAM you will use for your script.

Edit: import and export are available now.

Thanks for the update! To answer your question: No, I just used the output from the code generator. It still just snap to the next color. Here's what it output this time:

Here's just a red to green fade. It just quickly blinks (what looks like) green and then goes back to red. I tried varying 800 and 400 MHz. And different neopixel types. No luck.

#include <Adafruit_NeoPixel.h>

class Strip
{
public:
uint8_t effect;
uint8_t effects;
uint16_t effStep;
unsigned long effStart;
Adafruit_NeoPixel strip;
Strip(uint16_t leds, uint8_t pin, uint8_t toteffects, uint16_t striptype) : strip(leds, pin, striptype) {
effect = -1;
effects = toteffects;
Reset();
}
void Reset(){
effStep = 0;
effect = (effect + 1) % effects;
effStart = millis();
}
};

struct Loop
{
uint8_t currentChild;
uint8_t childs;
bool timeBased;
uint16_t cycles;
uint16_t currentTime;
Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;}
};

Strip strip_0(70, 8, 70, NEO_GRB + NEO_KHZ800);
struct Loop strip0loop0(1, false, 1);

//[GLOBAL_VARIABLES]

void setup() {

//Your setup here:

strip_0.strip.begin();
}

void loop() {

//Your code here:

strips_loop();
}

void strips_loop() {
if(strip0_loop0() & 0x01)
strip_0.strip.show();
}

uint8_t strip0_loop0() {
uint8_t ret = 0x00;
switch(strip0loop0.currentChild) {
case 0:
ret = strip0_loop0_eff0();break;
}
if(ret & 0x02) {
ret &= 0xfd;
if(strip0loop0.currentChild + 1 >= strip0loop0.childs) {
strip0loop0.currentChild = 0;
if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;}
}
else {
strip0loop0.currentChild++;
}
};
return ret;
}

uint8_t strip0_loop0_eff0() {
// Strip ID: 0 - Effect: Fade - LEDS: 70
// Steps: 1.3333333333333333 - Delay: 75
// Colors: 2 (50.0.0, 0.50.0)
// Options: duration=100, every=1,
if(millis() - strip_0.effStart < 75 * (strip_0.effStep)) return 0x00;
uint8_t r,g,b;
double e;
e = (strip_0.effStep * 75) / 100;
r = ( e ) * 0 + 50 * ( 1.0 - e );
g = ( e ) * 50 + 0 * ( 1.0 - e );
b = ( e ) * 0 + 0 * ( 1.0 - e );
for(uint16_t j=0;j<70;j++) {
if((j % 1) == 0)
strip_0.strip.setPixelColor(j, r, g, b);
else
strip_0.strip.setPixelColor(j, 0, 0, 0);
}
if(strip_0.effStep >= 1.3333333333333333) {strip_0.Reset(); return 0x03; }
else strip_0.effStep++;
return 0x01;
}