Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is no translation for that post!




Simple Sketch Reque...
 
Share:
Notifications
Clear all

Simple Sketch Request


(@bbitz01)
Active Member
Joined: 3 years ago
Posts: 6
Topic starter  

Hello,

First just let me say that I have no prior experience with coding on an Arduino. Recently I purchased an Arduino Nano (or a Chinese Knockoff, actually) and a 5M WS2812B LED strip to make some DIY Computer lights. By messing around with the examples from the Adafruit Neopixel library and the "Arduino – LEDStrip effects for NeoPixel and FastLED" post here on Tweaking4All, I was able to get a lot of effects that I liked. There was one, however, that I couldn't quite figure out.

I'd like a trail effect, much like the "Meteor Rain" effect in the aforementioned post, except I want it to restart back at the front of the strip smoothly instead of stopping at the end of the strip and then restarting again at the beginning, so that if you placed the two ends of the strip next to one another it would be a smooth loop. It would be essentially identical to the effect in this video:

I use the Adafruit Neopixel library, but if it's easier to do with FastLED I'd be glad to switch.

Thanks in advance. 


ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 8 years ago
Posts: 2018
 

Hi bbitz01,

sorry for the late reply - the holidays tend to gobble up a lot of time 

So you basically want the effect to loop around?
I do not have my Arduino near me, so I'm just doing a guess here ... and this example will never leave the function

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {  
  setAll(0,0,0); int i = 0;
   while(true){
    // 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); i++; if(i=NUM_LEDS+NUM_LEDS) { i=0; }
  }
}

Like I said: I haven't tested this, and I hope I didn't make a typo 


ReplyQuote
(@bbitz01)
Active Member
Joined: 3 years ago
Posts: 6
Topic starter  

hans,

If I put in your code correctly (which I'm not sure I did), I have this:

#include <Adafruit_NeoPixel.h>
#define PIN 3
#define NUM_LEDS 81

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  meteorRain(0xff,0xff,0xff,10, 64, true, 30);
}

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {  
  setAll(0,0,0);
  int i = 0;
  
  while(true){
    
    // 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);

    i++;
    if(i=NUM_LEDS+NUM_LEDS) { i=0; }
  }
}

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  
}

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

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
}

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

Unfortunately this just lights up the first LED on my strip white. It doesn't move, fade, etc. Perhaps I've put in the code wrong?

And no need to worry about a late reply, we've all got things to do.


ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 8 years ago
Posts: 2018
 

I'll have to wait until I get home (on a holiday trip right now) to do some testing.
I may have overlooked something. Unfortunately, I do not have my Arduino with me to do testing  ...

Happy New Year!


ReplyQuote
(@bbitz01)
Active Member
Joined: 3 years ago
Posts: 6
Topic starter  

hans,

Any luck with the sketch? I haven't messed with my Arduino in a while, kind of forgot about it if I'm honest.  

Hope you enjoyed your holidays.


ReplyQuote


 Hans
(@hans)
Noble Member Admin
Joined: 8 years ago
Posts: 2018
 

Haha, I had forgotten about it as well ... sorry! 

First of all; I'd recommend using FastLED instead of NeoPixel.
As for the code (still not able to test this myself), I think I may have found a boo-boo ... (3rd line from the bottom, added a "-1");

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {  
  setAll(0,0,0);
  int i = 0;
  
  while(true){
    
    // 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);
    i++;
    if(i=NUM_LEDS+NUM_LEDS-1) { i=0; }
  }
}

But even with that, I would have expected to see at least something happen. Does the strip work properly with other effects?


ReplyQuote
(@bbitz01)
Active Member
Joined: 3 years ago
Posts: 6
Topic starter  

hans,
I'm having the same issue as last time. Using this code (with the part you wrote):

#include <Adafruit_NeoPixel.h>
#define PIN 3
#define NUM_LEDS 81
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  meteorRain(0xff,0xff,0xff,10, 64, true, 30);
}

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {  
  setAll(0,0,0);
  int i = 0;
  
  while(true){
    
    // 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);
    i++;
    if(i=NUM_LEDS+NUM_LEDS-1) { i=0; }
  }
}


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  
}

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

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
}

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

I get this:
http://s61.photobucket.com/user/bbitz01/media/IMG-2406_zpsfa0jhuez.jpg .html?sort=3&o=0
That one light stays just like that and does not fade, flash, change color, move, or anything else.
The strip does work just fine with other effects. With very similar code, using the default meteor rain effect from the post mentioned earlier:

