Debugging millis code

Hello, I have a problem with my loop where it is something that after a while hick up it...

What I am doing. I am blinking LEDs from digitalPin 10 and I have a indication on pin 7 that lights up another LED that the program is on. While I have pushed the button I start this program, to power this I use a powerbank and to keep it alive I use a function to send a signal to the powerbank every 4 sec that, hey we are still running do not sleep.

Everything works fine but after a maybe 30 sec the Pin 8 that puts out signal every 4 sec is constantly HIGH.

My guess is that it is something that hick up in this section

if (flashFlag == true)
  {
    //*************
    //flashing timer
    //is it time to toggle the LED ?
    if (micros() - flashMircos >= interval)
    {
      //restart timer
      flashMircos = flashMircos + interval;

      //toggle LED
      digitalWrite(LEDpin, !digitalRead(LEDpin));
      digitalWrite(onIndicationLED, HIGH);
      keepAlive();
    }

Here are the full code

#define PUSHED            LOW

#define LEDon             HIGH
#define LEDoff            LOW

#define firstFrequency          100//100 Hz
#define secondFrequency         200//200 Hz
#define thirdFrequency          250//250 HZ

//***********************************************************************
//Switch connection
//+5V---[internal pullup resistor]---[input]---[switch]---GND(0V)
const byte startSwitch  = 2;

const byte LEDpin       = 10;  //[output pin]---[LED >|]---[220R]---GND/0V
const byte keepAlivePin = 8;
const byte onIndicationLED = 7;

byte currentState;
byte lastStartState;
byte lastStopState;
byte frequencyCounter;

bool flashFlag          = false;

//timing stuff
unsigned long onIndicationMillis;
unsigned long keepAliveMillis;
unsigned long switchMillis;
unsigned long xMillis;
unsigned long flashMircos;


//const unsigned long xMinutes = 10 * 60 * 1000ul;  //10 minutes
const unsigned long xMinutes   = 20 * 1000ul;        //for testing use only 4 seconds

const unsigned long timeOne   = 1000000ul / (firstFrequency  * 2);
const unsigned long timeTwo   = 1000000ul / (secondFrequency * 2);
const unsigned long timeThree = 1000000ul / (thirdFrequency  * 2);

unsigned long interval;


static int last = 0;
static bool keepAliveSignal = false;





//***********************************************************************
void setup()
{
  pinMode(onIndicationLED, OUTPUT);
  pinMode(keepAlivePin, OUTPUT);
  pinMode(LEDpin, OUTPUT);
  
  pinMode(startSwitch, INPUT_PULLUP); //pushed/closed = LOW

  interval = timeOne;

} //END of setup()

//***********************************************************************
void loop()
{
  
  

  //**************************
  //check the switches every 50ms
  //time to check our switches ?
  if (millis() - switchMillis >= 50)
  {
    //restart timer
    switchMillis = millis();

    checkSwitches();

  }

  //**************************
  //is flashing enabled ?
  if (flashFlag == true)
  {
    //*************
    //flashing timer
    //is it time to toggle the LED ?
    if (micros() - flashMircos >= interval)
    {
      //restart timer
      flashMircos = flashMircos + interval;

      //toggle LED
      digitalWrite(LEDpin, !digitalRead(LEDpin));
      digitalWrite(onIndicationLED, HIGH);
      keepAlive();
    }

    //**************
    //X minute timer
    //has X minutes expired ?
    if (millis() - xMillis >= xMinutes)
    {
      //restart the timer
      xMillis = millis();

      //next frequency
      frequencyCounter++;

      //**************
      if (frequencyCounter == 1)
      {
        interval = timeTwo;
      }

      //**************
      else if (frequencyCounter == 2)
      {
        interval = timeThree;
      }

      //**************
      else if (frequencyCounter > 2)
      {
        //disable flashing
        flashFlag = false;

        //turn LED OFF
        digitalWrite(LEDpin, LEDoff);
        digitalWrite(onIndicationLED, LEDoff);
        digitalWrite(keepAlivePin, LOW);
      }
    }

  } //END of if (flashFlag == true)

  //**************************

} //END of loop()


//***********************************************************************

void keepAlive() 
{
    
    if (millis() - last > 4000) // cycle length 4 s
    {
        digitalWrite(keepAlivePin, HIGH);
        last = millis(); // record the time when pulse actually goes high
        keepAliveSignal = true;
    }
    else
    if (keepAliveSignal && millis() - last > 450) // wait until AT LEAST 450 ms has passed
    {
        digitalWrite(keepAlivePin, LOW);
        keepAliveSignal = false;
    }
}




void checkSwitches()
{
  //**************************
  //Start switch
  currentState = digitalRead(startSwitch);

  //has the switch changed state ?
  if (lastStartState != currentState)
  {
    //update to the new state
    lastStartState = currentState;

    //when we 'are not' flashing, was the switch just pushed/closed ?
    if (flashFlag == false && currentState == PUSHED)
    {
      //start the x timer
      xMillis = millis();

      //initalize frequency counter
      frequencyCounter = 0;

      //select the flash frequency
      interval = timeOne;

      //start the flashing timer
      flashMircos = micros();

      //enable flashing
      flashFlag = true;
    }

    else if (flashFlag == true && currentState == PUSHED)
    {
      //disable flashing
      flashFlag = false;

      //turn LED OFF
      digitalWrite(LEDpin, LEDoff);
      digitalWrite(onIndicationLED, LEDoff);
      digitalWrite(keepAlivePin, LOW);
    }
  }
}

Thirty second problems are often caused by inappropriate use of int where unsigned long was required. In this case:

static int last = 0;

wildbill:
Thirty second problems are often caused by inappropriate use of int where unsigned long was required. In this case:

static int last = 0;

Big thanks! @wildbill that does look like it working now, will try having the scetch running for 45 min and se if it still works for so long!

This line

flashMircos = flashMircos + interval;

should be

flashMircos = micros();

guix:
This line

flashMircos = flashMircos + interval;

should be

flashMircos = micros();

Thanks!

if (keepAliveSignal && millis() - last > 450)

This line technically works find without parenthesis, but they would help clarify your intent.

guix:
This line

flashMircos = flashMircos + interval;

should be

flashMircos = micros();

The original code should work fine, and is how to do it when you want a precise interval that does not drift.

Once 'frequencyCounter' counts up past 2 it will have to count up past 255 before it rolls over back to zero. I'm surprised it isn't reset somewhere.

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