# Digital Input – buttons and switches

Pushbuttons or switches connect two points in a circuit when you press them. When the pushbutton is open (unpressed) there is no connection between the two legs of the pushbutton, so the pin is connected to ground (through the pull-down resistor) and reads as LOW, or 0. When the button is closed (pressed), it makes a connection between its two legs, connecting the pin to 5 volts, so that the pin reads as HIGH, or 1.

If you have no resistor when it’s closed it becomes be a short circuit and when it’s open it doesn’t have a defined/predictable value (it would float between 0 and 1 according to environmental condition).

Upload this code and open the serial monitor:

```void setup() {
Serial.begin(9600);
pinMode(2, INPUT);
}

void loop() {
int sensorValue = digitalRead(2);
Serial.println(sensorValue, DEC);
}
```

“Serial.println(sensorValue, DEC);” is equivalent to println in Processing.

# Digital Input & digital output

We are ready to make our first (sort of) interactive object.
Something terrifying: add the blinking LED to your circuit and connect it to PIN 13.

This code reads the signal from the button and sends it to the LED.

```int LEDPin = 13;
int buttonPin = 2;

void setup() {
pinMode(buttonPin, INPUT);
pinMode(LEDPin, OUTPUT);
}

void loop() {
int value = digitalRead(buttonPin);
digitalWrite(LEDPin, value);
}```

Exercises
This is something we could have done without the Arduino so let’s make it more interesting.

1. Make it blink only when the button is down or viceversa.
2. Start blinking when the button is pressed and blink forever.

More advanced stuff below.

# Pull up and pull down resistors

You’ll always see resistor connected to switches. That’s because when a circuit is open you’ll probably have parts of the circuit with floating value: the digital signal is inconsistently moving between +5V and 0V.

The solution is to use a “pull down” resistor between the switch and the ground to force a value to LOW when the circuit is open:

Or the opposite logic: forcing a HIGH value with a “pull up” resistor.

Note: The 100 ohm resistor in the scheme is to avoid a short circuit, that would happen only if you accidentally set the pin to output and set its value to LOW basically connecting +5V and ground, so it a cautionary measure.

Exercise
Make a click counter like Luke Loeffler’s with a software output:

You’ll notice there are false positives. This is not a software (sketch) problem, but actually a mechanical problem.

Inside the little tactile switch is a small disc spring. When you push the button you squeeze the spring so that it makes contact with the two wire connections. When you release, the spring bounces back. This works great except that, well, the spring is springy. And that means that once in a while, when you press the button it bounces around a little in the switch, making and breaking contact a few times before settling.

# Debounce

This is the software solution to this mechanical problem.

```
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
}

void loop() {
// read the state of the switch into a local variable:

// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH),  and you've waited
// long enough since the last press to ignore any noise:

// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}

if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state: