Author Topic: How do you code your delays and waits  (Read 9095 times)

0 Members and 1 Guest are viewing this topic.

Offline jancumpsTopic starter

  • Supporter
  • ****
  • Posts: 1272
  • Country: be
  • New Low
How do you code your delays and waits
« on: March 23, 2014, 11:25:04 am »
I'm curious about the options to wait/delay that you use (for instance, if the spec of a device says to wait 10msec after a command before it is ready to receive the next command).
Do you use a loop, a timer/counter, an interrupt, something else?

 

Offline han

  • Frequent Contributor
  • **
  • Posts: 311
  • Country: 00
Re: How do you code your delays and waits
« Reply #1 on: March 23, 2014, 11:39:56 am »
loop delay in low end 8 bit micro controller because it's simple
interrupt/timer for complex device since loop delay is bad when using complex device (e.g computer)
 

Offline jancumpsTopic starter

  • Supporter
  • ****
  • Posts: 1272
  • Country: be
  • New Low
Re: How do you code your delays and waits
« Reply #2 on: March 23, 2014, 11:46:51 am »
Really depends entirely on the rest of the code you have and how it all fits together etc. Their are different ways to do such a thing.
That's what I'm interested in. These different ways you are mentioning.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: How do you code your delays and waits
« Reply #3 on: March 23, 2014, 11:48:30 am »
It depends on the actual application. I use both. For start-ups, I tend to initialize the slow devices first and then do software delays (looping around).

Once the code is running, I typically use a flag to maintain timing - this allows the mcu to take care of other tasks while the slow process is running.
================================
https://dannyelectronics.wordpress.com/
 

Offline madires

  • Super Contributor
  • ***
  • Posts: 7752
  • Country: de
  • A qualified hobbyist ;)
Re: How do you code your delays and waits
« Reply #4 on: March 23, 2014, 12:08:50 pm »
I use whatever works best in a given situation. Another method is to create a stacked or cascaded wait with calls and nops in assembler.
« Last Edit: March 23, 2014, 12:21:29 pm by madires »
 

Offline 8086

  • Super Contributor
  • ***
  • Posts: 1084
  • Country: gb
    • Circuitology - Electronics Assembly
Re: How do you code your delays and waits
« Reply #5 on: March 23, 2014, 12:10:50 pm »
Depends on:

Type of micro
Clock frequency
Language used
Length of delay
 

Offline han

  • Frequent Contributor
  • **
  • Posts: 311
  • Country: 00
Re: How do you code your delays and waits
« Reply #6 on: March 23, 2014, 12:29:30 pm »
loop delay:
   pro:- simple easy to use
         -  not much things to wrong
   con:- 100% cpu time when not optimized
          - cpu cannot do anything else (except its threaded operation)
          - waste on computing power
   typical uses : -simple program
                         -your program didn't have anything else to do
                         -if you lazy to learn how to use interrupt properly


interrupt/timer/counter:
   pro: - cpu can do someting else
           - power save mode can be done
           - most precise timing
   con: - more complex programming
           - too much interrupt can ruin your day





 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 9925
  • Country: nz
Re: How do you code your delays and waits
« Reply #7 on: March 23, 2014, 12:48:22 pm »
I usually dedicate one hardware timer to delays. I enable its overflow interrupt and write code to increment many variables inside the interrupt handler. These variables are reset to zero when they reach a set point which stops the incrementing.
So my clk_100Hz variable might count 50 interrupt events then reset where as my clk_200Hz variable might count 100 etc.. then reset to zero

Inside the main program loop i then check these 'flag variables' for a zero condition and run any code that i want repeating at that rate. (Then i set it back to 1 so it starts counting again).

Although you can divide any clock down to as slow as you want you should configure the timer so the overflow interrupt happens as slow as you can get away with so it doesn't take up CPU time needlessly. This can be done with a combination of changing the timers clock setting and updating the timers count register to a value which will overflow sooner. The timers clock settings give you course control and the counter register gives you fine control to get the interrupt running at the right speed so your delay numbers make sense, eg, 10 count = 1 ms 

I wrote a page in the wiki with an example a while back Here
« Last Edit: March 23, 2014, 01:03:11 pm by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: How do you code your delays and waits
« Reply #8 on: March 23, 2014, 01:13:13 pm »
Quote
loop delay:
         -  not much things to wrong

Try to write one with awareness of cpu speed and works under all optimization levels.
================================
https://dannyelectronics.wordpress.com/
 

Offline han

  • Frequent Contributor
  • **
  • Posts: 311
  • Country: 00
Re: How do you code your delays and waits
« Reply #9 on: March 23, 2014, 01:41:02 pm »
Quote
loop delay:
         -  not much things to wrong

Try to write one with awareness of cpu speed and works under all optimization levels.


the only problem i ever get is only wrong delay period (e.g longer / shorter delay)

using interrupt blindly can cause greater headache
 

Offline jaxbird

  • Frequent Contributor
  • **
  • Posts: 778
  • Country: 00
