Digital Sandbox Arduino Companion

Pages
Contributors: jimblom
Favorited Favorite 5

8. The Reaction Tester

Computers are great at doing math and automating boring tasks, but everyone knows that their true purpose is to play games. Let's create a game on the Digital Sandbox! But in order to control the game we need to add input.

Background Information

Up to this point, our Digital Sandbox experience has been very one-sided. Output to tiny yellow LEDs. Output to larger white LEDs. Output to RGB LEDs. Change the fade value of the output. Output, output, output. Let's flip the tables on the Sandbox, and send some input to the board!

Inputs are signals or values sent into a system. Some of the most common inputting components are buttons or switches. Buttons on a keyboard are an input to your computer because they send data into that system.

if statements are critical when assessing the status of an input and taking an action based on it - if button A is pressed, then print an "a." We can take the if statement a step further by adding an else condition, which allows us to control what happens if the if statement evaluates to false. So now we can say something like "if the egg floats, throw it away, otherwise (else) fry it and eat it!"

Active Parts

alt text

Code Components

This time we introduce a new function, plus a riff on the if statement.

Digital Input: digitalRead([pin])

The digitalRead([pin]) function is used to read the voltage of a pin. It can tell you if a pin is HIGH (~5V) or LOW (~0V).

There's just one parameter to the digitalRead() function -- a pin that you want to read. Make sure to set the pin as an INPUT, using the pinMode() function, before you read it!

This function is different from the others because it returns a value. Instead of just writing out the function call and skipping to the next line, we actually have to use the digitalRead() function in conjunction with other bits of code.

The digitalRead() function will come back with one of two values: HIGH or LOW. You can use that return value as part of a conditional test in an if statement, for example:

language:c
if (digitalRead(2) == HIGH)
{
    // Do something, because the button is pressed
}

Or, if you so pleased, you could store the value of the digitalRead() function inside a variable, like this:

language:c
example_variable = digitalRead(2);

If/Else: if( [condition] ){ [true consequence] } else { [false consequence] }

We'll use an extension of the if statement this time: the if...else statement. if/else allows us to take one action if the condition is true and a different action if it's false.

Here's the anatomy of an if/else:

language:c
if ( [consequence] )
{
    // Do something because the consequence is true
}
else
{
    // Do something because the consequence is false
}

if/else is really handy when you're dealing with digital outputs which can only be in one of two states. If a button is pressed, do something, otherwise do something else.

Equivalence Test

In this experiment we'll be using the equivalence test (==) in our if statement conditional. That's right, there are a pair of = signs. That's to differentiate the equivalence test from the assignment operator (=). While the single equal-sign assignment sets one value to another, the equivalence test is asking if two values are equal and producing either a true or false response.

If you're ever creating a conditional statement, make sure you use the equivalence operator if you're asking if two values are equal.

Sketch and Experiment

Here's the sketch. It's a big one! Check out the comments for a line-by-line explanation. This is the Sandbox_08_Reaction_Tester.ino sketch.

language:c
    // Sandbox 08: Reaction Tester

/* Computers are great at doing math and automating boring tasks, but everyone 
   knows that their _true_ purpose is to play games. Let's create a game on the 
   Digital Sandbox! In order to control the game we need to add **input**.

   Up to this point, our Digital Sandbox experience has been very one-sided. 
   _Output_ to tiny yellow LEDs. _Output_ to larger white LEDs. _Output_ to RGB 
   LEDs. Change the fade value of the _output_. Output, output, output. Let's 
   flip the tables on the Sandbox, and send some **input** to the board!

   This experiment introduces the digitalRead([pin]) function. This is the first
   time we'll use a function that RETURNS A VALUE. Instead of simply creating a
   function call and going to the next line, we need to do something with the
   function -- either assign it to a variable or use it in a conditional.
*/

// The led variable should run between 4 and 8. It's used to control the white
// leds (D4-D8), one at a time.
int led = 4;
// The speed variable controls how fast the LEDs cycle from one to the next.
// A larger value, means a slower cycle.
int speed = 100;

// setup()! Time to set up some OUTPUTs...and INPUTs!
void setup()
{
    // Set the button and switch as INPUTs:
    pinMode(2, INPUT);
    pinMode(12, INPUT);

    // Set all LEDs as outputs:
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
}

void loop()
{
    // The first if statement sets the SPEED of the game.
    // digitalRead() can either return HIGH or LOW. If the switch is in the "1"
    // position, the digitalRead() function will return HIGH.
    if (digitalRead(2) == HIGH) // If the switch is set to 1...
    {
        speed = 50;             // ...set speed to 50 (fast)
    }
    else                        // Else the switch will be set to 0...
    {
        speed = 150;            // ...so set the speed to 150 (slow)
    }

    // The button on pin 12 will be HIGH when pressed and LOW otherwise.
    if (digitalRead(12) == HIGH)    // If the button is pressed
    {
        digitalWrite(led, HIGH);    // Turn the active LED on, nothing else.
    }
    else                            // Otherwise, if the button is released
    {
        digitalWrite(led, LOW);     // Turn the active LED off.

        led = led + 1;              // Increment the led variable by 1
        if (led > 8)                // If led is out of our range (4-8)
        {
            led = 4;                // Set it back to the bottom (LED 4).
        }

        digitalWrite(led, HIGH);    // Turn on the new LED

        delay(speed);               // Delay for speed ms.
    }

    // The else statement above will take up the majority of the loop() if the
    // button is released. One LED will turn off, the next will turn on, and
    // a short delay will occur before we loop back.
}

There are two important if/else statements in this program, which each test the status of an input. The top if/else tests pin 2, which is connected to the switch. If the switch is set to one (e.g. HIGH), then we set a variable called speed to 50. If the switch is set to zero (LOW), then speed becomes 150.

The second if/else tests pin 12, which is tied to the small button. When the button is pressed, then the input is set to one (HIGH), and it's zero when released. This means that, when the button is being pressed, the code in the then will execute. When the button is not being pressed, the else code will run.

Can you guess what will happen in each of the pin 12 test cases? Upload the sketch to your board to find out!

This is a very simple game. Pick a number between four and eight, and try to make the LED stop on that number by pressing the button. To switch between easy and hard mode, move the switch from 0 to 1. Can you make it stop in the middle on hard mode?

Your Turn!

  • Trick your friend and swap which direction of the switch sets it to easy mode -- make zero hard and one easy.
  • Swap the function of the switch and the button, so you have to press the button to set the difficulty and flick the switch to stop the LEDs.