Schedule‎ > ‎

03A: Decisions and Digital I/O


Questions, Answers and Review

  • Questions from last class?
  • Questions about homework?

^ top

Making Decisions

Learner Outcomes

At the end of the lesson the student will be able to:

  • Discuss what is meant by the term flow of control
  • Make use of relational expressions to make decisions
  • Implement decisions using if statements
  • Compare numbers, characters and strings

^ top

Using if Statements Review

  • Flow of control (or control flow) refers to the order in which programs execute instructions
  • By default, code executes sequentially: one statement after another, top to bottom, left to right
  • We previously discussed how to change the flow using a selection statement
  • An if-statement only executes if a test condition evaluates to true
  • As an example, we have the following code with an if-statement

Example Program With an if-Statement

#include <ArduinoSTL.h>
using namespace std;

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
Serial.setTimeout(-1);
cout << "I'm thinking of a number between 1 and 10." << endl;
cout << "Can you guess it?" << endl;
cout << "Enter your first guess: " << endl;
}

void loop() {
if (Serial.available()) {
int guess = 0;
cin >> guess;
while (Serial.available()) { //clear out any line-end chars
Serial.read();
}
cout << "You entered: " << guess << endl;
digitalWrite(LED_BUILTIN, LOW);
if (7 == guess) {
cout << "*** Correct! ***" << endl;
digitalWrite(LED_BUILTIN, HIGH);
}
cout << "Try again." << endl;
}
}

Syntax of an if-statement

  • An if statement has two parts: a test and a body
  • The body can have zero or more statements
  • The statements in the body execute if and only if the test evaluates to true
  • If the test condition evaluates to false, the computer skips the code
  • Syntax:
    if (test)
    {
       statement1
       statement2
       ...
    }
    
  • Where:
    • test: the test condition to evaluate
    • statementX: the statements to execute depending on the test
  • For example:
        if (7 == guess) {
    cout << "*** Correct! ***" << endl;
    }
  • In the above, the (7 == guess) is a test that the 7 is equal to the value of guess
  • putting the variable on the right side is a trick to avoid the error of forgetting to use 2 equal signs for a comparison. (guess = 7) which will compile correctly, but not be what you want.(7 = guess) will generate a compiler error.
  • For clarity:
    • Write the if on a different line than the body
    • Indent within the curly braces

Diagram of if Statement Operation

if-statement syntax and flow chart

About those Curly Braces

  • Technically, the if statement affects only the single statement that follows
  • We use curly braces to make that one statement into a block of statements
  • This allows us to put any number of statements within the body
  • Curly braces are not always required, but the best practice is to always include them

Check Yourself

  1. True or false: an if-statement requires a test condition.
  2. The code inside the curly braces executes when x is equal to ________.
    if (x == 3) {
      x = 1;
    }
    
  3. The value of x after the following code executes is ________.
    int x = 7;
    if (x == 3) {
      x = 1;
    }
    
  4. True or false: an if-statement affects only the single statement following it unless curly braces are used.

^ top


Boolean Variables and Relationships

  • Notice that relational expressions always evaluate to true or false
  • Thus we can assign a relational expression to a Boolean variable
    bool test = 5 != 2;
    cout << test; // 1 means true
    
  • Notice how Boolean values are displayed
    • false == 0
    • true == 1
  • In a Boolean context, zero is false and any other number is interpreted as true

Check Yourself

  1. The value of x after the following code executes is ________.
    int x = 3;
    int y = 4;
    if (x < y) {
      x = y;
    }
    
  2. The value of y after the following code executes is ________.
    int x = 42;
    bool y = (x == 3);
    

^ top

Using if-else Statements

  • Sometimes we want to choose between two actions
  • If a condition is true
    • then do this
  • Otherwise it is false
    • so do something else
  • To make this type of selection we use an if...else statement
  • Syntax:
    if (test)
    {
       statements1
    }
    else
    {
       statements2
    }
    
  • Where:
    • test: the test condition to evaluate
    • statementsX: the statements to execute depending on the test
  • For example:
    if (7 == guess) {
      cout << "*** Correct! ***";
    } else {
      cout << "Sorry, that is not correct." << endl;
      cout << "Try again." << endl;
    }
    

