That isn't doing subtraction. I must admit I get confused when I look at rollover on unsigned variables.
The add works too but isn't useful for watching millis() approach. Your clocks example is easier to see it here. I know that 2 - 10 is 4 on our base-12 clock and I can look for >= 4. But if I add 4 to 10 and get 2 then think that I can say if ( now >= 2 ) it will be true at 11. But the rollover works fine and the difference is figured elsewhere.
Not that you didn't have it figured before you wrote the line I quoted, I am sure. You're the type that would have to figure it out before letting go, aren't you?
The first is an odd use of the comma operator that doesn't do what you are apparently looking for.
The second is the classic of all classic C mistakes. = (assignment) versus == (comparison).
Unless you're just having me on for saying that you would have figured it out before posting, I can't prove that part so I can't be 100% sure you did.
start += 1000 moves the start point even past rollover, from 10 to 2 as it were.
Here is where the difference, the subtraction is taken:
if (((uint16_t)micros() - start) >= 1000) {
I am a bit in wonder that that code does the conditional and update start in under 1 usec or if it should be start += 999? Is the Arduino millisecond there really 1.000 or 1.001 msec?
I've messed around with trying to reduce the time difference condition to just two values instead of three; now and target time rather than now, start and interval and never got a fully clean solution. I can make it work if I cut the maximum interval by half using an if-else but it's not clean nor worth saving 4 bytes.
The code looks correct to me. Apart from using 16-bit values instead of 32-bit, it's equivalent to code that we'd use to deal with millis() and will handle the rollover correctly. All it's being used for is to detect when 1000 micros have elapsed, so there's no issue with the difference (between micros() and start) exceeding a 16-bit value.
GoForSmoke:
Really though, that code looks like it might be efficient or sumthing. XD
Or this, which handles longer delays:
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:
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.
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!
Jim_Socks:
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.
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.
void countandpour(byte array, byte volume)
So what will the result of the multiplication be ?