Code works with Serial Monitoring, but not without

I'm trying to create a non-blocking sketch (no Delay(), no For loops) to smoothly cross fade an RGB LED from one colour to another using analogWrite() on three pins. It's tricky because the R/G/B steps from the initial PWM value to the next might not be the same, e.g. I want to start with all three off (black, rgb(0,0,0)) and cross fade up to an orange (rgb(248, 117, 49)) in a set amount of time (e.g. 2550 ms). Focusing on one colour first, I can get the Blue LED to fade up from black to pure blue (rgb,0,0,255) when outputting to the serial monitor but not when I comment out the #define statement at the top of the sketch, or even when removing all the Print() statements - the blue LED does not come on at all.

Arduino Pro Mini (5V, 16Mhz, powered by SparkFun Serial Basic Breakout board)

I've tried:

  1. Compiling/loading with both the 1.8.13 IDE and the newer 2.0.3 - same result.
  2. Using other pins on the Arduino Pro Mini - same result
  3. Removing all Serial.print() lines with the conditional #ifdef wrapper - same result
// Comment out the line below for production
// (serial monitoring affects timings)
#define DEBUG_MODE

bool isCommonAnode  = true;               // Set to false for common cathode

int redPin          = 9;
int grnPin          = 10;
int bluPin          = 11;

int delayBeforeStartupMS  = 3000;
int powerUpFadeTimeMS     = 2550;
int delayBeforeWarpMS     = 4500;

unsigned long timeStampMS = 0;

bool startupSeq     = false;
bool gotoWarp       = false;
bool startLoop      = false;

// Colours
int black[3]        = { 0, 0, 0 };
int blue[3]         = { 0, 0, 255 };

// Set initial colour values
int redVal          = black[0];
int grnVal          = black[1]; 
int bluVal          = black[2];

// Initialize colour variables
int prevR           = redVal;
int prevG           = grnVal;
int prevB           = bluVal;

int delayB          = 0;

// R/G/B PWM step values
int stepR;
int stepG; 
int stepB;

bool fadingB        = false;


void setup() {

#ifdef DEBUG_MODE
  Serial.begin(9600);
  
  Serial.println("-----------");
  Serial.println("DEVMODE ON");
  Serial.println("-----------");
#endif
  
  pinMode(redPin, OUTPUT);              // sets the pins as output
  pinMode(grnPin, OUTPUT);   
  pinMode(bluPin, OUTPUT); 

  // Set initial values (black)
  if ( isCommonAnode == true ) {
    analogWrite(redPin, 255 - redVal);  // Write current values to LED pins
    analogWrite(grnPin, 255 - grnVal);  // (using common anode, so need to use '255-')   
    analogWrite(bluPin, 255 - bluVal); 
  } else {
    analogWrite(redPin, redVal);        // Write current values to LED pins
    analogWrite(grnPin, grnVal); 
    analogWrite(bluPin, bluVal);        
  }

}

