//Modern turn lights v.3.2.0 for scooters and motorcycles with arduino and ws2812b - by Fedaceag Ionut ( Youtube - Think small, build big! )
#include <FastLED.h> //FastLed library version 3.2.1 - https://github.com/FastLED/FastLED/wiki/Overview or http://fastled.io/ with NEOPIXEL or WS2812B
#define Num_LED 18 // number of leds for the big strip - should be the at least the number of leds from the small strips multiply by tree (in this case the minimum should be 10 x 3 = 30 leds)
#define Blinker_LED 4 // number of leds for the small strips
CRGB ledsA[Num_LED];
//input pins
const int Button_Left = A1; // turn left
const int Button_Right = A2; // turn right
const int Button_Reverse = A4; // engine on to start day lights
const int Button_Brake = A3; // brake lights
const int Button_Park = A0; // tail lights
int halfOfLeds = (Num_LED / 2);
int buttonStateL = 0;
int buttonStateR = 0;
int ReverseOn = 0;
int Brake = 0;
int ParkLight = 0;
int leftLeds = 0;
int rightLeds = 0;
int tailLeft = halfOfLeds - 1;
int tailRight = halfOfLeds;
int brakeToOffL = 0;
int brakeToOffR = 0;
int stateLT = 0;
int stateRT = 0;
uint8_t gBrtL = 0;
uint8_t gBrtR = 0;
// The RGB color codes can be found here https://github.com/FastLED/FastLED/wiki/Pixel-reference
unsigned long turnColor = CRGB::Orange; // turn signal color
int maxBrt = 254; // maxim brightness day lights - from 0 to 254
int maxBrtBrake = 254; // maxim brightness Brake lights - from 0 to 254
int maxBrtParkLight = 70; // maxim brightness tail lights - from 0 to 254
int delayTurnLedAnim = 50; //delay of each led in turn light animation
int delayTurnLedOff = 250; //delay from animation to black (is used twice)
int delayLedToDayLight = 250; //delay from animation to day light on
int ParkDelay = 100; //delay for animation tail lights on or off
int nrAnimAfterOff = 2; //number of animations for a single impulse
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long currentMillisSC = 0;
unsigned long previousMillisSC = 0;
void setup() {
pinMode(Button_Left, INPUT);
pinMode(Button_Right, INPUT);
pinMode(Button_Reverse, INPUT);
pinMode(Button_Brake, INPUT);
pinMode(Button_Park, INPUT);
FastLED.addLeds<NEOPIXEL, 2>(ledsA, Num_LED); //big led strip rear turn signals, brake light, tail lights
attachInterrupt(digitalPinToInterrupt(Button_Left), btnPressL, RISING); // we use interrupt for instant reaction of turn lights
attachInterrupt(digitalPinToInterrupt(Button_Right), btnPressR, RISING); // we use interrupt for instant reaction of turn lights
fill_solid(ledsA, Num_LED, CRGB::Black); // some led strips are all on at power on, so let's power them off at boot
FastLED.show();
start1();
start2();
}
void start1() {
int start = 0;
int end = Num_LED - 1;
while (start < end) {
ledsA[start] = CRGB::Red;
ledsA[end] = CRGB::Red;
FastLED.show();
ledsA[start] = CRGB::Black;
ledsA[end] = CRGB::Black;
EVERY_N_MILLISECONDS(100){
start++;
end--;
}
}
}
void start2() {
int start = Num_LED / 2 - 1;
int end = Num_LED / 2;
while (start >= 0 && end < Num_LED) {
ledsA[start] = CRGB::Red;
ledsA[end] = CRGB::Red;
FastLED.show();
EVERY_N_MILLISECONDS(100){
start--;
end++;
}
}
fill_solid(ledsA, Num_LED, CRGB::Black);
}
void loop() {
// read the input state
buttonStateL = digitalRead(Button_Left);
buttonStateR = digitalRead(Button_Right);
currentMillisSC = millis();
if (buttonStateL == HIGH) {
stateLT = 1;
previousMillisSC = currentMillisSC;
}
if (buttonStateR == HIGH) {
stateRT = 1;
previousMillisSC = currentMillisSC;
}
//function for hazard lights
if (stateLT != 0 && stateRT != 0) {
leftLeds = Blinker_LED - 1;
rightLeds = Num_LED - Blinker_LED;
for (int dot = 0; dot < Blinker_LED; dot++) {
ledsA[leftLeds] = turnColor;
ledsA[rightLeds] = turnColor;
FastLED.show();
currentMillis = previousMillis = millis();
while (previousMillis + delayTurnLedAnim >= currentMillis) {
TailAndBrake();
FastLED.show();
currentMillis = millis();
}
leftLeds--;
rightLeds++;
}
currentMillis = previousMillis = millis();
while (previousMillis + delayTurnLedOff >= currentMillis) {
TailAndBrake();
FastLED.show();
currentMillis = millis();
}
leftLeds = Blinker_LED - 1;
for (int dot = 0; dot < Blinker_LED; dot++) {
ledsA[leftLeds] = 0x000000;
leftLeds--;
}
rightLeds = Num_LED - Blinker_LED;
for (int dot = 0; dot < Blinker_LED; dot++) {
ledsA[rightLeds] = 0x000000;
rightLeds++;
}
FastLED.show();
currentMillis = previousMillis = millis();
while (previousMillis + delayTurnLedOff >= currentMillis) {
TailAndBrake();
FastLED.show();
currentMillis = millis();
}
buttonStateL = digitalRead(Button_Left);
buttonStateR = digitalRead(Button_Right);
stateLT++;
stateRT++;
if (buttonStateL != HIGH || buttonStateR != HIGH || stateLT >= nrAnimAfterOff || stateRT >= nrAnimAfterOff) {
if (buttonStateL == HIGH) {
stateLT = 1;
} else {
stateLT = 0;
gBrtL = 0;
}
if (buttonStateR == HIGH) {
stateRT = 1;
} else {
stateRT = 0;
gBrtR = 0;
}
if (buttonStateL != HIGH && buttonStateR != HIGH) {
currentMillis = previousMillis = millis();
while (previousMillis + delayLedToDayLight >= currentMillis) {
TailAndBrake();
FastLED.show();
currentMillis = millis();
}
leftLeds = Blinker_LED - 1;
rightLeds = Num_LED - Blinker_LED;
tailLeft = Blinker_LED;
tailRight = Num_LED - Blinker_LED;
}
}
//function for left turn lights
} else if (stateLT != 0) {
leftLeds = Blinker_LED - 1;
for (int dot = 0; dot < Blinker_LED; dot++) {
ledsA[leftLeds] = turnColor;
FastLED.show();
currentMillis = previousMillis = millis();
while (previousMillis + delayTurnLedAnim >= currentMillis) {
TailAndBrake();
FastLED.show();
currentMillis = millis();
}
leftLeds--;
}
currentMillis = previousMillis = millis();
while (previousMillis + delayTurnLedOff >= currentMillis) {
TailAndBrake();
FastLED.show();
currentMillis = millis();
}
leftLeds = Blinker_LED - 1;
for (int dot = 0; dot < Blinker_LED; dot++) {
ledsA[leftLeds] = 0x000000;
leftLeds--;
}
FastLED.show();
currentMillis = previousMillis = millis();
while (previousMillis + delayTurnLedOff >= currentMillis) {
TailAndBrake();
FastLED.show();
currentMillis = millis();
}
stateLT++;
if (stateLT >= nrAnimAfterOff && buttonStateL != HIGH) {
stateLT = 0;
gBrtL = 0;
currentMillis = previousMillis = millis();
while (previousMillis + delayLedToDayLight >= currentMillis) {
TailAndBrake();
FastLED.show();
currentMillis = millis();
}
leftLeds = Blinker_LED - 1;
tailLeft = Blinker_LED;
tailRight = Num_LED - Blinker_LED;
}
//function for right turn lights
} else if (stateRT != 0) {
rightLeds = Num_LED - Blinker_LED;
for (int dot = 0; dot < Blinker_LED; dot++) {
ledsA[rightLeds] = turnColor;
FastLED.show();
currentMillis = previousMillis = millis();
while (previousMillis + delayTurnLedAnim >= currentMillis) {
TailAndBrake();
FastLED.show();
currentMillis = millis();
}
rightLeds++;
}
currentMillis = previousMillis = millis();
while (previousMillis + delayTurnLedOff >= currentMillis) {
TailAndBrake();
FastLED.show();
currentMillis = millis();
}
rightLeds = Num_LED - Blinker_LED;
for (int dot = 0; dot < Blinker_LED; dot++) {
ledsA[rightLeds] = 0x000000;
rightLeds++;
}
FastLED.show();
currentMillis = previousMillis = millis();
while (previousMillis + delayTurnLedOff >= currentMillis) {
TailAndBrake();
FastLED.show();
currentMillis = millis();
}
stateRT++;
if (stateRT >= nrAnimAfterOff && buttonStateR != HIGH) {
stateRT = 0;
gBrtR = 0;
currentMillis = previousMillis = millis();
while (previousMillis + delayLedToDayLight >= currentMillis) {
TailAndBrake();
FastLED.show();
currentMillis = millis();
}
rightLeds = Num_LED - Blinker_LED;
tailLeft = Blinker_LED;
tailRight = Num_LED - Blinker_LED;
}
} else {
TailAndBrake();
FastLED.show();
}
}
//function for Brake lights, tail lights
void TailAndBrake() {
Brake = digitalRead(Button_Brake);
ParkLight = digitalRead(Button_Park);
ReverseOn = digitalRead(Button_Reverse);
if (ParkLight == HIGH && Brake == LOW && ReverseOn == LOW) {
if (stateLT == 0 && stateRT == 0) {
if (tailLeft >= 0) {
EVERY_N_MILLISECONDS( ParkDelay ) {
ledsA[tailLeft] = CHSV(0, 255, maxBrtParkLight);
tailLeft--;
}
}
if (tailRight < Num_LED) {
EVERY_N_MILLISECONDS( ParkDelay ) {
ledsA[tailRight] = CHSV(0, 255, maxBrtParkLight);
tailRight++;
}
}
} else if (stateLT != 0 && stateRT != 0) {
if (tailLeft >= Blinker_LED) {
EVERY_N_MILLISECONDS( ParkDelay ) {
ledsA[tailLeft] = CHSV(0, 255, maxBrtParkLight);
tailLeft--;
}
}
if (tailRight < Num_LED - Blinker_LED) {
EVERY_N_MILLISECONDS( ParkDelay ) {
ledsA[tailRight] = CHSV(0, 255, maxBrtParkLight);
tailRight++;
}
}
} else {
if (stateLT != 0) {
if (tailLeft >= Blinker_LED) {
EVERY_N_MILLISECONDS( ParkDelay ) {
ledsA[tailLeft] = CHSV(0, 255, maxBrtParkLight);
tailLeft--;
}
}
if (tailRight < Num_LED) {
EVERY_N_MILLISECONDS( ParkDelay ) {
ledsA[tailRight] = CHSV(0, 255, maxBrtParkLight);
tailRight++;
}
}
}
if (stateRT != 0) {
if (tailLeft >= 0) {
EVERY_N_MILLISECONDS( ParkDelay ) {
ledsA[tailLeft] = CHSV(0, 255, maxBrtParkLight);
tailLeft--;
}
}
if (tailRight < Num_LED - Blinker_LED) {
EVERY_N_MILLISECONDS( ParkDelay ) {
ledsA[tailRight] = CHSV(0, 255, maxBrtParkLight);
tailRight++;
}
}
}
}
} else if (Brake == HIGH) {
if (stateLT == 0 && stateRT == 0) {
fill_solid( ledsA, Num_LED, CHSV(0, 255, maxBrtBrake));
} else if (stateLT != 0 && stateRT != 0) {
for (int i = Blinker_LED; i < halfOfLeds; i++) {
ledsA[i] = CHSV(0, 255, maxBrtBrake);
}
for (int i = halfOfLeds; i < Num_LED - Blinker_LED; i++) {
ledsA[i] = CHSV(0, 255, maxBrtBrake);
}
} else {
if (stateLT != 0) {
for (int i = Blinker_LED; i < halfOfLeds; i++) {
ledsA[i] = CHSV(0, 255, maxBrtBrake);
}
for (int i = halfOfLeds; i < Num_LED; i++) {
ledsA[i] = CHSV(0, 255, maxBrtBrake);
}
}
if (stateRT != 0) {
for (int i = halfOfLeds; i < Num_LED - Blinker_LED; i++) {
ledsA[i] = CHSV(0, 255, maxBrtBrake);
}
for (int i = 0; i < halfOfLeds; i++) {
ledsA[i] = CHSV(0, 255, maxBrtBrake);
}
}
}
tailLeft = halfOfLeds - 1;
tailRight = halfOfLeds;
brakeToOffL = 1;
brakeToOffR = 1;
} else if (ReverseOn == HIGH) {
if (stateLT == 0 && stateRT == 0) {
fill_solid( ledsA, Num_LED, CRGB::White);
} else if (stateLT != 0 && stateRT != 0) {
for (int i = Blinker_LED; i < halfOfLeds; i++) {
ledsA[i] = CRGB::White;
}
for (int i = halfOfLeds; i < Num_LED - Blinker_LED; i++) {
ledsA[i] = CRGB::White;
}
} else {
if (stateLT != 0) {
for (int i = Blinker_LED; i < halfOfLeds; i++) {
ledsA[i] = CRGB::White;
}
for (int i = halfOfLeds; i < Num_LED; i++) {
ledsA[i] = CRGB::White;
}
}
if (stateRT != 0) {
for (int i = halfOfLeds; i < Num_LED - Blinker_LED; i++) {
ledsA[i] = CRGB::White;
}
for (int i = 0; i < halfOfLeds; i++) {
ledsA[i] = CRGB::White;
}
}
}
tailLeft = halfOfLeds - 1;
tailRight = halfOfLeds;
brakeToOffL = 1;
brakeToOffR = 1;
} else {
if (tailLeft < halfOfLeds - 1) {
EVERY_N_MILLISECONDS( ParkDelay ) {
tailLeft++;
ledsA[tailLeft] = CHSV(0, 0, 0);
}
} else {
if (stateLT != 0) {
if (brakeToOffL == 1) {
for (int i = Blinker_LED; i < halfOfLeds; i++) {
ledsA[i] = CHSV(0, 0, 0);
}
brakeToOffL = 0;
}
} else {
for (int i = 0; i < halfOfLeds; i++) {
ledsA[i] = CHSV(0, 0, 0);
}
}
}
if (tailRight > halfOfLeds) {
EVERY_N_MILLISECONDS( ParkDelay ) {
tailRight--;
ledsA[tailRight] = CHSV(0, 0, 0);
}
} else {
if (stateRT != 0) {
if (brakeToOffR == 1) {
for (int i = halfOfLeds; i < Num_LED - Blinker_LED; i++) {
ledsA[i] = CHSV(0, 0, 0);
}
brakeToOffR = 0;
}
} else {
for (int i = halfOfLeds; i < halfOfLeds * 2; i++) {
ledsA[i] = CHSV(0, 0, 0);
}
}
}
}
}
//function for left signal interrupt
void btnPressL() {
stateLT = 1;
for (int nr = 0; nr < 1500; nr++) {
buttonStateR = digitalRead(Button_Right);
if (buttonStateR == 1) {
stateRT = 1;
}
}
}
//function for right signal interrupt
void btnPressR() {
stateRT = 1;
for (int nr = 0; nr < 1500; nr++) {
buttonStateL = digitalRead(Button_Left);
if (buttonStateL == 1) {
stateLT = 1;
}
}
}