Re: How do you code your delays and waits
« Reply #10 on: March 23, 2014, 01:43:04 pm »
Highly depends on the situation and what you are programming in.

Some suggestions (some already mentioned)

  • a simple NOP loop if you got nothing better to do.
  • Put the mcu to sleep for the duration if you are on battery power.
  • One or more timer interrupt based counters.
  • If you go full assembly, write your main loop with a constant cycle count independent of the code path to keep track of timings.

Etc, ect, lots of room for creativity here if you need to squeeze more cycles out of your mcu or save a few bytes of memory.


Analog Discovery Projects: http://www.thestuffmade.com
Youtube random project videos: https://www.youtube.com/user/TheStuffMade
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: How do you code your delays and waits
« Reply #11 on: March 23, 2014, 01:53:13 pm »
Quote
using interrupt blindly can cause greater headache

Using anything blindly can cause greater headache.

Quote
Highly depends on the situation and what you are programming in.

Yeah. creating delays() is one of those simple yet highly challenging things due to the large number of approaches that can be deployed.
================================
https://dannyelectronics.wordpress.com/
 

Offline jaxbird

  • Frequent Contributor
  • **
  • Posts: 778
  • Country: 00
Re: How do you code your delays and waits
« Reply #12 on: March 23, 2014, 02:30:35 pm »
Quote
Highly depends on the situation and what you are programming in.

Yeah. creating delays() is one of those simple yet highly challenging things due to the large number of approaches that can be deployed.

Agree, it really depends on the accuracy, frequency and environment required plus what else needs to be taken care of at the same time. Priority etc, no best practice to recommended without very specific details.

Analog Discovery Projects: http://www.thestuffmade.com
Youtube random project videos: https://www.youtube.com/user/TheStuffMade
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: How do you code your delays and waits
« Reply #13 on: March 23, 2014, 05:35:53 pm »
It's not difficult at all to implement a systick-styled timer. The issues are resource and cycle drain.

a low end mcu may have 2-3 timers and dedicating one to time keeping can be expensive.

not to mention that you likely need to keep time over a few seconds at a minimum so a 32-bit type is needed. That means isr and reading and writing 32-bit types frequently in a 8-bitter.

so it is doable, but not wise to do, in my view.
================================
https://dannyelectronics.wordpress.com/
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 3439
  • Country: us
Re: How do you code your delays and waits
« Reply #14 on: March 24, 2014, 03:19:51 am »
With MCU's, I am only familiar with the ATMega using the Arduino boot loader.

Everything that must be done or are done in the start(), I would use delay().  Stuff done in the loop(), I use an elapse timer unless it is in the single-digit millisecond range.
 

Offline SL4P

  • Super Contributor
  • ***
  • Posts: 2318
  • Country: au
  • There's more value if you figure it out yourself!
Re: How do you code your delays and waits
« Reply #15 on: March 24, 2014, 06:55:33 am »
What I usually do is setup a timer interrupt at the highest tick rate I'm going to need (e.g. 100mS), and simply increment a global variable with each tick.  Use an unsigned int or long as the counter, and reset those counters for each time domain as needed* - e.g. user interface events are cleared when a button is released so that new events will time-up from that.

In main() code, I test when the tick count reaches my next desired trigger point, an execute the required code.
You can test several times for different tasks, or maintain 'separate' tickers at divisors of the main tick count.
Remember to put as little as you can within the interrupt routinbe to keep the time-critical takk on-time, and called when 'you' want them.

You can also perform relative timing - e.g. button down + 1500mS represents a long-press event.
Remember to arrange your timed 'ifs' in order that the most important calls are made first !!

The possibilities are endless.  Or as others have mentioned - simple while() loops are OK in single-task code... as long as there is no chance of getting stuck in the loop!.  WDT are made to protect you from this (* e.g. above)!
Don't ask a question if you aren't willing to listen to the answer.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: How do you code your delays and waits
« Reply #16 on: March 24, 2014, 11:11:11 am »
-reset those counters for each time domain as needed* -

I wouldn't reset it - just keep it running. Local timing events will keep their timing info locally. With this approach, multiple timing events can be kept concurrently and independently.

an almost true systick implementation.
================================
https://dannyelectronics.wordpress.com/
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6460
  • Country: nl
Re: How do you code your delays and waits
« Reply #17 on: March 24, 2014, 11:33:50 am »
It's not difficult at all to implement a systick-styled timer. The issues are resource and cycle drain.
a low end mcu may have 2-3 timers and dedicating one to time keeping can be expensive.
not to mention that you likely need to keep time over a few seconds at a minimum so a 32-bit type is needed. That means isr and reading and writing 32-bit types frequently in a 8-bitter.
so it is doable, but not wise to do, in my view.
I generally use one HW timer to generate an universal 1ms tick. Not only for timekeeping but also for other tasks that have to wait for an event for instance (not extremely timecritical stuff).
That 1ms tick I can subscribe 8 or 16 bit timers. Indeed I never use 32 bit timers on 8 bit uC, instead I sub-subscribe a second timer on a primary timer, for instance one 16bit 60000 count (for one second) on the 1ms and then another 16 bits on the 1s . So I cascade timers.
 

