Help With Head Light Flasher Program

Hi All

I’m trying to write a program which performs 2 functions:

  • Turns head-lights on when a rocker switch is pressed
  • Flashes the flights (no matter if head lights are on or off)

I can get the head lights to turn on and off no problem, and i’ve added code to essentially check if the flash button is pressed and then run through the flashing function.

I dont want to use delays as i would like to keep the program running, so i’m using millis()

I have been using a boolean to define if the lights should be on or off, which i can then flip to do the flashing if the lights are either on or off.
This allows me to flash the lights no matter if the headlight switch is on or off.

For some reason this code isn’t working; lights turn on fine, but nothing happens when i press the flash button.

Any help is appreciated.

bool pressedFlash;
bool HLStatus;

unsigned long startFlashMillis;
unsigned long currentFlashMillis;

void setup()
{
  pinMode(8, INPUT);
  pinMode(7, OUTPUT);
  pinMode(9, INPUT);
  digitalWrite(7, LOW);
  HLStatus = false; // initial setting to false
  pressedFlash = false;
  
  startFlashMillis = millis(); // initial start time
}

void flash() // flash function
{
  currentFlashMillis = millis(); // flash function start time
  unsigned long flashTime = 200;
  
  if (digitalRead(9) && !pressedFlash) // if button is pressed and it was not pressed before start flash
  {
    HLStatus = !HLStatus; // flip head light status
    pressedFlash = true; // flash button was pressed
    startFlashMillis = currentFlashMillis; // start timing of flash function
  }
 
  if (pressedFlash && ((currentFlashMillis - startFlashMillis)>= flashTime))
  {
    HLStatus = !HLStatus;
    pressedFlash = false;
  }
  
}

void loop()
{
  if (!pressedFlash)
  {
  	HLStatus = digitalRead(8);
    digitalWrite(7, HLStatus);
  }
  flash();
}

Have you tried printing the value of pertinent variables before each test on their value is performed ? Are the values what you expect ?

I found it difficult to follow the logic of your program, which was not helped because the inputs are anonymous pin numbers rather than having meaningful names.

How are the switches wired ? Do you have pulldown resistors on the inputs to keep them in a known state ?

UKHeliBob:
Have you tried printing the value of pertinent variables before each test on their value is performed ? Are the values what you expect ?

I found it difficult to follow the logic of your program, which was not helped because the inputs are anonymous pin numbers rather than having meaningful names.

How are the switches wired ? Do you have pulldown resistors on the inputs to keep them in a known state ?

I have not done this and to be honest not sure how.

I've replaced the pin numbers with names, see my code below and see if this helps.

I dont have pulldown resistors at the moment as I am testing this digitally first.

Here is the setup to see how it works:

bool pressedFlash;
bool HLStatus;

unsigned const int HLRelayPin = 7;
unsigned const int HLMainPin = 8;
unsigned const int flashPin = 9;

unsigned long startFlashMillis;
unsigned long currentFlashMillis;

void setup()
{
  pinMode(HLMainPin, INPUT);
  pinMode(HLRelayPin, OUTPUT);
  pinMode(flashPin, INPUT);
  digitalWrite(HLRelayPin, LOW);
  HLStatus = false; // initial setting to false
  pressedFlash = false;
  
  startFlashMillis = millis(); // initial start time
}

void flash() // flash function
{
  currentFlashMillis = millis(); // flash function start time
  unsigned long flashTime = 200;
  
  if (digitalRead(flashPin) && !pressedFlash) // if button is pressed and it was not pressed before start flashing
  {
    HLStatus = !HLStatus; // flip head light status
    pressedFlash = true; // flash button was pressed
    startFlashMillis = currentFlashMillis; // start timing of flash function
  }
 
  if (pressedFlash && ((currentFlashMillis - startFlashMillis)>= flashTime)) // if flash start and flash time elapsed, flip head light state
  {
    HLStatus = !HLStatus;
    pressedFlash = false;
  }
  
}

void loop()
{
  if (!pressedFlash)
  {
  	HLStatus = digitalRead(HLMainPin);
    digitalWrite(HLRelayPin, HLStatus);
  }
  flash();
}

Without pulldown resistors (10k) from pin to ground, the inputs can float HIGH when the button is not pressed causing "ghost" operation. Why not wire the switches from GND to input pin and use:

