LED strip pulse/waterfall effect on input

I am fairly new to arduino coding, I can do a lot of the basics and have been experimenting with LED's, and have started with some addressable LED's. I have an idea for a project but am falling short on how to code one of the main effects I am looking for.
Basically, I want to send a pulse of LED's down the strip on an input, like a button push. So if the button is pushed, a group of like 3 LED's will light up and travel down the strip to the end and stop.
(Reference any waterfall or raindrop effect video here, theres a bunch but no access to codes)
I can find some code examples of the overall effect in a loop, but nothing for an input.

I plan to turn this into a new music reactive effect, with different frequencies of music sending a pulse of different colors down the strip, with a potentiometer to change the speed of the pulse ( like this video LED Strip trail effect - YouTube )

For reference, I am using an arduino uno and the basic addressable LED's with simply the data input, like the ws2812b's. Code examples would be most helpful, as I am better at editing code to meet my specifications than creating my own from scratch

Please help!

1 Like

Sounds easy enough. When the button is pressed, make the first theree leds the colour you want. Also have a "scroll" function which, every few milliseconds, performs a loop where it starts at the end of the strip and works back to the start, copying the colour of each led from the led before it.

Which library are you using? Adafruit or Fastled?

If you can get a sketch working that sets the first 3 leds based on a switch input, and post that, we can help with the scroll function. Use code tags when you post your sketch!

Okay so I am using the FastLED library and have gotten a pulse to go down the strip on a button push/input (sending voltage to pin 7 in my code) as posted below:

#include<FastLED.h>
#define NUM_LEDS 30

CRGBArray<NUM_LEDS> leds;
int INpin = 7;
int input = 0;

void setup()
{
FastLED.addLeds<NEOPIXEL,A0>(leds, NUM_LEDS);
pinMode(INpin, INPUT);
}
void loop() {

input=digitalRead(INpin);
if (input > 0) {
for(int dot = 0; dot <= NUM_LEDS; dot++)
{ leds[dot] = CRGB::Blue;
FastLED.show();
leds[dot] = CRGB::Black;
delay(50); }
}
}

as it is right now, the pulse has to go the whole way down the strip before another can be sent. I am trying to have a pulse go whenever the button is pushed, no matter how far down the previous one is. Also, possibly holding down the button could send a larger pulse and a simple press and release could send a short pulse. Thanks for the help so far

1 Like

What part of "Use code tags when you post your sketch!" did you not understand? Did you think I typed that because I like typing? I try to help and you disrespect me.

Sorry, I am new to the forum and honestly did not know what you meant, but I have looked it up and understand now

So why does your code still not have code tags around it?

OKay, so I have slightly edited what I had, and below (hopefully correctly posted) is the new code. I still cannot figure out how I can start a new cycle with a button push even if the first cycle has not completely finished yet. So what I am trying to do is have the first LED's light up whenever the button is pushed and travel down the strip.

#include<FastLED.h>
#define NUM_LEDS 30

CRGBArray<NUM_LEDS> leds;
int INpin = 7;
int input = 0;

void setup() 
{ 
FastLED.addLeds<NEOPIXEL,A0>(leds, NUM_LEDS); 
pinMode(INpin, INPUT);
}
 void loop() {
  
input=digitalRead(INpin);
if (input > 0) { 
for(int i = 0; i <= NUM_LEDS; i++)   
 {   leds[i] = CRGB::Blue;
     FastLED.show();
     leds[i ] = CRGB::Black;   
     delay(50);   
 }
}   
    }

OK, I have not tested this, let me know what happens:

#include<FastLED.h>
#define NUM_LEDS 30
#define SCROLL_SPEED 50

CRGBArray<NUM_LEDS> leds;

int INpin = 7;
int input = 0;
unsigned long lastUpdate;

void setup() {
  FastLED.addLeds<NEOPIXEL, A0>(leds, NUM_LEDS);
  pinMode(INpin, INPUT);
}

void loop() {

  input = digitalRead(INpin);
  if (input == HIGH)
    leds[0] = CRGB::Blue;
  else
    leds[0] = CRGB::Black;

  if (millis() - lastUpdate > SCROLL_SPEED) {
    lastUpdate += SCROLL_SPEED;
    for (int i = NUM_LEDS - 1; i > 0; i--)
      leds[i] = leds[i - 1];
    FastLED.show();
  }
}
1 Like

PaulRB:
OK, I have not tested this, let me know what happens:

Thanks a ton, that is exactly what I needed. The duration of the button push changes the length of the pulse. Now I can impliment this with different buttons leading to different colors and eventually swapping the buttons for an audio frequency range with the intensity triggering the pulse

You're welcome. What's important to me is that you understand how the code works, so if you have any questions, just ask.

Hi everyone I am fairly new to this arduino coding, I can do a lot of the basics and have been experimenting with regular LED's, however I have ordered the Adafruit Neopixel 12. I need these circuit to work for this project I have at Uni idea for a project but I am struggling on how to code the main effects I am looking for.
So essentially, I want to send a pulse to the LED ring that will beat like a heart, and I have a mini disc motor that will work in sync with this LED. Unfortunately I haven't managed to find anything for this and I need to get this done as soon as possible.

For reference, I am using an arduino uno and the the codes I am using for the LED and Motor have been posted below. If anyone can help than that would be absolutely amazing.
This one is for the LED

#include <Adafruit_NeoPixel.h>
//Hacked from the original Adafruit library demo
 
#define PIN 6   //my control pin
 
// 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(16, PIN, NEO_GRB + NEO_KHZ800);
 
 
 
void setup() {
 strip.begin();
  strip.setBrightness(5); //adjust brightness here
  strip.show(); // Initialize all pixels to 'off'
}
 
void loop() {
  //Start out with a pink brain looking color
  colorWipe(strip.Color(255, 48, 48), 1); // Hot Pink
 
  //Throb read and then fade out
  heartThrob(40);
}
 
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}
 
void rainbow(uint8_t wait) {
  //secret rainbow mode
  uint16_t i, j;
 
  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}
 
 
void heartThrob(uint8_t wait) {
  uint16_t i, j;
 
  //Adjust 60 and 90 to the starting and ending colors you want to fade between. 
  for(j=60; j<90; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}
 
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

And this one is for the motor

Motor is attached to pin 9 in series with a 5.6K resistor
*/
int i = 0;
void setup() { // bring the Motor up nicely from being off
  for(i = 0 ; i <= 15; i+=1)
  {
    analogWrite(9, i);
    delay(5);
  }
}
void loop()
{
  for(i = 15 ; i <= 255; i+=1)
  { 
    analogWrite(9, i);
    if (i > 150) {
      delay(4);
    }
    if ((i > 125) && (i < 151)) {
      delay(5);
    }
    if (( i > 100) && (i < 126)) {
      delay(7);
    }
    if (( i > 75) && (i < 101)) {
      delay(10);
    }
    if (( i > 50) && (i < 76)) {
      delay(14);
    }
    if (( i > 25) && (i < 51)) {
      delay(18);
    }
    if (( i > 1) && (i < 26)) {
      delay(19);
    }
  }
  for(i = 255; i >=15; i-=1)
  {
    analogWrite(9, i);
    if (i > 150) {
      delay(4);
    }
    if ((i > 125) && (i < 151)) {
      delay(5);
    }
    if (( i > 100) && (i < 126)) {
      delay(7);
    }
    if (( i > 75) && (i < 101)) {
      delay(10);
    }
    if (( i > 50) && (i < 76)) {
      delay(14);
    }
    if (( i > 25) && (i < 51)) {
      delay(18);
    }
    if (( i > 1) && (i < 26)) {
      delay(19);
    }
  }
  delay(870);
}

Thank you guys in advance. I appreciate your help

Hi.

Thanks for using code tags. Did you find out about them in the forum sticky post? Because it gives lots of other useful advice about how to get the best help. Links to components, for example. Posting a schematic diagram of your circuit. And you should start your own thread, not hijack someone else's old thread. You can put links to other threads in your own thread to refer to them if you want.

One of the most important things to write in your post is to say what you want help with. You have posted some code and said you need help, but you don't say what/why you need help with, exactly. Do you need to merge these two pieces of code? Have you attempted that and what happened? What exactly do you mean by "in sync"?

Reading your two pieces of code, and assuming that what you want to do is merge them together (while not really understanding how you want to sync them) I can tell you that it is not going to be easy or quick. The problem is this. Both pieces of code were written with the assumption that they would have the Arduino's processing power all to themselves. They were not written to cooperate with other pieces of code and share the processing resource between them. They are both written in a style referred to as "blocking code", because neither will allow other code to run until they have finished running. So both pieces of code will need to be pretty much entirely re-written in a non-blocking style.

On a PC with a multi-core cpu, with a multi-tasking operating system like Windows or Linux, this kind of thing is not a problem. You can have multiple threads running independently and because they are running on different cores or different threads managed by the OS, it's ok for them to use the "blocking" style.

But Arduino has one CPU core and no operating system. So the programmer has to use the more difficult non-blocking style of coding.

There may be a way to avoid re-writing the code. It all depends how you want to achieve this "sync" between the LEDs and motor. Can you describe this idea in more detail?

Hi everyone, I am working on a very similar project am very new to coding. I am also using ws2812b's and arduino uno and a button.

I need the light strip to get a pulse of light to go down and then back up the strip every time the button is pressed and have this continue in a loop. every time the button is pressed a new pulse starts while the previous pulse stays

eg: button pressed --> light pulse goes up and down strip --> button pressed again --> now there are two pulses on the strip.

I undertsand that I have to set a limit on the amount of pulses which can run before a reset but am fine with what ever the max is and do not know how to determine what it will be.

I was going to use if and for loops but i think if i modify the code posted above it would work using the fastled library.

Does anyone have any suggestions of how I should modify it.

I am very new to coding and the project is due soon so any advice/help would be extremely appreciated.

@imaan, please read the advice I gave Designer_D above about thread hijacking.

1 Like