Pages: 1 2 [3] 4   Go Down
Author Topic: Delays and unsigned long  (Read 2888 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Why can't delay look like this?

Code:
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?
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 95
Posts: 4768
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Why can't delay look like this?

Code:
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.  smiley-lol
Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Really though, that code looks like it might be efficient or sumthing.  smiley-lol

Or this, which handles longer delays:

Code:
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:
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.
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 95
Posts: 4768
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The code in reply # 30 is the better one.

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Illinois, US
Offline Offline
Jr. Member
**
Karma: 2
Posts: 97
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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  smiley-wink

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!
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 95
Posts: 4768
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You're not using CO2 pressure to drive the liquids? Any chance to feed from overhead and use gravity?

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 109
Posts: 4078
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
void countandpour(byte array, byte volume)
So what will the result of the multiplication be ?
Code:
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 ?
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 95
Posts: 4768
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


volume is a byte, not an unsigned long. 
Code:
void countandpour(byte array, byte volume)
So what will the result of the multiplication be ?
Code:
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?
Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 109
Posts: 4078
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
pourdelay is 7496
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 95
Posts: 4768
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Code:
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:
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:
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 ){}

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 109
Posts: 4078
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ?
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 65
Posts: 2107
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

volume is promoted to int, and the result overflows 16-bits

100 * 9250 = 11100001110101001000

shortened to 16 bits is 0001110101001000
which is 7496

« Last Edit: March 01, 2013, 08:30:04 am by pYro_65 » Logged


Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 95
Posts: 4768
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That's what mixed-types math can do for anyone.
Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 109
Posts: 4078
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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()
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Pages: 1 2 [3] 4   Go Up
Jump to: