Getting LED blinking patterns without DELAY and running code with quick input

Hello, I'm having a hard time figuring out how to get my LEDs to blink in a specific pattern. Specifically, I want them to blink rapidly a few times then remain on steady. The input will be the brake lights from my pickup truck through a voltage divider. So far I've been able to get it to either blink indefinitely (code below) or just stay on steady when I thought it should be blinking.

The second issue I'm having is how to make a block of code run after an input is sensed... but the input has already gone low. This will be the turn signals on the truck. The input goes on and off so fast the code doesn't complete. I want each blink to force it to fade on/off once completely. Surprisingly, I have gotten the fade up/down to work through the use of some tutorials online. It works as expected through my test button. But of course, I can hold down the test button long enough to get a full sequence.

Here is my current code. Where am I going wrong?

/*Adding custom brake illumination to my pickup truck's LED brake bar installed between the tailgate and bumper.

By John Powell (s10blazed) August 2017.

*/

//Input triggers from the truck wiring via voltage dividers.

  const int leftLightTrigger = 5; //The input from the truck to know when to use the left turn signal.  
  const int rightLightTrigger = 6; //The input from the truck to know when to use the right turn signal.  
  const int reverseLightsTrigger = 7; //The input from the truck to know when to use the reverse lights.
  const int brakeLightsTrigger = 8; //The input from the truck to know when to use the brake lights.

//Output pins to activate each MOSFET
  
  const int leftLightAction = 9; //Output pin to activate left MOSFET.
  const int rightLightAction = 10; //Output pin to activate right MOSFET.
  const int reverseLightsAction = 11; //Output pin to activate reverse MOSFET.
  const int brakeLightsAction = 3; //Output pin to activate brake MOSFET.
  
//Strobe states for each action.  Not sure if I actually need these yet.
      
  int brakeStrobeState = LOW; //Assign a state to create a strobing effect as the brake lights illuminate.
  int revStrobeState = LOW; //Assign a state to create a strobing effect as the reverse lights illuminate.
  int leftStrobeState = 0; //Assign a state to create a strobing effect as the left turn signal light illuminate.
  int rightStrobeState = 0; //Assign a state to create a strobing effect as the right turn signal light illuminate.
  
//Setting up timers to start at zero as soon as the board boots up.
  
  unsigned long revMillis = 0;        // Reverse light timer initialization.
  unsigned long leftTurnMillis = 0;   // left turn timer initialization.
  unsigned long rightTurnMillis = 0;  // right turn timer initialization.
  unsigned long brakeMillis = 0;      // brake light timer initialization.
  
//Constants I can change to affect the rate that blinking and fading occurs once I get it working right.
  
  const long interval = 50; //Time that it takes to change the fadeIncrement i.e. speed of fade.
  
  const int minPWM = 125;  //Minimum brightness of the fading LEDs.  
  const int maxPWM = 255; //Max LED brightness.  Just keep it 255.
  
  byte fadeIncrement = 20; //The amount the brightness changes at each interval. i.e. smoothness of fade
  
//The following lines were added because I copied them from Bald Engineer's example of fading LEDs without delay. https://www.baldengineer.com/fading-led-analogwrite-millis-example.html
  
  #define UP 0 // ???
  #define DOWN 1 // ???
 
  byte fadeDirection = UP; //Tells the statement to go from minPWM to maxPWM and gets changed to down after hitting max.
    
void setup() {
        
// Setting up the proper pins as inputs.
        
  pinMode(leftLightTrigger, INPUT);
  pinMode(rightLightTrigger, INPUT);
  pinMode(reverseLightsTrigger, INPUT);
  pinMode(brakeLightsTrigger, INPUT);
  
// Setting up the proper pins as outputs
  
  pinMode(leftLightAction, OUTPUT);
  pinMode(rightLightAction, OUTPUT);
  pinMode(reverseLightsAction, OUTPUT);
  pinMode(brakeLightsAction, OUTPUT);
  
}

void loop() {
  
unsigned long currentMillis = millis(); //Capturing the time at each loop.
  
if (digitalRead(brakeLightsTrigger) == HIGH) { //Determine if the brakes are currently applied
 brakeLights(); //Run the brakeLights function
}  
else {
  digitalWrite(brakeLightsAction, LOW); //Otherwise, turn the lights off when brakes are not applied
}

//Placeholder code for the reverse lights.  Simplifed to test the hardware layout. Will eventually use same format as brake lights
if (digitalRead(reverseLightsTrigger) == HIGH) {
      digitalWrite(reverseLightsAction, HIGH);
    }
    else {
      digitalWrite(reverseLightsAction, LOW);
    }
    
//Right turn signal 
if (digitalRead(rightLightTrigger) == HIGH) { //Checks to determine when right turn signal is activated.  Is only high for a moment
      rightTurnSignal(currentMillis); //Calls right turn signal function and sends the current millis with it
    }
    else {
      digitalWrite(rightLightAction, LOW); //Otherwise the lights should not be on. I might have to run left/right at half PWM for running lights
    }
    
//Placeholder code for left turn signal.  Simplified to test hardware layout.  Will eventually use same format as right turn signal    
if (digitalRead(leftLightTrigger) == HIGH) {
      digitalWrite(leftLightAction, HIGH);
    }
    else {
      digitalWrite(leftLightAction, LOW);
    }
    
}

