How Do Momentary Push Switches Work In Arduino?

I hope this isn't as silly as the topic sounds.

I'm working on Project 4 in 'Beginning Arduino' by Michael McRoberts. I didn't like his UK style traffic lights with pedestrian button, so I decided to clean it up and change it to US style. Especially since his pedestrian call button didn't seem to work.

The first thing I found was another 'new breadboard' problem. This board is long enough so they split it. In other words you could have separate Hi and Lo voltage buses for each of the 4 sections of a board. It's been a long time since I put one of these into service and I forgot the jumpers. No wonder the pedestrian call button didn't work. All the parts were connected to a power bus with no power on it, or ground. All they were getting was the signals from the Arduino.

Now the real question. The only push button I have handy for the pedestrian call is a momentary, which is what I would expect to find on a traffic light anyway. How do I capture the button push? It's connected to Digital I/O Pin 2, but only raises that pin to a high while it is pushed. If I was using an event-driven programming language, or even ladder logic, trapping it would be easy, but . . . . how do you do it in Arduino? Or do I just need to check the value at the end of each of the three delays in the lighting cycle?

This is the code I am using for testing at this point:

// Project 4 - Traffic Light with Pedestrian Walk Light
// US Style 

int carRed = 10;
int carYellow = 9;
int carGreen = 8;
int pedRed = 7;
int pedGreen = 6;
int button = 2;
int state = 0; // Button press state.
int crossTime = 5000;
unsigned long changeTime;  // Time since button press.


void setup() 
{
  pinMode(carRed, OUTPUT);
  pinMode(carYellow, OUTPUT);
  pinMode(carGreen, OUTPUT);
  pinMode(pedRed, OUTPUT);
  pinMode(pedGreen, OUTPUT);
  pinMode(button, INPUT);
  // Set up to start with pedRed ON.
  digitalWrite(pedRed, HIGH);
}

void loop() 
{
    // Call the function to change the lights.
    cycleLights();
}

// The function that manipulates the lights.
void cycleLights()
{
    digitalWrite(carRed, LOW);
    digitalWrite(carGreen, HIGH);
    delay(10000);
     
    digitalWrite(carGreen, LOW); // Green to OFF
    digitalWrite(carYellow, HIGH); // Yellow to ON.
    delay(3000); // Hold for 3 seconds.
    
    digitalWrite(carYellow, LOW); // Yellow to OFF
    digitalWrite(carRed, HIGH); // Red to ON.
    delay(10000); // Hold for 10 second.
     
    int state = digitalRead(button);
    if ((state == HIGH) && ((millis() - changeTime) > 5000))
      {
        digitalWrite(pedGreen, HIGH);
        delay(1000);
        digitalWrite(pedGreen, LOW);
      }
// Loop
}

McRoberts will probably get to it later in the book, but . . .

The only push button I have handy for the pedestrian call is a momentary, which is what I would expect to find on a traffic light anyway. How do I capture the button push? It's connected to Digital I/O Pin 2, but only raises that pin to a high while it is pushed. If I was using an event-driven programming language, or even ladder logic, trapping it would be easy, but . . . . how do you do it in Arduino? Or do I just need to check the value at the end of each of the three delays in the lighting cycle?

Look at the StateChangeDetection example in the IDE.

At some point you will want/need to stop using delay() for the timing otherwise the program will pause at various points and the pedestrian button press will not be recognised. Look at the BlinkWithoutDelay example in the IDE and Gammon Forum : Electronics : Microprocessors : How to do multiple things at once ... like cook bacon and eggs to see a technique that avoids this problem.

t's connected to Digital I/O Pin 2,

How? With duct tape? Details matter a great deal.

For instance, a switch has two legs. Connecting both of them to pin 2 makes no sense. So, presumably, that is not what you did. What you did, though, you didn't explain.

If your using delay then you need to keep your finger on the button until the program sees it, go of course you could look at blink without delay. But any program with delay's init is not worth debugging let alone writing!.

Mark

PaulS:

t's connected to Digital I/O Pin 2,

How? With duct tape? Details matter a great deal.

For instance, a switch has two legs. Connecting both of them to pin 2 makes no sense. So, presumably, that is not what you did. What you did, though, you didn't explain.

Well, I spent 2 paragraphs explaining the switch I have, but it is not compatible with the breadboard.

So let's say I'll be using a single pole momentary. One side connected to +5vdc, the other connected to Gnd through a 200 Ohm resistor, and to Digital I/0 Pin 2 on the Arduino UNO. (Pull Down Configuration?)

As to the use of 'delays', I use them because the book does and I don't know any better. Is there a better way to set the cycle time for the lights? Like using the 'millis' function?

The two ways normally used are polling and interrupt routine. A button push
doesn't really warrant squandering an interrupt on, its a slow things, so you'd
just poll in loop(). You should always code such that loop() is repeatedly being called
fast enough for all the polled actions to be handled promptly.

The simplest way to do the hardware is button between pin and ground, enable
on-chip pullup resistor:

  pinMode (button_pin, INPUT_PULLUP) ;

The pin is then active-low, so digitalRead() returns false when the button is
pressed. Software debouncing is usually needed to prevent multiple triggering
due to contact bounce.

Well, I spent 2 paragraphs explaining the switch I have,

Well, it's a lovely switch, and all that rot, but you still haven't said how it is really connected.

but it is not compatible with the breadboard.

What does this mean? You have jumper wires, don't you?

As to the use of 'delays', I use them because the book does and I don't know any better. Is there a better way to set the cycle time for the lights? Like using the 'millis' function?

Of course. The blink without delay example even shows how. And, just because the book uses delay() to illustrate a point doesn't mean that works in real life. In general, it does not.

PaulS:

Well, I spent 2 paragraphs explaining the switch I have,

Well, it's a lovely switch, and all that rot, but you still haven't said how it is really connected.

but it is not compatible with the breadboard.

What does this mean? You have jumper wires, don't you?

As to the use of 'delays', I use them because the book does and I don't know any better. Is there a better way to set the cycle time for the lights? Like using the 'millis' function?

Of course. The blink without delay example even shows how. And, just because the book uses delay() to illustrate a point doesn't mean that works in real life. In general, it does not.

Why did you read the first and third paragraphs and skip over this?:

So let's say I'll be using a single pole momentary. One side connected to +5vdc, the other connected to Gnd through a 200 Ohm resistor, and to Digital I/0 Pin 2 on the Arduino UNO. (Pull Down Configuration?)

In actuality, I don't have a working switch yet, which doesn't matter since I'm not going to start the project until I find out from someone, apparently not you, how I'm going to handle it's input.

In actuality, I don't have a working switch yet, which doesn't matter since I'm not going to start the project until I find out from someone, apparently not you, how I'm going to handle it's input.

Have you looked at the StateChangeDetection example in the IDE as I suggested in reply #1 ?

Why did you read the first and third paragraphs and skip over this?:

Because that was NOT in the initial post, where you claim to have spent two paragraphs describing the switch.

So let's say I'll be using a single pole momentary.

The initial post says

The only push button I have handy for the pedestrian call is a momentary, which is what I would expect to find on a traffic light anyway. How do I capture the button push? It's connected to Digital I/O Pin 2, but only raises that pin to a high while it is pushed.

So, are you using that momentary contact switch, and it is already (vaguely) connected, or are you planning to use some switch that will be connected in some specific fashion?

In actuality, I don't have a working switch yet, which doesn't matter since I'm not going to start the project until I find out from someone, apparently not you, how I'm going to handle it's input.

If you'd asked, up front, "Can I use this switch, and, if so, how do I connect and use it?", the answers you got would have been a whole lot different.

Of course you can use that switch. 99.9% of projects that use switches use momentary contact switches. Connect one leg to ground, and the other to a digital pin. Turn on the internal pullup resistor (using INPUT_PULLUP in the pinMode() call). Then, digitalRead() will return LOW when the switch is pressed, and HIGH when it is not.

The state change detection example shows you how to detect when the switch BECOMES pressed (or released), as opposed to IS pressed (or released), so that you can do things when the switch state changes.

That is how normal pedestrian crossing switches work. The computer controlling the light sees when the switch changes from not pressed to pressed, and notes that it needs to cycle the pedestrian crossing light on at the next available opportunity.