Ever since I came across the Arduino platform, I felt really pissed off with (the existence) of the delay() function, because it was created with the (evil) solo purpose of wasting time between executions of the loop() function.
I have rapidly created a counter to substitute this function in every sketch of my own, with the downside of having to adjust the counted number for every single program (because different program sizes take different times to be executed). This scenario have just changed, because I am presenting you my very own professional way to not waste precious time of your Arduino. It is a sketch that allows you to run a piece of code every 'x' microseconds while leaving the rest of the time free for execution of more code!.
The code takes advantage of the micros() function, present in the stock Arduino language and IDE, which returns the time (in microseconds) that Arduino has been running since the last reset. Essentially what I do is to execute my main function (which I can freely choose) only every given time; this "given" time can be adjusted by updating its value (in microseconds) in an IF loop.
The sketch is available on my GitHub and doesn't require any special library or installation, only the stock micros() function. Essentially your custom code, such as blinking leds, goes in between the quotes I have wrote (as seen below):
The main advantage in this code is that you can execute a code every 'x' microseconds (utilizing the sketch exactly as it is) or multiple codes every 'y' microseconds (by adding new IF conditions based on the same couter). You can not forget to fill your setup() function as needed; your timing will always be respected, since you don't write a code big enough (that takes more time than your delay) to be executed.
I would greatly appreciate to hear from you guys, any suggestion, criticism, upsides, downsizes, anything that can make the code work better. You can reach me on twitter @embedded_clovis or email: clovisf AT gmail DOT com .
well, it has one disadvantage: you need 2 long variables and a boolean (that's 9 bytes) for each delay() in your code. if you have lots of them, that's quite some RAM "wasted".
ReplyDeleteplus, you need to call each variable with an appropriate name, which also adds quite some code management overhead.
note that I'm not advocating the use of delay() in general. I tend to avoid it whenever possible, using something similar to your approach. which, by the way, is also similar to the standard BlinkWithoutDelay example...
it's just that I don't see it really fit as drop-in replacement for every delay(). in particular for users new to Arduino and programming in general.
cheers,
Aldo
Hi Mr. Aldo, nice to see you around!.
DeleteAbout the number of delays in the code, I think I have the solution for that: I can always use one counter only and interrupt my code with different "numbers" (or times) to be counter. That leaves me using only two long variables.
You are completely right about code management and all the "new users" thing, which are point I need to improve in the code.
Thank you for the valuable feedback,
I am still looking for a "drop-in" replacement for delay() that can be used generically in most sketches without changing much else.
ReplyDeleteWhat about three possible enhancements?
ReplyDelete1) use return ((time - previousTime >= 999990). It should not be necessary to use an if condition (which is a boolean expression) to return true or false (which are also boolean expressions)
2) use a variable nextTime= time+999990 and check (micros()>nextTime); which should be easier/simpler to understand and to comppute
3) what about time-overflow? A certain time after the reset the timer read by micro() should be zero again. Could this be a surprise?