Help with programming

Hey all, very very very new to Arduino and recently took on a project to replace my daytime running lights on my motorcycle with some ws2812 LED strips so i can incorporate sequential signals as well as a “knight rider” effect.

I found the the code online and it belongs to Ionut Fedaceag who created this exactly for this purpose.

After messing with my breadboard and connections all day, I have it working. All the buttons work and send the desired commands but i have two small issues that seem to do more with the programming end…

  1. The knight rider lights will not interrupt the day time running lights, so if DTRL are on, the knight rider lights will not initiate. If DTRL are off they work fine. How could I add an interrupt for this?

  2. How would I go about reversing the sequential order the LED’s illuminate for the left and right signals? They currently sequentially illuminate starting at the wired end and repeat once the end of the strip is reached. I’l like them to start at the end of the strip.

There are only two ws2812 strips with 10 LED’s each in this project.

Not sure how it works on these forums since I just signed up, but I’ll post the code below…

//Modern turn lights v.1.0.0 with arduino and ws2812b by Fedaceag Ionut

#include <FastLED.h> //FastLed library version 3.2.1 - Overview · FastLED/FastLED Wiki · GitHub or http://fastled.io/ with NEOPIXEL or WS2812B
#define NUM_STRIPS 2 // number of led strips (in this example are front left and front right)
#define NUM_LEDS_PER_STRIP 20 // number of leds per each strip
CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP];
uint8_t gHue = 0; // rotating “base color” used by many of the patterns

const int buttonPinL = 2; // turn left
const int buttonPinR = 3; // turn right
const int buttonPinEng = 4; // engine on to start day lights
const int buttonPinKnightRider = 5; // knight rider lights

int buttonStateL = 0;
int buttonStateR = 0;
int engineOn = 0;
int KnightRiderState = 0;

int stateL = 0;
int stateR = 0;

uint8_t gBrtL = 0;
uint8_t gBrtR = 0;
int maxBrt = 120; // maxim brightness day lights - from 0 to 255

int delayTurnLedAnim = 25; //delay of each led in turn light animation
int delayTurnLedOff = 250; //delay from animation to black (is used twice)
int delayLedToDayLight = 500; // delay from animation to day light on
int nrAnimAfterOff = 3; // number of animations for a single impulse

void setup() {
//Serial.begin(9600);
pinMode(buttonPinL, INPUT);
pinMode(buttonPinR, INPUT);
pinMode(buttonPinEng, INPUT);
pinMode(buttonPinKnightRider, INPUT);

FastLED.addLeds<NEOPIXEL, 8>(leds[0], NUM_LEDS_PER_STRIP); //led strip for front left
FastLED.addLeds<NEOPIXEL, 9>(leds[1], NUM_LEDS_PER_STRIP); //led strip for front right

attachInterrupt(digitalPinToInterrupt(buttonPinL),btnPressL,RISING); // we use interrupt for instant reaction of turn lights
attachInterrupt(digitalPinToInterrupt(buttonPinR),btnPressR,RISING); // we use interrupt for instant reaction of turn lights

fill_solid(leds[0], NUM_LEDS_PER_STRIP, CRGB::Black); // some led strips are all on at power on, so let’s power them off at boot
fill_solid(leds[1], NUM_LEDS_PER_STRIP, CRGB::Black); // some led strips are all on at power on, so let’s power them off at boot
FastLED.show();
}

