Loading...
Pages: [1]   Go Down
Author Topic: Newby question: falling edge of input switch  (Read 291 times)
0 Members and 1 Guest are viewing this topic.
Seattle, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Sydney
Offline Offline
God Member
*****
Karma: 14
Posts: 717
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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


Seattle, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Seattle, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: December 16, 2012, 12:25:24 pm by cosmos275 » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 311
Posts: 35470
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Seattle, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 311
Posts: 35470
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Seattle, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Groovy, thanks

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

Thanks!
Logged

Seattle, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Left Coast, CA (USA)
Online Online
Brattain Member
*****
Karma: 279
Posts: 15310
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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


Quote
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).

Quote
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
« Last Edit: December 16, 2012, 08:37:12 pm by retrolefty » Logged

Seattle, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Left Coast, CA (USA)
Online Online
Brattain Member
*****
Karma: 279
Posts: 15310
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Seattle, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1]   Go Up
Print
 
Jump to: