My circuit for my Harley Davidson Probeam Fog Lights

Hello All,
I would like to share my project. Any bikers out there? :grin:

I purchased Probeam fog lights to mount on my 2003 Harley Davidson Softail Springer FXSTSI. The two fog lights are 20w, 1.6a each total of 3.2a.

The fog lights have a low beam and a high beam, the default fog light is the low beam, "halo" it is on all the time, like "running lights on a car", I wanted to have the fog lights "blink" at 100ms, on-demand, to give a heads up to cagers, "people in cars", like a car driver that may make a left turn in front of me. "I never saw him officer", you hear it all the time.

So I will have two momentary-on switches, mounted verticle, on the handlebar, they will have 12v led indicators built-in. They are both momentary-on but one of them, the "top one with a red LED indicator, that turns on the high beam, will act like a "latched switch",
"in code", you press it once and the high beam fog lights come on, and will stay on until you press it again. The bottom switch, a momentary-on, will blink the fog lights, either the low beam alone or both the low beam and the high beam, "if the high beams are on", also the switch that turns on the high beams, will also turn off all the fog lights if it is given a "long press", 2.5 seconds
and it will turn them back on with another "long press" 2.5 seconds, but just the low beams will come on, the high beams will be off, since the default mode is low beams always on.

Here is my working schematic, and my script which runs on the ATEMEGA328 tested on a breadboard. I will be soldering it on a proto board that will live under the seat of my Harley.

I hope this helps you. This is the stuff I always look for, and I swore I would share it if, when, I ever figured it out.

It was a big learning curve for me, I am new to electronics and rusty in Arduino code. My code is crude compared to coders I see on this forum, but it works.

If anyone wants to streamline my script with arrays or a state machine please do, and share it. Thanks, and I hope this helps some of you. I give credit to Blackfin in my script, I saw his post for how to execute a "Long Press" with a switch.
y



//I edited code from Blackfin "Hold button for 5 seconds for an LED to turn and stay on"  https://forum.arduino.cc/t/hold-button-for-5-seconds-for-an-led-to-turn-and-stay-on/574197/3
//John Guarnieri script 01_17_2022 Harley Davidson Probeam Fog Lights blink at 100ms and also poer off all fog lights with long button press
#define LEDon  HIGH
#define LEDoff  LOW
//
#define DISABLED  false
#define ENABLED  true

//int
int blinkInterval = 100; //100ms
int short_key_press_time = 30;
int Long_Switch_Press_Time = 2500; //2.5 seconds

//unsigned long
unsigned long previousBlink;
unsigned long currentMillis;
unsigned long previousMillis;

unsigned long
timeStart_1; //long press time check  

unsigned long
timeStart_2;  //short press time check   


//buttons
const byte button_blink_the_fog_lights = 4;
const byte switch_turn_on_the_high_beam_fog_lights = 5;

//LED's
const int fog_light_low_beam = 6;
const int fog_light_low_beam_indicator = 7;
const int fog_light_high_beam = 8;
const int fog_light_high_beam_indicator = 9;

//long
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers


//bool
bool blinkState = DISABLED;
bool First_Long_Press = ENABLED; 
bool First_Short_Press = ENABLED;
bool Do_Not_Run_First_Short_Press_Flag = DISABLED;
bool the_high_beam_fog_lights_are_on = DISABLED;
bool All_The_Fog_Lights_Are_Off = DISABLED;
bool high_beam_pin_flag = DISABLED;
bool second_long_press_dont_turn_on_the_high_beam_fog_lights = DISABLED;


bool
bCheckingSwitch_1; //long press check switch_turn_on_the_high_beam_fog_lights

bool
bCheckingSwitch_2;  //short press check switch_turn_on_the_high_beam_fog_lights
byte
    currSwitch, //high beam fog light button state changes
    lastSwitch;
 
