Go Down

Topic: NeoPixel Code Generator (Read 17411 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

Go Up