void loop() {

  static unsigned long startTimeBlueMS  = millis();

  unsigned long currentTimeMS           = millis();
  static unsigned long timeStampMS      = millis();

#ifdef DEBUG_MODE
    Serial.print("currentTimeMS = ");
    Serial.print(currentTimeMS);
    Serial.print(", startTimeBlueMS = ");
    Serial.println(startTimeBlueMS);
#endif

  if ( (currentTimeMS >= delayBeforeStartupMS) && (startupSeq == false) ) {
    startupSeq  = true;        // don't revert back to false or this will repeat with the next iteration    
    startLoop   = true;        // set boolean for first time thru loop                
  }

  // 1. Initial power-up -> dish and impulse crystal fade up to an orange/copper colour
  // ==================================================================================
  if ( (startupSeq == true) && (gotoWarp == false) ) {

    if ( startLoop == true ) {
      // Do this once for each cross fade colour
      bluVal    = blue[2];      // new value for Blue
      delayB    = calculateDelay(prevB, bluVal, powerUpFadeTimeMS);
      stepB     = prevB;        // set PWM step increment value to previous Blue value
      fadingB   = true;         // set flag for fading Blue

      startLoop = false;

#ifdef DEBUG_MODE
      Serial.print("bluVal = ");
      Serial.print(bluVal);
      Serial.print(", delayB = ");
      Serial.print(delayB);
      Serial.print(", stepB = ");
      Serial.print(stepB);
      Serial.print(", fadingB = ");
      Serial.println(fadingB);
#endif

    }
    
    if ( ( (currentTimeMS - startTimeBlueMS) >= delayB ) && ( fadingB == true ) ) { 

#ifdef DEBUG_MODE
      Serial.print("currentTimeMS = ");
      Serial.print(currentTimeMS);
      Serial.print(", startTimeBlueMS = ");
      Serial.print(startTimeBlueMS);
      Serial.print(", stepB = ");
      Serial.println(stepB);
#endif

      if ( stepB != bluVal ) {                

        if ( isCommonAnode == true ) {
          // analogWrite(redPin, 255 - redVal);  // Write current values to LED pins
          // analogWrite(grnPin, 255 - grnVal);  // (using common anode, so need to use '255-')   
          if ( bluVal > prevR ) {
            analogWrite(bluPin, 255 - (stepB++)); 
          } else {
            analogWrite(bluPin, 255 - (stepB--)); 
          }

        } else {
          // analogWrite(redPin, redVal);        // Write current values to LED pins
          // analogWrite(grnPin, grnVal); 
          if ( bluVal > prevR ) {
            analogWrite(bluPin, stepB++); 
          } else {
            analogWrite(bluPin, stepB--); 
          }       
        }
        
        startTimeBlueMS = currentTimeMS;         // set wait timer

      } else {
        // Done fading this colour
        fadingB = false;
      }



    } else {
      
      // Cross fade complete; update current values for next cross fade
      prevR       = redVal; 
      prevG       = grnVal; 
      prevB       = bluVal;   

      gotoWarp    = true;                     // set state variable to begin check for next cross fade
      timeStampMS = currentTimeMS;            // start timer for pause before going to warp

#ifdef DEBUG_MODE
      // Serial.print("prevR = ");
      // Serial.print(prevR);
      // Serial.print(", prevG = ");
      // Serial.print(prevG);
      Serial.print(", prevB = ");
      Serial.print(prevB);
      Serial.print(", gotoWarp = ");
      Serial.print(gotoWarp);
      Serial.print(", timeStampMS = ");
      Serial.println(timeStampMS);
#endif

    }
    

  }


  // 2. Go to warp
  // =============



}


int calculateDelay(int prevValue, int endValue, int overallFadeTimeMS) {
  // For delay between PWM steps, value needs to be positive so take absolute value of difference
  int delayMS = abs((endValue - prevValue));  // What's the overall gap?
  
  if (delayMS) {                              // If its non-zero, 
    delayMS = overallFadeTimeMS/delayMS;      //   divide by overallFadeTimeMS
  } 
  
  return delayMS;
}

Use counters, for example, int red, blu, grn; and change the color value in a while() condition (a forever-loop). Then, use a direction variable, for example, int dir = 1; to increase color values, and when it is time to change direction (at color maximum or minimum), dir = !dir; and "add" the direction to the color value for example, "color + minus-one" is the same as "color minus one."

But a while() loop is blocking code, and this will ultimately have other code to individually blink additional LEDs and other features. This is just prototyping for the RGB LED but it has to be non-blocking.

If no iterative software loop can exist, maybe your LED solution is hardware. I think the code to switch LEDs is too time-consuming for interrupts.

@RossAWaddell I have taken a low level flight about your sketch and I am baffled. I see no reason for behaviour you observe.

Can you try leaving in the Serial.begin() call, and print just one thing in setup() but squelch all the other printing?

When I am in my lab I will try your code, maybe I am not seeing it looking through the tiny window out here.

a7

Who is talking about interrupts?

Switching LEDs on and off or changing the PWM value using analgoWrite() is very fast enough to be done in an interrupt service routine, even if it is unfashionable.

a7

@alto777: So, while it worked fine before with debug on (Serial Monitoring), now if I do as you ask the LED no longer works.

I'm baffled ....

// Comment out the line below for production
// (serial monitoring affects timings)
#define DEBUG_MODE

bool isCommonAnode  = true;               // Set to false for common cathode

int redPin          = 9;
int grnPin          = 10;
int bluPin          = 11;

int delayBeforeStartupMS  = 3000;
int powerUpFadeTimeMS     = 2550;
int delayBeforeWarpMS     = 4500;

unsigned long timeStampMS = 0;

