VirtualDelay

Introduction

The standard delay() function blocks the Arduino which is not allowed sometimes. We can find several examples on Internet to overcome this, but there was no method to use non-blocking delays on an easy way. Therefore, I have built the VirtualDelay library. It has been kept as simple as possible to save memory space and optimize the speed.
See the whole article HERE

Advantages of the VirtualDelay library

  • It doesn't block anymore.
  • It can used for a chain of delays too, this was previously not possible.
  • The interface is straightforward.
  • The delay time can set in micro-seconds or milli-seconds.

Interface

There are 2 member functions, see the examples how to use.
done() Use this if we need just one delay.
proceed() Use this if we need more delays with one VirtualDelay object. End with done().

Notes

The VirtualDelay must always run inside a loop, but this is usually the case with embedded software such as the Arduino platform.
We need an "if" statement, in contrast with the standard delay() function.
The timing of VirtualDelay starts at the beginning of the sketch in contrast to delay() which starts at the function itself.

The simplest VirtualDelay example

Here a simple blinking LED sketch with the VirtualDelay:

#include <Arduino.h>
#include <VirtualDelay.h>
 
const byte ledPin = 13;
 
bool b;
VirtualDelay virtualDelay(millis);
 
void setup()
{ pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}
 
void loop()
{ if(virtualDelay.done(500)) digitalWrite(ledPin, b=!b); // the LED blinks on and off
}

Interesting. Thanks for sharing.

Can you explain how it works?

As far as I can see this

    if(virtualDelay.done(500))  {
        digitalWrite(ledPin, b=!b); // the LED blinks on and off
    }

is equivalent to this

    if (millis() - previousMillis >= 500) {
        previousMillis += 500;
        digitalWrite(ledPin, b=!b);
    }

...R

Robin2:
Interesting. Thanks for sharing.

Can you explain how it works?

As far as I can see this

    if(virtualDelay.done(500))  {

digitalWrite(ledPin, b=!b); // the LED blinks on and off
    }



is equivalent to this


if (millis() - previousMillis >= 500) {
        previousMillis += 500;
        digitalWrite(ledPin, b=!b);
    }




...R

Yes it is equivalent in this example I suppose.

Can you explain, please, how your program works?

...R

where can I download the .zip for this library? I don't see it on arduino's website or the site above (http://www.avdweb.nl/arduino/libraries/virtualdelay.html)

It seems like you've managed to turn a round wheel square. Intriguing.

Haha don't let them get you down. I tried to share my solution to the blocking delay() deal and I was told that it was something like "empty code that adds no functionality." or something similar.

If it helps you great. I know I'd be far less happy without mine. (It fixes what I don't want to think about.) I suppose that people just think different. Therefore different things stump different people.

-jim lee

Writing a program for a microprocessor is very different from writing a program for a PC that runs at 1.6GHz and had 2 Gigabytes or more of RAM.

IMHO thorougly learning Blink Without Delay helps people to see the design of microprocessor programs from a more useful point of view.

...R

Robin2:
Writing a program for a microprocessor is very different from writing a program for a PC that runs at 1.6GHz and had 2 Gigabytes or more of RAM.

...and??

Running multiple sections at once, and timing is in no way specific to uc's and the capabilities of the device really mean nothing here. If you think that millis() is some 'special' type of event management you are quite mistaken.

In fact the BWoD example is extremely trivial compared to systems with multiple cores and threading. Getting something to trigger at a certain value of 'millis()' in no way compares to synchronization of threads using mutex's and semaphores. And before you say it, yes there are many microprocessors that have multiple cores and there are even OS's for AVR which have threading models in them.

Robin2:
IMHO thorougly learning Blink Without Delay helps people to see the design of microprocessor programs from a more useful point of view.

So you hide the design and useful features of the processor in functions like millis() but turn your nose up at code that uses millis() inside it. Learning to use this library for instance will still give someone the ability to understand timing principles.

And I'm sure you are quick to dismiss operating systems for the AVR, however threading and synchronization are fundamental parts of modern computing. On powerful multi core uc's the basic single threading approach you know and love may mean that you can never use the real potential of the CPU.

It is far more beneficial to be able to use tools written for a purpose than to hack a specific piece of hardware to bits trying to understand its intricacies. You should never prematurely optimize Robin, just get some results then improve.

Even as I was writing Reply #7 I was conscious that I was not expressing what I wanted to say very well, but at the time it was the best I could come up with.

My objection is not about using tools (I habitually use an electric saw rather than a hand saw) but about the business of visualizing how a microprocessor program needs to be constructed.

You, yourself say "Running multiple sections at once, and timing is in no way specific to uc's" which leads me to believe that you (consciously or unconsciously) understand what needs to happen. Perhaps you have forgotten when you didn't.

But when I see people struggling to understand BWoD I see people who do NOT understand what needs to happen. My objection to hiding the innards of BWoD is because doing so delays the moment when they reach that understanding. And, from what I have seen here on the Forum, those newbies also make a lot of other silly mistakes that are also associated with that absence of understanding.

I guess I see BWoD as the equivalent of learning the alphabet if one wants to read and write.

When a person is writing a program for a PC it mostly does not matter whether it uses CPU cycles or RAM efficiently and people who do not understand stuff can get perfectly satisfactory results. You cannot ignore the limitations of an MCU.

...R

Robin2:
I guess I see BWoD as the equivalent of learning the alphabet if one wants to read and write.

You pointed out in reply #1 that the two examples are equivalent. A beginner could use either version to learn the same concept of triggering an event after a certain amount of time, rather than waiting/delaying.

You have simply taken preference for one high level API over the other. And neither show any fundamentals of micro-controllers as they implement the low level functionality internally.

And both causes a waste of cycles if millis() can be entirely removed and the hardware timer callback used directly, as every millisecond, or whatever true resolution millis() has, an interrupt is run.

But I guess you see it as fine to "ignore the limitations" when the benefit of an easy to use high level API makes your code simpler to understand... This library is providing the same benefits you are endorsing with the Arduino API, but at the same time are arguing against.

Don't get me wrong, a trade off for efficiency vs ease of use is fine when it is within your programs constraints, however, here you are comparing an orange with an orange.

I think we are each looking at different aspects of the same thing. Let's agree to disagree.

...R

Robin2:
Let's agree to disagree.

...R

Never!
Its a fight to the death.

I do not see how the skills learned in one of the above mentioned examples are not commutative with the other. Maybe you're talking about mostly unimportant stuff like the long value or the use of the >= comparison...

Thanks, seems interesting, but, what about the download link?

alah:
Thanks, seems interesting, but, what about the download link?

There doesn't appear to be a zip download, but you can copy and paste the code from the web page (linked in first post).

----- IMPORTANT -----

The library has been completely rewritten because there was a bug in the function proceed(). see:
http://www.avdweb.nl/arduino/libraries/virtualdelay.html

Thanks avandalen

I've downloaded your updated Delay library from Github
Github

I'm going to start playing with it.

The thought of the Delay() stopping code execution drives me crazy. >:(

Cheers

Rick Hubka

Hi!
Does it work with Leonardo?
According description it's great but can't compile

rhubka:
Thanks avandalen

I've downloaded your updated Delay library from Github
Github

I'm going to start playing with it.

The thought of the Delay() stopping code execution drives me crazy. >:(

Cheers

Rick Hubka
try the new version, everything is tested

sechen:
Hi!
Does it work with Leonardo?
According description it's great but can't compile

yes AVR and SAMD21