Chapter 3

More Arduino Programming Tricks

IN THIS CHAPTER

check Reading the status of push buttons

check Generating random numbers

check Using a potentiometer as input

In this chapter, you learn some additional Arduino programming techniques that will become invaluable in your Arduino projects. Specifically, you learn how to handle input data in the form of push buttons, how to generate random numbers that will make your programs more interesting by adding a degree of randomness, and how to read the value of a potentiometer.

Using a Push Button with an Arduino

In Chapter 2 of this minibook, you learn how to connect an LED to an Arduino I/O pin and turn the LED on or off by using digitalWrite function in an Arduino program. The digitalWrite function uses the I/O pins as output pins by setting the status of an I/O pin to HIGH or LOW so that external circuitry (such as an LED) can react to the pin’s status.

But what if you want to use an I/O pin as an input instead of an output? In other words, what if you want the Arduino to react to the status of an external circuit instead of the other way around? The easiest way to do that is to connect a push button to an I/O pin. Then, you can add commands to your Arduino program to detect whether the push button is pressed.

There are two ways to connect a push button to a Arduino I/O pin:

Figure 3-1 shows examples of both active-high and active-low push buttons. In the active-high circuit, the I/O pin is connected to ground through resistor R1 when the push button is not pressed. Thus, the voltage at the I/O pin is 0. When the push button is pressed, the I/O pin is connected to images through R1, causing the I/O pin to see images. As a result, the I/O pin is LOW when the button is not pressed and HIGH when the button is pressed.

image

FIGURE 3-1: Active-high and active-low input circuits.

In the active-low circuit, the I/O pin is connected to images through R1, causing the I/O pin to go HIGH. But when the button is pressed, the current is shorted to ground through R1, causing the voltage at the I/O pin to drop to zero. Thus, the I/O pin is HIGH when the button isn't pressed and LOW when the button is pressed.

warning Note that in both circuits, R1 is connected between the images and ground to prevent a short circuit. Without this resistor, the Arduino would likely be damaged when the button is pressed.

technicalstuff In an active-high circuit, R1 is called a pull-down resistor because it pulls the current from the I/O pin down to zero when the push button isn't depressed. In an active-low circuit, R1 is called a pull-up resistor because it pulls the voltage at the I/O pin up to Vdd (images) when the push button isn't depressed.

Checking the Status of a Switch in Arduino

Once you’ve connected a switch to an Arduino I/O pin, you need to know how todetermine whether the switch is open or closed from an Arduino program. The easiest way to do that is to first designate the pin as an input pin by calling the pinMode function, and then checking the status of the input pin by calling the digitalRead function. The digitalRead function returns 0 or 1 depending on the current status of the input pin.

For example, you can designate pin 10 as an input pin like this:

pinMode(10, INPUT);

Then, to get the status of the pin, you could call digitalRead like this:

int Pin10Status;
Pin10Status = digitalRead(10);

The digitalRead function returns the current status of pin 10 and stores it in an int variable named Pin1Status. You can then test the status of the pin in an if statement:

if (Pin10Status == 1)
{
// The switch has been pressed!
}

In many cases, you can shorten your code by skipping the need for a variable to store the result of the pinRead function, like this:

if (digitalRead(10))
{
// The switch has been pressed!
}

Notice in the preceding if statement that two consecutive right parentheses are required. The first one closes the list of arguments passed to the digitalRead function; the second one closes the expression in the if statement.

Here’s an example that lights an LED on pin 0 if the user presses the button on pin 10 and turns on the LED when the button is released:

if (digitalRead(10))
{
digitalWrite(0, HIGH);
}
Else
{
digitalWrite(0, LOW);
}

Here, the LED on pin 0 is made HIGH if the button is pressed and LOW if the button isn’t pressed.

Listing 3-1 shows an interesting program that works with an Arduino that has a push button switch connected to pin 10 and LEDs connected to pins 0 and 1. The program flashes the LED connected to pin 0 on and off at quarter-second intervals until the push button switch is depressed. Then, it flashes the LED on pin 1.

LISTING 3-1 The Push Button Program

// The LED Flasher Program with a Push Button
// Doug Lowe
// September 16, 2016
//
// This program flashes one of two LEDs connected to
// pins 0 and 1, depending on whether the push button on
// pin 10 is pressed.

void setup() {
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(10, INPUT);
}

void loop() {
if (digitalRead(10) == 1)
{
digitalWrite(0, HIGH);
delay(250);
digitalWrite(0, LOW);
delay(250);
}
else
{
digitalWrite(1, HIGH);
delay(250);
digitalWrite(1, LOW);
delay(250);
}
}

Project 45 shows how to build a simple circuit you can use to test the program in Listing 3-1, and Figure 3-2 shows the completed circuit.

image

FIGURE 3-2: A circuit for testing an active-high push button switch (Project 45).

Project 45: A Push-Button Controlled Arduino LED Flasher

In this project, you connect a breadboard with two LEDs and a push button to an Arduino UNO board.

image
image
image

Parts

  • One computer with Arduino IDE installed
  • One Arduino UNO board
  • One mini-B USB cable
  • One small solderless breadboard (RadioShack 2760003)
  • Two 5mm red LEDs (RadioShack 2760209)
  • One normally open DIP breadboard push button
  • Two images resistors (yellow-violet-brown)
  • One images resistor
  • Five jumper wires

Steps

  1. Insert the resistors.

    images: J4 to ground

    images: J8 to ground

    images: J28 to ground

  2. Insert the LEDs.

    LED

    Anode

    Cathode

    LED1

    I6

    I4

    LED2

    I10

    I8

  3. Insert the push button.

    The pins should be inserted in E26, F26, E28, and F28 such that the switch opens and closes across rows 26 and 28.

  4. Connect a jumper from J26 to the positive voltage bus on the breadboard.
  5. Connect jumpers from the breadboard to the digital pins on the UNO board.

    Breadboard

    Digital Pin

    J6

    0

    J10

    1

    H28

    10

  6. Connect the ground bus to the UNO board ground.

    Use a jumper to connect any hole in the ground bus on the breadboard to either of the GND pins on the UNO board.

  7. Connect the positive bus to the UNO board images.

    Use a jumper to connect any hole in the ground bus on the breadboard to the 5 V pin on the UNO board.

  8. Connect the UNO to the computer.

    Use the mini-B USB connector.

  9. Upload the Flashing LED program (see Listing 3-1) to the UNO.

    LED2 will flash on an off a quarter-second intervals. If you press the push button, LED1 will flash instead.

Randomizing Your Programs

Many computer-controlled applications require a degree of randomness to their operation. A classic example is the Indiana Jones ride at Disneyland and Disney World. Every time you go on this ride, the adventure is slightly different. At the start, there are three doors that your vehicle can drive through; the exact door chosen for your ride is determined randomly. Many other details of the ride are randomly varied in an effort to make the adventure slightly different every time you ride it.

You can add a bit of randomness to your own Arduino programs by using the random function. This function returns a random number whose value lies within a range that you specify via a pair of arguments.

The first argument indicates the minimum value you want returned. Somewhat confusingly, the second argument is one greater than the maximum value you want. For example, if you want a value within the range of 1 to 10, you would call the random function like this:

random(1,11);

Listing 3-2 shows a sample program that lights LED1 (pin 0) until the push button on pin 14 is pressed. Then, it switches to LED2 (pin 2) for a random period of time between 1 and 5 seconds. It then switches back to LED1. This program will work with the circuit you built for Project 45.

Note that the program does a bit of math for the delay function. The random function generates a number between 1 and 5, and the delay function multiplies this number by 1,000 to delay the appropriate number of seconds.

LISTING 3-2 The Random Program

// Random Program
// Doug Lowe
// September 16, 2016
//
// This program turns on the LED at pin 1 for a random
// number of seconds between 1 and 5 when the push
// button on pin 10 is pressed. When the push button is
// not pressed, the LED on pin 0 is turned on.

void setup() {
pinMode(0, OUTPUT);
pinMode(10, INPUT);
}
void loop() {
if (digitalInput(10) == 1)
{
digitalWrite(0, LOW);
digitalWrite(1, HIGH);
delay(random(1, 6) * 1000);
digitalWrite(1, LOW);
digitalWrite(0, HIGH);
}
}

Each time you press the push button in this program, the LED on pin 1 lights up for a different length of time, between 1 and 5 seconds.

technicalstuff It turns out that the random function isn’t really all that random. The random function applies a complex mathematical calculation to create a sequence of numbers that appear to be random. However, the numbers aren’t actually random. That’s because when you start the program, the random number generator is seeded with a default starting value, and the random function will generate the same sequence of numbers.

Thus, the program in Listing 3-2 always generates the same sequence of random delays. In particular, the sequence for the first ten button presses will always be as follows:

  • First press: 3 seconds
  • Second press: 5 seconds
  • Third press: 4 seconds
  • Fourth press: 4 seconds
  • Fifth press: 1 second
  • Sixth press: 3 seconds
  • Seventh press: 5 seconds
  • Eighth press: 4 second
  • Ninth press: 4 seconds
  • Tenth press: 5 seconds

This sequence appears fairly random, but every time you reset the program and start over, the sequence will be identical.

You can get around this lack of true randomness by calling the randomSeed function to provide a seed value for the random function. The seed value provides a starting point within the sequence of random numbers generated by the random function. If you use a different seed value each time the program runs, you’ll get a different random sequence each time.

So, how do you use a different seed value? You can do that easily enough by using the millis function, which returns the number of milliseconds that the program has been running. If you call the millis function when the user presses a button, and use its return value to seed the random number calculation, you’ll get a truly random result.

Listing 3-3 shows an improved version of the random program that uses this technique to create a truly random delay. It turns out that only one additional line of code is needed to properly randomize the delay:

randomSeed(millis());

This line reseeds the random number generator each time the button is pressed. Thus, a true random value is generated.

LISTING 3-3 An Improved Version of the Random Program

// Random Program
// Doug Lowe
// September 16, 2016
//
// This program turns on the LED at pin 1 for a random
// number of seconds between 1 and 5 when the push
// button on pin 10 is pressed. When the push button is
// not pressed, the LED on pin 0 is turned on.

void setup() {
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(10, INPUT);
}

void loop() {
if (digitalInput(10) == 1)
{
randomSeed(millis());
digitalWrite(0, LOW);
digitalWrite(1, HIGH);
delay(random(1, 6) * 1000);
digitalWrite(1, LOW);
digitalWrite(0, HIGH);
}
}

Reading a Value from a Potentiometer

As you know, a potentiometer (often called a pot) is simply a variable resistor with a knob you can turn to vary the resistance. Pots of various types are often used as input devices for Arduino projects. For example, you might use a simple pot to control the speed of a pair of flashing LEDs: As you turn the pot’s knob, the rate at which the LEDs flash changes.

The Arduino can read the value of a pot directly using any of its six analog input ports. On the Uno board, these ports are located on a six-pin header that’s on the opposite side of the digital ports. Each of these ports converts a voltage level between 0 V and a reference voltage to a integer between 0 and 1023. Although you can change the reference voltage for an analog port, we’ll use the standard reference voltage of images.

Figure 3-3 shows how simple it is to connect a potentiometer to an Arduino. Here, the two outside terminals of the potentiometer are connected to ground and images, respectively, and the middle terminal is connected to an analog input port.

image

FIGURE 3-3: Connecting a pot to an Arduino I/O pin.

To read the value of an analog input in an Arduino program, you use the analogRead function. This function accepts the number of the port to be read as an argument and returns a number between 0 and 1023 to indicate the voltage at the input relative to the reference voltage of images. Thus, if the voltage is 2.5 V, the analogRead function will return 511.

Listing 3-4 shows a simple program that alternately flashes LEDs connected to pins 0 and 1. The rate at which the LEDs flash is set by a potentiometer on analog pin 0. As you can see, the program simply uses the value returned by the analogRead function as the delay between flashes. Thus, as the user turns the potentiometer’s knob, the flash rate varies between 0 and a tad over one second.

LISTING 3-4 An LED Flashing Program That Uses a Pot

// Variable Rate Flasher
// Doug Lowe
// September 16, 2016
//
// This program flashes a pair of LEDs on pins 0 and 1
// at a rate set by a potentiometer on analog input pin
// 0.

int Rate;

void setup() {
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
}

void loop() {
Rate = analogRead(0);
digitalWrite(0, LOW);
digitalWrite(1, HIGH);
delay(Rate);
digitalWrite(1, LOW);
digitalWrite(0, HIGH);
delay(Rate);
}

Project 46 shows how to build a circuit that includes a images potentiometer so that you can test the code in Listing 3-4. Figure 3-4 shows the completed circuit.

image

FIGURE 3-4: A circuit that uses a potentiometer to control flashing LEDs (Project 46).

Project 46: A Variable-Rate LED Flasher

In this project, you connect a breadboard with two flashing LEDs and a potentiometer that controls the rate at which the LEDs flash.

image
image
image

Parts

  • One computer with Arduino IDE installed
  • One Arduino UNO board
  • One mini-B USB cable
  • One small solderless breadboard (RadioShack 2760003)
  • Two 5mm red LEDs (RadioShack 2760209)
  • One images potentiometer
  • Two images resistors (yellow-violet-brown)
  • Seven jumper wires

Steps

  1. Insert the resistors.

    images: J8 to ground

    images: J4 to ground

  2. Insert the LEDs.

    LED

    Anode

    Cathode

    LED1

    G10

    G8

    LED2

    G6

    G4

  3. Insert the potentiometer.

    The pins should be inserted in F24, F26, and F28.

  4. Connect jumpers from the breadboard to the digital pins on the UNO board.

    Breadboard

    Uno Pin

    J10

    Digital 0

    J6

    Digital 1

    J26

    Analog 0

  5. Connect the ground bus to the UNO board ground.

    Use a jumper to connect any hole in the ground bus on the breadboard to either of the GND pins on the UNO board.

  6. Connect the positive bus to the UNO board images.

    Use a jumper to connect any hole in the ground bus on the breadboard to the 5 V pin on the UNO board.

  7. Connect the UNO to the computer.

    Use the mini-B USB connector.

  8. Upload the Variable-Rate Flasher (see Listing 3-4) to the UNO.

    The LEDs will alternately flash at a rate determined by the potentiometer. When you turn the knob on the potentiometer, the rate of flashing will increase or decrease.