Diagram of if-else Statement Operation

if-else operation
  • Notice that there is no test condition for the else clause
    if (7 == guess) {
      cout << "*** Correct! ***";
    } else {
      cout << "Sorry, that is not correct." << endl;
      cout << "Try again." << endl;
    }
    
  • The decision on which set of statements to use depends on only one condition
  • Note that we could write an if-else as a pair of complementary if statements instead, like:
    if (7 == guess) {
    cout << "*** Correct! ***";
    }
    if (7 != guess) {
    cout << "Sorry, that is not correct." << endl;
    cout << "Try again." << endl;
    }
  • However, it is easier and clearer to write an if-else statement instead
  • For clarity, write the if and else parts on different lines than the other statements
  • Also, indent the nested statements
  • We can see an example of an if-else statement in the following example

Example Sketch With an if-else Statement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <ArduinoSTL.h>
using namespace std;

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
Serial.setTimeout(-1);
cout << "I'm thinking of a number between 1 and 10." << endl;
cout << "Can you guess it?" << endl;
cout << "Enter your first guess: " << endl;
}

void loop() {
int guess = 0;
if (Serial.available()) {
cin >> guess;
cout << "You entered: " << guess << endl;
digitalWrite(LED_BUILTIN, LOW);
if (7 == guess) {
cout << "*** Correct! ***" << endl;
digitalWrite(LED_BUILTIN, HIGH);
} else {
    cout << "Sorry, that is not correct. " << "Try again." << endl;
}
}
}

Formatting the if-else Statement

  • It is important to format the if-else statement professionally
        if (7 == guess) {
    cout << "*** Correct! ***" << endl;
    digitalWrite(LED_BUILTIN, HIGH);
    } else {
    cout << "Try again." << endl;
    }
  • Note how the conditional code is indented inside both the if and else portions
  • This lets us easily see which code is conditional and which is not
  • Also note the placement of curly braces
  • Different groups have different practices for placing curly braces on if and if-else statements
  • In practice, you should use the style dictated by your group's policy
    • Or your professor's instructions
  • For the acceptable styles for this course see the instructions at: Curly Braces

Check Yourself

  1. True or false: an if-else statement allows the programmer to select between two alternatives.
  2. The problem with the following if-else statement is ________.
    if (7 == guess) {
        cout << "*** Correct! ***" << endl;
    }
    else (7 != guess) {
        cout << "Sorry, that is not correct." << endl;
    }
    
  3. The value of x after the following code segment executes is ________.
    int x = 5;
    if (x > 3) {
        x = x - 2;
    }
    else {
        x = x + 2;
    }
    
  4. True or false: always indent inside the curly braces of an if-else-statement.

^ top

Nested if Statements

  • We can improve our guessing game by providing hints
  • If the guess is too low or too high, we let user know
  • For example, if the answer is 7 and the guess is 5, we would display
    cout << "Your guess is too low, try again." << endl;
    
  • What test condition would we write to test for a low guess?
  • What test condition would we write to test for a high guess?

Multiple Test Conditions

  • We will need multiple test conditions for all the possible cases:
    • Guess too low
    • Guess too high
    • Guess is correct
  • Novice programmers often use a sequence of if statements for these tests, like:
    if (guess < 7) {
      cout << "Your guess is too low." << endl;
    }
    if (guess > 7) {
      cout << "Your guess is too high."<< endl;
    }
    if (guess == 7) {
      cout << "*** Correct! ***" << endl;
    }
    
  • While this works, it is not the recommended way because it is:
    • Not clear that only one of the assignment statements will be executed for a given value of guess
    • Inefficient since all three conditions are always tested
  • A better way is to nest if statements

Nested if-else Statements

  • A better way to implement our tests is with nested if statements
  • We can include if statements within other if statements, nesting in either the if clause or the else clause
  • When nested in the if clause, the inner if statement is evaluated only if the test condition of the outer if first evaluates to true
  • When nested in the else clause, the inner if statement is evaluated only if the test condition of the outer if first evaluates to false
  • The following code shows an example of an if statement nested in the else clause
  • How would we rewrite the code to nest within the if clause?

Example Showing a Nested if Statement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <ArduinoSTL.h>
using namespace std;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
Serial.setTimeout(-1);
Serial.print("I'm thinking of a number between");
Serial.print(" 1 and 10.\nCan you guess it?\n\n");
Serial.println("Enter your first guess.");
}

void loop() {
int guess = 0;
cin >> guess;
cout << "You entered: " << guess << endl;
digitalWrite(LED_BUILTIN, LOW);
if (7 == guess) {
cout << "*** Correct! ***" << endl;
digitalWrite(LED_BUILTIN, HIGH);
} else {
if (guess < 7) {
cout << "Your guess is too low, try again." << endl;
} else {
cout << "Your guess is too high, try again" << endl;
}
}
}

Nesting in the else Clause

  • We can nest in either the if clause or the else clause
  • When we nest in the else clause, the else clause does not execute if the test evaluates to true
  • The else part executes only when the if test condition evaluates to false
  • The if statement inside the else clause works in the same way
  • By continuing to nest in the else clause, we can build a series of test conditions
  • The first test condition that evaluates to true executes and the remainder of the clauses are skipped
  • Let us trace through the logic in the following code extracted from the last example assuming guesses of 5, 8 and 7

Example of Nesting in the else Clause

  if (7 == guess) {
cout << "*** Correct! ***" << endl;
digitalWrite(LED_BUILTIN, HIGH);
} else {
if (guess < 7) {
cout << "Your guess is too low, try again." << endl;
} else {
cout << "Your guess is too high, try again" << endl;
}
}

Formatting the else-if Statement

    If the nesting is carried out too deeply, nested if-else-if statements become hard to read:
    if (test1) {
      // do something1
    } else {
      if (test2) {
        // do something2
      } else {
        if (test3) {
          // do something3
        ...
        }
      }
    }
    
  • Because of this tendency to creep to the right, we write nested else-if statement in a special way:
    if (test1) {
      // do something1
    } else if (test2) {
      //do something2
    } else if (test3) {
      //do something3
    ...
    }
    
  • We remove the curly-braces for the else clause and align everything to the left
  • Now the logic is easy to follow:
    • The computer starts at the top
    • The computer checks each condition, one after the other
    • Once the selection is made and processes, the computer skips the rest of the options
  • We can see the previous example reformatted below

Example Showing a Nested else-if Statement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <ArduinoSTL.h>
using namespace std

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
Serial.setTimeout(-1);
Serial.print("I'm thinking of a number between");
Serial.print(" 1 and 10.\nCan you guess it?\n\n");
Serial.println("Enter your first guess.");
}

void loop() {
int guess = 0;
cin >> guess;
cout << "You entered: " << guess << endl;
digitalWrite(LED_BUILTIN, LOW);
if (guess < 7) {
cout << "Your guess is too low, try again." << endl;
} else if (guess > 7) {
cout << "Your guess is too high, try again." << endl;
} else {
cout << "*** Correct! " << endl;
digitalWrite(LED_BUILTIN, HIGH);
}
}

Programming Style: Indentation of else-if Statements

  • Format nested else-if statements without the curly braces between the else and if clauses
  • Then align code to the left as shown below:
  •  if (guess < 7) {
    cout << "Your guess is too low, try again." << endl;
    } else if (guess > 7) {
    cout << "Your guess is too high, try again." << endl;
    } else {
    cout << "*** Correct! " << endl;
    digitalWrite(LED_BUILTIN, HIGH);
    }
  • This formatting more clearly shows that we are making a single choice among multiple alternatives
  • Also, it prevents indentations from cascading to the right as we add more selections

