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
}
}