I'm using an Arduino Uno (Elegoo) and FastLED to animate turn signals onto WS2812B strips. I have two strips, left and right, for the turn signals. These are going onto a motorcycle. I'm using buck converters on the turn signals and brake to send a 3V3 high to pins A0,A1, and A2.
I have a simple(ish) program to do this. I have it set up so that when pin A0 or A1 is high, the corresponding strip runs a For loop that sends a soft orange light pulsing down the strip. This works perfectly except one thing.
A turn signal on a bike will read as "H,L,H,L,H,L......." until the turn signal switch is turned off. There are a few ways I think I can get around this.
One way would be to have it run the loop for (x)ms so that there is a delay between reads. Once there has been a Low for two(three?) consecutive reads, then it goes back to white. This would work pretty well, but it seems pretty sloppy. Not only will this stay on for a time after I've turned the turn signal off, but there is a potential for a mismatch between pulses from the input in the case that the space width varies slightly between reads.
Another way is for the arduino to read the input, run the loop for the animation once, pause, read the input again, and repeat until both reads are 0, then it returns to the DRL function.
I copied and modified code from the "ColorPalette" example from the FastLED library to do most of this. I think that my code could be significantly simplified, and I don't necessarily need to use palettes to achieve what I need, it's just what I found.
How can I do either option? To be honest, I've been poring over this code for a while and it seems to get more confusing the more I look into it. I think there is a lot of redundancy that could be trimmed down. I couldn't figure out where to upload my sketch, but here's my full code.
#include <FastLED.h>
#define LED_PIN_R 5
#define LED_PIN_L 6
#define BRIGHTNESS 200
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define NUM_STRIPS 2
#define NUM_LEDS_PER_STRIP 60
#define NUM_LEDS NUM_LEDS_PER_STRIP * NUM_STRIPS
#define RturnPin A0
#define LturnPin A1
#define brakePin A2
//set up array
CRGB leds[NUM_LEDS];
#define UPDATES_PER_SECOND 100
int blink = 0;
// const int LturnPin = 8;
// const int RturnPin = 9;
// const int brakePin = 7;
int LturnVal = 0;
int RturnVal = 0;
int brakeVal = 0;
// bool lTurn;
// bool rTurn;
// bool brake;
CRGBPalette16 currentPalette;
TBlendType currentBlending;
void setup() {
delay(3000); // power-up safety delay
//Add the LED
FastLED.addLeds<LED_TYPE, LED_PIN_R, COLOR_ORDER>(leds, 0, NUM_LEDS_PER_STRIP).setCorrection(TypicalLEDStrip);
FastLED.addLeds<LED_TYPE, LED_PIN_L, COLOR_ORDER>(leds, NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
pinMode(LturnPin, INPUT);
pinMode(RturnPin, INPUT);
pinMode(brakePin, INPUT);
currentPalette = RainbowColors_p;
currentBlending = LINEARBLEND;
}
void loop() {
whiteOut();
FastLED.show();
LturnVal = digitalRead(LturnPin);
RturnVal = digitalRead(RturnPin);
brakeVal = digitalRead(brakePin);
//Serial.println(LturnVal);
//Serial.println(RturnVal);
static uint8_t startIndex = 0;
startIndex = startIndex + 1; /* motion speed */
DRL(startIndex);
if (LturnVal == 1 & brakeVal == 1) {
turnSignalBrake();
leftTurn(startIndex);
FastLED.show();
//FastLED.delay(1000 / UPDATES_PER_SECOND);
}
if (RturnVal == 1 & brakeVal == 1) {
turnSignalBrake();
rightTurn(startIndex);
FastLED.show();
//FastLED.delay(1000 / UPDATES_PER_SECOND);
} else if (RturnVal && !brakeVal) {
turnSignal();
rightTurn(startIndex);
// FastLED.delay(1000);
FastLED.show();
// FastLED.delay(1000 / UPDATES_PER_SECOND);
} else if (LturnVal && !brakeVal) {
turnSignal();
leftTurn(startIndex);
// FastLED.delay(1000);
FastLED.show();
//FastLED.delay(1000 / UPDATES_PER_SECOND);
}
if (brakeVal == 1 && LturnVal == 0 && RturnVal == 0) {
fill_solid(leds, NUM_LEDS, CRGB::Red);
FastLED.show();
FastLED.delay(100);
} else {
whiteOut();
FastLED.show();
}
}
void rightTurn(uint8_t colorIndex) {
uint8_t brightness = 200;
//Right Turn Signal
for (int i = 0; i < 60; ++i) {
leds[i] = ColorFromPalette(currentPalette, colorIndex, brightness, currentBlending);
colorIndex += 1;
//break;
}
}
void leftTurn(uint8_t colorIndex) {
uint8_t brightness = 200;
//Left Turn Signal
for (int i = 60; i < 120; ++i) {
leds[i] = ColorFromPalette(currentPalette, colorIndex, brightness, currentBlending);
colorIndex += 1;
//break;
}
}
void DRL(uint8_t colorIndex) {
uint8_t brightness = 200;
//Left Turn Signal
for (int i = 0; i < NUM_LEDS; ++i) {
leds[i] = ColorFromPalette(currentPalette, colorIndex, brightness, currentBlending);
colorIndex += 1;
}
}
void turnSignal() {
// 'black out' all 16 palette entries...
fill_solid(currentPalette, 16, CRGB::Black);
// and set every fourth one to white.
int i = 0;
currentPalette[i] = CRGB::DarkOrange;
i = i + 4;
currentPalette[i] = CRGB::DarkOrange;
i = i + 4;
currentPalette[i] = CRGB::DarkOrange;
i = i + 4;
currentPalette[i] = CRGB::DarkOrange;
}
void turnSignalBrake() {
// 'black out' all 16 palette entries...
fill_solid(leds, NUM_LEDS, CRGB::Red);
// FastLED.show();
fill_solid(currentPalette, 16, CRGB::Red);
// and set every fourth one to white.
int i = 0;
currentPalette[i] = CRGB::DarkOrange;
i = i + 4;
currentPalette[i] = CRGB::DarkOrange;
i = i + 4;
currentPalette[i] = CRGB::DarkOrange;
i = i + 4;
currentPalette[i] = CRGB::DarkOrange;
}
void brake() {
// fill_solid( currentPalette, 16, CRGB::Red);
// uint8_t brightness = 255;
// //Left Turn Signal
// for( int i = 0; i < NUM_LEDS; ++i)
// {
// leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
// colorIndex += 1;
// }
/* Function for*/
fill_solid(leds, NUM_LEDS, CRGB::Red);
FastLED.show();
//FastLED.delay(100);
}
void whiteOut() {
fill_solid(currentPalette, 16, CRGB::White);
}