Function executes sometimes just once and sometimes twice?!

All

I'm having a very hard time to understand why my program is executing a section of code sometimes once (as designed) and sometimes is running through it twice.

The part of the code is meant to flash an OUTPUT by set number of times, sometimes its the correct amount and sometimes its double; I have no idea why at this point.

Here is the section with the flashing function:

void flash() // flash function
{
  currentFlashMillis = millis(); // flash function start time

  if (!doingFlashing) // if flash button was not tapped before (first flash) start timing
  {
    doingFlashing = true; // starting flash function
    startFlashMillis = currentFlashMillis; // start timing of first flash
    tapAuxLight = false; // tap now done
  }

  if (((currentFlashMillis - startFlashMillis) >= flashTime) && (NFlashes < (flashQTY*2))) // if flash time has elapsed, flip light status. Increment NFlashes and save time.
  {
      startFlashMillis = currentFlashMillis;
      NFlashes++;
      if (HL1Status == LOW) {
        HL1Status = HIGH;
      } 
      else {
        HL1Status = LOW;
      }
  }

  if (NFlashes > ((flashQTY*2)-1)) // once flashQTY is done, stop flashing. 
  {
    NFlashes = 0;
    doingFlashing =  false;
  }
}

In this section the flashQTY is 3, so it cycles and increments 6 times to make it turn on and then off 3 times, but sometimes its cycling 12 times?!

The function is triggered by the duration at which a button is pressed, maybe there is an error here which is causing it to cycle twice?

void checkAuxLight() // function which checks for how long the aux light button was pressed
{
  currentAuxLightMillis = millis();
     // is aux light button was pressed, set to pressed, and start timing
  if (!pressedAuxLight) {
    pressedAuxLight = true;
    startAuxLightMillis = currentAuxLightMillis;
  }
     // if aux light was pressed for short time, set to tapped aux light
  if (!digitalRead(auxLightPin) && ((currentAuxLightMillis - startAuxLightMillis)) < holdAuxTime && ((currentAuxLightMillis - startAuxLightMillis) > errorAuxTime)) {
    tapAuxLight = true;
    pressedAuxLight = false;
  }
     // if aux light was pressed for long time, set to hold aux light
  if (digitalRead(auxLightPin) && (currentAuxLightMillis - startAuxLightMillis) > holdAuxTime && !(waitAuxLight == true)) {
    holdAuxLight = !holdAuxLight;
    waitAuxLight = true;
  } 

  if (!digitalRead(auxLightPin) && waitAuxLight == true) {
  pressedAuxLight = false;
  waitAuxLight = false;
  }
}

Here is the full code for those that may find it useful:
Any help is very much appreciated as its just not consistent.

Thanks,
Ben

// Pin detail
const int HL1RelayPin = 7;
const int HL2RelayPin = 4;
const int HLMainPin = 8;
const int auxLightPin = 9;

// Headlight program variables
bool HL1Status;
bool HL2Status;
bool pressedAuxLight;
bool waitAuxLight;
bool tapAuxLight;
bool holdAuxLight;
bool doingFlashing;
int NFlashes = 0;
int flashQTY = 3;

unsigned long startFlashMillis;
unsigned long currentFlashMillis;
unsigned long startAuxLightMillis;
unsigned long currentAuxLightMillis;

const long flashTime = 150; // timing between each flash state
const long errorAuxTime = 50; // 
const long holdAuxTime = 1000; // time required to press aux light button for hold function

void setup()
{
  
  pinMode(HLMainPin, INPUT_PULLUP); // main head light switch pin 
  pinMode(HL1RelayPin, OUTPUT); // relay which control head light 1 pin
  pinMode(HL2RelayPin, OUTPUT); // relat which controls head light 2 pin
  pinMode(auxLightPin, INPUT_PULLUP); // flash button pin
  digitalWrite(HL1RelayPin, LOW); // initial LOW setting
  digitalWrite(HL2RelayPin, LOW); // 

  // head light parameters
  HL1Status = false; // initial setting to false
  HL2Status = false; // initial setting to false
  pressedAuxLight = false; // initial setting to false
  waitAuxLight = false; // initial setting to false
  holdAuxLight = false; // initial setting to false
  doingFlashing = false; // initial setting to false
}