void loop() {
// read the input state
buttonStateL = digitalRead(buttonPinL);
buttonStateR = digitalRead(buttonPinR);
KnightRiderState = digitalRead(buttonPinKnightRider);
EVERY_N_MILLISECONDS( 1 ){
engineOn = digitalRead(buttonPinEng);
}

//function for hazard lights
if(stateL != 0 && stateR != 0){

for(int dot = 0; dot < NUM_LEDS_PER_STRIP; dot++) {
leds[0][dot] = 0xff6a00; // color for left turn light
leds[1][dot] = 0xff6a00; // color for right turn light
FastLED.show();
delay(delayTurnLedAnim);
}

delay(delayTurnLedOff);
fill_solid(leds[0], NUM_LEDS_PER_STRIP, CRGB::Black);
fill_solid(leds[1], NUM_LEDS_PER_STRIP, CRGB::Black);
FastLED.show();
delay(delayTurnLedOff);

if(buttonStateL != HIGH || buttonStateR != HIGH){

if(buttonStateL == HIGH){
stateL = 1;
}else{
stateL = 0;
gBrtL = 0;
}

if(buttonStateR == HIGH){
stateR = 1;
}else{
stateR = 0;
gBrtR = 0;
}

if(buttonStateL != HIGH && buttonStateR != HIGH){
delay(delayLedToDayLight);
}

}

//function for left turn lights
}else if(stateL != 0){

if(KnightRiderState == HIGH && engineOn == LOW){
fill_solid(leds[1], NUM_LEDS_PER_STRIP, CRGB::Black);
}

for(int dot = 0; dot < NUM_LEDS_PER_STRIP; dot++) {
leds[0][dot] = 0xff6a00; // color for left turn light
FastLED.show();
delay(delayTurnLedAnim);
}

delay(delayTurnLedOff);
fill_solid(leds[0], NUM_LEDS_PER_STRIP, CRGB::Black);
FastLED.show();
delay(delayTurnLedOff);

stateL++;
if(stateL >= nrAnimAfterOff && buttonStateL != HIGH){
stateL = 0;
gBrtL = 0;
delay(delayLedToDayLight);
}

//function for right turn lights
}else if(stateR != 0){

if(KnightRiderState == HIGH && engineOn == LOW){
fill_solid(leds[0], NUM_LEDS_PER_STRIP, CRGB::Black);
}

for(int dot = 0; dot < NUM_LEDS_PER_STRIP; dot++) {
leds[1][dot] = 0xff6a00; // color for right turn light
FastLED.show();
delay(delayTurnLedAnim);
}

delay(delayTurnLedOff);
fill_solid(leds[1], NUM_LEDS_PER_STRIP, CRGB::Black);
FastLED.show();
delay(delayTurnLedOff);

stateR++;
if(stateR >= nrAnimAfterOff && buttonStateR != HIGH){
stateR = 0;
gBrtR = 0;
delay(delayLedToDayLight);
}

}else{

if(stateL == 0 && engineOn == HIGH){
if(gBrtL <= maxBrt){
EVERY_N_MILLISECONDS( 1 ) { gBrtL++; }
fill_solid( leds[0], NUM_LEDS_PER_STRIP, CHSV(0,0,gBrtL));
FastLED.show();
}
}else{
if(gBrtL > 0){
EVERY_N_MILLISECONDS( 1 ) { gBrtL–; }
fill_solid( leds[0], NUM_LEDS_PER_STRIP, CHSV(0,0,gBrtL));
FastLED.show();
}else{
if(KnightRiderState == HIGH){
gHue = 0;
//EVERY_N_MILLISECONDS( 20 ) { gHue++; }
fadeToBlackBy( leds[0], NUM_LEDS_PER_STRIP, 20);
int pos = beatsin16( 30, 0, NUM_LEDS_PER_STRIP-1 );
leds[0][pos] += CHSV( gHue, 255, 192);
FastLED.show();
}
}
}

if(stateR == 0 && engineOn == HIGH){
if(gBrtR <= maxBrt){
EVERY_N_MILLISECONDS( 1 ) { gBrtR++; }
fill_solid( leds[1], NUM_LEDS_PER_STRIP, CHSV(0,0,gBrtR));
FastLED.show();
}
}else{
if(gBrtR > 0){
EVERY_N_MILLISECONDS( 1 ) { gBrtR–; }
fill_solid( leds[1], NUM_LEDS_PER_STRIP, CHSV(0,0,gBrtR));
FastLED.show();
}else{
if(KnightRiderState == HIGH){
gHue = 0;
//EVERY_N_MILLISECONDS( 20 ) { gHue++; }
fadeToBlackBy( leds[1], NUM_LEDS_PER_STRIP, 20);
int pos = beatsin16( 30, 0, NUM_LEDS_PER_STRIP-1 );
leds[1][pos] += CHSV( gHue, 255, 192);
FastLED.show();
}
}
}
}
}