bool startupSeq     = false;
bool gotoWarp       = false;
bool startLoop      = false;

int black[3]        = { 0, 0, 0 };
int blue[3]         = { 0, 0, 255 };

// Set initial colour values
int redVal          = black[0];
int grnVal          = black[1]; 
int bluVal          = black[2];

// Initialize colour variables
int prevR           = redVal;
int prevG           = grnVal;
int prevB           = bluVal;

int delayB          = 0;

// R/G/B PWM step values
int stepR;
int stepG; 
int stepB;

bool fadingB        = false;


void setup() {

#ifdef DEBUG_MODE
  Serial.begin(9600);
  
  // Serial.println("-----------");
  Serial.println("DEBUG_MODE ON");
  // Serial.println("-----------");
#endif
  
  pinMode(redPin, OUTPUT);              // sets the pins as output
  pinMode(grnPin, OUTPUT);   
  pinMode(bluPin, OUTPUT); 

  // Set initial values (black)
  if ( isCommonAnode == true ) {
    analogWrite(redPin, 255 - redVal);  // Write current values to LED pins
    analogWrite(grnPin, 255 - grnVal);  // (using common anode, so need to use '255-')   
    analogWrite(bluPin, 255 - bluVal); 
  } else {
    analogWrite(redPin, redVal);        // Write current values to LED pins
    analogWrite(grnPin, grnVal); 
    analogWrite(bluPin, bluVal);        
  }

}

void loop() {

  static unsigned long startTimeBlueMS  = millis();

  unsigned long currentTimeMS           = millis();
  static unsigned long timeStampMS      = millis();

// #ifdef DEBUG_MODE
//     Serial.print("currentTimeMS = ");
//     Serial.print(currentTimeMS);
//     Serial.print(", startTimeBlueMS = ");
//     Serial.println(startTimeBlueMS);
// #endif

  if ( (currentTimeMS >= delayBeforeStartupMS) && (startupSeq == false) ) {
    startupSeq  = true;        // don't revert back to false or this will repeat with the next iteration    
    startLoop   = true;        // set boolean for first time thru loop                
  }

  // 1. Initial power-up -> dish and impulse crystal fade up to an orange/copper colour
  // ==================================================================================
  if ( (startupSeq == true) && (gotoWarp == false) ) {

    if ( startLoop == true ) {
      // Do this once for each cross fade colour
      bluVal    = blue[2];      // new value for Blue
      delayB    = calculateDelay(prevB, bluVal, powerUpFadeTimeMS);
      stepB     = prevB;        // set PWM step increment value to previous Blue value
      fadingB   = true;         // set flag for fading Blue

      startLoop = false;

// #ifdef DEBUG_MODE
//       Serial.print("bluVal = ");
//       Serial.print(bluVal);
//       Serial.print(", delayB = ");
//       Serial.print(delayB);
//       Serial.print(", stepB = ");
//       Serial.print(stepB);
//       Serial.print(", fadingB = ");
//       Serial.println(fadingB);
// #endif

    }
    
    if ( ( (currentTimeMS - startTimeBlueMS) >= delayB ) && ( fadingB == true ) ) { 

// #ifdef DEBUG_MODE
//       Serial.print("currentTimeMS = ");
//       Serial.print(currentTimeMS);
//       Serial.print(", startTimeBlueMS = ");
//       Serial.print(startTimeBlueMS);
//       Serial.print(", stepB = ");
//       Serial.println(stepB);
// #endif

      if ( stepB != bluVal ) {                

        if ( isCommonAnode == true ) {
          // analogWrite(redPin, 255 - redVal);  // Write current values to LED pins
          // analogWrite(grnPin, 255 - grnVal);  // (using common anode, so need to use '255-')   
          if ( bluVal > prevR ) {
            analogWrite(bluPin, 255 - (stepB++)); 
          } else {
            analogWrite(bluPin, 255 - (stepB--)); 
          }

        } else {
          // analogWrite(redPin, redVal);        // Write current values to LED pins
          // analogWrite(grnPin, grnVal); 
          if ( bluVal > prevR ) {
            analogWrite(bluPin, stepB++); 
          } else {
            analogWrite(bluPin, stepB--); 
          }       
        }
        
        startTimeBlueMS = currentTimeMS;         // set wait timer

      } else {
        // Done fading this colour
        fadingB = false;
      }



    } else {
      
      // Cross fade complete; update current values for next cross fade
      prevR       = redVal; 
      prevG       = grnVal; 
      prevB       = bluVal;   

      gotoWarp    = true;                     // set state variable to begin check for next cross fade
      timeStampMS = currentTimeMS;            // start timer for pause before going to warp

// #ifdef DEBUG_MODE
//       // Serial.print("prevR = ");
//       // Serial.print(prevR);
//       // Serial.print(", prevG = ");
//       // Serial.print(prevG);
//       Serial.print(", prevB = ");
//       Serial.print(prevB);
//       Serial.print(", gotoWarp = ");
//       Serial.print(gotoWarp);
//       Serial.print(", timeStampMS = ");
//       Serial.println(timeStampMS);
// #endif

    }
    

  }


  // 2. Go to warp
  // =============



}