void setup() 
{  
   pinMode(fog_light_low_beam,OUTPUT);
   pinMode(fog_light_low_beam_indicator,OUTPUT);
   pinMode(fog_light_high_beam,OUTPUT);
   pinMode(fog_light_high_beam_indicator,OUTPUT);
  
   pinMode(button_blink_the_fog_lights,INPUT_PULLUP);
  pinMode( switch_turn_on_the_high_beam_fog_lights,INPUT_PULLUP );
  lastSwitch = digitalRead( switch_turn_on_the_high_beam_fog_lights );
  bCheckingSwitch_1 = DISABLED;

  bCheckingSwitch_2 = DISABLED;
  //turn on the led
  digitalWrite(fog_light_high_beam,LEDoff);
  digitalWrite(fog_light_high_beam_indicator,LEDoff);
  digitalWrite(fog_light_low_beam,LEDon);
  digitalWrite(fog_light_low_beam_indicator,LEDon);
  //need this for serial monitor output
  Serial.begin(115200);
} //end void setup

void loop() 
{
  
  if ( (millis() - lastDebounceTime) > debounceDelay) //debounce button press
  {
     currSwitch = digitalRead(switch_turn_on_the_high_beam_fog_lights);
     lastDebounceTime = millis(); //set the current time
     //call the function check_high_beam_fog_light_switch()
     check_high_beam_fog_light_switch();
  } 
     //call the function blink_the_fog_lights()
     blink_the_fog_lights(); 
  
} //end void loop

void check_high_beam_fog_light_switch()
{
  //if the switch is low now and doesn't match its
  //previous reading, it means the switch has changed
  //either unpressed-to-pressed or pressed-to-unpressed
   
  if( currSwitch != lastSwitch )
  {   
     //if low now, the change was unpressed to pressed
     if( currSwitch == LOW )
     {
        //in that case, get the time now to start the
        //5-sec delay...
        timeStart_1 = millis();
        timeStart_2 = millis(); 
        //...indicate we're now timing a press...
        bCheckingSwitch_1 = ENABLED;
        bCheckingSwitch_2 = ENABLED;
        //Serial.println("short press ");
        //Serial.println(timeStart_2);
     }  //if
     else
     {
        //was a rising edge (button being released)
        //cancel checking the switch timing now since 
        //it's not being held hown
        bCheckingSwitch_1 = DISABLED;
        bCheckingSwitch_2 = DISABLED;
        //Serial.println("Short_press release");
     }//end else
      
     //and save the lastSwitch = currSwitch;
     lastSwitch = currSwitch;
       
  }//end if
 
    
  //if we haven't seen a rising edge, keep checking the
  //timing
  if( bCheckingSwitch_1 )//long press happening here switch_turn_on_the_high_beam_fog_lights
  {
     //Serial.println("short press happening here");
     toggle_OFF_and_ON_all_the_fog_lights_long_press(); 
  }//end if

  if( bCheckingSwitch_2 )//short press happening here switch_turn_on_the_high_beam_fog_lights
  {
     
     //this flag happens if all the fog lights were turned off, 
     //you dont want to turn on any fog lights until 
     //another long press happens to turn all the fog lights back on
     if(!Do_Not_Run_First_Short_Press_Flag)
     {
        toggle_OFF_and_ON_just_the_high_beam_fog_lights(); 
     }
    
  }//end if   
}   //end void check_high_beam_fog_light_switch()