Check Yourself

  1. True or false: you can nest if statements in the if clause, the else clause, or both.
  2. In the following code snippet, when guess = 8 the code displays ________
    if (guess != 7) {
        if (guess < 7) {
            cout << "Your guess is too low, try again." << endl;
        } else {
            cout << "Your guess is too high, try again" << endl;
        }
    } else {
        cout << "*** Correct! ***" << endl;
    }
    
  3. In the following code snippet, when guess = 7 the code displays ________
    if (guess < 7) {
        cout << "Your guess is too low, try again." << endl;
    } else if (guess > 7) {
        cout << "Your guess is too high, try again." << endl;
    } else {
        cout << "*** Correct! ***" << endl;
    }
    
  4. The following code snippet prints ________
    int x = 1;
    if (x > 0) {
      x = x + 5;
    } else if (x > 1) {
      x = x + 2;
    } else {
      x = x + 7;
    }
    cout << x;
    
  5. The following code snippet prints ________
    int x = 0;
    if (x > 0) {
      x = x + 5;
    } else if (x > 1) {
      x = x + 2;
    } else {
      x = x + 7;
    }
    cout << x;
    

^ top

Exercise 1: Changing the Blink Rate (10m)

In this exercise we use if-else-if to change the blinking rate of the built-in LED.

Starter Code

/**
CS-11M
Name: The name of this program
Purpose: describe the purpose of this program

@author Your name here
@version 1.0 Today's date here
*/

#include <ArduinoSTL.h>
using namespace std;

int num = 0;

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
cout << "Enter a 1 or 2 or 3 to set the LED blink rate." << endl;
}

void loop() {
if (Serial.available()) {
cin >> num;
while (Serial.available()) { //put this after your cin statement
Serial.read();
}
cout << "You entered: " << num << endl;
}
}

Specifications

  1. Start the Arduino IDE with a new sketch New button and save the project as if-else-if.
  2. Copy the starter code above and paste it into the if-else-if sketch.
  3. Compile the sketch to verify you copied the starter code correctly.
  4. After the first if-statement, add another if-statement that tests for num equal to one and that blinks the LED at 1000 ms if true, like:
    if (1 == num) {
      digitalWrite(13, HIGH);
      delay(1000);
      digitalWrite(13, LOW);
      delay(1000);
    }
    
  5. Compile and upload your code to verify the changes, opening the serial monitor to test the program.

    Make sure the LED blinks when you enter the number 1 into the serial monitor. If you have problems, ask a classmate or the instructor for help.

  6. Add an else-if statement that tests for num equal to two and that blinks the LED at 2 seconds.
  7. Add an else statement that blinks the LED at 3 seconds if the number is 3 or anything other than 1 or 2.
  8. Compile and upload your code to verify it works correctly.

    You should now be able to toggle between the three rates by entering a one or a two or a three into the serial monitor. If you have problems, ask a classmate or the instructor for help.

  9. Submit your if-else-if.ino file  to Canvas.

When finished, please help those around you.


^ top

Summary

  • Flow of control (or control flow) refers to the order in which programs execute instructions
  • By default, code executes sequentially: one statement after another, top to bottom, left to right
  • An if-statement only executes if a test condition evaluates to true
  • An if statement has two parts: a test and a body
  • The body can have zero or more statements
  • The statements in the body execute if and only if the test evaluates to true
  • If the test condition evaluates to false, the computer skips the code
  • Syntax:
    if (test) {
       statement1
       statement2
       ...
    }
    
  • Where:
    • test: the test condition to evaluate
    • statementX: the statements to execute depending on the test
  • One way to make a test condition is with relational operators
  • Relational operators compare two values and evaluate to either true or false
  • The basic C/C++ relational operators are: ==, !=, <, <=, >, >=
  • To choose between two actions we use an if-else statement
  • Syntax:
    if (test) {
       statements1
    } else {
       statements2
    }
    
  • Where:
    • test: the test condition to evaluate
    • statementsX: the statements to execute depending on the test
  • When we need to evaluate multiple test conditions, we may nest if statements
  • We can nest if statements either in the if clause or the else clause
  • Each has benefits depending on the logic we need to implement
  • Nesting in the else clause we can build a series of logically related test conditions
  • As an example:
    if (test1) {
      // do something1
    } else if (test2) {
      //do something2
    } else if (test3) {
      //do something3
    ...
    }
    
  • Notice the formatting that removes the curly braces for the else clause