Offline SL4P

  • Super Contributor
  • ***
  • Posts: 2318
  • Country: au
  • There's more value if you figure it out yourself!
Re: How do you code your delays and waits
« Reply #18 on: March 25, 2014, 01:22:45 am »
-reset those counters for each time domain as needed* -

I wouldn't reset it - just keep it running. Local timing events will keep their timing info locally. With this approach, multiple timing events can be kept concurrently and independently.

If your tick timing is critical, or can have problems with interrupts too close together - then reset the counter(s) on and to - a known value !  Allowing the counter to wrap around is OK, but not predictable if you are  using a preset value other than zero as a counter calibration start point.

e.g. if you reset the tick-counter arbitrarily, then then next interrupt event may occur 'too soon' r 'too late' if you are using it as a constant (e.g. time-of-day), or your LED blinky may randomly give a double-blink, and you wonder why !

Don't ask a question if you aren't willing to listen to the answer.
 

Offline ve7xen

  • Super Contributor
  • ***
  • Posts: 1192
  • Country: ca
    • VE7XEN Blog
Re: How do you code your delays and waits
« Reply #19 on: March 25, 2014, 05:19:53 am »
I often do 1ms ticks, the ISR simply incrementing the current time. In main, I then have a scheduler queue (simple) which contains the target time and either a function pointer or index for a switch block to do the work, sorted by target time. Each loop pass just needs to check if the target time of the queue head is reached or not, and pop/execute it if so. For delays shorter than 1ms like satisfying setup times, busy wait is usually fine.

Timing precision isn't guaranteed (worst case is probably if your 1ms turns into 0ms, I think), but execution order is, it's pretty easy to extend (e.g. add priority) and manage, and you're not blocking interrupts for very long. Likewise, I usually try to have my ISRs just collect data or set pre-processed outputs/settings and submit an event to the queue for processing if necessary.
« Last Edit: March 25, 2014, 05:23:09 am by ve7xen »
73 de VE7XEN
He/Him
 

Offline zapta

  • Super Contributor
  • ***
  • Posts: 6190
  • Country: us
Re: How do you code your delays and waits
« Reply #20 on: March 25, 2014, 01:05:17 pm »
In my last project I used a 16 bit counter with 4usec ticks. For short critical ticks (e.g. half a start bit with serial bit banging) I busy loop that polls the timer.  For longer time period I extend it in the main loop() to a global uint32 time in millis, no interrupts needed.  Then I used multiple instances of a simple class that tracks time in millis based on the global uin32 time in millis  https://github.com/zapta/linbus/blob/master/prototype/arduino/passive_timer.h
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: How do you code your delays and waits
« Reply #21 on: March 25, 2014, 01:06:05 pm »
Quote
That 1ms tick I can subscribe 8 or 16 bit timers. Indeed I never use 32 bit timers on 8 bit uC,

You can still get sub 1ms timing resolution (for example, down to 1us on a 1Mhz mcu) even if your timer overflows every 1ms. It just increases the overhead when you read that value, and / or you are willing to live with non-atomicity.

================================
https://dannyelectronics.wordpress.com/
 

jucole

  • Guest
Re: How do you code your delays and waits
« Reply #22 on: March 25, 2014, 11:51:25 pm »
For PIC projects with very small delays I setup some #DEFS to some NOPs;  for longer non-critical I sometimes do loops on NOP's;  but if I need longer still then instead of loops on loops of NOPs I use the internal timers;   a while back I created a simple c# application to create the code for delays using timers on PICs.

ISR "Tickers", as mentioned are very handy to ensure you widget does everything it needs to at the right time.

 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 9925
  • Country: nz
Re: How do you code your delays and waits
« Reply #23 on: March 26, 2014, 12:02:58 am »
On the subject of timing. If anyone else decides to use a raw 2-4khz piezo beeper with a <20mhz mcu make sure you put it on a timer output pin and don't try to pulse it in software. 

I had a mistake on one of my PCBs where the beeper ended up on an input compare pin instead of an output compare pin so i couldn't drive it in hardware. I had to resort to interrupt driven software toggling the pin at 4khz.
It was quite hard to get a 'pure' sound out of it. All other active interrupts randomly delayed execution of the beeper interrupt and caused a 'dirty tone'
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline Rerouter

  • Super Contributor
  • ***
  • Posts: 4694
  • Country: au
  • Question Everything... Except This Statement
Re: How do you code your delays and waits
« Reply #24 on: March 26, 2014, 01:26:41 am »
As my recent project have been lower power, i put the processor into sleep and have a watchdog wake it up close to the required delay (I'm not doing mission critical stuff, e.g. waiting greater than 400ms for a sensor to wake up)

other than that, it comes down to why your waiting, if its just wait 500ms to prevent registering a button press twice, then use a time stamp compare and remove the delay altogether,

my other normal way is doing a time compare and return system, and it can work well even for large code, though i will admit it makes it a little less maintainable,
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf