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...
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.
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;
}
}
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.
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.
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?
#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.
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();
}