void toggle_OFF_and_ON_all_the_fog_lights_long_press()
{
 //if the millis count now is 2500 or more higher
 //than it was when the press was detected (timeStart_1),
 //turn on the LED
 
 if( (millis() - timeStart_1 ) >= Long_Switch_Press_Time          //long press 2.5 seconds turn off all the fog lights
 )
    if (First_Long_Press) //switch_turn_on_the_high_beam_fog_lights
    {
       //because the low beam fog lights are always on go low first
       digitalWrite(fog_light_low_beam,LEDoff);
       digitalWrite(fog_light_low_beam_indicator,LEDoff);
       digitalWrite(fog_light_high_beam,LEDoff);
       digitalWrite(fog_light_high_beam_indicator,LEDoff);
       high_beam_pin_flag = DISABLED;
       First_Long_Press = DISABLED;
       bCheckingSwitch_1 = DISABLED;
       //latest add seems to work
       bCheckingSwitch_2 = DISABLED;
       currSwitch = 1;
       All_The_Fog_Lights_Are_Off = ENABLED;
       //this flag happens if all the fog lights were turned off, 
       //you dont want to turn on any fog lights until 
       //another long press happens to turn all the fog lights back on
       Do_Not_Run_First_Short_Press_Flag = ENABLED;
       Serial.println("Long press high beam fog lights are OFF");
       //Serial.println("high_beam_pin_flag"); 
       //Serial.println(high_beam_pin_flag); 
           
    }
    else //second long press here switch_turn_on_the_high_beam_fog_lights
    {
       digitalWrite( fog_light_low_beam,LEDon);
       digitalWrite( fog_light_low_beam_indicator,LEDon);
       //didn't need this here
       //digitalWrite( fog_light_high_beam,LEDon);
       //digitalWrite( fog_light_high_beam_indicator,LEDon);
       
       
       //fix I set lastSwitch to HIGH because after turning off all the fog lights
       //and then turning all the fog lights back on, when I pressed the turn on the high beam button it was
       //already in the LOW position so you had to press it twice to turn on the high beam fog lights, setting lastSwitch = HIGH; fixed it
       //lastSwitch was LOW screwing me up so set it to HIGH
       //this lastSwitch = HIGH; fires off a short press if currSwitch, and/or lastSwitch, "the high beam fog light button state changes", get out of sync on a button press, in some situatons. 
    
       lastSwitch = HIGH;
       Serial.println("Long press high beam fog lights are ON");
       second_long_press_dont_turn_on_the_high_beam_fog_lights = ENABLED;
       high_beam_pin_flag = ENABLED;
       First_Long_Press = ENABLED;
       All_The_Fog_Lights_Are_Off = DISABLED;
      
       //FIX
       //this is the fix set "First_Short_Press = false;" for when First_Short_Press 
       //was = to "true" "HIGH" and should have been false "LOW" if
       //it were true at the wrong time the high beams would
       //only turn off on a second short press, and not the first short press which is normal operation
       //on and off on the first short press
      
       First_Short_Press = DISABLED; //LOW
     
      
       bCheckingSwitch_1 = DISABLED;
       //latest add seems to work
       bCheckingSwitch_2 = DISABLED;
       currSwitch = 1;
       //turn off the flag
       Do_Not_Run_First_Short_Press_Flag = DISABLED;         
    }
}// end void toggle_OFF_and_ON_all_the_fog_lights_long_press()


void toggle_OFF_and_ON_just_the_high_beam_fog_lights()  //short press
{
 //if the millis count now is 2500 or more higher
 //than it was when the press was detected (timeStart_1),
 //turn on the LED
  if( (millis() - timeStart_2 ) >= short_key_press_time          //short press time
 )
    //Serial.println("First_Short_Press");
    //Serial.println(First_Short_Press);
    //Serial.println("Do_Not_Run_First_Short_Press_Flag");
    //Serial.println(Do_Not_Run_First_Short_Press_Flag);
    if (First_Short_Press && !Do_Not_Run_First_Short_Press_Flag )//if First_Short_Press true set the fog_light_high_beam, HIGH "ON"
    {
       //because the low beam fog lights are always on go low first
       second_long_press_dont_turn_on_the_high_beam_fog_lights = DISABLED;
       digitalWrite( fog_light_high_beam,LEDon);
       digitalWrite( fog_light_high_beam_indicator,LEDon);
       high_beam_pin_flag = ENABLED;
       the_high_beam_fog_lights_are_on = ENABLED;
       First_Short_Press = DISABLED;
       bCheckingSwitch_2 = DISABLED;
       currSwitch = 1;
       //testing here
       second_long_press_dont_turn_on_the_high_beam_fog_lights = DISABLED;
       Serial.println("Short press high beam fog lights are ON");
         
    }
    else //if First_Short_Press = false turn set the fog_light_high_beam, LOW "OFF"
    {
       //Serial.println("Do_Not_Run_First_Short_Press_Flag");
       //Serial.println(Do_Not_Run_First_Short_Press_Flag);
             
       digitalWrite( fog_light_high_beam,LEDoff);
       digitalWrite( fog_light_high_beam_indicator,LEDoff);
                
       high_beam_pin_flag = DISABLED;
       the_high_beam_fog_lights_are_on = DISABLED;
       First_Short_Press = ENABLED;
       bCheckingSwitch_2 = DISABLED; 
       currSwitch = 1;
    
       Serial.println("Short press high beam fog lights are OFF"); 
               
    }              
} //end void toggle_OFF_and_ON_just_the_high_beam_fog_lights()


