Inconsistent results from code?

I’m working on a Nixie clock, and thankfully i’ve got the clock itself working fine. I’m trying to implement a cathode poisoning prevention routine, basically I need to cycle all the digits in all the tubes every 5-10 minutes or so. This is proving to be a bigger challenge than anticipated.

The code is not consistent, it doesn’t consistently recognize that the minutes one’s digit is a 5 or 0. More importantly though, is that if it does recognize a 5 or 0 sometimes only the ones digit will cycle, other times all digits will cycle indefinitely, yet others nothing will happen.

Any ideas?


  rtc.getTime();  //Get the current I2C time
  int Ones = int(t.min);  //Cast the minutes time into an int
  int HOURS = int(t.min);  //Cast the minutes time into an int

  int ONES_DIGIT = Ones%10;  //Get the ones digit
  int START_MILLIS = millis();  //Store the time before the loop starts.
  int MIN_ONES = 0;    //Create variables for loop.
  int MIN_TENS = 0;
  int HOURS_ONES = 0;
  int HOURS_TENS = 0;
  int DTIME = 250;  //Variable to try different delay times.

  if((ONES_DIGIT != LAST_MINS)){  //Run if the current ones digit is not equal to the last time this was run.
                                  //Only runs once per minute.
    if(ONES_DIGIT == 0 || ONES_DIGIT == 5){  //Only run every 5 minutes, when ones digit is 0 or 5.
      Serial.print("CATHODE POISONING AT ");  //Printing this to check if the if statement is being run.
      while(millis() < (START_MILLIS + 5000)){  //Run this loop for 5 seconds
        MIN_ONES = random(0,9);  //Pick a random number
        if(millis() > (START_MILLIS + DTIME)){  //Wait one delay time then start random number
          MIN_TENS = random(0,9);}
        if(millis() > (START_MILLIS + 2*DTIME)){  //Wait two delay time then start random number
          HOURS_ONES = random(0,9);}
        if(millis() > (START_MILLIS + 3*DTIME)){  //Wait three delay time then start random number
          HOURS_TENS = random(0,9);}

        WRITE_TUBE(MIN_ONES, MIN_TENS,1);    //Write data to tubes.

    delay(75);}  //Delay so number change is visible.
    LAST_MINS = ONES_DIGIT;}  //Set LAST_MINS global to the current ones digit.


int START_MILLIS = millis();

Variables holding time values should be unsigned long.

Your code to work out whether an elapsed time has passed will not handle millis() rollover correctly so it may misbehave after a few weeks. Where you have:

while(millis() < (START_MILLIS + 5000))

the correct implementation would be:

while(millis() - START_MILLIS < 5000)

In abstract terms the behaviour is the same, but only the second version produces correct behaviour when the value of millis() rolls over.

Some of the code looks a bit dodgy (int HOURS = int(t.min); for example) but I don’t see anything that is definitely wrong. I’m a bit surprised to see you generating random numbers - it seems unnecessary, and the logic was complex enough to not be obvious whether it was correct - but I’m pretty sure your fundamental problem was caused by using the wrong variable type for time values.

Thank you, that makes perfect sense. I chose the random numbers for looks, im not sure if i'll keep it. What i'd really like to do is implement a slot machine type cycling, but I'm not sure if I feel like spending the time!

Thanks again!