void checkAuxLight() // function which checks for how long the aux light button was pressed
{
  currentAuxLightMillis = millis();
     // is aux light button was pressed, set to pressed, and start timing
  if (!pressedAuxLight) {
    pressedAuxLight = true;
    startAuxLightMillis = currentAuxLightMillis;
  }
     // if aux light was pressed for short time, set to tapped aux light
  if (!digitalRead(auxLightPin) && ((currentAuxLightMillis - startAuxLightMillis)) < holdAuxTime && ((currentAuxLightMillis - startAuxLightMillis) > errorAuxTime)) {
    tapAuxLight = true;
    pressedAuxLight = false;
  }
     // if aux light was pressed for long time, set to hold aux light
  if (digitalRead(auxLightPin) && (currentAuxLightMillis - startAuxLightMillis) > holdAuxTime && !(waitAuxLight == true)) {
    holdAuxLight = !holdAuxLight;
    waitAuxLight = true;
  } 

  if (!digitalRead(auxLightPin) && waitAuxLight == true) {
  pressedAuxLight = false;
  waitAuxLight = false;
  }
}

void flash() // flash function
{
  currentFlashMillis = millis(); // flash function start time

  if (!doingFlashing) // if flash button was not tapped before (first flash) start timing
  {
    doingFlashing = true; // starting flash function
    startFlashMillis = currentFlashMillis; // start timing of first flash
    tapAuxLight = false; // tap now done
  }

  if (((currentFlashMillis - startFlashMillis) >= flashTime) && (NFlashes < (flashQTY*2))) // if flash time has elapsed, flip light status. Increment NFlashes and save time.
  {
      startFlashMillis = currentFlashMillis;
      NFlashes++;
      if (HL1Status == LOW) {
        HL1Status = HIGH;
      } 
      else {
        HL1Status = LOW;
      }
  }

  if (NFlashes > ((flashQTY*2)-1)) // once flashQTY is done, stop flashing. 
  {
    NFlashes = 0;
    doingFlashing =  false;
  }
}

void headLights()
{
  digitalWrite(HL1RelayPin, HL1Status); // output head light 1 status
  digitalWrite(HL2RelayPin, HL2Status); // output head light 2 status
  HL2Status = digitalRead(HLMainPin); // set HL2Status to main head light switch

  if (digitalRead(auxLightPin) || pressedAuxLight) // if button is aux light button is pressed, check aux light button timing
  {
    checkAuxLight();
  }

  if (digitalRead(HLMainPin) && !doingFlashing) // if main head light switch is on, and not flashing
  {
    if(holdAuxLight) // if hold aux is on then turn HL1 on
    {
      HL1Status = true;
    }
    else
    {
      HL1Status = false;
    }
  }

  if (!digitalRead(HLMainPin) && !doingFlashing) // if main head light switch is on, and not flashing
  {
    HL1Status = false;
  }

  if (tapAuxLight || doingFlashing) // if the aux light button is tapped or was tapped (before resetting) then do flash function
  {
    flash();
  }
}


void loop()
{
headLights();
}

correct me if I'm wrong but I do see any switch debounce in you code which could explain why you are getting that behaviour.

try including a switch debounce in you code and see if that fixes the issue.

Thats for introducing we to 'switch debounce'; i'd never heard of the term.

Since posting this thread I added a serial print to check the number of flashes it performs, and since adding it i hasnt played through twice. I'm not quite sure adding a serial is fixing the issue, but I'll look at some switch debounce code as well.

I'm not quite sure adding a serial is fixing the issue,

Output to Serial takes time so depending where you put it in the code it may be acting as a short delay which effectively debounces the input.