void blink_the_fog_lights()
{
   if (!All_The_Fog_Lights_Are_Off)//NOT all the fog lights are off so proceed, else don't proceed
   {
      currentMillis = millis(); // better to store in variable, for less jitter
      if (currentMillis - previousMillis >= blinkInterval) 
      {   // enough time passed yet?
         previousMillis = currentMillis; // sets the time we wait "from"
    
         if (digitalRead(button_blink_the_fog_lights)==LOW) //blink fog light switch pressed LOW
         {   
            if (high_beam_pin_flag)//YES true high beam fog lights are ON you can blink both low and high fog lights
            {         
               
               if (!second_long_press_dont_turn_on_the_high_beam_fog_lights)//NOT
               {
                  Serial.println("blinking low beams and high beams");
                  digitalWrite(fog_light_low_beam,!digitalRead(fog_light_low_beam)); // shortcut to toggle the LED
                  digitalWrite(fog_light_low_beam_indicator,!digitalRead(fog_light_low_beam_indicator)); // shortcut to toggle the LED 
                  digitalWrite(fog_light_high_beam,!digitalRead(fog_light_high_beam)); // shortcut to toggle the LED
                  digitalWrite(fog_light_high_beam_indicator,!digitalRead(fog_light_high_beam_indicator)); // shortcut to toggle the LED 
               }               
               else
               {
                  Serial.println("blinking just the low beams");
                  digitalWrite(fog_light_low_beam,!digitalRead(fog_light_low_beam)); // shortcut to toggle the LED
                  digitalWrite(fog_light_low_beam_indicator,!digitalRead(fog_light_low_beam_indicator)); // shortcut to toggle the LED 
               }
           }      
            else  //false the high beam fog lights are off just blink the low beam fog lights
            { 
               Serial.println("blinking just the low beams");
               digitalWrite(fog_light_low_beam,!digitalRead(fog_light_low_beam)); // shortcut to toggle the LED
               digitalWrite(fog_light_low_beam_indicator,!digitalRead(fog_light_low_beam_indicator)); // shortcut to toggle the LED 
            }      
         }
         else  //blink switch released not pressed HIGH
         {
      
            if (!high_beam_pin_flag)//NOT means false the high beam fog lights are off
            {   
               digitalWrite(fog_light_low_beam,LEDon);
               digitalWrite(fog_light_low_beam_indicator,LEDon);  
            }
            else  //true means the high beam fog lights are ON
            {
               digitalWrite(fog_light_low_beam,LEDon);
               digitalWrite(fog_light_low_beam_indicator,LEDon);  
               if (!second_long_press_dont_turn_on_the_high_beam_fog_lights)//NOT second long press so turn on the high beam fog lights
              {
                 digitalWrite(fog_light_high_beam,LEDon);
                 digitalWrite(fog_light_high_beam_indicator,LEDon); 
              }
              else //true second_long_press_dont_turn_on_the_high_beam_fog_lights, so do NOT turn on the high beam fog lights
              {
                 digitalWrite(fog_light_high_beam,LEDoff);
                 digitalWrite(fog_light_high_beam_indicator,LEDoff);
              }              
           }
         }  //end (digitalRead(button_blink_the_fog_lights)==LEDoff)  
      }//end millis
   }//end all the fog lights are not off
} //end void blink_the_fog_lights()

Nice work.

You could move this to

Exhibition / Gallery

section of the fora.

BTW your variable names make my wrists hurt. S’lotta typing… :expressionless:

a7

1 Like

Thanks, move it or copy it? Variable name have to make sense to me LOL

1 Like

Hello
All in all a good definition of variable names will be reducing the work to write comments. I like it, good work.
Have a nice day and enjoy coding in C++.

1 Like

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