pinMode(HLMainPin, INPUT_PULLUP);

The logic will be inverted so it's LOW when the button is pressed, HIGH otherwise, no resistors needed.

outsider:
Without pulldown resistors (10k) from pin to ground, the inputs can float HIGH when the button is not pressed causing "ghost" operation. Why not wire the switches from GND to input pin and use:

pinMode(HLMainPin, INPUT_PULLUP);

The logic will be inverted so it's LOW when the button is pressed, HIGH otherwise.

Thanks for the suggestion, I will probably do that once I have an Arduino to play with.

I managed to get it to work with the following code.
My issue was I wasn't outputting the status of the head light at each loop so the flashing function was running but I coudnt see the results.
Secondly I need a check at each flash so that the correct flash timing is done without interrupting the loop.

bool pressedFlash;
bool HLStatus;
bool didFirstFlash;
bool didSecondFlash;
bool didThirdFlash;
bool didFourthFlash;

unsigned const int HLRelayPin = 7;
unsigned const int HLMainPin = 8;
unsigned const int flashPin = 9;

unsigned long startFlashMillis;
unsigned long currentFlashMillis;

unsigned long flashTime = 200;

void setup()
{
  pinMode(HLMainPin, INPUT); // main head light switch pin 
  pinMode(HLRelayPin, OUTPUT); // relay which control head light pin
  pinMode(flashPin, INPUT); // flash button pin
  digitalWrite(HLRelayPin, LOW); // initial LOW setting
  HLStatus = false; // initial setting to false
 

  // flash function parameters
  pressedFlash = false; // initial setting to false
  didFirstFlash = false;
  didSecondFlash = false;
  didThirdFlash = false;
  didFourthFlash = false;
  startFlashMillis = millis(); // initial start time
}

void flash() // flash function
{
  currentFlashMillis = millis(); // flash function start time
  
  if (!pressedFlash) // if flash button was not pressed before (first flash)
  {
    HLStatus = !HLStatus; // flip head light status
    pressedFlash = true; // flash button was pressed
    startFlashMillis = currentFlashMillis; // start timing of first flash
  }
 
  if (pressedFlash && ((currentFlashMillis - startFlashMillis) >= flashTime)) // if first flash time elapsed, flip head light state
  {
    HLStatus = !HLStatus;
    didFirstFlash = true;
  }

  if (didFirstFlash && ((currentFlashMillis - startFlashMillis) >= (2*flashTime))) // if second flash time elapsed, flip head light state
  {
    HLStatus = !HLStatus;
    didSecondFlash = true;
  }
  
  if (didSecondFlash && ((currentFlashMillis - startFlashMillis) >= (3*flashTime))) // if third flash time elapsed, flip head light state
  {
    HLStatus = !HLStatus;
    didThirdFlash = true;
  }

  if (didThirdFlash && ((currentFlashMillis - startFlashMillis) >= (4*flashTime))) // if fourth flash time elapsed, flip head light state
  {
    HLStatus = !HLStatus;
    didFourthFlash = true;
  }

  if (didFourthFlash && ((currentFlashMillis - startFlashMillis) >= (5*flashTime))) // if fifth flash time elapsed, flip head light state
  {
    HLStatus = !HLStatus;
    pressedFlash = false;
    didFirstFlash = false;
    didSecondFlash = false;
    didThirdFlash = false;
    didFourthFlash = false;
  }
  
}

void loop()
{
  digitalWrite(HLRelayPin, HLStatus); // head lights status driven by HLStatus
  
  if (!pressedFlash) // if the flash button was not pressed, check head light status from main switch
  {
    HLStatus = digitalRead(HLMainPin); // set HLStatus to main head light switch
  }
  
  if (digitalRead(flashPin) || pressedFlash) // if the flash button is pressed or was pressed (before resetting) then do flash function
  {
  flash();
  }
}

I would like to try and make the code more efficient now as it seems pretty long and complex to do what i thought would be a simple task.

I will probably do that once I have an Arduino to play with.

I assume you're working on a simulator? :slight_smile:
Do you want a certain number of flashes or flash as long as the button is pressed?

outsider:
I assume you’re working on a simulator? :slight_smile:
Do you want a certain number of flashes or flash as long as the button is pressed?

Yes, using simulator.
The program was to make a certain number of flashes once pressed and then revert back to the main switch