void btnPressL(){
stateL = 1;
for(int nr = 0; nr < 1500; nr++) {
buttonStateR = digitalRead(buttonPinR);
if(buttonStateR == 1){
stateR = 1;
}
}
}

void btnPressR(){
stateR = 1;
for(int nr = 0; nr < 1500; nr++) {
buttonStateL = digitalRead(buttonPinL);
if(buttonStateL == 1){
stateL = 1;
}
}
}

Read the sticky at the top of the forum “Read this before posting a programming question”.

If you post your code as described in the how to use this forum sticky, more forum members will read it.

Likewise, post your schematic in CAD or a picture of a hand drawn circuit in jpg or png. PLEASE- not a pretty Fritzing picture.

Your nomenclature is confusing. You don’t use interrupts as your question implies, and you reference functions in your comments where there are no functions. It adds to confusing when we use the same words for different meanings.

I would not put so much in the loop() function. I would reorganize the program where your comments say function, make a real function. You make decisions in the loop() function (AKA State Table) and call the functions as needed. When you organize your program this way, a coherent logic flow becomes more obvious.

On to your questions.

  1. What is DTRL? It’s not mentioned anywhere in the code. If it’s a logic level, then when you detect it in loop() just set the LEDs to black. No interrupt required.
  2. Since you are using for loops to control the blink, just reverse the logic.
 for(int dot = 0; dot < NUM_LEDS_PER_STRIP; dot++) {

becomes

 for(int dot = NUM_LEDS_PER_STRIP; dot >0; dot--) {

There are only two ws2812 strips with 10 LED’s each in this project.

#define NUM_LEDS_PER_STRIP 20              // number of leds per each strip

Not sure how it works on these forums since I just signed up, but I’ll post the code below…

Posting code within </> code-tags is one of the things.

  1. The knight rider lights will not interrupt the day time running lights, so if DTRL are on, the knight rider lights will not initiate. If DTRL are off they work fine. How could I add an interrupt for this?

As Steve already mentioned you don’t need an interrupt (as if that would help at all anyway) You only call (or actually conditionally executed the section) the Knightrider function (section, but it should be a function)

 if(gBrtR <= maxBrt){     
        EVERY_N_MILLISECONDS( 1 ) { gBrtR++; }
        fill_solid( leds[1], NUM_LEDS_PER_STRIP, CHSV(0,0,gBrtR));
        FastLED.show();  
      }     
    }else{
      if(gBrtR > 0){        
        EVERY_N_MILLISECONDS( 1 ) { gBrtR--; }
        fill_solid( leds[1], NUM_LEDS_PER_STRIP, CHSV(0,0,gBrtR));
        FastLED.show();
      }else{
        if(KnightRiderState == HIGH){          
          gHue = 0;
          //EVERY_N_MILLISECONDS( 20 ) { gHue++; }
          fadeToBlackBy( leds[1], NUM_LEDS_PER_STRIP, 20);
          int pos = beatsin16( 30, 0, NUM_LEDS_PER_STRIP-1 );
          leds[1][pos] += CHSV( gHue, 255, 192);
          FastLED.show();
        }

if these other 2 conditions are not met. (with the ‘else’) That is where you can modify the condition(s).

  1. What is DTRL?

Day Time Running Lights ? sometimes the answer is more obvious than what our mind comes up with.

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