Jump to a specific time in a program for debugging

I have a program that run over a course of 30 or so minutes.
Let's say I want to debug something that happens in the 20 minute and I don't want to wait all that time to arrive to that point in program. Is there anyway I could jump to a specific time in the code? (assuming I'm in a non-blocking code)

Hi,
yes, it must exist, but without seeing your code it is impossible to try to help you.
Using the proper </> tags, post your code.

Let us know which UNO/Mega ... and what other components you are using.
It would be nice to also attach the schematic of your project.

I feel your pain. There is no one good way, but you can program in anticipation of having this problem.

One idea is to make you code go fast motion by having alternate time constants for things that that are timed. You might run something in seconds instead of minutes by changing a few numbers. You might have a set on alternate constants that see that "20 minutes" has gone by, and revert to real time passage.

Another method is to know your state variables well enough to make the program think it is already been running for 20 minutes - simply fake all the results that would have been arrived at and jam them into the variables that would inform the logic of being at twenty minutes.

If you are trying to find a pesky error that crops only after some good time, it may be better to think your way through it rather than try to catch it in the act. Sometimes making good guesses and isolating suspicious logic or operations in smaller test programs can be useful.

HTH and looking forward to other ideas prolly better. Since I don't ever make any mistakes in my code, this kinda thing is more theoretical for me. :wink:

a7

If you want to handle time in minutes then increment your clock variable every minute. If you want to go to minute 20 then set your clock to 20. If you want to skip 20 minutes then increment your clock by 20.

Such a virtual clock was introduced by Simula67, the grandparent of all OO languages and simulation. Guess what the "67" is meaning.

I'm using Uno.

here is the code -
The function I would like to jump to a specific time at is startSequence

#define NUM_SOLENOIDS 9
//for debuging//
#define DEBUG 0
#define PrintingTime 1

//time translating//
#define sec * 1000
#define min * 60000
#define ms * 1

//reseting access//
void(* resetFunc) (void) = 0;

uint16_t millisOffset;
unsigned long currentMillis = millis();


//Button//
uint32_t tSwitch;
bool bState;
uint8_t swNow, swLast;
const uint8_t pinBtn = 11;

const uint8_t pinLED = A0;


 
//reseting//
bool buttonState;
uint32_t lastTimeButtonWasNotPressed;
uint16_t resetTime = 3000;  

//timeIs//
unsigned long hours = 0;
uint8_t minutes = 0; 
uint8_t seconds = 0; 
unsigned long milliseconds = 0;
unsigned long interval = 10000;

//solenoid structure//
struct Solenoid
{
  unsigned long startTime;       // The time this solenoid is first active
  unsigned long stopTime;        // The time this solenoid becomes inactive
  unsigned long minPulse;        // The minimum time the next pulse is generated
  unsigned long maxPulse;        // The maximum time the next pulse is generated
  unsigned long nextPulseStart;  // The time of the next pulse starts
  unsigned long nextPulseStop;   // The time of the next pulse  stops
  unsigned long pulseLength;     // The on time of the pulse
  uint8_t pin;                   // solenoid GPIO pin number
};

Solenoid mySolenoids[NUM_SOLENOIDS] = { 0 min, 40 min, 7 sec, 12 sec, 0, 0, 20 ms, 2, //solenoid num 0
                                        0 min, 40 min, 7 sec, 12 sec, 0, 0, 20 ms, 3,//solenoid num 1
                                        0 min, 40 min, 7 sec, 12 sec, 0, 0, 20 ms, 4, //solenoid num 2
                                        0 min, 40 min, 5 sec, 9 sec, 0, 0, 20 ms, 5,//solenoid num 3
                                        0 min, 40 min, 5 sec, 9 sec, 0, 0, 20 ms, 6,
                                        0 min, 40 min, 5 sec, 9 sec, 0, 0, 20 ms, 7,
                                        0 min, 40 min, 3 sec, 7 sec, 0, 0, 20 ms, 8, 
                                        0 min, 40 min, 3 sec, 7 sec, 0, 0, 20 ms, 9,
                                        0 min, 40 min, 3 sec, 7 sec, 0, 0, 20 ms, 10, 
                                      };



void setup()
{
  Serial.begin(115200);
  for (uint8_t i = 0; i < NUM_SOLENOIDS; i++)
  {
    pinMode(mySolenoids[i].pin, OUTPUT);
  }
  
  pinMode( pinBtn, INPUT_PULLUP );
  pinMode( pinLED, OUTPUT );
  swLast = digitalRead( pinBtn );
  tSwitch = currentMillis;
  bState = false;

    #if DEBUG
    Serial.println("Debug is on! ");
    #endif
    
//    #if DEBUG2
    
    
}

  void loop()
  {
    toggleSwitch();
    startSequence(toggleSwitch());
    reseting();
    update_time(); 
  
}


//button function//

bool toggleSwitch() 
{
  if( (millis() - tSwitch) >= 50ul )
  {
        tSwitch = currentMillis;
      
        swNow = digitalRead( pinBtn );
        if( swNow != swLast )
        {
            swLast = swNow;
            if( swNow == LOW )
            {
                bState ^= true;
                if( bState == true )
                digitalWrite( pinLED, HIGH );
                else
                digitalWrite( pinLED, LOW );
                
                #if DEBUG
                Serial.print("Button State: ");
                Serial.println(bState);
                #endif
                
                millisOffset = currentMillis; 
            }
        
        }
          
    }
    return bState;

}

//sequence timing function//

void startSequence(bool buttonState)
{  
 currentMillis = millis() - millisOffset;
for (uint8_t x = 0; x < NUM_SOLENOIDS; x++)
  {
    if(buttonState == 1)
    {
    // Is this solenoid active
    if (mySolenoids[x].startTime < currentMillis && mySolenoids[x].stopTime > currentMillis)
    {
      // Do we need to calculate a next pulse time?
  

      if (mySolenoids[x].nextPulseStop < currentMillis)
      {
        // Turn off solenoid
        digitalWrite(mySolenoids[x].pin, LOW);

        // Calculate nextPulseStart & nextPulseStop
        long  startOffset =random(mySolenoids[x].minPulse, mySolenoids[x].maxPulse);
        #if DEBUG
        Serial.print("solenoid number: ");
        Serial.println(x);
        Serial.print("time between pulses in ms: ");
        Serial.println(startOffset);
        #endif
        mySolenoids[x].nextPulseStart = startOffset + currentMillis;
        mySolenoids[x].nextPulseStop = mySolenoids[x].nextPulseStart + mySolenoids[x].pulseLength;
      }

      // Are we currently in the middle of a pulse?
      if (mySolenoids[x].nextPulseStart < currentMillis &&
          mySolenoids[x].nextPulseStop  > currentMillis)
      {
        //turn on solenoid
        digitalWrite(mySolenoids[x].pin, HIGH);
      }
    }
    
    if (currentMillis > mySolenoids[x].stopTime)
    {
      digitalWrite(mySolenoids[x].pin, LOW);   
    }

  }
  else
  {
    digitalWrite(mySolenoids[x].pin, LOW);
  }
 }
}


//reseting function//

bool reseting()
{
  buttonState = digitalRead(pinBtn);
  if (buttonState == HIGH)
  {
    lastTimeButtonWasNotPressed = millis();
  }
  if (millis() - lastTimeButtonWasNotPressed >= resetTime) {
    

    Serial.println("Resetting Arduino Program");
    Serial.println();
    digitalWrite(pinLED, HIGH);
    delay(100);
    digitalWrite(pinLED, LOW);
    delay(100);
     digitalWrite(pinLED, HIGH);
    delay(100);
    digitalWrite(pinLED, LOW);
    delay(100);
     digitalWrite(pinLED, HIGH);
    delay(100);
    digitalWrite(pinLED, LOW);
    delay(100);
    digitalWrite(pinLED, HIGH);
    delay(100);
    digitalWrite(pinLED, LOW);
    delay(100);
    digitalWrite(pinLED, HIGH);
    delay(100);
    digitalWrite(pinLED, LOW);
    delay(100);
    resetFunc();
  }
}


void update_time() {
  static unsigned long previous_millis = millis(); 
  static unsigned long previous_print = millis();
  unsigned long delta_t = millis() - previous_millis;
  previous_millis = millis();

  //Increment milliseconds with time between function calls.
  milliseconds += delta_t;
  //Increment seconds by milliseconds/1000.
  seconds += milliseconds / 1000;
  //Get rid of the seconds-part and only keep the remainder (prevents overflow in far future).
  milliseconds %= 1000;
  //Increment minutes by seconds/60.
  minutes += seconds / 60;
  //Get rid of the minutes-part and only keep the remainder.
  seconds %= 60;
  //Increment hours by minutes/60.
  hours += minutes / 60;
  //Get rid of the hours-part and only keep the remainder.
  minutes %= 60;


  //Check if interval has elapsed.
    
  if(millis() - previous_print > interval)
  {
    //Save print time.
    previous_print = millis();   
    //Print time in format HH:mm:ss.
    #if PrintingTime
    Serial.print("Time is: ");
    if(hours <= 9)
    Serial.print("0");
    Serial.print(hours);
    Serial.print(":");
    if(minutes <= 9)
    Serial.print("0");     
    Serial.print(minutes);
    Serial.print(":");
    if(seconds <= 9)
    Serial.print("0");
    Serial.print(seconds);
    Serial.println();
    #endif

  }
}
  

For testing time-activated functions, most people either speed up the clock tick rate, or change the time settings so that long waits are not required for specific events to be activated.

...is a waste of Flash. Don't do that.

Allow me to introduce the F-macro.

Replace all calls to millis with a call to micros. Everything will run 1000 times faster. If it can.

You can probably get away with multiplying the value returned from millis. For example, I think using millis() * 5 will make your program run five times faster.

you could write your own millis function and add a 20 minutes offset for testing.

uint32_t myMillis()
{
  return millis() + 20 * 60 * 1000UL;
}

and use myMillis() instead of millis().

If your testing is finished, just delete the offset and return the plain millis().

unfortunately you messed arround with the calculation of your hour/minutes also and therefore it will not work as expected in a first step. But this is due to your creative way of calculating hours/minutes/seconds ...

may be this helps:

/*
   https://forum.arduino.cc/t/jump-to-a-specific-time-in-a-program-for-debugging/1035212/8

   will be deleted in 2022-11
*/

#define NUM_SOLENOIDS 9
//for debuging//
#define DEBUG 1
#define PrintingTime 1

//time translating//
#define sec * 1000
#define min * 60000
#define ms * 1

//reseting access//
void(* resetFunc) (void) = 0;

uint16_t millisOffset;
unsigned long currentMillis;


//Button//
uint32_t tSwitch;
bool bState;
uint8_t swNow, swLast;
const uint8_t pinBtn = 11;

const uint8_t pinLED = A0;

//reseting//
bool buttonState;
uint32_t lastTimeButtonWasNotPressed;
uint16_t resetTime = 3000;

//timeIs//
unsigned long hours = 0;
uint8_t minutes = 0;
uint8_t seconds = 0;
unsigned long milliseconds = 0;
unsigned long interval = 10000;

//solenoid structure//
struct Solenoid
{
  unsigned long startTime;       // The time this solenoid is first active
  unsigned long stopTime;        // The time this solenoid becomes inactive
  unsigned long minPulse;        // The minimum time the next pulse is generated
  unsigned long maxPulse;        // The maximum time the next pulse is generated
  unsigned long nextPulseStart;  // The time of the next pulse starts
  unsigned long nextPulseStop;   // The time of the next pulse  stops
  unsigned long pulseLength;     // The on time of the pulse
  uint8_t pin;                   // solenoid GPIO pin number
};

Solenoid mySolenoids[NUM_SOLENOIDS] = { 0 min, 40 min, 7 sec, 12 sec, 0, 0, 20 ms, 2, //solenoid num 0
                                        0 min, 40 min, 7 sec, 12 sec, 0, 0, 20 ms, 3,//solenoid num 1
                                        0 min, 40 min, 7 sec, 12 sec, 0, 0, 20 ms, 4, //solenoid num 2
                                        0 min, 40 min, 5 sec, 9 sec, 0, 0, 20 ms, 5,//solenoid num 3
                                        0 min, 40 min, 5 sec, 9 sec, 0, 0, 20 ms, 6,
                                        0 min, 40 min, 5 sec, 9 sec, 0, 0, 20 ms, 7,
                                        0 min, 40 min, 3 sec, 7 sec, 0, 0, 20 ms, 8,
                                        0 min, 40 min, 3 sec, 7 sec, 0, 0, 20 ms, 9,
                                        0 min, 40 min, 3 sec, 7 sec, 0, 0, 20 ms, 10,
                                      };


uint32_t myMillis()
{
  return millis() + (20 * 60 * 1000UL);
}

void setup()
{
  Serial.begin(115200);
  for (uint8_t i = 0; i < NUM_SOLENOIDS; i++)
  {
    pinMode(mySolenoids[i].pin, OUTPUT);
  }

  pinMode( pinBtn, INPUT_PULLUP );
  pinMode( pinLED, OUTPUT );
  swLast = digitalRead( pinBtn );
  tSwitch = myMillis();
  bState = false;

#if DEBUG
  Serial.println("Debug is on! ");
#endif
  //    #if DEBUG2
}

void loop()
{
  toggleSwitch();
  startSequence(toggleSwitch());
  reseting();
  update_time();
}


//button function//
bool toggleSwitch()
{
  if ( (myMillis() - tSwitch) >= 50ul )
  {
    tSwitch = currentMillis;

    swNow = digitalRead( pinBtn );
    if ( swNow != swLast )
    {
      swLast = swNow;
      if ( swNow == LOW )
      {
        bState ^= true;
        if ( bState == true )
          digitalWrite( pinLED, HIGH );
        else
          digitalWrite( pinLED, LOW );

#if DEBUG
        Serial.print("Button State: ");
        Serial.println(bState);
#endif

        millisOffset = currentMillis;
      }
    }
  }
  return bState;
}

//sequence timing function//

void startSequence(bool buttonState)
{
  currentMillis = myMillis() - millisOffset;
  for (uint8_t x = 0; x < NUM_SOLENOIDS; x++)
  {
    if (buttonState == 1)
    {
      // Is this solenoid active
      if (mySolenoids[x].startTime < currentMillis && mySolenoids[x].stopTime > currentMillis)
      {
        // Do we need to calculate a next pulse time?

        if (mySolenoids[x].nextPulseStop < currentMillis)
        {
          // Turn off solenoid
          digitalWrite(mySolenoids[x].pin, LOW);

          // Calculate nextPulseStart & nextPulseStop
          long  startOffset = random(mySolenoids[x].minPulse, mySolenoids[x].maxPulse);
#if DEBUG
          Serial.print("solenoid number: ");
          Serial.println(x);
          Serial.print("time between pulses in ms: ");
          Serial.println(startOffset);
#endif
          mySolenoids[x].nextPulseStart = startOffset + currentMillis;
          mySolenoids[x].nextPulseStop = mySolenoids[x].nextPulseStart + mySolenoids[x].pulseLength;
        }

        // Are we currently in the middle of a pulse?
        if (mySolenoids[x].nextPulseStart < currentMillis &&
            mySolenoids[x].nextPulseStop  > currentMillis)
        {
          //turn on solenoid
          digitalWrite(mySolenoids[x].pin, HIGH);
        }
      }

      if (currentMillis > mySolenoids[x].stopTime)
      {
        digitalWrite(mySolenoids[x].pin, LOW);
      }
    }
    else
    {
      digitalWrite(mySolenoids[x].pin, LOW);
    }
  }
}


//reseting function//

bool reseting()
{
  buttonState = digitalRead(pinBtn);
  if (buttonState == HIGH)
  {
    lastTimeButtonWasNotPressed = myMillis();
  }
  if (myMillis() - lastTimeButtonWasNotPressed >= resetTime) {
    Serial.println("Resetting Arduino Program");
    Serial.println();
    digitalWrite(pinLED, HIGH);
    delay(100);
    digitalWrite(pinLED, LOW);
    delay(100);
    digitalWrite(pinLED, HIGH);
    delay(100);
    digitalWrite(pinLED, LOW);
    delay(100);
    digitalWrite(pinLED, HIGH);
    delay(100);
    digitalWrite(pinLED, LOW);
    delay(100);
    digitalWrite(pinLED, HIGH);
    delay(100);
    digitalWrite(pinLED, LOW);
    delay(100);
    digitalWrite(pinLED, HIGH);
    delay(100);
    digitalWrite(pinLED, LOW);
    delay(100);
    resetFunc();
  }
}



void update_time()   // modified by noiasca
{
  static unsigned long previous_millis = 0;
  static unsigned long previous_print = 0;
  uint32_t currentMillis = myMillis();
  previous_millis = currentMillis;

  //us fraction for milliseconds
  milliseconds = currentMillis % 1000;

  seconds = (currentMillis / 1000) % 60;
  minutes = (currentMillis / 1000 / 60) % 60;
  hours = (currentMillis / 1000 / 60 / 60 ) % 24;

  //Check if interval has elapsed.

  if (myMillis() - previous_print > interval)
  {
    //Save print time.
    previous_print = myMillis();
    //Print time in format HH:mm:ss.
#if PrintingTime
    Serial.print("Time is: ");
    if (hours <= 9)
      Serial.print("0");
    Serial.print(hours);
    Serial.print(":");
    if (minutes <= 9)
      Serial.print("0");
    Serial.print(minutes);
    Serial.print(":");
    if (seconds <= 9)
      Serial.print("0");
    Serial.print(seconds);
    Serial.println();
#endif
  }
}

Thanks for your example which seems to work just fine. Although when I try to use it with a little different code it was not working for me.

Can you see why? What am I missing?

#define NUM_SOLENOID 9

//time translating//
#define sec * 1000
#define min * 60000
#define ms * 1


//for debuging//
#define PrintingTime 1


uint8_t switchPin = 11;       // uint8_t is an unsigned (positive) 8-bit integer.  Giving the compiler this detail rather than a generic 'byte' helps it treat it as you would expect, resulting in Serial.print not needing that 'DEC' argument.
uint8_t ledPin = A0;
uint8_t buttonPressCount = 0; // Note an uint8_t stores a number from 0-255, so after 255 the buttonPressCount will go back to 0 again.  If you want to store a larger integer, use uint16_t (0-65535), uint32_t (0-4294967295), or even uint64_t (0-18446744073709551615).

uint8_t currentButtonState = HIGH;
uint8_t lastButtonState = HIGH;

uint32_t firstPressMillis = 0; // unsigned longs are uint32_t, an unsigned 32 bit integer.
uint32_t secondPressMillis = 0;
uint32_t currentMillis;

/////

//timeIs//
unsigned long hours = 0;
uint8_t minutes = 0; 
uint8_t seconds = 0; 
unsigned long milliseconds = 0;
unsigned long interval = 10000;



//PULSE//
const uint16_t PULSE =  100;

//Solenoid structure//
struct Solenoid
{
  unsigned long startTime;       // The time this led is first active after a buttun is first pressed
  unsigned long minPulse;        // The minimum time the next pulse is generated
  unsigned long maxPulse;        // The maximum time the next pulse is generated
  unsigned long nextPulseStart;  // The time of the next pulse starts
  unsigned long nextPulseStop;   // The time of the next pulse  stops
  unsigned long pulseLength;     // The on time of the pulse
  uint8_t pin;                   // led GPIO pin number
};
                                   // Start pulse min max        
Solenoid mySolenoid[NUM_SOLENOID] = {
                                     0 min, 1 sec, 2 sec, 0, 0, PULSE, 2, //solenoid num 0
                                     1 min, 1 sec, 2 sec, 0, 0, PULSE, 3,//solenoid num 1
                                     2 min, 1 sec, 2 sec, 0, 0, PULSE, 4, //solenoid num 2
                                     3 min, 7 sec, 12 sec, 0, 0, PULSE, 5, //solenoid num 3
                                     4 min, 7 sec, 12 sec, 0, 0, PULSE, 6,//solenoid num 4
                                     5 min, 7 sec, 12 sec, 0, 0, PULSE, 7, 
                                     6 min, 7 sec, 12 sec, 0, 0, PULSE, 8, 
                                     7 min, 7 sec, 12 sec, 0, 0, PULSE, 9,
                                     8 min, 7 sec, 12 sec, 0, 0, PULSE, 10

                                      };




///end solenoid struct//

struct SolenoidEnd
{
  unsigned long startTime;       // The time this led is first active after a buttun is first pressed
  unsigned long stopTime;        // The time this led becomes inactive after a buttun is second time pressed
  unsigned long minPulse;        // The minimum time the next pulse is generated
  unsigned long maxPulse;        // The maximum time the next pulse is generated
  unsigned long nextPulseStart;  // The time of the next pulse starts
  unsigned long nextPulseStop;   // The time of the next pulse  stops
  unsigned long pulseLength;     // The on time of the pulse
  uint8_t pin;                   // led GPIO pin number
};
   //                                       start   end    minpulse maxpulse
SolenoidEnd mySolenoidEnd[NUM_SOLENOID] = {
                                            0 sec, 2 min, 7 sec, 12 sec, 0, 0, PULSE, 2, //solenoid num 0
                                            0 sec, 2 min, 7 sec, 12 sec, 0, 0, PULSE, 3,//solenoid num 1
                                            0 sec, 2 min, 7 sec, 12 sec, 0, 0, PULSE, 4, //solenoid num 2
                                            0 sec, 2 min, 7 sec, 12 sec, 0, 0, PULSE, 5, 
                                            0 sec, 2 min, 7 sec, 12 sec, 0, 0, PULSE, 6,
                                            0 sec, 2 min, 7 sec, 12 sec, 0, 0, PULSE, 7,
                                            0 sec, 2 min, 7 sec, 12 sec, 0, 0, PULSE, 8, 
                                            0 sec, 2 min, 7 sec, 12 sec, 0, 0, PULSE, 9,
                                            0 sec, 2 min, 7 sec, 12 sec, 0, 0, PULSE, 10 

                                      };



// millis function for offseting (debug from a specific time)

uint32_t myMillis()
{
  return millis() + (20  * 60 * 1000UL);
}
                                     
void setup()
{
    Serial.begin(115200);

    // Setup the button.
    pinMode(switchPin, INPUT_PULLUP);
    

    // Setup the LED.
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin, LOW);
  
  // Solenoid
  for (uint8_t i = 0; i < NUM_SOLENOID; i++)
  {
    pinMode(mySolenoid[i].pin, OUTPUT);
  }
}

void loop()
{
  buttonPress();
  startSequence();
  endSequence();
  update_time();
  
}


void buttonPress ()
{
    byte currentButtonState = digitalRead (switchPin);
    if (lastButtonState != currentButtonState)  {
        lastButtonState = currentButtonState;
        delay (10);             // debounce

        if (LOW == currentButtonState)  {
            buttonPressCount++;
          Serial.print("Button press count: ");
          Serial.println(buttonPressCount);
            firstPressMillis = myMillis();
          Serial.print("button pressed time: ");
          Serial.println(firstPressMillis);
            digitalWrite (ledPin, ! digitalRead (ledPin));
        }
    }
}



void startSequence()
{  
 if(buttonPressCount == 1)
 {
   currentMillis = myMillis() - firstPressMillis;
for (uint8_t x = 0; x < NUM_SOLENOID; x++)
  {
   
    // Is this led active
    if (mySolenoid[x].startTime < currentMillis)
    {
      // Do we need to calculate a next pulse time?
  

      if (mySolenoid[x].nextPulseStop < currentMillis)
      {
        // Turn off led
        digitalWrite(mySolenoid[x].pin, LOW);

        // Calculate nextPulseStart & nextPulseStop
        long  startOffset =random(mySolenoid[x].minPulse, mySolenoid[x].maxPulse);
        mySolenoid[x].nextPulseStart = startOffset + currentMillis;
        mySolenoid[x].nextPulseStop = mySolenoid[x].nextPulseStart + mySolenoid[x].pulseLength;
      }

      // Are we currently in the middle of a pulse?
      if (mySolenoid[x].nextPulseStart < currentMillis &&
          mySolenoid[x].nextPulseStop  > currentMillis)
      {
        //turn on solenoid
        digitalWrite(mySolenoid[x].pin, HIGH);
      }
    }
  }
}
}

