I am periodically running a pump for 12 hour sets and I am currently using millis() to set a future time for the pump to shut off. ie if (millis()>futuremillis) digital.Write(LED, LOW). This works great except for the fact that I know that at one point around the 50 day mark I will hit the end of the millis() limit and it will probably mess up all my timing. I don't know exactly what will happen because I don't care to wait for 50 days to find out. I have thought of a way to fix it but I don't know exactly what the best way to fix it is. Here is my idea.
if (millis() > 45 days && timerOn= false)
{
"Set millis() back to zero!!!"
or
"Reset the whole arduino!!"
}
I figure this might work just because if the timer is not on I really don't care if it is resting itself or messing with millis(). If this is an okay idea my question is, How do I reset millis() back to zero? or Is there a way to reset the arduino without using setting the reset pin high (I don't like doing this just because I prefer to use the least amount of wires possible.)
and I am currently using millis() to set a future time for the pump to shut off. ie if (millis()>futuremillis) digital.Write(LED, LOW).
That is the wrong way to do it. You need to record when the pump was turned on, and, periodically, see it it has been on long enough (now - then >= on time).
This way, it won' matter iff millis() rolls over (as long as on time is less than 49+ days).
lar3ry:
duration = millis() - startTime // calculate the duration, and check it for enough
Okay I think I understand. My problem might be that I don't understand the unsigned math. You are saying. I will set duration to 12 hours and record start time and have something like this
if(millis()-startTime >= duration) Shut er down!
I am okay with this but I would like to know why this is right. For example I set it for a 12 hour set at 49.9 days (we will say it roles over at 50 for simplicity) This means that I would want it to shut off when millis()= 0.4 days
Okay
what happens when it just roles over
if(0.01 days - 49.9 days >= 0.5 days "12 hrs") Wouldn't this return a negative number until it reaches 49.9 days? But wait I remember that the unsigned numbers can only be positive. Wouldn't that mean that it would shut off as soon as it rolled over?
I am a stupid mechanical engineer playing in your world of electrical engineering. Help me understand.
Okay in summary unsigned long has different mathematical properties and because of them I don't have to worry about the millis() wrap so change your system to use the above subtraction method and don't complain.
jacob84401:
Okay in summary unsigned long has different mathematical properties and because of them I don't have to worry about the millis() wrap so change your system to use the above subtraction method and don't complain.
It's all in the algorithm. There's nothing tricky or sneaky about it... just plain ordinary unsigned math that does exactly what it is supposed to do, and in this case, exactly what you wanted it to do. Did you try Nick's example on the Mac calculator? If not, the Windows-supplied calculator also has a Programmer's calculator View. Run through his example, paying attention to the binary values as you put the numbers in, and at the end, showing the result.
Given that millis returns you an unsigned long, you could do some experiments with unsigned longs near the limit to demonstrate what happens at rollover - no need to wait for the ~50 days.
Or, "change your system to use the above subtraction method and don't complain."
unsigned is a red-herring, the lower bits of differences/sums of signed or unsigned
values are always correct when the higher bits are truncated because no result
bit depends on any more significant bits of the arguements.
Or put another way an unsigned long is arithmetic modulo 2^32, and modular
subtraction works modulo 2^32!
This works in decimal too, if modulo 10 or 100 or 1000 or some power of ten.