#include <Adafruit_NeoPixel.h>
#define PIN 3
#define NUM_LEDS 81
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  meteorRain(0xff,0xff,0xff,10, 64, true, 30);
}

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

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  
}

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

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
}

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

I get this (the effect is moving around, it's just a still picture):
.html?sort=3&o=1
Perhaps I'm doing something wrong on my end? Additionally, for some reason I've never been able to get FastLED to work, don't know why.  
Thanks.


ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 8 years ago
Posts: 2018
 

Hi bbitz01,

the link of the picture didn't work, and when I changed "http" to "https" I got a picture of PC case ... ?

Anyhoo ... we must be overlooking something simple, although I'm surprised that FastLED isn't working for you. Maybe the knock off Nano is to blame, but I kinda doubt that.
I still do not have my hardware available to test, so let's see what could be wrong with the code. I have moved around code a little to make it more readable for myself ...

This is what should work, or at least should show "something" ....

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {  
int i=0;   setAll(0,0,0);
   while(true) { // was: 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); }  else if (i<j) { setPixel(NUM_LEDS-j, red, green, blue); } // added this so it does "negative" LED positions as well
    }
   
    showStrip();
    delay(SpeedDelay); i++; if(i>=NUM_LEDS+NUM_LEDS) { i=0; }
  }
}

I'm not sure what I'm overlooking if this one doesn't work - then again, it's early in the morning here and I may need some more coffee 


ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 8 years ago
Posts: 2018
 

p.s. you can also post an image or small video a an attachment ... 

For video I recommend pulling it through HandBrake to get a more efficient file size.


ReplyQuote
(@bbitz01)
Active Member
Joined: 3 years ago
Posts: 6
Topic starter  

hans,

Yes, it is a computer case - the LED strip goes in a ring around the edge (that's why I want the effect to be a full circle instead of cutting off at the end of the strip). You can't see the strip in the first picture, but you can in the second.

Anyways, the code you posted this time did work - the effect the same as the code from the original post, I'm assuming this is what you were going for just to make sure everything works properly. 


ReplyQuote


(@bbitz01)
Active Member
Joined: 3 years ago
Posts: 6
Topic starter  

Did a bit of playing. Removed the while statement and removed the //was, so now it's just for(int i = 0; i < NUM_LEDS+NUM_LEDS; i++) {
The code is as follows:

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {  
  int i=0;
  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); } 
      else if (i<j)
          { setPixel(NUM_LEDS-j, red, green, blue); } // added this so it does "negative" LED positions as well
    }
   
    showStrip();
    delay(SpeedDelay);

    i++;
    if(i>=NUM_LEDS+NUM_LEDS) { i=0; }
  }
}
This also works, thought it isn't a complete loop. The effect also seems to run significantly faster than when the while statement was still there, don't know if that's worth anything.
Also a correction to my previous post, it's the first picture with the strip, not the second.

ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 8 years ago
Posts: 2018
 

Cool to see that you've gotten a little further and I'm sorry that I do not have the ability to test (at the moment).
It shouldn't be impossible to make this loop though.

One note; in your code check out these lines:

i++;
if(i>=NUM_LEDS+NUM_LEDS) { i=0; }

In your case it will keep resetting the for-loop and make it keep going and going and going ...

Under ideal circumstances we'd want the leds to be addressed even when beyond number of LEDs.
What I mean with that; if we have 10 leds, and the counter (i) is goes to the 11th led, then that 11th led should become the first led.

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {  
  int i=0;
  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); } 
      else // try removing this: if (i<j)
          { setPixel(NUM_LEDS-j, red, green, blue); } // added this so it does "negative" LED positions as well
    }
   
    showStrip();
    delay(SpeedDelay);
    i++;
    if(i>=NUM_LEDS+NUM_LEDS) { i=0; }
  }
}

In the "draw meteor" section, you may want to toy with that loop.


ReplyQuote

Like what you see and you'd like to help out? 

The best way to help is of course by assisting others with their questions here in the forum, but you can also help us out in other ways:

- Do your shopping at Amazon, it will not cost you anything extra but may generate a small commission for us,
- send a cup of coffee through PayPal ($5, $10, $20, or custom amount),
- become a Patreon,
- donate BitCoin (BTC), or BitCoinCash (BCH).

Share: