Control WS2811 patterns based on input

Hello. I am new to Arduino and am looking for a way to control WS2811 addressable LED's based on whether or not a pin has been shorted

E.G. if a relay shorts pins D7 to ground then it displays a certain pattern. If D8 is shorted then a different pattern is shown. If no pins are shorted I would like it to display a fallback pattern.

I have looked at the Fast LED examples and see in the DemoReel100 calls different functions that loop by...

void rainbow() 
{
  // FastLED's built-in rainbow generator
  fill_rainbow( leds, NUM_LEDS, gHue, 7);
}

Is there a way to define buttons at the beginning of this program and have them only "play" when a pin is shorted?

e.g.

#define PIN_BUTTON_1 7
#define PIN_BUTTON_2 8
#define PIN_BUTTON_3 9

I assume this would be defined as an if statement

e.g.

if PIN_BUTTON_1 = Low then run

void rainbow()
{
// FastLED's built-in rainbow generator
fill_rainbow( leds, NUM_LEDS, gHue, 7);
}

else something

Did i mention I am new to Arduino? I need a little direction or pointed to a guide

By the way. This is for a car wash bay. The idea is to have each cycle of the wash to have its own little show. This can be controlled via a relay going to the arduino. Additionally I want to setup a "runway" display with all green lights leading the vehicle into the wash bay until it is in place. where it then goes all red to indicate to stop. I think I can figure this out once I have the above figured out.

Thanks

Welcome to the forum

if (digitalRead(PIN_BUTTON_1) == LOW)
{
  rainbow();
}

I have the feeling that you're trying to run before you can walk (or even crawl). If so, I suggest that you start working your way through some of the basic examples that come with the IDE; I think that the DigitalReadSerial example should have given you the needed guidance.

I took your and UKHeliBob's advice and looked up the DigitalReadSerial example and came up with this.

#include <FastLED.h>

FASTLED_USING_NAMESPACE

#define DATA_PIN    3
//#define CLK_PIN   4
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS    258
//#define PIN_BUTTON_1 7
//#define PIN_BUTTON_2 8
#define PIN_BUTTON_3 9
#define BRIGHTNESS          96
#define FRAMES_PER_SECOND  120

CRGB leds[NUM_LEDS];




// digital pin 7 has a pushbutton attached to it. Give it a name:
int PIN_BUTTON_1 = 7;
int PIN_BUTTON_2 = 8;
// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // make the pushbutton's pin an input:
  pinMode(PIN_BUTTON_1, INPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input pin:
  int buttonState = digitalRead(PIN_BUTTON_1);

  // print out the state of the button:

if (digitalRead(PIN_BUTTON_1) == LOW)
{
  rainbow();
}
if (digitalRead(PIN_BUTTON_2) == LOW)
{
  juggle();
}
//if (digitalRead(PIN_BUTTON_3) == LOW)
//{
//  sinelon();
//}

  //Serial.println(buttonState); 
  delay(1);  // delay in between reads for stability
}

void rainbow() 
{
  // FastLED's built-in rainbow generator
  fill_rainbow( leds, NUM_LEDS, 7);
}
void juggle() {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, NUM_LEDS, 20);
  uint8_t dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}

But nothing happens. Where did I go wrong?

How are the button pins wired ?

D7 to button - Button to GND
D8 to Button - Button to GND

Start by using pinMode(PIN_BUTTON_1, INPUT_PULLUP); instead of pinMode(PIN_BUTTON_1, INPUT);; repeat for the other buttons. This will prevent that your inputs float.

Next, before calling rainbow(), add a Serial.print so you can see if the button is indeed pressed.

if (digitalRead(PIN_BUTTON_1) == LOW)
{
  Serial.println(F("Calling rainbow()"));
  rainbow();
}

Do the same for the other buttons.

Now test to see if you're buttons work; you should see the serial output.

In you setup, when you started, does rainbow() work? I assume that your original code looked something like below.

...
...
void loop()
{
  rainbow();
}
1 Like

I assume you mean for me to place the pinMode(PIN_BUTTON_1, INPUT_PULLUP); variables into where they are defined like follows

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // make the pushbutton's pin an input:
  pinMode(PIN_BUTTON_1, INPUT_PULLUP);
  pinMode(PIN_BUTTON_2, INPUT_PULLUP);
  pinMode(PIN_BUTTON_3, INPUT_PULLUP);
  pinMode(PIN_BUTTON_4, INPUT_PULLUP);
}

and placing the serial output before each call of the if statement like so.

if (digitalRead(PIN_BUTTON_1) == LOW)
{
  Serial.println(F("Calling rainbow()"));
  rainbow();
}
if (digitalRead(PIN_BUTTON_2) == LOW)
{  
  Serial.println(F("Calling juggle()"));
  juggle();
}
  delay(1);  // delay in between reads for stability
}

Well I did this and nothing happens with the LED's nor do I see anything in the serial output.

Thank you again for helping me with this.

Go another step back; disconnect the WS2811 strip.

void setup()
{
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // make the pushbutton's pin an input:
  pinMode(PIN_BUTTON_1, INPUT_PULLUP);
  pinMode(PIN_BUTTON_2, INPUT_PULLUP);
  pinMode(PIN_BUTTON_3, INPUT_PULLUP);
  pinMode(PIN_BUTTON_4, INPUT_PULLUP);
}

void loop()
{
  if (digitalRead(PIN_BUTTON_1) == LOW)
  {
    Serial.println(F("Calling rainbow()"));
  }
  if (digitalRead(PIN_BUTTON_2) == LOW)
  {  
    Serial.println(F("Calling juggle()"));
  }
}

With that you should see an endless stream of "Calling ..." when you press a button. If that is not the case, check, double check, triple check your wiring.

If that works, add the strip stuff but do not connect the strip. You should still see your serial output; do you?

If yes, add the strip itself.

Note:
You are missing this in setup(); without it your LEDs will never work. Why did you leave it out?

FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);

It was an error on my part. Was cleaning up fixing random errors and accidentally took it out.

I was also missing

FastLED.show();

after

void loop()
{

everything is working as it should now

Thank you for all your help

Great :+1:

Can you post your final code?

I was just doing that

#include <FastLED.h>
FASTLED_USING_NAMESPACE
#define DATA_PIN    3
//#define CLK_PIN   4
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS    258
#define BRIGHTNESS          96
#define FRAMES_PER_SECOND  120
CRGB leds[NUM_LEDS];


// digital pin 7-10 has a pushbutton attached to it. Give it a name:
int PIN_BUTTON_1 = 7;
int PIN_BUTTON_2 = 8;
int PIN_BUTTON_3 = 9;
int PIN_BUTTON_4 = 10;
// the setup routine runs once when you press reset:
void setup() 
{
  FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
  delay(3000); // 3 second delay for recovery
  

  
 // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // make the pushbutton's pin an input:
  pinMode(PIN_BUTTON_1, INPUT_PULLUP);
  pinMode(PIN_BUTTON_2, INPUT_PULLUP);
  pinMode(PIN_BUTTON_3, INPUT_PULLUP);
  pinMode(PIN_BUTTON_4, INPUT_PULLUP);
}

void loop()
{
   // insert a delay to keep the framerate modest
  FastLED.delay(1000/FRAMES_PER_SECOND); 

  FastLED.show();  
  if (digitalRead(PIN_BUTTON_1) == LOW)
{
  Serial.println(F("Calling rainbow()"));
  rainbow();
}
if (digitalRead(PIN_BUTTON_2) == LOW)
{  
  Serial.println(F("Calling juggle()"));
  juggle();
}
  delay(1);  // delay in between reads for stability
}


void rainbow() 
{
  // FastLED's built-in rainbow generator
  fill_rainbow( leds, NUM_LEDS, 7);
}

void rainbowWithGlitter() 
{
  // built-in FastLED rainbow, plus some random sparkly glitter
  Serial.println(F("Calling rainbow add glitter()"));
  rainbow();
  addGlitter(80);
}

void addGlitter( fract8 chanceOfGlitter) 
{
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;
  }
}

void juggle() {
  Serial.println(F("Calling juggle()"));
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, NUM_LEDS, 20);
  uint8_t dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}

I still need to figure out how to setup a default pattern when no button is pressed and create patterns for all the buttons defined. Right now I only have 2 but will be adding more later.

Thank you again for all your help

I have made some progress. I figured out that if you place function after the last function but before the void loop closing } that it will use that as the default pattern

}

  FastLED.show();  
  if (digitalRead(PIN_BUTTON_4) == LOW)
{
  Serial.println(F("Calling cylon()"));
  cylon();
}

rainbow(); //Displays rainbow as default when no button is triggered

}

Issue is that when a button is pressed all of the LED's from the rainbow function are still on.

what is needed to clear all led's before calling a new function?

  if (digitalRead(PIN_BUTTON_1) == LOW) //reads button 1
{
  Serial.println(F("Calling cylon()")); //prints serial status that the button is pressed
//Need something here to clear all leds before calling cylon()
  cylon(); 
}

Call a function to turn off all of the LEDs, such as the FastLED clear() function

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.