int calculateDelay(int prevValue, int endValue, int overallFadeTimeMS) {
  // For delay between PWM steps, value needs to be positive so take absolute value of difference
  int delayMS = abs((endValue - prevValue));  // What's the overall gap?
  
  if (delayMS) {                              // If its non-zero, 
    delayMS = overallFadeTimeMS/delayMS;      //   divide by overallFadeTimeMS
  } 
  
  return delayMS;
}

@alto777 : there's something weird with the first #ifdef DEBUG_MODE block at the top of the loop(). If I comment out every other block, the blue LED works fine. but if I comment out this block, it stops working.

#ifdef DEBUG_MODE
    Serial.print("currentTimeMS = ");
    Serial.print(currentTimeMS);
    Serial.print(", startTimeBlueMS = ");
    Serial.println(startTimeBlueMS);
#endif

Hi Ross, After a quick look over I don't see anything obviously wrong. But possibly some kind of timing issue due to the addition of print statements. Perhaps take out the print and replace with delays which you can change and then watch the behavior. Just an idea. Hopefully not a bad one. Good luck.

TBH I can't make heads or tails of your code. Too much sun and other beach effects.

But I think there is a clue in your comment that the serial printing effects the timing.

I suspect that in the logic there is some kind of sensitivity to the precise timing, and the presence (or absence) of what are effectively fairly long delays as if you called delay() means that the flow falls into some kind of pattern that makes things stop. Happening.

It shouldn't be like you are channeling Heisenberg - there should be a way to have your information flowing out of serial without changing the program output.

A test would be to replace the serial output with delays that are about the same. Don't do that, too painful.

You could crank up the baud rate to 115200 or higher and see what happens.

When I am sober get to my lab I will read your prose description of where you are trying to go with this. I think the code could be much simpler.

a7

We can't both have a bad idea like that!

a7

@alto777 : I don’t think the baud rate will make a difference as the code works WITH serial monitoring and at least that first conditional build block, but not WITHOUT serial monitoring.

@anon24968741 : if I comment out the #define DEBUG_MODE at the top of the sketch and add a delay(1000); to the top of the loop(), it works - the blue light slowly fades up, although much slower since it hits that delay(1000); every time thru the loop().

Doesn't help me, though.

Who is talking about fashion? And to answer your question, YOU are talking about interrupts. They are not intended for slow illumination of LEDs to make them visible because interrupts are 100% blocking code. Everything waits until the semaphore is returned. Thanks for asking your question.

If you are ever not late arriving at this test

    if ( ( (currentTimeMS - startTimeBlueMS) >= delayB ) && ( fadingB == true ) ) { 

You will execute this early
 else {
        // Done fading this colour
        fadingB = false;
      }

It took a while to spot, since there is so much going on between the if and the else here. You have to rework your logic here. It's a tangle, perhaps you have your brain around it, I would just kinda start again with a clean slate.

I would probably do it based on a new value for the LED every N milliseconds, taking fade steps of an appropriate size, sorta inside out or backwards from your calculated delay and unit steps.

You can use this what I put in my test of your code, I saw it get there right away with no debug printing "helping" your logic:


  // 2. Go to warp
  // =============

static bool WTF;
if (!WTF) {
  Serial.println("IN WARP SECTION");
  WTF = true;
} // end of loop function

to see it get there when printing isn't consistently making you late for the timed test.


Where? You introduced interrupts into the conversation, or the search tool is broken.

a7

Sry, I didn't realize I was talking about interrupts!

I thought you brought them into this converation. I will read more carefully.

a7

@alto777 : forgive my ignorance, but how did you see the code get there without serial monitoring enabled? Also, the else statement you quote isn't the one associated with the if block you indicate is the problem; this is:

else {
      
      // Cross fade complete; update current values for next cross fade
      prevR       = redVal; 
      prevG       = grnVal; 
      prevB       = bluVal;   

      gotoWarp    = true;                     // set state variable to begin check for next cross fade
      timeStampMS = currentTimeMS;            // start timer for pause before going to warp
    }

I don't understand what you mean by "late for the timed test".

  if ( (startupSeq == true) && (gotoWarp == false) ) {

    if ( ( (currentTimeMS - startTimeBlueMS) >= delayB ) && ( fadingB == true ) ) {

    } else {

      gotoWarp    = true;                     // set state variable to begin check for next cross fade
    }

  }

Removing all the non-applicable code, the problem is that, without the delay caused by printing, the 2nd if statement will be false because the time interval is less than delayB. This causes gotoWarp to be set to true, which then makes the 1st if statement false.

1 Like

Sry, I never said it was! I only said you'd get there, as @david_2018 has illustrated by removing the feathers and flesh from the bird, leaving only the skeleton.

I should have made clear that the timed test was the if condition I quoted - the logic that you were employing to ensure the code in the block was only executed every delayB milliseconds. Again, @david_2018 has expressed this better.

I saw more about the nature of the problem when I added the code that shows you reach Warp Speed right away. When the printing is disabled.

As I stripped the program down, first while maintaining functionality, and then by massive edits, I just plain saw it.

In the IDE if you park the cursor next to a brace, the corresponding brace will be marked. This makes seeing what's in the body (or removing it!).

The IDE has little buttons in the margin that let you collapse the body of an if or else, this is s no damages method of poking around skeletally, so to speak.

I did not use the wokwi logic analyser and some digitalWrite() statements to trace the flow. I came close to needing to do. I've used that both for finding errors and for confirming correct behaviour in tight code that would allow no time for printing.

wokwi Arduino simulator

They offer one of those cheap logic analysers.

cheap logic analyser

which I recommend, but suggest you try not to get involved with too soon - old fashioned thinking is the best debugging tool and serial printing and/or LEDs can get you a long way before you start with (or even ever need) more sophisticate toos.

a7

1 Like

@alto777 & @david_2018: Thank you so much! That else {} block was left over from a previous non-blocking attempt with different logic. I only want to execute what's in that else {} block once ALL the LEDs have completed their fade.

I realize there are probably more efficient ways to do this, so I will continue to work on it now that I've resolved the problem with this updated code:

// Comment out the line below for production
// (serial monitoring affects timings)
//#define DEBUG_MODE

bool isCommonAnode  = true;               // Set to false for common cathode

int redPin          = 9;
int grnPin          = 10;
int bluPin          = 11;

int delayBeforeStartupMS  = 3000;
int powerUpFadeTimeMS     = 2550;
int delayBeforeWarpMS     = 4500;

unsigned long timeStampMS = 0;

bool startupSeq     = false;
bool gotoWarp       = false;
bool startLoop      = false;

int black[3]        = { 0, 0, 0 };
int blue[3]         = { 0, 0, 255 };

// Set initial colour values
int redVal          = black[0];
int grnVal          = black[1]; 
int bluVal          = black[2];

// Initialize colour variables
int prevR           = redVal;
int prevG           = grnVal;
int prevB           = bluVal;

int delayB          = 0;

// R/G/B PWM step values
int stepR;
int stepG; 
int stepB;

bool fadingB        = false;


void setup() {

#ifdef DEBUG_MODE
  Serial.begin(9600);
  
  Serial.println("DEBUG_MODE ON");
#endif
  
  pinMode(redPin, OUTPUT);              // sets the pins as output
  pinMode(grnPin, OUTPUT);   
  pinMode(bluPin, OUTPUT); 

  // Set initial values (black)
  if ( isCommonAnode == true ) {
    analogWrite(redPin, 255 - redVal);  // Write current values to LED pins
    analogWrite(grnPin, 255 - grnVal);  // (using common anode, so need to use '255-')   
    analogWrite(bluPin, 255 - bluVal); 
  } else {
    analogWrite(redPin, redVal);        // Write current values to LED pins
    analogWrite(grnPin, grnVal); 
    analogWrite(bluPin, bluVal);        
  }

}

void loop() {

  static unsigned long startTimeBlueMS  = millis();

  unsigned long currentTimeMS           = millis();
  static unsigned long timeStampMS      = millis();

#ifdef DEBUG_MODE
    Serial.print("currentTimeMS = ");
    Serial.print(currentTimeMS);
    Serial.print(", startTimeBlueMS = ");
    Serial.println(startTimeBlueMS);
#endif

  if ( (currentTimeMS >= delayBeforeStartupMS) && (startupSeq == false) ) {
    startupSeq  = true;        // don't revert back to false or this will repeat with the next iteration    
    startLoop   = true;        // set boolean for first time thru loop                
  }

  // 1. Initial power-up -> dish and impulse crystal fade up to an orange/copper colour
  // ==================================================================================
  if ( (startupSeq == true) && (gotoWarp == false) ) {

    if ( startLoop == true ) {
      // Do this once for each cross fade colour
      bluVal    = blue[2];      // new value for Blue
      delayB    = calculateDelay(prevB, bluVal, powerUpFadeTimeMS);
      stepB     = prevB;        // set PWM step increment value to previous Blue value
      fadingB   = true;         // set flag for fading Blue

      startLoop = false;

#ifdef DEBUG_MODE
      Serial.print("bluVal = ");
      Serial.print(bluVal);
      Serial.print(", delayB = ");
      Serial.print(delayB);
      Serial.print(", stepB = ");
      Serial.print(stepB);
      Serial.print(", fadingB = ");
      Serial.println(fadingB);
#endif

    }
    
    if ( ( (currentTimeMS - startTimeBlueMS) >= delayB ) && ( fadingB == true ) ) { 

#ifdef DEBUG_MODE
      Serial.print("currentTimeMS = ");
      Serial.print(currentTimeMS);
      Serial.print(", startTimeBlueMS = ");
      Serial.print(startTimeBlueMS);
      Serial.print(", stepB = ");
      Serial.println(stepB);
#endif

      if ( stepB != bluVal ) {                

        if ( isCommonAnode == true ) {
          // analogWrite(redPin, 255 - redVal);  // Write current values to LED pins
          // analogWrite(grnPin, 255 - grnVal);  // (using common anode, so need to use '255-')   
          if ( bluVal > prevR ) {
            analogWrite(bluPin, 255 - (stepB++)); 
          } else {
            analogWrite(bluPin, 255 - (stepB--)); 
          }

        } else {
          // analogWrite(redPin, redVal);        // Write current values to LED pins
          // analogWrite(grnPin, grnVal); 
          if ( bluVal > prevR ) {
            analogWrite(bluPin, stepB++); 
          } else {
            analogWrite(bluPin, stepB--); 
          }       
        }
        
        startTimeBlueMS = currentTimeMS;         // set wait timer

      } else {
        // Done fading this colour
        fadingB = false;
      }

    } 
    
    if ( fadingB == false ) {

      // Cross fade complete; update current values for next cross fade
      prevR       = redVal; 
      prevG       = grnVal; 
      prevB       = bluVal;   

      gotoWarp    = true;                     // set state variable to begin check for next cross fade
      timeStampMS = currentTimeMS;            // start timer for pause before going to warp

#ifdef DEBUG_MODE
      // Serial.print("prevR = ");
      // Serial.print(prevR);
      // Serial.print(", prevG = ");
      // Serial.print(prevG);
      Serial.print(", prevB = ");
      Serial.print(prevB);
      Serial.print(", gotoWarp = ");
      Serial.print(gotoWarp);
      Serial.print(", timeStampMS = ");
      Serial.println(timeStampMS);
#endif

    }

  }


  // 2. Go to warp
  // =============



}


int calculateDelay(int prevValue, int endValue, int overallFadeTimeMS) {
  // For delay between PWM steps, value needs to be positive so take absolute value of difference
  int delayMS = abs((endValue - prevValue));  // What's the overall gap?
  
  if (delayMS) {                              // If its non-zero, 
    delayMS = overallFadeTimeMS/delayMS;      //   divide by overallFadeTimeMS
  } 
  
  return delayMS;
}