^ top

Arduino Digital I/O

Learner Outcomes

At the end of the lesson the student will be able to:

  • Discuss what is meant by digital I/O
  • Write code to control digital input and output pins

^ top

Digital I/O

  • Arduino is intended for physical computing and thus has many I/O possibilities
  • Much of the I/O is through attaching electronics to the Arduino pins
  • These attachments can be either digital (on or off) or analog with various voltage levels
  • We will discuss Digital I/O today
Lightning as voltage

Representing Two States 

  • Digital means there are two states
  • In electronics, we represent these two states as low and high voltages
  • Recall that voltage is the difference in electric charge between two points
  • Typically, the Arduino uses 0 volts (ground) as low and +5 volts as high
  • Arduino designates these states as LOW and HIGH
  • The LOW and HIGH states can be input and output using Arduino's digital pins

Arduino's HIGH and LOW Voltage States

Digital signal states: high and low

Source: arduinomatic.com

Check Yourself

  1. A digital signal has ________ states.
    1. 0
    2. 1
    3. 2
    4. 3 or more
  2. In electronics, digital states are represented using the electromotive potential difference between two points expressed in ________.
  3. For the Arduino, a LOW state is ground and a HIGH state is ________.

^ top

Digital Pins and I/O Functions

  • The Arduino has many digital pins available
  • For example, the Arduino Uno from our kit has 14 digital pins numbered 0 to 13
  • These pins can be used as either input or output using the functions described below
  • Some of the pins have specialized functions in addition
  • For example, pins 0 and 1 receive (RX) and transmit (TX) serial data
Arduino pinout

Source: arduinomatic.com

Digital I/O Functions

Name Description
pinMode() Calling pinMode(pin, mode) configures the specified pin to behave either as an INPUT, INPUT_PULLUP or OUTPUT.
digitalWrite() Calling digitalWrite(pin, value) writes a HIGH or a LOW value to the specified digital pin.
digitalRead() Calling digitalRead(pin) returns a HIGH or a LOW value from the specified digital pin.

Check Yourself

  1. The Arduino Uno has 14 digital pins, numbered ________ to ________.
  2. True or false: in addition to providing digital I/O, some digital pins have specialized functions.
  3. Digital pins can be put into this many modes: ________.
    1. 1
    2. 2
    3. 3
    4. 4
  4. The function to write a digital HIGH or LOW value is named ________.
  5. The function to read a digital HIGH or LOW value is named ________.

^ top

Coding Digital I/O

  • We can write Arduino commands to control the digital pins
  • To set the pins to input or output, we call the pinMode(pin, mode) function
  • Where:
    • pin: the digital pin to set (0 - 13)
    • mode: one of INPUT, INPUT_PULLUP or OUTPUT
  • We will look at basic examples of input and output in this section

Digital Output

  • We have made use of an LED attached to digital pins for output, such as blinking with pin 13
  • With digital output set to a HIGH state, the pin provides up to 40 milliamps (mA) of current at 5 volts
  • The pins are useful for powering LEDs which typically use less than 40 mA
  • Loads greater than 40 mA, like motors, require a transistor or other interface circuitry
  • Pins configured as outputs can be damaged or destroyed if they are connected to either the ground or positive power rails
  • We must protect the output using component such as a resistor
  • Digital output is coded using the digitalWrite(pin, value) function
  • Where:
    • pin: the digital pin to set (0 - 13)
    • value: either HIGH or LOW
  • For example, from the blink sketch:
    void loop() {
      digitalWrite(13, HIGH);
      delay(1000);
      digitalWrite(13, LOW);
      delay(1000);
    }
    

