Digital Input
Making some LEDs blink is cool, but it's even better when you can control them with an input, like a switch. Using your two handmade switches from the Introducing the Switch lesson, you will learn how to read a switch as an input and make it affect the behavior of an LED.
You will learn:
+ how to use Arduino's serial monitor
+ how to read a switch's on/off state
+ pull-up and pull-down resistors
+ how to blink an LED by closing a switch
Materials
Download the attached file. This contains the final example sketches for this lesson. Follow along step-by-step to learn how to open, use and change the example sketches. Only use the first two sketches in this folder when you really get stuck.
+ microcontroller
+ USB cable
+ 10K Ohm resistor
+ 1 x sewable LED
+ alligator leads
+ handmade high-five switch from Introducing the Switch lesson
+ handmade snap switch from Introducing the Switch lesson
Downloads
Build Circuit
Follow the diagram to make connections between your handmade switch and the microcontroller.
Switch --> ground (-) LilyPad
Switch --> pin 2 LilyPad
Open Sketch
Open up the Arduino program and navigate to:
File > Examples > Basics > DigitalReadSerial
Copy and paste the example sketch in a new window and save as DigitalReadDemo.
Upload
Upload the sketch by hitting the upload button. There is not an LED in this circuit that can tell whether or not the switch is doing what it's supposed to; all the action is happening on board. So, how do you know your switch is open and closing? You can read the results in the serial monitor!
The Serial Monitor
The Arduino environment has a built-in feature that allows you to see if your switches and sensors are working. This feature is the serial monitor. It displays what is being communicated through the serial port. The serial port is a virtual port that allows data to flow in between the computer and your board through the USB cable.
The DigitalReadDemo sketch reads the signal coming in from the digital pin your switch is connected to. Remember, a digital signal will either give you a 1 or 0. This 1 or 0 will be printed in the serial monitor for you to see. We will go over how it prints to the serial monitor a little later in this lesson. To open the serial monitor, click the button that has what looks like a magnifying glass in the upper-right hand corner of the sketch window in the Arduino IDE.
When opened, there should be a string of 0s and 1s printing. Press the switch and see if anything happens. If a 0 isn't already there, one will pop up. Do you notice anything about the behavior of the switch and the prints in the monitor? It's hard to actually see a relationship between your press and when it prints a 0 or 1. Your goal is to get a clear 0 or 1 printing in the window when the switch is open and the opposite printing when it is closed. Why isn't this happening?
This is happening because what you have now is a floating pin. When the switch is closed the switch lead connected to ground is referenced which is why you get a 0. When the switch is open, the pin doesn't know what to reference because it's not connected to ground or power. So, how do we give it a reference?
The answer is a pull-up or pull-down resistor.
Add a Pull-down Resistor
Grab your 10K Ohm resistor and connect it to the switch and board as shown. I sewed my resistor to a piece of fabric to make it easy to reuse and clip to, but you can clip to the metal leads just the same.
When a resistor with a value of 10K ohm or higher is connected between the input pin and ground, it pulls the pin down to 0 volts when the switch is open. When pulled LOW to ground (0 volts), the input pin reads 0.
Upload the DigitalReadDemo sketch and open up the serial monitor. 0s will print until the switch is pressed. When the switch closes, the digital input is pulled to HIGH to 3.3v, which will print 1s. You can now see a clear relationship between your presses and the printed data!
Enable Pull-up Resistor
There is a second way to fix a floating pin that does not require you to hook up an extra resistor in your circuit.
Remove the 10k Ohm resistor and connect the switch back to ground:
Switch --> ground (-)
Switch --> pin 2
The LilyPad USB microcontroller and most Arduino boards already have resistors connected to some pins. These are called the board's internal pull-up resistors. They are called pull-up instead of pull-down because instead of them being connected to ground (0V), they are connected to power (3.3V). Using them really helps to minimize the amount of hardware you need to deal with.
Instead of adding an external resistor to the circuit, the internal pull-ups are enabled through software in the Arduino sketch. To enable the internal pull-ups via software, simply add _PULLUP to the pinMode() function in your sketch:
pinMode(pushButton, INPUT_PULLUP);
This added piece of code is highlighted above
Open Serial Monitor
Upload the sketch with _PULLUP added to enable the pull-ups and open the serial monitor. The pin your switch is connected to now references 3.3 volts and prints 1 when the switch is open and prints 0 when closed.
To read a switch you must always either enable the pull-up resistors or add a pull-down resistor to the circuit yourself. This is the final digitalReadDemo sketch! Let's take a look at what this code is doing.
The Code
Serial.begin()
To read the signal coming in from your board through USB, you need to open up a serial connection. Serial.begin() opens up that port. This command is always put in the setup function since it only needs to execute once.
Serial.begin(9600);
The rate at which the data travels is 9600 bits per second. The door is open now to let the data come in and go out between the computer and the Arduino.
DigitalRead()
Next, a variable is created to hold the data coming in from your switch. The function digitalRead() is used to see if the signal is HIGH/LOW, or 0/1. The function takes one argument, the pin number that you want it to read which is stated using the pushButton variable. In other words, this line of code says "Put the 0 or 1 coming from pin 2 into the variable named buttonState."
int buttonState = digitalRead(pushButton);
Serial.println()
To print the data coming from the switch, use the Serial.println() function. It takes one argument, the variable that holds the data you want to print. In our case, this the buttonState variable that holds that 0 or 1 coming from our switch.
Serial.println(buttonState);
The "ln" at the end of "print" is short for "line" and means there is a carriage return (new line) each time the value is printed. This creates an easy-to-read vertical stream of data flowing in the serial monitor.
Combine Input and Output
So far, you have learned how to blink an LED output and read a switch input. Now, let's get one affecting the other. Keep the switch on pin 2 and make these new connections using a sewable LED:
LED power (+) --> pin 3
LED ground (-) --> ground (-)
In the Arduino IDE Navigate to:
Examples > Digital > Button
Copy and paste the example sketch in a new window and save as buttonLEDdemo.
Plug in the pin number of your LED and switch and enable the pull-up resistor for your switch.
const int buttonPin = 2; const int ledPin = 3;
pinMode(buttonPin, INPUT_PULLUP);
In this example sketch, there is no serial port set up, so you need to add this line between the curly brackets of the setup() function.
Serial.begin(9600);And this line to print the button state in loop() directly under buttonState = digitalRead(buttonPin);.
Serial.println(buttonState);
Upload
Upload sketch and open the serial monitor.
A 1 will be printing as the switch is open and the LED is on. When the switch is closed, the LED will go off and a 0 will print. Great! The LED is being controlled by your actions!
The Code
If you look at the buttonLEDdemo, you will see there are some new lines of code. Let's take a closer look.
If Statement
The new item in this sketch is the If() Statement. It allows you to make something happen depending on whether a given condition is true or not. What's used in this sketch is actually a common variation of the if() statement called the if-else. This is the whole if-else statement:
if (buttonState == HIGH) { digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); }
The condition part of the statement is this:
(buttonState == HIGH)
the characters "==" means "is equal to". If this condition is true, the code between the curly brackets { } are executed. The if() statement above also uses a variable and the digitalWrite() function, which you learned about in the previous Digital Output lesson. In plain words, this is how the code before the word else reads:
If the buttonState (our variable that holds the state of the switch) is equal to HIGH (1/open switch), write a HIGH signal (3.3V) to the ledPin (the variable that holds the pin our LED is connected to). In other words, if the switch is open, turn the LED on.
else
If the condition is false (button does not equal LOW), the code within the curly brackets { } after the word else gets executed. Let's put it all together with the first part and say what the whole if-else statement is doing:
If the buttonState is equal to LOW, turn the LED on. Else, turn the LED off.
Phew! How are you doing? It takes some getting used to. Reading code is the first step to writing it just like any language. If you need, head over to the if() statement page on the Arduino website I link to above and study it a bit more to get used to what it does. The if() statement is a foundation of programming and you will be using it more in your Arduino programming adventures.
Using HIGH and LOW
Ok, let's get back to something hands on. Right now the buttonLEDdemo sketch turns the LED on when the switch is not pressed and open. What if you wanted to turn the LED off when it is open instead?
Take a look at the if() statement again. The condition says if the buttonState is HIGH, turn the LED HIGH, else (when the buttonState is LOW) turn the LED LOW. As you learned in the Introducing the Microcontroller lesson, LOW is the same as 0 when talking about a switch and 0 volts when talking about an LED. Alternatively, HIGH is the same as 1 and 3.3 volts.
So, how do we get the LED to turn on when the switch is closed (0/LOW) instead of open (1/HIGH) by altering the code? Can you guess?
It's done by changing the HIGH portion of the condition to LOW in the if() statement so it reads:
If the buttonState is equal to LOW (0, closed switch), turn on LED.
if (buttonState == LOW) { digitalWrite(ledPin, HIGH); }
Upload the sketch and press the switch, the LED will turn on only when you press the switch!
Add a Second Output
Now that you are getting more familiar with the code, let's add a second output.
Grab a second sewable LED and make these new connections:
LED power (+) --> pin 9
LED ground (-) --> ground (-)
When connecting the LED to the ground on the LilyPad USB you will notice that there isn't much room left. This is a common occurrence since multiple components in a circuit need to be grounded for electricity to pass through them. When prototyping, you will need room to ground more than two components often.
This is when your handmade snap switch comes in as a breakout for the ground pin (-) on the LilyPad. In general, a breakout extends and exposes the pins of a board. This is what the socket side of the snap switch can do for the ground (-) pin on your LilyPad USB.
Breakout Ground Pin
Disconnect the two alligator leads on the ground pin. Take the socket side of your snap switch and snap it onto the back of the LilyPad USB.
With the breakout snapped on, you now have room to clip on all three components: one switch and two LEDs. Keep this in your wearable electronics toolbox, it will come in handy for prototypes to come!
Open Sketch
From the sketches you downloaded earlier in this lesson, find and open the button2LEDdemo sketch.
This sketch combines the if() statement and two instances of digitalWrite(). Each instance uses a variable that contains either of the LED pins.
Upload
Hit the upload button and press the switch. Both LEDs will turn on while the switch is closed. Look at the sketch, can you write down why that is happening by reading and translating the code?
Experiment:
By using the else-if statement, which is different than the if-else you are currently using, alter your sketch to do these two things:
+ if the switch is pressed, turn ledPin1 HIGH and ledPin2 LOW
+ if the switch is not pressed, turn ledPin1 LOW and ledPin2 HIGH
Test Your Knowledge
{ "id": "quiz-1", "question": "A switch is connected, you have enabled your board’s pull-up resistors and you open the serial monitor. When the switch is left open what will print in the serial monitor?", "answers": [ { "title": "1", "correct": true }, { "title": "0", "correct": false } ], "correctNotice": "That's correct", "incorrectNotice": "That's incorrect" }
{ "id": "quiz-2", "question": "To read a switches state you would use the digitalWrite() function.", "answers": [ { "title": "false", "correct": true }, { "title": "true", "correct": false } ], "correctNotice": "That's correct", "incorrectNotice": "That's incorrect" }
{ "id": "quiz-3", "question": "This line of code turns on an LED connected to pin 3: digitalWrite(3, HIGH);", "answers": [ { "title": "false", "correct": false }, { "title": "true", "correct": true } ], "correctNotice": "That's correct", "incorrectNotice": "That's incorrect" }
Show your final working circuit using the button2LEDdemo sketch below! The experiment is extra credit :)