void endSequence()
{
  if(buttonPressCount >= 2)
 {
   currentMillis = myMillis() - firstPressMillis;
for (uint8_t x = 0; x < NUM_SOLENOID; x++)
  {
   
    // Is this led active
    if (mySolenoidEnd[x].startTime < currentMillis && mySolenoidEnd[x].stopTime > currentMillis)
    {
      // Do we need to calculate a next pulse time?
  

      if (mySolenoidEnd[x].nextPulseStop < currentMillis)
      {
        // Turn off led
        digitalWrite(mySolenoidEnd[x].pin, LOW);

        // Calculate nextPulseStart & nextPulseStop
        long  startOffset =random(mySolenoidEnd[x].minPulse, mySolenoidEnd[x].maxPulse);
        mySolenoidEnd[x].nextPulseStart = startOffset + currentMillis;
        mySolenoidEnd[x].nextPulseStop = mySolenoidEnd[x].nextPulseStart + mySolenoidEnd[x].pulseLength;
      }

      // Are we currently in the middle of a pulse?
      if (mySolenoidEnd[x].nextPulseStart < currentMillis &&
          mySolenoidEnd[x].nextPulseStop  > currentMillis)
      {
        //turn on led
        digitalWrite(mySolenoidEnd[x].pin, HIGH);
      }
    }
  }
}

}



