Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: Replace delay() with a custom function

  1. #1
    Senior Member
    Join Date
    Jan 2015
    Location
    France
    Posts
    110

    Replace delay() with a custom function

    Hello,

    In arduino delay is blocking. So one have to replace delay with his own function ?

    Is this one a good sample or is there more efficient ?

    Code:
    void wait(uint_least16_t timeToWait)
    {
      unsigned long startCount = millis();
      while (millis() < (startCount + timeToWait))
      {
      }
    }
    Thank you,
    Manu

  2. #2
    Senior Member
    Join Date
    Jan 2020
    Location
    Toscana
    Posts
    128
    And?
    What else does this do other than shifting electrons on the power line? It is blocking as well. Also it has the chance to wait for ages if it encounters overflow....

    BTW what is blocking? Interrups, serial, USB and DMA, etc, transfers keep on working during delay. So?

  3. #3
    Senior Member
    Join Date
    Jan 2015
    Location
    France
    Posts
    110
    Thank you guy,
    ultra constructive answer. In France starting a post with "And?" mean that you feel like the one who asked is a pure idiot. Same in Italy ?

    Excuse me to refer to
    https://www.arduino.cc/reference/en/...ns/time/delay/
    and to try to understand the "note and warnings" things.

    Maybe I'm too idiot to ask...

    Maybe trying to understand :
    https://www.pjrc.com/teensy/td_timing.html
    gotcha : Can't do anything while waiting
    and asking is not the way to understand. Need to look at my crystal ball...

    BTW, thank you

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,178
    The purpose of delay() is to block the current code execution path for a fixed time. As noted anything else outside the current code path capable of background interrupt or operation will continue.

    Also as suggested millis() returns a uint32_t that can wrap and dealing with that would be like this:
    Code:
    void wait(uint_least16_t timeToWait)
    {
      unsigned long startCount = millis();
      while ( (millis() - startCount) < timeToWait )
      {
      }
    }
    Actually the Arduino definition of delay() as PJRC implements on T_4x is below and while counting away the requested milliseconds it calls out to yield() to facilitate certain Serial and other "Event" 'background' processing::
    Code:
    void delay(uint32_t msec)
    {
    	uint32_t start;
    
    	if (msec == 0) return;
    	start = micros();
    	while (1) {
    		while ((micros() - start) >= 1000) {
    			if (--msec == 0) return;
    			start += 1000;
    		}
    		yield();
    	}
    }
    For a non-blocking way to defer certain processing look at example usage of elapsedMillis: pjrc.com/teensy/td_timing_elaspedMillis.html

    Or the Blink Without Delay type example:: ...\examples\02.Digital\BlinkWithoutDelay\BlinkWit houtDelay.ino

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,178
    Quote Originally Posted by Manu View Post
    Thank you guy,
    ultra constructive answer. In France starting a post with "And?"
    ...
    Please don't infer or inject ill will to text answers - especially across potential language/location barriers ...

    And? says/asks many other things - generally best not to assume the worst!

    hopefully post #4 is more informative and acceptably worded - but as noted the definition of delay() is to block current code path for a specified time - so "And?" questions are possibly:
    > perhaps post/question as written was unclear to 'the reader' - but here is an attempt to clarify to get to a resolution of the issue at hand?
    > is that not the desired reason to use it?
    > is there another desired outcome or alternative needed?
    > the posted 'alternative' attempt appears to present the exact same net effect as included delay() as posted?
    > given the linked arduino reference it also suggests : arduino.cc/en/Tutorial/BlinkWithoutDelay

    Perhaps others - none of which suggest an ID10T error with regard to the initial post.

  6. #6
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,408
    To add on to what the others have asked/answered.

    It is sometimes hard to know exactly how to answer... Many times the questions don't have enough information to give a decent answer. Things like for which Teensy? Are you just wanting to learn something or is there some underlying problem you are trying to solve.

    One of the great things about Arduino on most platforms. Almost all of the source code for the system is installed on your machine. So if you wonder how something is done, you can easily just look at the sources. Only exceptions I have worked on are some of the Robotis Boards (OpenCM, OpenCR), where they build and release archive files (plus header files). So anytime I want to understand how it is done, I usually bring up some form of Editor (in my case sublimetext) and either if lucky when I have an open folder on Teensy directories, it finds what I am looking for in symbols, else I just do a global search over the whole open folder or a subset of folders, to find the symbol.

    But simple answer:

    The function delay is built into the core file and maybe you can or maybe you can not replace it.

    That is in the case of T4.x, the function is in the source file delay.c which I believe only has two symbols it contains (delay and micros), neither of which are defined with weak attribute. And as the core files are built and put into an archive file (.a), if your sketch had both of these symbols defined than my guess is the linker might be happy. If you only defined your version of delay, than the linker will bring this file in it and as such the linker will error out with duplicate symbols. In the case of T3.x and TLC, it is in pins_teensy.c and there are a lot of symbols defined in this file so would be a pain to try to replace just delay... Of course in either case you could simply edit the sources and change it how you need it. But again this effects everything you compile using those sources.

    Now is yours more efficient? (Actually assuming you use @defragsters version that handles the case where the timer overflows and goes back to 0...) You gain not calling yield.
    So in that case could be faster. Of course it will also break anything that makes use of yield functionality. Things like using Arduino things like void SerialEvent() {....} to process an event...
    But over the last few releases of Teensyduino, we put work in to help minimize that. In many cases it may boil back down to check one or two flags and return...

    Hope that helps.

  7. #7
    Senior Member
    Join Date
    Jan 2020
    Location
    Toscana
    Posts
    128
    @Manu:
    Sorry, if I got too upset about you trying to say the delay function is inferior to your piece of code, even if your code has violated all common sense of programming logic.
    And?
    No, I did not want to humiliate you.

  8. #8
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    560
    If you want some things to continue and others to be delayed, consider using threads.

    > It is sometimes hard to know exactly how to answer

    Yes, kudos to the experts that spend valuable time trying (and mostly succeeding).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •