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

0 Members and 1 Guest are viewing this topic.

Offline Psi

  • Super Contributor
  • ***
  • Posts: 9946
  • Country: nz
Re: How do you code your delays and waits
« Reply #25 on: March 26, 2014, 01:37:29 am »
Does anyone have tips/tricks for dealing with wrap-around on global tick variables?
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline mazurov

  • Frequent Contributor
  • **
  • Posts: 524
  • Country: us
Re: How do you code your delays and waits
« Reply #26 on: March 26, 2014, 01:40:28 am »
Some time ago I wrote a code to drive HD44780-compatible display. The application for which it was written is very sensitive to blocking so loop/nop delays are not possible. I have a queue to feed the display consumed by a timer interrupt. Depending on the data, the interrupt reloads its own (timer's) period register - there are two commands requiring longer delays. Here's the link -> https://www.circuitsathome.com/mcu/driving-a-character-lcd-using-pic24-enhanced-parallel-master-port
With sufficient thrust, pigs fly just fine - RFC1925
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: How do you code your delays and waits
« Reply #27 on: March 26, 2014, 02:23:18 am »
Does anyone have tips/tricks for dealing with wrap-around on global tick variables?

I usually ignore them because what matters is deltas, so when doing the math on unsigned values it should wrap around naturally and the deltas would be preserved

so for unsigned shorts:

2 - 33 = 65505
 0x0002
 0x0021
 0xFFE1

Code: [Select]
    unsigned short val1, val2, val3;
    val1 = 2;
    val2 = 33;
    val3 = val1 - val2;

So as long as you don't wrap around more than once per measurement you'll be fine.

Edit: to explain a bit better

2 - 33 = 65505 is the same as (65536)+2-33, where the 65536 is all the values that a 16 bit unsigned integer can hold (including 0).

So the rule of thumb will be (2^x)+val1-val2 = delta if val1 is less than val2, where x is the bit count for your unsigned register. And the 2^x is implied and doesn't need to be coded because your are using deltas.




« Last Edit: March 26, 2014, 02:34:55 am by miguelvp »
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: How do you code your delays and waits
« Reply #28 on: March 26, 2014, 02:44:56 am »
I should have used better names for my variables so replying again

Code: [Select]
    unsigned short beginTime, endTime, deltaTime;

    beginTime = 33;
    endTime = 2; // after warp-around
    deltaTime = endTime - beginTime;
 

Offline ecat

  • Frequent Contributor
  • **
  • Posts: 296
  • Country: gb
Re: How do you code your delays and waits
« Reply #29 on: March 26, 2014, 02:46:30 am »
Does anyone have tips/tricks for dealing with wrap-around on global tick variables?

What are you trying to achieve? What are you trying to avoid? Why is wrap-around a problem?
What CPU are you using? What size is its native integer? How does the compiler handle addition when using larger than native integer types?

tl;dr
It depends ;)
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 9946
  • Country: nz
Re: How do you code your delays and waits
« Reply #30 on: March 26, 2014, 03:01:12 am »
I thought it was pretty obvious.

You have a variable that ticks (incremented from interrupt/hardware timer).
Eventually it's going to wrap-around and start from zero again.
If you try and use that for timestamping things then you have to deal with the situation of the wrap occuring during two timestamps.

You can detect the wrap around and remove it but then you have to consider that the wrap may occur multiple times etc..

Are there any coding tips/tricks to handle this in a simple way.
« Last Edit: March 26, 2014, 03:03:27 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: How do you code your delays and waits
« Reply #31 on: March 26, 2014, 03:19:36 am »
I thought it was pretty obvious.

You have a variable that ticks (incremented from interrupt/hardware timer).
Eventually it's going to wrap-around and start from zero again.
If you try and use that for timestamping things then you have to deal with the situation of the wrap occuring during two timestamps.

You can detect the wrap around and remove it but then you have to consider that the wrap may occur multiple times etc..

Are there any coding tips/tricks to handle this in a simple way.

Not sure if you saw my answer.