///time printing///


void update_time() {
  static unsigned long previous_millis = myMillis(); 
  static unsigned long previous_print = myMillis();
  unsigned long delta_t = myMillis() - previous_millis;
  previous_millis = myMillis();

  //Increment milliseconds with time between function calls.
  milliseconds += delta_t;
  //Increment seconds by milliseconds/1000.
  seconds += milliseconds / 1000;
  //Get rid of the seconds-part and only keep the remainder (prevents overflow in far future).
  milliseconds %= 1000;
  //Increment minutes by seconds/60.
  minutes += seconds / 60;
  //Get rid of the minutes-part and only keep the remainder.
  seconds %= 60;
  //Increment hours by minutes/60.
  hours += minutes / 60;
  //Get rid of the hours-part and only keep the remainder.
  minutes %= 60;


  //Check if interval has elapsed.
    
  if(myMillis() - previous_print > interval)
  {
    //Save print time.
    previous_print = myMillis();   
    //Print time in format HH:mm:ss.
    #if PrintingTime
    Serial.print("Time is: ");
    if(hours <= 9)
    Serial.print("0");
    Serial.print(hours);
    Serial.print(":");
    if(minutes <= 9)
    Serial.print("0");     
    Serial.print(minutes);
    Serial.print(":");
    if(seconds <= 9)
    Serial.print("0");
    Serial.print(seconds);
    Serial.println();
    #endif

  }
}

