Delay not working as I'd expect

I’ve just re-programmed my (very old) Particle to add a new function to an old piece of code. In the loop{} there was a delay(2000) line to stop it cycling too fast. This has stopped working! When I re-programmed the device, the firmware went from 1.5.x to 2.1.0. Is this the cause?
I wrote another very simple piece of code (see below) to test the delay function.

// Test delay function in firmware 2.1.0

void setup() {
	pinMode(7, OUTPUT);                        // Write- to the LED
}

void loop()
{
    	TimeDelay(1500);          // 1.5s loop delay
        FlashLED(1, 10);
}

void TimeDelay(long MS) {
    delay(MS);
}

int FlashLED(int flashes, int FPI)  {
    long halfperiod = 500/FPI;
    for (int d = 0; d < flashes; d++) { 
        digitalWrite(7, HIGH);
        delay(halfperiod); 
        digitalWrite(7, LOW);
        delay(halfperiod); 
    }
}

The TimeDelay(MS) is completely ignored, but the halfperiod delay in the FlashLED function works correctly. Where did I go wrong? Any clues gratefully accepted.

No idea if this has anything to do with your issue, but when you ask about what you’re doing wrong, one answer would be: “Your FlashLED does not return an int although the function signature promises to”

And for coding style, you should try to avoid blocking code (including delay() calls) wherever possible and you should use D7 instead of an anonymous number 7 :wink:

For your blink logic I’d rather use a Software Timer and for the loop() cadence a millis() approach like this

const uint32_t CADENCE = 1500;
void loop() {
  static uint32_t msLastLoop = 0;
  if (millis() - msLastLoop < CADENCE) return;
  msLastLoop = millis(); 

  // loop action
}
1 Like

I very much take on board your “what am I doing wrong” comments.
Using a software timer probably is good practice, but it doesn’t explain why a simple piece of (simplified) code such as
loop() {
FlashLED();
delay(1500);
}
ignores the delay statement completely and just loops round with whatever time period is built into the FlashLED sub-routine. This used to work fine with firmware 1.5 but not with 2.1. Is there a (multi)threading issue here? I have a lot of code in various projects and am not particularly happy about having to “work round” all the delay statements. Funny that the delay statements in the FlashLED subroutine work OK.

I’d have to try it out myself, but have never had this issue really, so my starting position is that this may rather be a misinterpretation of the observed behaviour.

However, I’ll have a curious try nonetheless :wink:


Update: I have now tried the code and as I expected the missing return statement seems to be the problem.

With the expected/required return statement in place this code behaves as expected

void setup() {
  pinMode(D7, OUTPUT);      
}

void loop() {
  delay(1500);
  FlashLED(10, 10);
}

int FlashLED(int flashes, int FPI)  {
  uint32_t halfperiod = 500/FPI;
  for (int d = 0; d < flashes; d++) { 
    digitalWrite(D7, HIGH);
    delay(halfperiod); 
    digitalWrite(D7, LOW);
    delay(halfperiod); 
  }
  return halfperiod;
}

comment it out and the error comes back.

Although this is a somewhat confusing behaviour, it’s still no surprise that bad coding practices produce unexpected/non-deterministic results.

It may have run but the code was still wrong, weven when the context didn’t render any obvious misbehaviour.

Thankyou. It is now running as expected. I vaguely recall in the mists of time that if a return was required, the web IDE would post an error to say so, but I may be wrong. Anyhow, I can now make progress (and improve my coding). Thanks again.

1 Like