Newby question: falling edge of input switch

Hi all. I just got an Uno and have a blinking LED, cool. I had some C programming, but it's rusty.

I'd like to write a code that does this: Turn on an output (turns on a motor). (The motor will eventually go over a switch and turn it on. A short time later it will run off the switch and the switch will go off). I'd like to have the motor turn off 1 second after the switch goes low (turns off). Then I want to wait a long time (4hrs) and repeat the whole process.

I think studying some examples will get me most of the way there, but does anyone know how to use the falling edge of an input (switch state)?

Thanks!

The falling edge is just noticing that the input was 1 and then goes to zero. You will need to set up a variable that remembers the current state each time through loop() and then acts when it sees the correct transition.

The blink without delay example will help you understand how to set up code to wait for a specified period without calling the delay function.

Thanks! That example is what I think I need. I think I'm off on what I'm trying to do. I was looking for the falling edge to be a fail safe, which it wouldn't be. I think instead, I'll set a timeout timer and if it times out before seeing the switch, I kill power.

Thanks!

So, with the blink without delay, it seems it won't work after 50 days is up or whenever millis() gets full and resets. Is there a way to do this continuously. For my application, I want the thing to run a few times a day indefinitely. Is there a way to manually reset millis? Thanks

Your watch rolls over twice a day. Has that ever caused you grief?

I guess my fear is that millis will roll from +a zillion to -a zillion and whatever math I'm doing from it will get messed up. The examples I see of bypass millis rollover don't seem to work unless I'm misunderstanding (highly likely)

In this example:

http://www.cmiyc.com/blog/2012/07/16/arduino-how-do-you-reset-millis/
void loop() {
if ((unsigned long)(millis() - waitUntil) >= interval) { // check for rollover
// It's time to do something!
digitalWrite(13, !digitalRead(13)); // Toggle the LED on Pin 13
waitUntil = waitUntil + interval; // wait another interval cycle

So, to me, this stops working when millis gets huge, then rolls over. Waituntil keeps getting incremented up to some large number, but when millis rollsover, nothing is there to roll Waituntil to a correspondingly small number. So, if I want my "do something" period to be 4 hours, it will work until 50 days, then my new period will be 50 days minus a couple hours.

What I'm trying to figure out is how to make a 24 hour routine that will won't get messed up.

Thanks

That is not a good way of using millis(). Addition using unsigned longs can cause rollover. However, subtraction involving unsigned longs always works.

if(millis() - then > interval)
{
   // do something

   then = millis();
}

This code will work regardless of whether then contains a large value and millis() returns a small value, or then contains a small value and millis() returns a large value,

As long, of course, as interval is less than 50 days.

Groovy, thanks

The "then = millis()" part seems to be what the other one lacked.

Thanks!

Nope, still confused

So, here I mocked this up in excel. Let's say Millis goes from -5 to 5. Third column is first minus second, like your code. When the third column = 2 the next "then" entry becomes the previous millis value, "-3" being the first example to show up in column 2. You can see that setting then = millis at a very high millis value puts it in a irretrievable place and int will never =2 again. So, after 50 days, I'm toast. Thoughts?
(I set then to start at -5, but doesn't matter what value, it always ends up not working)

TIA

millis then int=2
-5 -5 0
-4 -5 1
-3 -5 2
-2 -3 1
-1 -3 2
0 -1 1
1 -1 2
2 1 1
3 1 2
4 3 1
5 3 2
-5 5 -10
-4 5 -9
-3 5 -8
-2 5 -7
-1 5 -6
0 5 -5
1 5 -4
2 5 -3
3 5 -2
4 5 -1
5 5 0
-5 5 -10
-4 5 -9
-3 5 -8
-2 5 -7

Let's say Millis goes from -5 to 5.

You missed the part about millis() returning a unsigned long, there is no -5 allowed with a unsigned long value, Just 0 to max 32 bit positive value.

unsigned long

Description
Unsigned long variables are extended size variables for number storage, and store 32 bits (4 bytes). Unlike standard longs unsigned longs won't store negative numbers, making their range from 0 to 4,294,967,295 (2^32 - 1).

long

Description
Long variables are extended size variables for number storage, and store 32 bits (4 bytes), from -2,147,483,648 to 2,147,483,647.

Lefty

Ok, sorry I misunderstood about the long.

Doesn't matter, let's say millis() goes from 1 to 5, then rolls over. Interval =2 works a couple times until then is large, then never to return to the value of 2. If it goes 0 to 50 days, it seems my project will only work for 50 days, then crap out...

millis then int=2
1 0 1
2 0 2
3 2 1
4 2 2
5 4 1
1 4 -3
2 4 -2
3 4 -1
4 4 0
5 4 1
1 4 -3
2 4 -2
3 4 -1
4 4 0
5 4 1
1 4 -3
2 4 -2
3 4 -1
4 4 0
5 4 1
1 4 -3

It's been explained in past posts why when using subtraction that there is no roll over problem. It involves there being a 33th bit position (a borrow bit) carried over in the subtraction. The software guys explained to well enough for me to believe it but I'll be damned if I can just re-explain it as I was told.

I suspect it should be made a sticky as it's a topic question that never goes away.

Lefty

I see (mostly)

http://arduino.cc/forum/index.php/topic,128354.0.html

Here's a good thread on it explaining in depth. I read it and understand to the point I'll take your word for it. Hopefully I can get to the point of testing it out before too long.

Thanks! Great forum