Digital Input

  • When set to INPUT the digital pins can read a voltage as HIGH or LOW
  • HIGH is when a voltage greater than 3 volts is present at the pin (5V boards)
  • LOW is when a voltage at the pin is less than 3 volts
  • When set to INPUT, the pin is in a high impedance state equivalent to a series resistor of 100 MΩ in front of the pin
  • Since very little current gets through, the pin has a very low effect on the circuit it is sampling
  • Digital input is coded using the digitalRead(pin) function
  • Where pin is the digital pin to read (0 - 13)
  • The function returns a value of HIGH or LOW that we can assign to a variable
  • For example:
    int buttonState = digitalRead(pushButton);
    
  • The following code uses digitalRead() to measure a pin on an Arduino
  • The Arduino is connected to a pushbutton circuit, which we explore in the next section

Example Code Calling digitalRead()

int pushButton = 2;

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

void loop() {
  int buttonState = digitalRead(pushButton); // read pin
  cout << buttonState << endl; // display state
  delay(100);
}

Check Yourself

  1. A digital pin can source (provide) current up to ________ milliamps.
  2. To read from a pin, set the pin mode to ________.
  3. Which of the following is a correct way to read a digital value from a pin and save the value read in a variable named foo?
    1. digitalRead(pin, foo)
    2. digitalRead(foo, pin)
    3. foo = digitalRead(pin)
    4. pin = digitalRead(foo)

^ top

Digital Input from Pushbuttons

  • One use for digital read is to test if a button is pressed
  • Buttons, or switches, connect two points in a circuit when pressed
  • When not pressed, there is no connection between the two sides of the button
  • The following image shows a pushbutton and its schematic symbol

Breadboard Pushbutton and Schematic Symbol

Pushbutton and schematic symbol

Source: arduinoclassroom.com

Floating Input and Pull-Up Resistors

  • Reading a switch that is open will result in a pin that is "floating"
  • Digital input pins are very sensitive and will pick up stray capacitance from nearby sources like breadboards, human fingers and wires
  • Any wire connected to an input pin will act like a little antenna and cause the input state to change
  • To solve the problem, we use a pull-up or pull-down resistor
  • The resistor pulls the pin to a known state when the switch is open
  • A 10kΩ resistor is often chosen as a pull-up or pull-down resistor
  • A kΩ is electrical resistance equal to one thousand ohms
  • So our resistor is equal to 10,000 Ohms

Example of Digital Read with a Pushbutton

  • Let us implement a pushbutton circuit with Arduino
  • Here is the Fritzing file for the circuit: button.fzz
  • We start with the following circuit breadboard
Push button circuit with pull-up resistor
  • One pole of the button is connected to pin 2 and then to 5 volts through a 10kΩ resistor
  • The resistor is known as a pull-up resistor because it connects to 5 volts, forcing the pin high by default
  • The other side of the button is connected to ground
  • When the button is pressed, the metal contacts close and force the pin to ground
  • The code to test for button presses is shown below

Example Sketch for Detecting Pushbuttons

#include <ArduinoSTL.h>
using namespace std;

int pushButton = 2;

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

void loop() {
int buttonState = digitalRead(pushButton); // read pin
cout << "buttonState is " << buttonState << endl; // display state
delay(1000);
}

^ top

Internal Pull-up Resistors

  • Arduino has internal pull-up resistors which are controlled by software
  • By default the internal pull-up resistors are turned off
  • We turn on the pull-up resistors by setting the pin mode to INPUT_PULLUP
  • For example:
    pinMode(2, INPUT_PULLUP);
    
  • On the Arduino Uno, the value of the pull-up is guaranteed to be between 20kΩ and 50kΩ
  • By changing the pin mode we can eliminate the pull-up resistor from our circuit
  • The new code and breadboard circuit is shown below

Example Sketch with INPUT_PULLUP

int pushButton = 2;

void setup() {
  Serial.begin(9600);
  pinMode(pushButton, INPUT_PULLUP);
}

void loop() {
  int buttonState = digitalRead(pushButton); // read pin
  cout << "buttonState is " << buttonState << endl; // display state
 }

Breadboard Without Pull-up Resistor

Push button circuit without pull-up resistor

^ top

Exercise 2: Counting Button Presses (10m)

In this exercise we write code to count button presses.

Parts

  • Solderless breadboard
  • Pushbutton
  • Jumper Wires

Breadboard Layout

Pushbutton circuit without pull-up resistor
  • Start with the Arduino unplugged.
  • Make the circuit as shown in the image.

Starter Code

int pushButton = 2;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int buttonState = digitalRead(pushButton); // read pin
  cout << buttonState << endl; // display state
 }

Specifications

  1. Start the Arduino IDE with a new sketch New button and save the project as button_counter.
  2. Copy the starter code above and paste it into the button_counter sketch.
  3. in Setup() add a statement to configure pin pushButton to be INPUT_PULLUP.
  4. Compile the sketch to verify you copied the starter code correctly.
  5. Add two new variables at the start of the code as follows:
    int counter = 0;
    int priorButtonState = LOW;    //this will store the last value of the ButtonState
    
  6. In the loop() function, replace the line displaying the button state with the following code:
    delay(1); // debounce - give button time to transition
    if (buttonState != priorButtonState) {
      priorButtonState = buttonState;
    }
    
  7. Inside the if statement Curly braces,  add another if statement that checks to see if buttonState is LOW.  If buttonState is LOW,  then add one to counter and print out the current count of button presses.
  8. Compile and upload your code to verify it works correctly.

    When you open the serial monitor, you should see a report of the button count increasing every time you press the breadboarded button. 

  9. Your output should look something like this:

  10. Count of button presses: 1
    Count of button presses: 2
    Count of button presses: 3
    Count of button presses: 4

  11.  If you have problems, ask a classmate or the instructor for help.

  12. Save your button_counter.ino file to submit to Canvas with the next homework.

When finished, please help those around you.

^ top

Summary

  • The Arduino has many digital pins we can use to read or write digital data as shown below
Arduino pinout

Source: arduinomatic.com

  • The commonly used functions for reading and writing digital data are shown below
Name Description
pinMode() Calling pinMode(pin, mode) configures the specified pin to behave either as an INPUT, INPUT_PULLUP or OUTPUT.
digitalWrite() Calling digitalWrite(pin, value) writes a HIGH or a LOW value to the specified digital pin.
digitalRead() Calling digitalRead(pin) returns a HIGH or a LOW value from the specified digital pin.
  • We have used digitalWrite() many times, like with the blink sketch
    void loop() {
      digitalWrite(13, HIGH);
      delay(1000);
      digitalWrite(13, LOW);
      delay(1000);
    }
    
  • For digital input we use code like:
    int buttonState = digitalRead(pushButton);
    
  • One use for digitalRead() is to test if a button is pressed
  • However, reading a switch that is open will result in a pin that is "floating"
  • Thus we add pull-up or pull-down resistors to "pull" to a default state
  • Rather than adding a pull-up resistor to our circuits, Arduino has an internal pull-up resistor we can enable
    pinMode(2, INPUT_PULLUP);
    

Further Study

  • constants: Arduino documentation describing the values of the digital pin modes: INPUT, INPUT_PULLUP, and OUTPUT.
  • Digital Pins: Arduino tutorial describing the properties of pins configured as INPUT, INPUT_PULLUP or OUTPUT.

^ top

Wrap Up and Reminders

  • For next homework, see the schedule
  • When class is over, please shut down your computer.
  • Complete unfinished exercises from today before the next class meeting

^ top



Subpages (2): button_counter if-else-if