The Arduino Inventor's Guide (45 page)

As soon as you apply power, the backlight should turn on. Try turning the potentiometer knob. Even with nothing displayed on the LCD, you should see the contrast of the screen change as you twist, from all dark at its lowest to 32 brightly lit rectangles at its highest.

If you don’t see this, double-check the wiring. Make sure that all of the power connections to the LCD match
Table 9-2
.

Once you have the LCD working, copy the code from
Listing 9-1
into Arduino and upload it to your device. This simple example should display the text
SparkFun Arduino
on the first line and a running counter on the second line.

LISTING 9-1:
Test code to display text and a running
millis()
counter to the LCD


#include
<
LiquidCrystal
.h>

LiquidCrystal
lcd(8, 9, 10, 11, 12, 13);
  
void
setup
()
  {

   lcd.
begin
(16, 2);  
//initializes interface to LCD

   lcd.
clear
();

   lcd.
print
("
SparkFun Arduino")
;
  }
  
void
loop
()
  {

   lcd.
setCursor
(0, 1);      
//move cursor to the 2nd line
                              
//(col 0, row 1)

   lcd.
print
(
millis
()/1000);
//print the number of
                              
//seconds elapsed
  }

Let’s take a look at what’s going on in this example. First, it includes the
LiquidCrystal.h
library

created by the Arduino community to simplify the six different control and data lines. This will make it easier for you to send instructions to the LCD.

Next, this code creates an object named
lcd
that uses the LiquidCrystal library

. Notice that this time when you create the object, you pass it a set of parameters that correspond with the LCD pins: the Register Select, Enable, and four data pins. This is where you configure which pin controls each function on the LCD. In some documentation, you may see this command as
LiquidCrystal lcd(RS, Enable, d4, d5, d6, d7)
.

You may be wondering why we don’t use four of the LCD pins. This LCD is able to transfer data on either four or eight data lines. According to the datasheet on the LCD, when you use four data lines, you use the top four pins on the LCD—the pins labeled d4, d5, d6, and d7. While it takes the Arduino twice as long to transfer data to the LCD this way, this helps to keep the circuit as simple as possible, and remember, the Arduino operates with a 16 MHz clock. That’s really fast!

The LiquidCrystal library has around 20 different commands that simplify control of this LCD. In this example, we’ll show you a few basic commands that allow you to configure the screen size, clear the screen, display information, and move the cursor.

The
setup()
part of the sketch has a few instructions that will run just once when the Arduino starts up. The first of these is
lcd.begin(16, 2);

, which sets up the size of the LCD as a 16 × 2 character LCD, allowing the library to correctly wrap text and move from one line to the next.

The next instruction,
lcd.clear();

, allows you to clear the screen before providing new text to display. It also resets the position of the cursor to the first character on the first line of the screen. Without this, the LCD would retain the last thing displayed.

Then, the command
lcd.print("SparkFun Arduino");

displays the text
SparkFun Arduino
on the LCD. Because the
lcd.clear()
instruction just cleared the screen, this text will appear on the first line of the display. This string of text is exactly 16 characters long and should fill the entire first line of the LCD. This command is similar to
Serial.print()
, but with
lcd.print()
you don’t need to be connected to a computer or have the Serial Monitor open to see text and information from your device.

The
loop()
refreshes the screen with new information each time it repeats. First it moves the cursor to the second line of the LCD using
lcd.setCursor(0, 1);

so it doesn’t overwrite the
SparkFun Arduino
text on the first line. The two numbers used in the
setCursor()
method indicate the position of the character (0) and the row (1). As is common in a lot of programming environments, Arduino counts starting with an index of 0, not 1.

NOTE

The LiquidCrystal library only works with character LCD displays. Graphic LCD screens are also available, but they use a different library called OpenGLCD, which allows you to display graphics such as lines, rectangles, and circles as well as text.

Finally, the sketch prints a counter

using another
lcd.print()
instruction. This counter uses the
millis()
function, which reports the number of milliseconds since the Arduino was powered on. Dividing this value by 1,000 shows a counter in seconds. We will use a similar technique for the race timer.

Now, can you figure out how to change the text to display your name on the first line? How about changing the time display to show the time elapsed in minutes instead of seconds? Play around with the code example until you’re comfortable with displaying data to the LCD. With just six GPIO pins from your Arduino, you can add an LCD readout to any project!

This example demonstrates the most commonly used instructions in the Arduino LiquidCrystal library, but if you want to check out the other commands that you can use, see
https://www.arduino.cc/en/Reference/LiquidCrystal/
.

Now that you have the LCD circuit working, it’s time to add the button, servo, and light-sensor circuit.

ADD THE REST OF THE ELECTRONICS

The Drag Race Timer will use a few parts that you’ve already put together in previous projects: a push button to start the race, a servo to control the starting gate for the car, and a photo resistor to detect when the car reaches the end of the track.
Figure 9-11
shows schematic diagrams of these three additional components.

FIGURE 9-11:
Schematic diagrams for additional components in the Drag Race Timer

Place a push button on the breadboard so that two legs are on either side of the center divide, and connect two of the legs on one side to pin 5 on the Arduino and GND. The parts will fill up most of the breadboard, so pay close attention to the rows on the breadboard and how the components are connected. To save space, this project uses the push button without the external pull-up resistor used in
Project 4
with the Reaction Timer. Instead, we’ll enable a pull-up resistor in the code.

Next, connect the servo motor that will open the starting gate. Using three male-to-male jumper wires, connect the signal wire (either yellow or white) to pin 4 on the Arduino, the red wire to the 5 V rail, and the black wire to the GND rail.

Finally, add the light-sensor circuit with a voltage divider circuit. Connect one end of a photoresistor to the 5 V power rail and the other end to the GND power rail, via a 10 kΩ pull-down resistor placed directly in the power rail. Connect the row that has both the photoresistor and the 10 kΩ pull-up resistor to pin A0 on the Arduino. This circuit should look similar to the circuit you used in the Night-Light in
Project 5
.

There are a lot of components in this circuit, so take your time and double-check your wiring against the diagram in
Figure 9-12
.

FIGURE 9-12:
Complete electronics for the Drag Race Timer, including a starting button and gate

PROGRAM THE DRAG RACE TIMER

Now let’s put it all together. Start a new sketch, and enter the code from
Listing 9-2
or download it from
https://www.nostarch.com/arduinoinventor/
. This example will bring together several concepts and ideas we’ve used separately in past projects.

LISTING 9-2:
Drag Race Timer sketch


#include
<
LiquidCrystal
.h>
  
#include
<
Servo
.h>
  
LiquidCrystal
lcd(8, 9, 10, 11, 12, 13);

Servo
startingGate;

const
byte
buttonPin = 5;
  
const
byte
servoPin = 4;
  
const
byte
finishSensor1Pin = A0;
  
const int
darkThreshold = 500;

int
finishSensor1;
  
boolean
finishFlag =
false
;
  
long
startTime;
  
long
stopTime;
  
float
raceTime;
  
void
setup
()
  {

   
pinMode
(buttonPin, INPUT_PULLUP);
    startingGate.
attach
(servoPin, 1000, 2000);
    startingGate.
write
(0);

   lcd.
begin
(16, 2);
    lcd.
clear
();
    lcd.
print
(
"Drag Race Timer"
);
    lcd.
setCursor
(0, 1);
    lcd.
print
(
"Push to start!"
);

   
while
(
digitalRead
(buttonPin) ==
HIGH
)
    {
    }
    lcd.clear();
    lcd.print(
"Go!"
);
    startingGate.write(180);
    startTime = millis();
  }
  
void
loop
()
  {

   finishSensor1 =
analogRead
(finishSensor1Pin);

   if ((finishFlag ==
false
) && (finishSensor1 < darkThreshold))
    {
      finishFlag =
true
;
      stopTime =
millis
();
      raceTime = stopTime - startTime;
      lcd.
clear
();
      lcd.
print
(
"Finish Time:"
);
      lcd.
setCursor
(0, 1);

   lcd.
print
(raceTime / 1000, 3);
    }
  }

Let’s take a look at how all this works. First, the sketch includes two libraries using the
#include
directive

,
LiquidCrystal.h
and
Servo.h
. Next, it initializes a
LiquidCrystal
object named
lcd
, similar to
Listing 9-1
, and a
Servo
object named
startingGate

.

Then, the sketch declares a set of constants for the pin connections used for the button, servo, and photoresistor circuits

. This means that, as you make changes and modifications, if you need to move a wire to a different pin on the Arduino, you’ll only have to change a single number in the code. The last constant, a threshold value named
darkThreshold
, is used to set the light level to detect when the car is blocking the light sensor. Here it’s set to
500
, roughly in the middle of the range of 0–1023, but you may need to adjust this value to suit the environment of your own room.

Next, the sketch declares a few variables

. The
finishSensor1
variable is used to store the raw value of the photoresistor sensor. The next variable,
finishFlag
, is a
state variable
, which is used to keep track of what state the sketch is in. The
finishFlag
variable is initialized to
false
and is used to indicate when the race is over (like the flag waved at the finish line to mark the winner of a Formula One race). We’ll set it later in the code based on the input value from the sensor. The next three variables are used to calculate the race time using the built-in
millis()
timer in Arduino.

Other books

When She's Bad by Leanne Banks
Sentinelspire by Mark Sehestedt
Ruin, The Turning by Lucian Bane
The Blue Between the Clouds by Stephen Wunderli
Madness by Allyson Young
Burn (Dragon Souls) by Fletcher, Penelope
The Buddha's Return by Gaito Gazdanov