Go Down

Topic: NeoPixel Code Generator (Read 23249 times) previous topic - next topic

Romonaga

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

musclenerdzllc

#16
Aug 14, 2019, 03:21 am Last Edit: Aug 14, 2019, 04:30 pm by 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):

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;
}


Adrianotiger

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...

Adrianotiger

#18
Aug 15, 2019, 03:01 pm Last Edit: Aug 15, 2019, 06:09 pm by Adrianotiger
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.

musclenerdzllc

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;
}


Adrianotiger

#20
Aug 19, 2019, 09:26 am Last Edit: Aug 19, 2019, 10:05 am by Adrianotiger
Unfortunately I does not have any led strip at the moment to test it.

The best way to solve it would be to open an issue on GitHub, so I can see if there is an error in the script itself or in your settings.

For the maths, everything is converted to an integers, and sometimes floats are necessary to have the right result. This could be the case with your settings (so I can change the code, if it is wrong).

But what I see is that, you want fade from one color to another one in just 100ms. With a step of 75ms. This will always show it as blink. If you want fade, you need much more steps. Step should be set between 5 and 20ms (under 5ms, it could be hard and could not be possible on an Arduino mini - so you will have 6 or 10 at the end - if you have also other sensors).

With a step of 5ms and a fade time of 100, this means 20 substeps where you will see color changing. At the moment, you have 1.3333: you will never see a fade in this way.

Edit: 800kHz and LED type are not relevant. On 99% of the projects, 800kHz and NEO_GRB are correct.

samckitt

I tried to use it to make a knight rider type light effect where it goes back & forth.  Code below, it errors compiling on line 113 (    ind = 40 - (strip_0.effStep - j * 0.16) % 40;), error message is:  "invalid operands of types 'double' and 'int' to binary 'operator%'"

I'm not a coder, just like tinkering.  Can someone help me out?  Thx


Code:
#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(165, 8, 165, NEO_GRB + NEO_KHZ800);
struct Loop strip0loop0(2, 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;
   case 1:
          ret = strip0_loop0_eff1();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: 165
   // Steps: 40 - Delay: 50
   // Colors: 2 (255.0.0, 0.0.0)
   // Options: rainbowlen=250, toLeft=true,
 if(millis() - strip_0.effStart < 50 * (strip_0.effStep)) return 0x00;
 float factor1, factor2;
 uint16_t ind;
 for(uint16_t j=0;j<165;j++) {
   ind = strip_0.effStep + j * 0.16;
   switch((int)((ind % 40) / 20)) {
     case 0: factor1 = 1.0 - ((float)(ind % 40 - 0 * 20) / 20);
             factor2 = (float)((int)(ind - 0) % 40) / 20;
             strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 0 * factor1 + 0 * factor2, 0 * factor1 + 0 * factor2);
             break;
     case 1: factor1 = 1.0 - ((float)(ind % 40 - 1 * 20) / 20);
             factor2 = (float)((int)(ind - 20) % 40) / 20;
             strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2, 0 * factor1 + 0 * factor2);
             break;
   }
 }
 if(strip_0.effStep >= 40) {strip_0.Reset(); return 0x03; }
 else strip_0.effStep++;
 return 0x01;
}

uint8_t strip0_loop0_eff1() {
   // Strip ID: 0 - Effect: Rainbow - LEDS: 165
   // Steps: 40 - Delay: 50
   // Colors: 2 (255.0.0, 0.0.0)
   // Options: rainbowlen=250, toLeft=false,
 if(millis() - strip_0.effStart < 50 * (strip_0.effStep)) return 0x00;
 float factor1, factor2;
 uint16_t ind;
 for(uint16_t j=0;j<165;j++) {
   ind = 40 - (strip_0.effStep - j * 0.16) % 40;
   switch((int)((ind % 40) / 20)) {
     case 0: factor1 = 1.0 - ((float)(ind % 40 - 0 * 20) / 20);
             factor2 = (float)((int)(ind - 0) % 40) / 20;
             strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 0 * factor1 + 0 * factor2, 0 * factor1 + 0 * factor2);
             break;
     case 1: factor1 = 1.0 - ((float)(ind % 40 - 1 * 20) / 20);
             factor2 = (float)((int)(ind - 20) % 40) / 20;
             strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2, 0 * factor1 + 0 * factor2);
             break;
   }
 }
 if(strip_0.effStep >= 40) {strip_0.Reset(); return 0x03; }
 else strip_0.effStep++;
 return 0x01;
}

Adrianotiger

It is (another) generator bug.
Replace this:
Code: [Select]
ind = 40 - (strip_0.effStep - j * 0.16) % 40;
With this in your code:
Code: [Select]
ind = 40 - (uint16_t)(strip_0.effStep - j * 0.16) % 40;

But I will update the generator, so it will cast the value to an integer in future.

samckitt

#23
Sep 05, 2019, 04:12 pm Last Edit: Sep 05, 2019, 04:13 pm by samckitt
OK I'll try that.  Thansk

St0ffel

I try to get this code to work...

Unfortunately, I can not get it to work.

Code: [Select]


#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(20, 3, 20, NEO_RGB + NEO_KHZ400);
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: Move - LEDS: 20
    // Steps: 60 - Delay: 50
    // Colors: 0 ()
    // Options: toLeft=false, rotate=true,
  if(millis() - strip_0.effStart < 50 * (strip_0.effStep)) return 0x00;
  uint32_t c = strip_0.strip.getPixelColor(19);
  for(uint16_t j=20-1;j>0;j--)
    strip_0.strip.setPixelColor(j, strip_0.strip.getPixelColor(j-1));
  strip_0.strip.setPixelColor(0, c);
  if(strip_0.effStep >= 60) {strip_0.Reset(); return 0x03; }
  else strip_0.effStep++;
  return 0x01;
}





are they errors in the code or from the generator?

Adrianotiger

I try to get this code to work...

Unfortunately, I can not get it to work.

Code: [Select]


#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(20, 3, 20, NEO_RGB + NEO_KHZ400);
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: Move - LEDS: 20
    // Steps: 60 - Delay: 50
    // Colors: 0 ()
    // Options: toLeft=false, rotate=true,
  if(millis() - strip_0.effStart < 50 * (strip_0.effStep)) return 0x00;
  uint32_t c = strip_0.strip.getPixelColor(19);
  for(uint16_t j=20-1;j>0;j--)
    strip_0.strip.setPixelColor(j, strip_0.strip.getPixelColor(j-1));
  strip_0.strip.setPixelColor(0, c);
  if(strip_0.effStep >= 60) {strip_0.Reset(); return 0x03; }
  else strip_0.effStep++;
  return 0x01;
}





are they errors in the code or from the generator?
Do you get any error message during compiling or does it not work when you try to execute it?

You have just an effect, and this effect will move your leds. But since you never set a color on your leds, they will stay without color ever if you move them.

You have to put a blink, fade or rainbow effect before. Moving a black led, will ever show you something on the strip.

SANTOURYUU_COS

I'm either trying to get a Rainbow effect with only yellow and white.
Nothing seems to wrong with the generated code, no errors shown on Arduino. For the life of me I can't get the LEDs to light up.


Adrianotiger

I'm either trying to get a Rainbow effect with only yellow and white.
Nothing seems to wrong with the generated code, no errors shown on Arduino. For the life of me I can't get the LEDs to light up.

It is hard to say what is wrong. If you can compile the code, the rainbow should work!

But the question is more:
- are you using neopixels? WS2812b?
- did you connected them to PIN 8?
- do you have a led strip with 60 leds?
- did you connected the ground of your led strip to your arduino?

I think it is more an issue with the circuit, read this wiki for more info: https://github.com/Adrianotiger/Neopixel-Effect-Generator/wiki/Arduino,-it's-simple

By the way, today, after a great help, the UI changed completely:


chilled35

Adriano!

What an utterly brilliant little utility you've created! I spent 2 mins last night popping in some values in the simulator on the GitHub repository, then easily two more hours experimenting with the code to see just what was possible.  Great Job!!

However, the application I have in mind requires two chase effects (of different colours) which loop up and down (actually around, my project is a black disc hovering in front of a black wall so the LEDs backlight it) so it looks similar in effect to the image here: https://imgur.com/gallery/raruixm - those arcs of colour rotate around on the screen - so in effect would simply roll up and down a strip.

How 'easy' would it be to code two different coloured chase effects that are sort of tied together that bounce up and down a strip (and even roll over one end back to the opposite end to achieve a circular look?

Adrianotiger

Thank you for trying the tool :D

The best solution would be to add a "chase" effect. Since there is nothing like that for the moment. It would not be hard to add this as effect, and could be a good todo for the next release.

For now, you can for example set 60 LEDS and use only 40 or 60 of them with this code:
Code: [Select]

{"NeoPixelEffects": {
 "strips":[
   {
     "pin" : "9",
     "leds" : "60",
     "frequence" : "800",
     "type" : "NEO_GRB",
     "loop" : [
       {
         "type" : "Loop",
         "looptype" : "time",
         "loopcount" : "1",
         "loop" : [
         {
           "type" : "EffectRainbow",
           "steps" : "137",
           "delay" : "20",
           "colors" : [
              {
                "red" : "0",
                "green" : "0",
                "blue" : "0",
                "white" : "0"
              },
              {
                "red" : "255",
                "green" : "255",
                "blue" : "0",
                "white" : "0"
              },
              {
                "red" : "0",
                "green" : "0",
                "blue" : "0",
                "white" : "0"
              },
              {
                "red" : "0",
                "green" : "0",
                "blue" : "0",
                "white" : "0"
              },
              {
                "red" : "0",
                "green" : "0",
                "blue" : "0",
                "white" : "0"
              }
            ],
           "options" : [
              {
                "name" : "rainbowlen",
                "value" : "60"
              },
              {
                "name" : "toLeft",
                "value" : "false"
              }
            ]
         }
         ]
       },
       {
         "type" : "EffectMove",
         "steps" : "16",
         "delay" : "50",
         "colors" : [

          ],
         "options" : [
            {
              "name" : "toLeft",
              "value" : "false"
            },
            {
              "name" : "rotate",
              "value" : "false"
            }
          ]
       },
       {
         "type" : "EffectMove",
         "steps" : "38",
         "delay" : "50",
         "colors" : [

          ],
         "options" : [
            {
              "name" : "toLeft",
              "value" : "true"
            },
            {
              "name" : "rotate",
              "value" : "false"
            }
          ]
       }
     ]
   }
 ]
}
}


But it is more a hacks, than a good solution :)

With a chase effect, you could also create animations like "K.I.T.T." car.

But at the end you want also create an animation with different colors, not just the same 2, right?

This tool can create only fixed animations, so they will never randomly change color or animation... Or better, not at the moment. Could be another todo ;)

If I find some time, I will try to add the chase effect, ok?

Go Up