// https://www.reddit.com/r/FastLED/comments/128nm00/code_help_request_v20/
// Included Libraries
#include <FastLED.h>
// Output Pin Definitions
#if defined(__AVR_ATmega328P__)
// use these pins on a Uno/Nano
#define LEFT_STRIP_PIN 2
#define RIGHT_STRIP_PIN 3
#define BRAKE_PIN 4
#define RIGHT_TURN_PIN 5
#define LEFT_TURN_PIN 6
#define PIN_CONFIG INPUT_PULLUP
#else
// otherwise use these pins
#define LEFT_STRIP_PIN 12
#define RIGHT_STRIP_PIN 14
// Input Pin Definitions
#define BRAKE_PIN 18
#define RIGHT_TURN_PIN 19
#define LEFT_TURN_PIN 21
#define PIN_CONFIG INPUT_PULLDOWN
#endif
// This Must Do Something
#define NUM_LEDS 48
CRGB leftStrip[NUM_LEDS];
CRGB rightStrip[NUM_LEDS];
//Enumeration States
enum State {
Running,
BrakeandLeftSignal,
BrakeandRightSignal,
Braking,
LeftSignal,
RightSignal,
Hazzard
};
// Arrays For The Led's. Left and Right have their own pattern and should not overlap when commanded
const uint8_t RunningArray_L[] = { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 };
const uint8_t RunningArray_R[] = { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 };
const uint8_t MarkerArray_L[] = { 15, 16, 17, 18, 47, 46 };
const uint8_t MarkerArray_R[] = { 15, 16, 17, 18, 47, 46 };
const uint8_t SignalArray_L[] = { 1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 15, 16, 17, 18, 20, 21, 23, 24, 26, 27, 29, 30, 34, 35, 37, 38, 40, 41, 43, 44, 46, 47 };
const uint8_t SignalArray_R[] = { 1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 15, 16, 17, 18, 20, 21, 23, 24, 26, 27, 29, 30, 34, 35, 37, 38, 40, 41, 43, 44, 46, 47 };
const uint8_t BrakeArray_L[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 };
const uint8_t BrakeArray_R[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 };
uint8_t strobeCount = 0;
void setup() {
Serial.begin(115200);
pinMode(BRAKE_PIN, PIN_CONFIG);
pinMode(LEFT_TURN_PIN, PIN_CONFIG);
pinMode(RIGHT_TURN_PIN, PIN_CONFIG);
FastLED.addLeds<WS2812B, LEFT_STRIP_PIN, GRB>(leftStrip, NUM_LEDS);
FastLED.addLeds<WS2812B, RIGHT_STRIP_PIN, GRB>(rightStrip, NUM_LEDS);
// Show the order the LEDs are connected
for (uint8_t ledno = 0; ledno < NUM_LEDS; ledno++) {
leftStrip[ledno] = CRGB::White;
rightStrip[ledno] = CRGB::White;
FastLED.show();
leftStrip[ledno] = CRGB::Black;
rightStrip[ledno] = CRGB::Black;
delay(25);
}
FastLED.clear(true);
}
void loop() {
// FastLED.clear(true); // Clear all Led's and prep for new state
FastLED.clear(); // Clear the LEDs buffers, but don't send them to prevent flickering to black constantly
static State lastState = -1;
State currentState = getCurrentState();
if (lastState != currentState) {
Serial.println(currentState);
lastState = currentState;
}
switch (currentState) {
case Running:
displayRunningLights();
break;
case Braking:
displayBrakingLights();
break;
case LeftSignal:
displayLeftSignalLights();
break;
case RightSignal:
displayRightSignalLights();
break;
case BrakeandLeftSignal:
displayBrakingAndLeftSignalLights();
break;
case BrakeandRightSignal:
displayBrakingAndRightSignalLights();
break;
case Hazzard:
displayLeftSignalLightsAndRightSignalLights();
break;
}
FastLED.show();
}
State getCurrentState() {
static bool wasBraking = false;
bool brakePinLow = digitalRead(BRAKE_PIN) == HIGH;
bool leftTurnPinLow = digitalRead(LEFT_TURN_PIN) == HIGH;
bool rightTurnPinLow = digitalRead(RIGHT_TURN_PIN) == HIGH;
if (!brakePinLow && wasBraking) {
wasBraking = false;
resetStrobeCount();
}
if (brakePinLow && leftTurnPinLow) {
wasBraking = false;
return BrakeandLeftSignal;
}
if (brakePinLow && rightTurnPinLow) {
wasBraking = false;
return BrakeandRightSignal;
}
if (leftTurnPinLow && rightTurnPinLow) {
return Hazzard;
}
if (brakePinLow) {
wasBraking = true;
return Braking;
}
if (leftTurnPinLow) {
return LeftSignal;
}
if (rightTurnPinLow) {
return RightSignal;
}
else {
return Running;
}
}
void resetStrobeCount() {
strobeCount = 0;
}
// Display Functions and Patterns.
void displayRunningLights() {
applyLightPattern(RunningArray_L, leftStrip, 0, 255, 150, sizeof(RunningArray_L) / sizeof(RunningArray_L[0]));
applyLightPattern(RunningArray_R, rightStrip, 0, 255, 150, sizeof(RunningArray_R) / sizeof(RunningArray_R[0]));
applyLightPattern(MarkerArray_L, leftStrip, 32, 255, 150, sizeof(MarkerArray_L) / sizeof(MarkerArray_L[0]));
applyLightPattern(MarkerArray_R, rightStrip, 32, 255, 150, sizeof(MarkerArray_R) / sizeof(MarkerArray_R[0]));
}
void displayBrakingLights() {
static bool strobeOn = false;
static unsigned long lastStrobeChange = 0;
unsigned long currentTime = millis();
uint8_t strobeValue = strobeOn ? 255 : 0;
if (strobeCount < 5) {
if (currentTime - lastStrobeChange >= 75) { // 75ms strobe interval, adjust for desired frequency
strobeOn = !strobeOn;
lastStrobeChange = currentTime;
if (!strobeOn) {
strobeCount++;
}
}
} else {
strobeValue = 255;
}
applyLightPattern(BrakeArray_L, leftStrip, 0, 255, strobeValue, sizeof(BrakeArray_L) / sizeof(BrakeArray_L[0]));
applyLightPattern(BrakeArray_R, rightStrip, 0, 255, strobeValue, sizeof(BrakeArray_R) / sizeof(BrakeArray_R[0]));
}
void displayLeftSignalLights() {
applyLightPattern(SignalArray_L, leftStrip, 32, 255, 255, sizeof(SignalArray_L) / sizeof(SignalArray_L[0]));
applyLightPattern(MarkerArray_L, leftStrip, 32, 255, 255, sizeof(MarkerArray_L) / sizeof(MarkerArray_L[0]));
applyLightPattern(RunningArray_R, rightStrip, 0, 255, 150, sizeof(RunningArray_R) / sizeof(RunningArray_R[0]));
applyLightPattern(MarkerArray_R, rightStrip, 32, 255, 150, sizeof(MarkerArray_R) / sizeof(MarkerArray_R[0]));
}
void displayRightSignalLights() {
applyLightPattern(SignalArray_R, rightStrip, 32, 255, 255, sizeof(SignalArray_R) / sizeof(SignalArray_R[0]));
applyLightPattern(MarkerArray_R, rightStrip, 32, 255, 255, sizeof(MarkerArray_R) / sizeof(MarkerArray_R[0]));
applyLightPattern(RunningArray_L, leftStrip, 0, 255, 150, sizeof(RunningArray_L) / sizeof(RunningArray_L[0]));
applyLightPattern(MarkerArray_L, leftStrip, 32, 255, 150, sizeof(MarkerArray_L) / sizeof(MarkerArray_L[0]));
}
void displayBrakingAndLeftSignalLights() {
applyLightPattern(SignalArray_L, leftStrip, 32, 255, 255, sizeof(SignalArray_L) / sizeof(SignalArray_L[0]));
applyLightPattern(MarkerArray_L, leftStrip, 32, 255, 255, sizeof(MarkerArray_L) / sizeof(MarkerArray_L[0]));
applyLightPattern(BrakeArray_R, rightStrip, 0, 255, 255, sizeof(BrakeArray_R) / sizeof(BrakeArray_R[0]));
}
void displayBrakingAndRightSignalLights() {
applyLightPattern(BrakeArray_L, leftStrip, 0, 255, 255, sizeof(BrakeArray_L) / sizeof(BrakeArray_L[0]));
applyLightPattern(SignalArray_R, rightStrip, 32, 255, 255, sizeof(SignalArray_R) / sizeof(SignalArray_R[0]));
applyLightPattern(MarkerArray_R, rightStrip, 32, 255, 255, sizeof(MarkerArray_R) / sizeof(MarkerArray_R[0]));
}
void displayLeftSignalLightsAndRightSignalLights() {
applyLightPattern(MarkerArray_L, leftStrip, 32, 255, 255, sizeof(MarkerArray_L) / sizeof(MarkerArray_L[0]));
applyLightPattern(MarkerArray_R, rightStrip, 32, 255, 255, sizeof(MarkerArray_R) / sizeof(MarkerArray_R[0]));
applyLightPattern(SignalArray_L, leftStrip, 32, 255, 255, sizeof(SignalArray_L) / sizeof(SignalArray_L[0]));
applyLightPattern(SignalArray_R, rightStrip, 32, 255, 255, sizeof(SignalArray_R) / sizeof(SignalArray_R[0]));
}
void applyLightPattern(const uint8_t *array, CRGB *strip, uint8_t h, uint8_t s, uint8_t v, uint8_t arraySize) {
for (int i = 0; i < arraySize; i++) {
strip[array[i]].setHSV(h, s, v);
}
}