//Brake Lights function
void brakeLights() {
  
unsigned long currentMillis = millis(); //Getting current millis as brake is pressed

for(int x=0; x<=3; x++) { //I want it to perform 4 quick blinks then remain solid
  
  if (currentMillis - brakeMillis >= interval) { //Checks to see if interval time has elapsed between brake light function call and brakeMillis
    
    brakeMillis = currentMillis; // Set brakeMillis to currentMillis for next iteration of FOR loop

    if (brakeStrobeState == LOW) { // LED should be low on first pass, so set it high
      brakeStrobeState = HIGH; //Set brakeStrobState high to it will light up as the action of blinking

    } else {
      brakeStrobeState = LOW; //If it was high on the last pass, turn it off for blink effect
    }
  
       digitalWrite(brakeLightsAction, brakeStrobeState);  // Make the LED light up with current brakeStrobeState from FOR loop
  }
  
}
   //digitalWrite(brakeLightsAction, HIGH); //When I uncomment this, I expect it to run after the FOR loop.  But the LED just remains HIGH when the trigger is active
}

//Right turn signal function
void rightTurnSignal(unsigned long thisMillis) { //Setting variable thisMillis using the data from the function call in LOOP, currentMillis
  
if (thisMillis - rightTurnMillis >= interval) { //Checking to see if enough time has elapsed to make a change
    
    if (fadeDirection == UP) { //Start by going UP
      rightStrobeState = rightStrobeState + fadeIncrement;  //Increase rightStrobeState by increment amount
      if (rightStrobeState >= maxPWM) { //Increase until it hits full brightness
       
        rightStrobeState = maxPWM; //At max, limit and change direction
        fadeDirection = DOWN; //Changed to DOWN to the else statement proceeds
      }
    } else {
      
      rightStrobeState = rightStrobeState - fadeIncrement; //Decrease rightStrobeState for fade out
      if (rightStrobeState <= minPWM) { //Decrease brightness until it hits minPWM as set above
        
        rightStrobeState = minPWM; //At min limit.  
        fadeDirection = UP; //Change to UP so the original IF statement can begin again
      }
    }

    analogWrite(rightLightAction, rightStrobeState);  //Writing the LED brightness after each check of the IF ELSE statement
     
    rightTurnMillis = thisMillis; //Reset millis for the next iteration
  }
}
for(int x=0; x<=3; x++) { //I want it to perform 4 quick blinks then remain solid
 
  if (currentMillis - brakeMillis >= interval) { //Checks to see if interval time has elapsed between brake light function call and brakeMillis

You can't have multitasking with this kind of programming. A for loop restricts the possible actions to only what is in the for loop while it is running. You can not have any control structures that don't complete rapidly and pass control to the next function in the loop immediately.

You're adding a half hour pit stop to the race. :slight_smile:

you seem to have a good understanding of the basics but your logic is written like its 4 programs that are added together rather than looking at the complete picture

first you have to work out whats most important between indicators and brake lights. If you look at your truck when you indicate and brake at the same time. One light will stay on and the direction you are turning will flash.

so you code should be written to work out which state you need to show.

brakes only
brakes plus right turn
brakes plus left turn
right turn only
left turn only

this piece of code

 if (digitalRead(rightLightTrigger) == HIGH) { //Checks to determine when right turn signal is activated.  Is only high for a moment
    rightTurnSignal(currentMillis); //Calls right turn signal function and sends the current millis with it
  }

only activates when the rightLightTrigger is high so that need to be changed to a pointer

something like

 if (digitalRead(rightLightTrigger) == HIGH) {
   requestRightSignal=1;
  }

then

if (requestRightSignal==1){
  rightTurnSignal();
}

also theres no need to pass currentmillis that has no logical use. (that can be a global updated in loop)

instead it should be something like

 if (digitalRead(rightLightTrigger) == HIGH) {
   requestRightSignal=1;
rightTurnMillis = thisMillis;//prime the timer
  }

now this code will be run all the time until you reset requestRightSignal to 0

if (requestRightSignal==1){
  rightTurnSignal();
}

so in void rightTurnSignal();{
you can do what ever you want until you reset to requestRightSignal to 0
}

so something like this

void rightTurnSignal() { //Setting variable thisMillis using the data from the function call in LOOP, currentMillis
  static byte  rightCounter;
  if (thisMillis - rightTurnMillis >= interval) { //Checking to see if enough time has elapsed to make a change

    if (fadeDirection == UP) { //Start by going UP
      rightStrobeState = rightStrobeState + fadeIncrement;  //Increase rightStrobeState by increment amount
      if (rightStrobeState >= maxPWM) { //Increase until it hits full brightness
        rightCounter++;
        rightStrobeState = maxPWM; //At max, limit and change direction
        fadeDirection = DOWN; //Changed to DOWN to the else statement proceeds
      }
    } else {

      rightStrobeState = rightStrobeState - fadeIncrement; //Decrease rightStrobeState for fade out
      if (rightStrobeState <= minPWM) { //Decrease brightness until it hits minPWM as set above

        rightStrobeState = minPWM; //At min limit.
        fadeDirection = UP; //Change to UP so the original IF statement can begin again
      }
    }
    if (rightCounter >= 3) {//ok faded 3 times time to exit 
      rightCounter = 0;//reset counter as its static 
      requestRightSignal = 0;// this is a global which tells the if in the main loop to block this function

    }

    analogWrite(rightLightAction, rightStrobeState);  //Writing the LED brightness after each check of the IF ELSE statement

    rightTurnMillis = thisMillis; //Reset millis for the next iteration
  }
}

so after working out your inputs to pointers you should have some logic to sort out which pointers are most important.

this is not compliable code its just shows how I would approach the problem.

/*Adding custom brake illumination to my pickup truck's LED brake bar installed between the tailgate and bumper.

  By John Powell (s10blazed) August 2017.

*/

//Input triggers from the truck wiring via voltage dividers.

const int leftLightTrigger = 5; //The input from the truck to know when to use the left turn signal.
const int rightLightTrigger = 6; //The input from the truck to know when to use the right turn signal.
const int reverseLightsTrigger = 7; //The input from the truck to know when to use the reverse lights.
const int brakeLightsTrigger = 8; //The input from the truck to know when to use the brake lights.

//Output pins to activate each MOSFET

const int leftLightAction = 9; //Output pin to activate left MOSFET.
const int rightLightAction = 10; //Output pin to activate right MOSFET.
const int reverseLightsAction = 11; //Output pin to activate reverse MOSFET.
const int brakeLightsAction = 3; //Output pin to activate brake MOSFET.

//Strobe states for each action.  Not sure if I actually need these yet.

int brakeStrobeState = LOW; //Assign a state to create a strobing effect as the brake lights illuminate.
int revStrobeState = LOW; //Assign a state to create a strobing effect as the reverse lights illuminate.
int leftStrobeState = 0; //Assign a state to create a strobing effect as the left turn signal light illuminate.
int rightStrobeState = 0; //Assign a state to create a strobing effect as the right turn signal light illuminate.

//Setting up timers to start at zero as soon as the board boots up.

unsigned long revMillis = 0;        // Reverse light timer initialization.
unsigned long leftTurnMillis = 0;   // left turn timer initialization.
unsigned long rightTurnMillis = 0;  // right turn timer initialization.
unsigned long brakeMillis = 0;      // brake light timer initialization.
unsigned long currentMillis = 0;
//Constants I can change to affect the rate that blinking and fading occurs once I get it working right.

const long interval = 50; //Time that it takes to change the fadeIncrement i.e. speed of fade.

const int minPWM = 125;  //Minimum brightness of the fading LEDs.
const int maxPWM = 255; //Max LED brightness.  Just keep it 255.

byte fadeIncrement = 20; //The amount the brightness changes at each interval. i.e. smoothness of fade

//The following lines were added because I copied them from Bald Engineer's example of fading LEDs without delay. https://www.baldengineer.com/fading-led-analogwrite-millis-example.html

#define UP 0 // tells compiler that the word up means 0 
//so fadeDirection == UP is really saying fadeDirection == 0
#define DOWN 1 // ???

byte brakeCounter=0;
byte  rightCounter=0;

byte fadeDirection = UP; //Tells the statement to go from minPWM to maxPWM and gets changed to down after hitting max.

void setup() {

  // Setting up the proper pins as inputs.

  pinMode(leftLightTrigger, INPUT);
  pinMode(rightLightTrigger, INPUT);
  pinMode(reverseLightsTrigger, INPUT);
  pinMode(brakeLightsTrigger, INPUT);

  // Setting up the proper pins as outputs

  pinMode(leftLightAction, OUTPUT);
  pinMode(rightLightAction, OUTPUT);
  pinMode(reverseLightsAction, OUTPUT);
  pinMode(brakeLightsAction, OUTPUT);

}

void loop() {

  currentMillis = millis(); //Capturing the time at each loop.

  if (digitalRead(brakeLightsTrigger) == HIGH) { //Determine if the brakes are currently applied
    requestBrakeLights = 1;//needs to be a global as a function can change it
    brakecounter=0;//keep flashing or make this brake light solid then flash on release of peddle
 }
  //Placeholder code for the reverse lights.  Simplifed to test the hardware layout. Will eventually use same format as brake lights
  if (digitalRead(reverseLightsTrigger) == HIGH) {
    // not sure what logic would be required?
  }
  //Right turn signal
  if (digitalRead(rightLightTrigger) == HIGH) { //Checks to determine when right turn signal is activated.  Is only high for a moment
    requestRightSignal = 1;//needs to be a global as a function can change it
    rightTurnMillis = thisMillis;//prime the timer might have to be made a onetime
    rightcounter = 0; //keep flashing until relaesed then flash 3 times
  }
  if (digitalRead(leftLightTrigger) == HIGH) {
    requestLeftSignal = 1;//needs to be a global as a function can change it
  }
}

//what about hazard lights?

if (requestBrakeLights == 1 && requestRightSignal == 0 && requestLeftSignal == 0) {
  brakeLights();
} else if (requestBrakeLights == 1 && requestRightSignal == 1 && requestLeftSignal == 0) {
  brakeplusRight();
} else if (requestBrakeLights == 1 && requestRightSignal == 0 && requestLeftSignal == 1) {
  brakeplusLeft();
} else if (requestBrakeLights == 0 && requestRightSignal == 1 && requestLeftSignal == 0) {
  rightTurnSignal();
} else if (requestBrakeLights == 0 && requestRightSignal == 0 && requestLeftSignal == 1) {
  leftTurnSignal();
} else {
  //make safe all lights off
}


//Brake Lights function
void brakeLights() {

static byte flash;
  if (currentMillis - brakeMillis >= interval) { //Checks to see if interval time has elapsed between brake light function call and brakeMillis
    brakeMillis = currentMillis; // Set brakeMillis to currentMillis for next iteration of FOR loop
    flash = ! flash;
    if ( flash==1){
     brakeStrobeState=255;
    }else {
      brakeStrobeState=0;
    }
    brakeCounter++;
  }

  if (brakeCounter >= 3) {
    brakeCounter = 0;
    requestBrakeLights = 0;
    brakeStrobeState = 0;
  }
  digitalWrite(brakeLightsAction, brakeStrobeState);  // Make the LED light up with current brakeStrobeState from FOR loop
}

void brakeplusRight() {
  if (digitalRead(brakeLightsTrigger) == HIGH) {
    analogWrite(leftLightAction, 255);
  }
  rightTurnSignal();
}
void brakeplusRight() {
  if (digitalRead(brakeLightsTrigger) == HIGH) {
    analogWrite(rightLightAction, 255);//make the right light on and bright
  }
  leftTurnSignal();//flash the left light
}

//Right turn signal function
void rightTurnSignal() { //Setting variable thisMillis using the data from the function call in LOOP, currentMillis
  
  if (thisMillis - rightTurnMillis >= interval) { //Checking to see if enough time has elapsed to make a change

    if (fadeDirection == UP) { //Start by going UP
      rightStrobeState = rightStrobeState + fadeIncrement;  //Increase rightStrobeState by increment amount
      if (rightStrobeState >= maxPWM) { //Increase until it hits full brightness
        rightCounter++;
        rightStrobeState = maxPWM; //At max, limit and change direction
        fadeDirection = DOWN; //Changed to DOWN to the else statement proceeds
      }
    } else {

      rightStrobeState = rightStrobeState - fadeIncrement; //Decrease rightStrobeState for fade out
      if (rightStrobeState <= minPWM) { //Decrease brightness until it hits minPWM as set above

        rightStrobeState = minPWM; //At min limit.
        fadeDirection = UP; //Change to UP so the original IF statement can begin again
      }
    }
    if (rightCounter >= 3) {
      rightCounter = 0;
      requestRightSignal = 0;
      rightStrobeState = 0;
    }

    analogWrite(rightLightAction, rightStrobeState);  //Writing the LED brightness after each check of the IF ELSE statement

    rightTurnMillis = thisMillis; //Reset millis for the next iteration
  }
}

Wow, thank you so much for your help. I truly do appreciate it and understand the amount of time/work you put into your demo code. It also makes me realize how far off I am on my goal, though.

I think I understand the part where I need to trigger the functions with a flag instead of calling them directly. I see how that will let my fading turn signals finish before they know its time to stop when the function resets the flag instead of the digitalread going away.

I also get the idea of setting up various logic states with the different combinations of flags being set. I'll setup a table later today to figure out the possible states and make a function for each one. Quickly off the top of my head I think I'd need:

Brakes
Reverse
Left
Right
Brakes+Reverse
Brakes+Left
Brakes+Right
Right+Left (hazards)
Brakes+Right+Left
Brakes+Reverse+Right+Left (brakes, in reverse, with hazards on??)

Then I would make an if, else if block like you did to read all of those possible variable states and perform the correct function?

I'll have a read through the rest of your code when I can sit down and really study it. I see a few variables getting incremented and I'm still trying to grasp how it all works together.

I'll give it a re-write and see how it goes from there.

Thanks again!

Brakes
Reverse
Left
Right
Brakes+Reverse
Brakes+Left
Brakes+Right
Right+Left (hazards)
Brakes+Right+Left
Brakes+Reverse+Right+Left (brakes, in reverse, with hazards on??)

Sounds like a job for using switch/case to turn the program into a state machine. Set the state based on the inputs and let switch/case execute the code required for the current state. When the requirement(s) of the state have been satisfied or the state changes due to external input(s) tidy up the lights (probably turn them all off) and move to the target state.

aarg:

for(int x=0; x<=3; x++) { //I want it to perform 4 quick blinks then remain solid

if (currentMillis - brakeMillis >= interval) { //Checks to see if interval time has elapsed between brake light function call and brakeMillis




You can't have multitasking with this kind of programming. A for loop restricts the possible actions to only what is in the for loop while it is running. You can not have any control structures that don't complete rapidly and pass control to the next function in the loop immediately.

You're adding a half hour pit stop to the race. :)

So a for statement pauses all action like a delay would? I was avoiding delays because this needs to be responsive. gpop1's quick example didn't use it so I'll have something to learn from. I just need to figure out a better way to flash them then stay solid.

Once you have written a plan you will probably find the plan look very much like the code.

The hardest part is going to be deciding how you want to enter the timing of the millis. If you are ok with dropping in to the code and the first "if" timer is true then its easy.

Just consider how you want to enter and when you want to exit

for example

brakes

I want the led to start full brightness as soon as the peddle is pressed. I want to fade 3 times then remain full brightness until the peddle is released.

or

I want the led to stay full brightness until the peddle is released then fade 3 times before turning off.

this will tell you where you need to set/unset flags and what you need to prime before running the action.

I think I am at the hardest part as you say. I made some progress on making the code work with flags to run the functions. I have them setup as simple digitalwrite's right now to simply make my test LEDs light up. I did try to get some code working on the right turn signal but so far its not working. It flashes so fast it stays dim. And it flashes in some weird pattern that I don't know how it even got it to do that.

I was also wondering if I would need to make another state for the brake lights. For example, brakeRequest = 1 for the flashing part and brakeRequest = 2 for solid. I hope I am over thinking that part. I just want 3 quick blinks as I press the brake and then to remain on solid after those 3 complete while it is being held down.

I think I am close on the fading turn signal. I want it's action to be similar to the Fade example in the Arduino IDE but without using delay at all.

Here is my code as I have it right now (minus some setup):

//Setting up timers to start at zero as soon as the board boots up.
  
  unsigned long revMillis = 0;        // Reverse light timer initialization.
  unsigned long leftTurnMillis = 0;   // left turn timer initialization.
  unsigned long rightTurnMillis = 0;  // right turn timer initialization.
  unsigned long brakeMillis = 0;      // brake light timer initialization.
  
//Constants I can change to affect the rate that blinking and fading occurs once I get it working right.
  
  const long interval = 50; //Time that it takes to change the fadeIncrement i.e. speed of fade.
  
  const int minPWM = 125;  //Minimum brightness of the fading LEDs.  
  const int maxPWM = 255; //Max LED brightness.  Just keep it 255.
  
  byte fadeIncrement = 20; //The amount the brightness changes at each interval. i.e. smoothness of fade
  
//The following lines were added because I copied them from Bald Engineer's example of fading LEDs without delay. https://www.baldengineer.com/fading-led-analogwrite-millis-example.html
  
  #define UP 0 // ???
  #define DOWN 1 // ???
 
  byte fadeDirection = UP; //Tells the statement to go from minPWM to maxPWM and gets changed to down after hitting max.
  
//Settings up request flags for each light action

  byte brakeRequest = 0;
  byte reverseRequest = 0;
  byte leftRequest = 0;
  byte rightRequest = 0;
  
//Counters to help with blinking 

  byte brakeCounter = 0;
  byte reverseCounter = 0;
  byte leftCounter = 0;
  byte rightCounter = 0;
  
  unsigned long currentMillis = 0; //Capturing the time at each loop. 
  
void setup() {
        
// Setting up the proper pins as inputs.
        
  pinMode(leftLightTrigger, INPUT);
  pinMode(rightLightTrigger, INPUT);
  pinMode(reverseLightsTrigger, INPUT);
  pinMode(brakeLightsTrigger, INPUT);
  
// Setting up the proper pins as outputs
  
  pinMode(leftLightAction, OUTPUT);
  pinMode(rightLightAction, OUTPUT);
  pinMode(reverseLightsAction, OUTPUT);
  pinMode(brakeLightsAction, OUTPUT);
  

}

void loop() {
    
if (digitalRead(brakeLightsTrigger) == HIGH) { //Determine if the brakes are currently applied
 brakeRequest = 1; //Set the brake request flag to TRUE
 brakeCounter = 0; //Given in example from gpop1 to "keep flashing or make this brake light solid then flash on release of peddle" - ???
}  

//Determine if reverse lights are on  
if (digitalRead(reverseLightsTrigger) == HIGH) {
  reverseRequest = 1;
  reverseCounter = 0;
}
    
//Right turn signal on?
if (digitalRead(rightLightTrigger) == HIGH) { 
  rightRequest = 1;
  rightCounter = 0;  
}
    
//Left turn signal on?
if (digitalRead(leftLightTrigger) == HIGH) {
  leftRequest = 1;
  leftCounter = 0;
}

//Determine if I should run just the brake lights
if (brakeRequest == 1 && leftRequest == 0 && reverseRequest == 0 && rightRequest == 0) {
  brakeLights();
}

//Determine if I should just run the left turn signal
if (brakeRequest == 0 && leftRequest == 1 && reverseRequest == 0 && rightRequest == 0) {
  leftTurnSignal();
}

//Determine if I should just run the right turn signal
if (brakeRequest == 0 && leftRequest == 0 && reverseRequest == 0 && rightRequest == 1) {
  rightTurnSignal();
}

//Determine if I should only use the reverse lights
if (brakeRequest == 0 && leftRequest == 0 && reverseRequest == 1 && rightRequest == 0) {
  reverseLights();
}

//Determine if I should use the brake lights and left turn signal simultaneously 
if (brakeRequest == 1 && leftRequest == 1 && reverseRequest == 0 && rightRequest == 0) {
  brakeLTLights();
}

//Determine if I should use the brake lights and the right turn signal simultaneously 
if (brakeRequest == 1 && leftRequest == 0 && reverseRequest == 0 && rightRequest == 1) {
  brakeRTLights();
}

//Determine if I should use the brake lights and reverse lights simultaneously 
if (brakeRequest == 1 && leftRequest == 0 && reverseRequest == 1 && rightRequest == 0) {
  brakeReverseLights();
}

//Determine if I should use the left and right together as hazard lights
if (brakeRequest == 0 && leftRequest == 1 && reverseRequest == 0 && rightRequest == 1) {
  hazardLights();
}

//Determine if I should use the brakes and hazard lights simultaneously 
if (brakeRequest == 1 && leftRequest == 1 && reverseRequest == 0 && rightRequest == 1) {
  brakeHazardsLights();
}

//All of em on.  Just use all the lights in some weird scenerio where I am backing up, stopping, with the hazards on
if (brakeRequest == 1 && leftRequest == 1 && reverseRequest == 1 && rightRequest == 1) {
  allLights();
}
//All of em off.  
if (brakeRequest == 0 && leftRequest == 0 && reverseRequest == 0 && rightRequest == 0) {
  digitalWrite(brakeLightsAction, LOW);
  digitalWrite(leftLightAction, LOW);
  digitalWrite(rightLightAction, LOW);
  digitalWrite(reverseLightsAction, LOW);
}

}

//Brake Lights function
void brakeLights() {
  digitalWrite(brakeLightsAction, HIGH); //Testing my function gets active on my test hardware
  brakeRequest = 0; //Reset the flag back to false to turn off the lights
}

//Left turn signal function
void leftTurnSignal() {
  digitalWrite(leftLightAction, HIGH); //Testing my function gets active on my test hardware
  leftRequest = 0; //Reset the flag back to false to turn off the lights
}

//Right turn signal function
void rightTurnSignal() { //
  
currentMillis = millis();  
  
if (currentMillis - rightTurnMillis >= interval) { //Checking to see if enough time has elapsed to make a change
    
    if (fadeDirection == UP) { //Start by going UP
      rightStrobeState = rightStrobeState + fadeIncrement;  //Increase rightStrobeState by increment amount
      if (rightStrobeState >= maxPWM) { //Increase until it hits full brightness
       
        rightStrobeState = maxPWM; //At max, limit and change direction
        fadeDirection = DOWN; //Changed to DOWN to the else statement proceeds
      }
    } else {
      
      rightStrobeState = rightStrobeState - fadeIncrement; //Decrease rightStrobeState for fade out
      if (rightStrobeState <= minPWM) { //Decrease brightness until it hits minPWM as set above
        
        rightStrobeState = minPWM; //At min limit.  
        fadeDirection = UP; //Change to UP so the original IF statement can begin again
      }
    }

    analogWrite(rightLightAction, rightStrobeState);  //Writing the LED brightness after each check of the IF ELSE statement
     
    rightTurnMillis = millis(); //Reset millis for the next iteration
  }
  rightRequest = 0;  //Reset the flag back to false to turn off the lights
}

//Reverse Lights function
void reverseLights() {
  digitalWrite(reverseLightsAction, HIGH);
  reverseRequest = 0; //Reset the flag back to false to turn off the lights
}

//Brake Lights and left turn function
void brakeLTLights() {
  
  brakeRequest = 0; //Reset the flag back to false to turn off the lights
  leftRequest = 0;
}

//Brake Lights and right turn function
void brakeRTLights() {
  
  brakeRequest = 0; //Reset the flag back to false to turn off the lights
  rightRequest = 0;
}

//Brake Lights and reverse lights function
void brakeReverseLights() {

  brakeRequest = 0; //Reset the flag back to false to turn off the lights
  reverseRequest = 0;
}

//Hazard lights function
void hazardLights() {
  
  leftRequest = 0; //Reset the flag back to false to turn off the lights
  rightRequest = 0;
}

//Brake Lights and hazard lights function
void brakeHazardsLights() {
  
  brakeRequest = 0; //Reset the flag back to false to turn off the lights
  leftRequest = 0;
  rightRequest = 0;
}

//All of em function
void allLights() {
  
  brakeRequest = 0; //Reset the flag back to false to turn off the lights
  leftRequest = 0;
  rightRequest = 0;
  reverseRequest = 0; 
}

I may have lead you in the wrong direction.

When we first started you seemed to want a light that flashed 3 times after a input was sensed. Well that's a simple set flag count to 3 then turn flag off code

Now you have given the real detail that is

flash 3 times then stay on.

now the code is while peddle is pressed count to 3 then set a flag to block the light turning off until peddle release.

The only reason you would need a flag to say you pressed the peddle is so you can check to what other flags are also present so you can decide what you want the lights to do.

The indicator you want to fade 3 times when you get a indicate signal ???? why

all I understand so far is the light bar takes 4 outputs to control.

I now have a understanding of the brakes, the other things you are trying to do haven't really been explained and I think once you explain them you will probably understand the code better.

I like function calls but sometime they present there own problems as you can break a function which doesn't allow for it to finish so you have to plan for these events. A example of this is the right indicator function.

if (brakeRequest == 0 && leftRequest == 0 && reverseRequest == 0 && rightRequest == 1) {
rightTurnSignal();
}

if the "IF" fails and something was set to run 3 times in the function then with out calling the function it will never finish so the right indicator may be stuck on. Now its simple to code around this as long as you understand that the problem exists.

You need to write a detailed description of what the lights need to do and it needs to be written for a 3 year old to read.

As you are using 4 outputs brakes-left-right-reverse you may not need all of the arguments. You may want the brake lights to flash 3 times fast no matter if the indicator is fading in and out. On the other hand if the indicator is the same leds as the brakes then you will need the arguments or it will look like your hazard lights are on when braking and turning.

Please do not post that does not compile unless that's the reason for posting it. I couldn't play in your code unless I added a lot of code and that's boring.

I did write a little code that at least shows how to make the brakes flash.

Notice that im using serial print to see what the arduino is doing.

#define brakeLightsAction 12
#define brakeLightsTrigger 2
#define rightTurnTrigger 3
#define rightLightAction 13
byte brakeCounter = 0;
byte brakeRequest = 0;
byte rightRequest = 0;
byte  rightCounter = 0;
int rightStrobeState = 0;

unsigned long currentMillis = 0;

byte flash = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode (brakeLightsAction, OUTPUT);
  pinMode (rightLightAction, OUTPUT);
  pinMode (brakeLightsTrigger, INPUT);
  pinMode (rightTurnTrigger, INPUT);
  Serial.begin(9600);
}

void loop() {
  currentMillis = millis();//update every loop
  byte brakePeddle = digitalRead(brakeLightsTrigger);
  byte rightTurnInput = digitalRead(rightTurnTrigger);

  if (brakePeddle == HIGH) { //Determine if the brakes are currently applied
    brakeRequest = 1; //Set the brake request flag to TRUE only when the peddle is applied
    Serial.println("peddle applied");
  } else {
    brakeRequest = 0;// unset when released
    digitalWrite(brakeLightsAction, LOW);//added as brakes is a function
    brakeCounter = 0;//prime the counter
    flash = 0;
  }

  if (rightTurnInput == HIGH) {
    rightRequest = 1;
    rightCounter = 0;
   Serial.println("right turn signal detected");
  }

  
 if (brakeRequest == 1 && rightRequest == 0) {
    brakeLights();
  }
  if (brakeRequest == 0 && rightRequest == 1) {
    rightTurnSignal();
  }
}


// put your main code here, to run repeatedly:
void brakeLights() {
  // 3 rapid flashs then stays on till peddle is released
  static unsigned long brakeMillis;

  if (currentMillis - brakeMillis > 250L) {
    flash = ! flash;
    Serial.println(flash);
    brakeCounter ++;
    brakeMillis = currentMillis;
  }

  if (flash == 1) {
    digitalWrite(brakeLightsAction, HIGH);
  } else {
    if (brakeCounter <= 6) {
      digitalWrite(brakeLightsAction, LOW);
    }
  }
}

void rightTurnSignal() { //
  static byte up;
  static unsigned long rightTurnMillis;

  if (currentMillis - rightTurnMillis >= 30) { //Checking to see if enough time has elapsed to make a change
    if (up == 1) {
      rightStrobeState = rightStrobeState + 5;//upslow 
    } else {
      rightStrobeState = rightStrobeState - 10;//down fast
    }
    if ( rightStrobeState >= 255) {
      rightStrobeState = 255;
      up = 0;
      rightCounter ++ ;
    }
    if ( rightStrobeState <= 100) {
      rightStrobeState = 100;
      up = 1;
    }
    rightTurnMillis = currentMillis; //Reset millis for the next iteration
  }
  Serial.print ("right counter ");
  Serial.println (rightCounter);
  if (rightCounter >= 3) {
    rightRequest = 0;  //Reset the flag back to false to turn off the lights
    rightStrobeState=0;
  }
  analogWrite(rightLightAction, rightStrobeState);
}

Sorry that I was unclear with my intentions. Also that I trimmed the code a bit to fit within the character limit of the post. I'll be aware of that in the future.

To give a more solid run-down of my goal let me explain. I have a light bar to install on the truck that goes between the tailgate and the bumper. It is just a long horizontal row of LEDs that uses the trailer hitch connector to get 12V for brakes, left turn, right turn, and reverse lights. Here is a link to a similar product in action: LED Light Bar with Reverse.

I wish to leave the stock lighting alone and only intercept the light bar 12V signal to be my inputs.

For the brake light portion of the bar, I'd like to mimic some motorcycle setups I've seen. Each time you press the pedal it will give 3 quick strobes and then remain on steady while the pedal is held. Here is an example of this: Strobing Brake Light then Steady.

I had considered using the same code for the reverse function. But I can forgo it all together or just make it a steady strobe.

The turn signals will do a fade effect like in the Arduino example. I've also seen the example renamed "breathing LED". It would be timed to fade on/off at the same rate that my stock tail light blinks (through trial and error) but without the sudden ON/OFF of a high/low digital write.

I don't think it matters now, but I attached the entire .INO file of this project.

I thank you again for your help and will parse through your example as soon as I am able to.

LED_Brake_Bar_copy.ino (9.45 KB)

ok that makes way more sense now. My only concern is that you may have to either rewire or ignore the brake wire output and just use the left and right indicator at the same time to act as a brake light. (still need the input from the brakes)

The strobe affect should work of the code I posted. The indicator code is wrong but it should be easy to fix as there's no need to count just fade in and out and monitor the indicator wire. If no pulse detected with in x amount of time the indicator must have been switch off so remove the flag and stop the bar fading in and out.

Theres people who are better at coding who could write something that looks at the pulses from the indicators and code the fade so it matchs the indicators.

brakes and indicator should be easy just light one side and fade the other in and out.

As for reverse it looks like the bar turns off the brakes and indicator display. That's something you will have to test as it may be hardware controlled that will be impossible to code around with out messing with the unit.

The LED bar I have is very simple. It is a row of LEDs where the brake lights and turn signal lights are separate LEDs that alternate. Every 3rd or 6th space (I can't recall specifically) between them has a white LED for reverse. They are all independently operated with their own wire and a common ground. The turn signal wire only sees +12v for a brief moment, but with the incandescent bulbs it stays on shortly after the signal is low again. I want the LEDs to be similar to that.

I feel like I'm taking a test for a class I haven't taken. I felt like I was so close in my original post but now I am in way over my head. All of the tutorials I've gone through use delay in all of the examples. I can do each function I want individually with that but it won't accomplish my goal.

I have been playing with your latest blink example and I can't get it to flash. It just comes on steady and occasionally stays on with the button no longer depressed. I thought it would be easy to get a HIGH/LOW, HIGH/LOW, HIGH/LOW, HIIIIIIIIIIIIIIGH pattern out of some lights.

Maybe its time to re-read my book a little slower.

s10blazed:
I feel like I'm taking a test for a class I haven't taken. I felt like I was so close in my original post but now I am in way over my head. All of the tutorials I've gone through use delay in all of the examples. I can do each function I want individually with that but it won't accomplish my goal.

I have been playing with your latest blink example and I can't get it to flash. It just comes on steady and occasionally stays on with the button no longer depressed. I thought it would be easy to get a HIGH/LOW, HIGH/LOW, HIGH/LOW, HIIIIIIIIIIIIIIGH pattern out of some lights.

Maybe its time to re-read my book a little slower.

there's the first clue

"It just comes on steady and occasionally stays on with the button no longer depressed."

I will admit that the code I post is not the code I tested. The reason is that arduino pins can detect a floating voltage. To combat this you can add a resistor (about 10kohm) between the arduino pin and negative or you can code different using INPUT_PULLUP which tells the arduino to add a internal resistor between the pin and +5. The button is then between the pin and negative. (code is HIGH not pushed, LOW pushed)

Serial print will tell you what the arduino is seeing. If it says peddle applied that means its reading a floating voltage on the pin

Serial.println("peddle applied");//code I posted has this line to test for that condition.

I do have pull down resistors on my inputs. It is just writing to the serial monitor for each loop. Even when I put it in the function itself, it repeats as the loop just repeats the function it seems like. Since I've added the following code to my loop, the lights shut off reliably.

if (digitalRead(brakeLightsTrigger) == HIGH) { //Determine if the brakes are currently applied
 brakeRequest = 1; //Set the brake request flag to TRUE
brakeCounter = 0;//prime the counter
} else {
  brakeRequest = 0; //set flag to false
  digitalWrite(brakeLightsAction, LOW); //manually turn off the brake lights
}

I've been playing with the brake/reverse combo. When I set them to simply strobe HIGH/LOW it works great. Reverse, brake, brake/reverse. It is all fast and smooth and shuts off every time.

But no steady HIGH state. Just strobing. :frowning:

This code should work. It compiles but I haven't tested it as I don't know the indicator timing on your truck

pin numbers will need to be set to what ever you are using

#define brakeLightsAction 12
#define brakeLightsTrigger 2
#define rightTurnTrigger 3
#define rightLightAction 13
#define leftTurnTrigger 1
#define leftLightAction 10
byte brakeCounter = 0;
byte brakeRequest = 0;
byte rightRequest = 0;
byte leftRequest = 0;
byte hazardRequest = 0;
int rightStrobeState = 0;
int leftStrobeState = 0;
unsigned long currentMillis = 0;
unsigned long rtMonitor = 0;
unsigned long ltMonitor = 0;
unsigned long hazardMonitor = 0;
byte flash = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode (brakeLightsAction, OUTPUT);
  pinMode (rightLightAction, OUTPUT);
  pinMode (leftLightAction, OUTPUT);
  pinMode (brakeLightsTrigger, INPUT);
  pinMode (rightTurnTrigger, INPUT);
  pinMode (leftTurnTrigger, INPUT);
  Serial.begin(9600);
}

void loop() {
  currentMillis = millis();//update every loop
  byte brakePeddle = digitalRead(brakeLightsTrigger);
  byte rightTurnInput = digitalRead(rightTurnTrigger);
  byte leftTurnInput = digitalRead(leftTurnTrigger);

  if (brakePeddle == HIGH) { //Determine if the brakes are currently applied
    brakeRequest = 1; //Set the brake request flag to TRUE only when the peddle is applied
    Serial.println("peddle applied");
  } else {
    brakeRequest = 0;// unset when released
    digitalWrite(brakeLightsAction, LOW);//added as brakes is a function
    brakeCounter = 0;//prime the counter
    flash = 0;
  }

  if (rightTurnInput == HIGH) {//signal will alternate high and low with indicator
    rightRequest = 1;
    rtMonitor = currentMillis;
    Serial.println("right turn signal detected");
  } else {
    if (currentMillis - rtMonitor >= 500) { //if not high for 500ms stop fade
      rightRequest = 0;
      rightStrobeState = 0;
    }
  }

  if (leftTurnInput == HIGH) {//signal will alternate high and low with indicator
    leftRequest = 1;
    ltMonitor = currentMillis;
    Serial.println("left turn signal detected");
  } else {
    if (currentMillis - ltMonitor >= 500) { //if not high for 500ms stop fade
      leftRequest = 0;
      leftStrobeState = 0;
    }
  }


  if (leftTurnInput == HIGH && rightTurnInput == HIGH) {//must be hazard input
    Serial.println("hazard signal detected");
    hazardMonitor = currentMillis;
    hazardRequest = 1;
  } else {
    if (currentMillis - hazardMonitor >= 500) { //if not high for 500ms stop fade
      hazardRequest = 0;
      leftStrobeState = 0;
      rightStrobeState = 0;
    }
  }
 if (brakeRequest == 1 && rightRequest == 0 && leftRequest == 0 && hazardRequest == 0 ) {
    brakeLights();
  } else if (brakeRequest == 0 && rightRequest == 1 && leftRequest == 0 && hazardRequest == 0 ) {
    rightTurnSignal();
  } else if (brakeRequest == 0 && rightRequest == 0 && leftRequest == 1 && hazardRequest == 0 ) {
    leftTurnSignal();
  }  else if (brakeRequest == 1 && rightRequest == 0 && leftRequest == 1 && hazardRequest == 0 ) {
    brakeLights();
    leftTurnSignal();
  }  else if (brakeRequest == 1 && rightRequest == 1 && leftRequest == 0 && hazardRequest == 0 ) {
    brakeLights();
    rightTurnSignal();
  } else if (brakeRequest == 0 && hazardRequest == 1 ) {
    leftTurnSignal();
    rightTurnSignal();
    //if left and right dont fade together just call one function say left
    //then copy left strobestate to the other light
    // thats why analogWrite follows this code
  } else if (brakeRequest == 1 && hazardRequest == 1 ) {
    brakeLights();
    leftTurnSignal();
    rightTurnSignal();
  }

  analogWrite(rightLightAction, rightStrobeState);//in loop and near the end of loop for a reason
  analogWrite(leftLightAction, leftStrobeState);//in loop and near the end of loop for a reason
  
}//END LOOP



void brakeLights() {
  // 3 rapid flashs then stays on till peddle is released
  static unsigned long brakeMillis;

  if (currentMillis - brakeMillis > 250L) {
    flash = ! flash;
    Serial.println(flash);
    brakeCounter ++;
    brakeMillis = currentMillis;
  }

  if (flash == 1) {
    digitalWrite(brakeLightsAction, HIGH);
  } else {
    if (brakeCounter <= 6) {
      digitalWrite(brakeLightsAction, LOW);
    }
  }
}

void rightTurnSignal() { //
  //input signal is pulsed. Stop x ammount of time after last high pulse
  static byte up;
  static unsigned long rightTurnMillis;

  if (currentMillis - rightTurnMillis >= 30) { //Checking to see if enough time has elapsed to make a change
    if (up == 1) {
      rightStrobeState = rightStrobeState + 15;//upfast
    } else {
      rightStrobeState = rightStrobeState - 5;//down slow
    }
    if ( rightStrobeState >= 255) {
      rightStrobeState = 255;
      up = 0;
    }
    if ( rightStrobeState <= 100) {
      rightStrobeState = 100;
      up = 1;
    }
    rightTurnMillis = currentMillis; //Reset millis for the next iteration
  }
  //analogWrite(rightLightAction, rightStrobeState);//moved to main loop
}

void leftTurnSignal() { //by passing a bit this could work left and right
  //input signal is pulsed. Stop x ammount of time after last high pulse
  static byte up;
  static unsigned long leftTurnMillis;

  if (currentMillis - leftTurnMillis >= 30) { //Checking to see if enough time has elapsed to make a change
    if (up == 1) {
      leftStrobeState = leftStrobeState + 15;//upfast
    } else {
      leftStrobeState = leftStrobeState - 5;//down slow
    }
    if ( leftStrobeState >= 255) {
      leftStrobeState = 255;
      up = 0;
    }
    if ( leftStrobeState <= 100) {
      leftStrobeState = 100;
      up = 1;
    }
    leftTurnMillis = currentMillis; //Reset millis for the next iteration
  }
  //analogWrite(leftLightAction, leftStrobeState);//moved to main loop
}

just seen your post

the reason its flashing is the brakecounter is the wrong side of the else statement. As you now want it to remain on until peddle release just move that one line so it primes the counter when the peddle is not pushed

Its time to repost your complete code. As changes are made its hard to remember which parts have been changed and impossible for anyone else to step in and give there advise. As we now have a good idea of what the lights do and how you are reading the inputs we can now get more people involved.