You could describe what "it was not working" means in detail. What does your version do under which condition - what should it do instead?

But in general I don't understand why you switched back to your old update_time() logic. It had a reason why I've changed it to a shorter logic without this separate delta logic and just relies on millis() (plus the offset).

consider the latest code I've posted:
assuming my uint32_t myMillis() function is with offset of 20 minutes: return millis() + (20 * 60 * 1000UL);

When I am running the program and pressing the button I'm expecting that all solenoid will be pulsing. Instead of that only the first solenoid (which is start time is 0ms) is pulsing.

My mistake. Will change that

when you do time traveling from one time (0) to another (+20 min) you jump immediately and miss all minutes between. Depending on your program logic other solenoids missed their start because your time didn't have their "start minute".

either set the states accordingly at the end of setup before you enter the loop or do a different time manipulation: let the time run fast at the beginning and switch over to "normal" time periods later.

Why it was working perfectly in the previous code? is it something to do with the button function?

I did some printing at the beginning of the void startSequence() function

Serial.println(firstPressMillis); is indeed very high number corresponding to the offset we set at the myMillis() function (20 minute offset)

while the Serial.println(currentMillis); is starting to print from 0 (and I'm expecting it to print also a very high number which correspond to the offset we set)

void startSequence()
{  

    if(buttonPressCount == 1)
 {
  currentMillis = myMillis() - firstPressMillis;
  Serial.println(firstPressMillis);
  Serial.println(currentMillis);
   for (uint8_t x = 0; x < NUM_SOLENOID; x++)
  {
currentMillis = myMillis() - firstPressMillis;

myMillis() will return "a high number" ... if you substract "a high number" in firstPressMillis you will get 0.

I'm confused about

  • the data structures, what is the purpose of SolenoidEnd and the created array mySolenoidEnd. The new structure looks very similar to the first one, but why do you need to repeat the pin assignment.
  • and the program logic you want the program to perform.

I think I can't offer more help without an overall description, a detailed program flow and precise timing diagrams.

I fixed it!

my buttonPress function had an argument:

firstPressMillis = myMillis();

but needed to be
firstPressMillis =currentMillis;

I made that end structure in order to have the ability to stop each solenoid after a certain time since the time the button was pressed for the second time (specify by stopTime variable)

so why is this information not in the first structure if they all belong to one pin?

I try this for hours and days without success. This is why I decided to make another struct. (I know is something you should avoid when programming. repeating same code)

it was discussed here

If you plan to adopt it further I suggest you do a refactoring now.
It will not get any better if you just add more lines of code.

1 Like