If you use deltas then there is no problem with unsigned computer math, doesn't get simpler than that.

If you want to keep a time stamp, use the deltas to update a bigger number (like an unsigned 64bit counter) provided you call the update within twice the wrap around time.

If using an interrupt then you can update the bigger number there making it available to the system.

If hardware counter (usually at least 32bits) or 4294967296, you have that many ticks per check So you might get in trouble if you don't update it once a second on a 4.29 GHz processor.

Edit: actually if you don't update it once in 2 seconds on a 4.29 GHz processor because it won't wrap around twice until then
« Last Edit: March 26, 2014, 03:30:59 am by miguelvp »
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 9946
  • Country: nz
Re: How do you code your delays and waits
« Reply #32 on: March 26, 2014, 03:44:10 am »
Edit: to explain a bit better

2 - 33 = 65505 is the same as (65536)+2-33, where the 65536 is all the values that a 16 bit unsigned integer can hold (including 0).

So the rule of thumb will be (2^x)+val1-val2 = delta if val1 is less than val2, where x is the bit count for your unsigned register. And the 2^x is implied and doesn't need to be coded because your are using deltas.

thanks, that makes sense :)
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline ecat

  • Frequent Contributor
  • **
  • Posts: 296
  • Country: gb
Re: How do you code your delays and waits
« Reply #33 on: March 26, 2014, 03:45:52 am »
I thought it was pretty obvious.

You have a variable that ticks (incremented from interrupt/hardware timer).
Eventually it's going to wrap-around and start from zero again.
If you try and use that for timestamping things then you have to deal with the situation of the wrap occuring during two timestamps.

You can detect the wrap around and remove it but then you have to consider that the wrap may occur multiple times etc..

Are there any coding tips/tricks to handle this in a simple way.

The simple answer is 'use a bigger integer'.
You can count the wrap arounds in the interrupt routine, maybe you can count them in you main loop - both methods are effectively making a bigger integer.

If you are constrained by code size, data size, execution time or the need to ensure your interrupt routine always executes in a fixed number of cycles then you may need something a little more imaginative than changing a uint16 to either a unit32 or something involving a couple of 'if' statements. Obviously ;)
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: How do you code your delays and waits
« Reply #34 on: March 26, 2014, 03:56:47 am »

thanks, that makes sense :)

Just make sure you use unsigned types if possible. Signed types will work as well but it's harder to wrap your head around it (pun intended).

But the problem with signed types is that it doesn't allow you to wait for two times the wrapping since some values will result on negative numbers, so stick to unsigned types.

Edit: And you have to measure within the wrap around not twice like I mentioned before I just tried it and it will only allow you up to 2^x-1 delta, but on a 32bit counter that is once a second in a 4.29GHz system.

i.e. maximum delta time possible is (2^x)-1 or 4294967295 on a 32 bit unsigned counter
« Last Edit: March 26, 2014, 04:15:32 am by miguelvp »
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: How do you code your delays and waits
« Reply #35 on: March 26, 2014, 10:58:38 am »
Quote
then you have to consider that the wrap may occur multiple times etc..

There is no cure for that (within the confines of the polling construct that we are discussing here) other than using a sufficiently large data type so it doesn't happen.
================================
https://dannyelectronics.wordpress.com/
 

Offline jancumpsTopic starter

  • Supporter
  • ****
  • Posts: 1272
  • Country: be
  • New Low
Re: How do you code your delays and waits
« Reply #36 on: March 30, 2014, 07:39:47 pm »
Some time ago I wrote a code to drive HD44780-compatible display. The application for which it was written is very sensitive to blocking so loop/nop delays are not possible. I have a queue to feed the display consumed by a timer interrupt. Depending on the data, the interrupt reloads its own (timer's) period register - there are two commands requiring longer delays. Here's the link -> https://www.circuitsathome.com/mcu/driving-a-character-lcd-using-pic24-enhanced-parallel-master-port
I'm going to check your library and see if I can make it work on the TI TMS570 ARM Cortex that I have running here.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf