Go Down

### Topic: Delays and unsigned long (Read 4307 times)previous topic - next topic

#### Nick Gammon

#30
##### Feb 28, 2013, 11:35 pm
You have a good point, although I'm still uneasy about that code.

Why can't delay look like this?

Code: [Select]
`void delay(unsigned long ms){  ms *= 1000;  // turn into microseconds  unsigned long start = micros ();  while (micros () - start < ms)    { }}`

I know, that will wrap around after 71 minutes, but who delays that long?
Please post technical questions on the forum, not by personal message. Thanks!

http://www.gammon.com.au/electronics

#### GoForSmoke

#31
##### Feb 28, 2013, 11:38 pm

You have a good point, although I'm still uneasy about that code.

Why can't delay look like this?

Code: [Select]
`void delay(unsigned long ms){  ms *= 1000;  // turn into microseconds  unsigned long start = micros ();  while (micros () - start < ms)    { }}`

I know, that will wrap around after 71 minutes, but who delays that long?

LOL, Procrastinators!

Really though, that code looks like it might be efficient or sumthing.  XD
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

#### Nick Gammon

#32
##### Mar 01, 2013, 12:28 am

Really though, that code looks like it might be efficient or sumthing.  XD

Or this, which handles longer delays:

Code: [Select]
`void delay(unsigned long ms){  unsigned long start;    // short delays, allow for the fact that we might  // be half-way through a millisecond  if (ms < 60000)    {    ms *= 1000;  // turn into microseconds    start = micros ();    while (micros () - start < ms)      { }    }  // end of if short delay  else    {  // longer delays    start = millis ();    while (millis () - start < ms)      { }    }  // end of longer delay}`

Bit long-winded maybe.

I'm inclined to go with the simple one:

Code: [Select]
`void delay(unsigned long ms){  unsigned long start = millis ();  while (millis () - start < ms)    { } }`

And just warn users that for very short delays, the time may be out a bit depending on how far through the next "millis" tick you start. However for short delays there is always delayMicroseconds.
Please post technical questions on the forum, not by personal message. Thanks!

http://www.gammon.com.au/electronics

#### GoForSmoke

#33
##### Mar 01, 2013, 12:33 am
The code in reply # 30 is the better one.

2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

#### Jim_Socks

#34
##### Mar 01, 2013, 07:26 am
WOW!

I got taken away on a short notice work trip, but I didn't expect to see three pages of replies when I returned!  You guys got way into it!

I am glad you spotted my folly with the = instead of ==, I'll fix that right away.

As for the suggestion that I should just pass delay(); an unsigned long- if you look at my code from page one, you will see that the array used AND the "pourdelay" ARE in fact unsigned long variables.  I am only hoping you can spot where I am overlooking something I am passing delay that isn't- as that would be an easy fix!

The discussion as to how delay works was a bit over my head, but what I pulled from it is that even though delay accepts an unsigned long variable, it still won't count past a regular integer?  (In the original post, I realized that 32 seconds alluded to it stopping after reaching integer length- I just hoped it wasn't true?)

So,if I follow discussion on the last page...  I should create a new version of the delay function, which will be able to count higher but slightly less accurately?  Let me know if I understood that incorrectly?

P.S.  Due to the pumps I am using and the vertical distance being covered by the lines, the pour is very slow.  I'll fix that later by ordering bigger pumps... maybe... it's still more convenient than digging out all the ingredients in a seven ingredient drink...- but for now anyways pour times can easily exceed 32 seconds even for regular sized drinks.  Sorry, Goforsmoke- no giant drinks here

Additionally, with the power supply I have used- only one pump is capable of running at any given time.  The idea that I should have the computer checking other sensors or running other pumps or doing anything at all whilst pumping isn't something I am interested in incorporating.  The code already keeps track of every bottle and alerts me when they reach a certain level- which is all the help I require from it.  When it is pouring- that's all I want it doing.

If I can fix this delay problem- I will be in business here.  Fingers crossed that I can!

#### Nick Gammon

#35
##### Mar 01, 2013, 08:04 am

So,if I follow discussion on the last page...  I should create a new version of the delay function, which will be able to count higher but slightly less accurately?  Let me know if I understood that incorrectly?

Delay should not fail after 32 seconds, something else will be wrong.
Please post technical questions on the forum, not by personal message. Thanks!

http://www.gammon.com.au/electronics

#### GoForSmoke

#36
##### Mar 01, 2013, 08:09 am
You're not using CO2 pressure to drive the liquids? Any chance to feed from overhead and use gravity?

2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

#### UKHeliBob

#37
##### Mar 01, 2013, 08:55 am
Quote
As for the suggestion that I should just pass delay(); an unsigned long- if you look at my code from page one, you will see that the array used AND the "pourdelay" ARE in fact unsigned long variables.  I am only hoping you can spot where I am overlooking something I am passing delay that isn't- as that would be an easy fix!

volume is a byte, not an unsigned long.
Code: [Select]
`void countandpour(byte array, byte volume)`
So what will the result of the multiplication be ?
Code: [Select]
`unsigned long pourdelay = 0;pourdelay = volume * 9250;delay(pourdelay);`
Could it ever result in a negative number ?
Using delay() with a negative number never seems to end.  Sound familiar ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

#### GoForSmoke

#38
##### Mar 01, 2013, 10:11 am

volume is a byte, not an unsigned long.
Code: [Select]
`void countandpour(byte array, byte volume)`
So what will the result of the multiplication be ?
Code: [Select]
`unsigned long pourdelay = 0;pourdelay = volume * 9250;delay(pourdelay);`
Could it ever result in a negative number ?

How does an unsigned number ever result in a negative?
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

#### UKHeliBob

#39
##### Mar 01, 2013, 10:30 am
I don't know.  Hence the question.
Would multiplying a byte by an unsigned long result in an unsigned long ?

This certainly does not produce the result that I would expect at first sight, but no doubt there is an explanation
Code: [Select]
`unsigned long pourdelay = 0;byte volume = 100;void setup() {  Serial.begin(9600);  pourdelay = volume * 9250;  Serial.print("pourdelay is ");  Serial.println(pourdelay);}void loop(){}`

Output
Code: [Select]
`pourdelay is 7496`
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

#### GoForSmoke

#40
##### Mar 01, 2013, 01:32 pm

Code: [Select]
`unsigned long pourdelay = 0;byte volume = 100;void setup() {  Serial.begin(9600);  pourdelay = volume * 9250;  Serial.print("pourdelay is ");  Serial.println(pourdelay);}void loop(){}`

Output
Code: [Select]
`pourdelay is 7496`

I see an 8-bit unsigned multiplied by a positive value signed int being assigned to an unsigned long.

Try this, it's tested and gives the answer I expect:

Code: [Select]
`unsigned long pourdelay = 0UL;byte volume = 100;void setup( void ) {  Serial.begin(9600);  pourdelay = (unsigned long)volume * 9250UL;  Serial.print("pourdelay is ");  Serial.println(pourdelay);}void loop( void ){}`
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

#### UKHeliBob

#41
##### Mar 01, 2013, 02:12 pm
Yours works as expected.  Of course it does, but that is not what the OP is doing in his routine.

In my routine, why does 100 * 9250 equal 7496 ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

#### pYro_65

#42
##### Mar 01, 2013, 02:27 pmLast Edit: Mar 01, 2013, 02:30 pm by pYro_65 Reason: 1
volume is promoted to int, and the result overflows 16-bits

100 * 9250 = 11100001110101001000

shortened to 16 bits is 0001110101001000
which is 7496

https://forum.arduino.cc/index.php?action=dlattach;topic=327736.0;attach=128670 New EEPROM library released
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

#### GoForSmoke

#43
##### Mar 01, 2013, 02:31 pm
That's what mixed-types math can do for anyone.
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

#### UKHeliBob

#44
##### Mar 01, 2013, 03:11 pm
And mixed type maths is what the OP is using, so all bets are off as to what he is actually using as a parameter to delay()
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Go Up

Please enter a valid email to subscribe