CS 153: Lab 2

Title image Fall 2018

Lab Exercise 2:

The purpose of this lab time is to give you an introduction to using the LCD display, push buttons, and coding loops and conditionals in C.


Connecting the LCD Display

The first thing we're going to do is wire the LCD display to your breadboard. LCD stands for liquid crystal display. LCD displayes are useful for providing small amounts of text or simple images to a user on an embedded system, and they use very little power.

  1. Take out your LCD display. Your display is a 2 x 16 display, which means there are two rows of 16 blocks. Each block can display a letter or possibly a 5x7 pixel icon. Each block is individually addressable using the Arduino LCD library.

    The LCD display has a header with 16 pins. You first need to insert this header into your breadboard. Place the LCD to one side of your breadboard and such that each pin locks into one of the 5-hole rows. Try to maximize the amount of board space left on your breadboard. It may take some effort to get the LCD seated in the breadboard. Be patient and don't force it. If you want some assistance, please ask. When you are done, it should look like the picture below.

  2. We will make use of twelve of the 16 pins. Three of the pins are control pins, four of the pins are for transferring data to the LCD, and four pins are for power and ground. To wire the board, we will be following the instructions on the Adafruit site. More detailed instructions are also available here

    The parts you will need besides your board include:

    • LCD
    • 10 kOhm variable resistor (pot) (picture below)
    • Breadboard
    • Lots of wires

    The pin connections are listed in the table below. Pin 1 of the LCD display is the pin closest to the edge of the LCD board. Pin 16 is the pin on the end in the middle of the board.

    You probably want to connect one of the red rail lines to 5V and its corresponding blue line to GND in order to make wiring the LCD easier. By convention, it's common to use black wires for ground connections and red wires for power connections

    LCD PinConnected toPurpose
    1Ground [GND]Ground for the backlight
    25V PowerPower for the backlight
    3Middle pin of the PotControls LCD contrast
    4Board pin 7LCD control pin
    5Ground [GND]Read enable control signal for sending data
    6Board pin 8LCD control pin
    7No Connectionunused data line
    8No Connectionunused data line
    9No Connectionunused data line
    10No Connectionunused data line
    11Board pin 9Data pin
    12Board pin 10Data pin
    13Board pin 11Data pin
    14Board pin 12Data pin
    155V PowerPower for the LCD controller
    16Ground [GND]Ground for the LCD controller

    In addition to the pins above, connect one side of the pot to ground and the other to 5V. The middle pin of the pot connects to pin 3 of the LCD.

    Once your LCD is wired, it should look like the following. When you connect your board, the backlight should turn on. If you turn the potentiometer, which controls contrast, you should see the LCD squares appear when you turn the pot to an appropriate setting.

Controlling the LCD

  1. Create a working directory for project 2. Open the Arduino IDE and create a new file. Put your name at the top and save it as lcdbasic.
  2. Delete the existing setup/loop code and create your standard main function skeleton. In addition, include the #include statement at the top of the file to include the LCD library functions.
    #include <LiquidCrystal.h>
    // initialize the LCD library by associating any needed LCD interface pin
    // with the arduino pin number it is connected to
    const int rs = 7, en = 8, d4 = 9, d5 = 10, d6 = 11, d7 = 12;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
    // main function
    int main() {
      // variable declaration here
      // other code here
  3. To initialize the LCD, use the function call lcd.begin(16, 2) after the call to init() in the main function. This initializes the LCD to a screen with 2 rows of 16 characters.
  4. To set the location of where to write characters, use the function lcd.setCursor(col, row), where col and row can either be numbers like 0, 0 or int variables. The two arguments specify the column and row to start writing a string. For example, using lcd.setCursor(0, 1) sets the cursor to the first character of the second (bottom) row. In your code set the cursor location to (0, 0).
  5. To send characters to the LCD, use the function lcd.write( string ), where string is a string like "Hello World" or a character array. For example, to write "Hello World" to the LCD, use lcd.write("Hello World");. After the call to setCursor, use lcd.write to send a message of your choice to the LCD
  6. Compile your program and upload it to your board to test it.

Making a Timer

In this section of the lab you will make a timer with your LCD. To reset the timer, use the reset button on the Metro board.

  1. Create a new code file. Copy your code from the prior step, but delete the lcd.setCursor and lcd.write function calls. Save the file as timer.
  2. After the lcd.begin function call, which is the end of the setup phase, we want to start a loop that runs forever. We can do this in one of two ways. The following are equivalent loops.
    // option 1
    while(1) {
      // code in here loops forever
    // option 2
    for(;;) {
      // code in here loops forever

    Whichever loop makes you happier, go ahead and put it into your code.

  3. Inside the loop, declare three variables. Declare curMS and curS as type unsigned long. Declare timestring as a character array with 16 values. For example:
    for(;;) {
      unsigned long curMS, curS;
      char timestring[16];
      // code goes here
  4. Assign to curMS the value returned by calling millis(). The millis() function returns the number of milliseconds since the last reset on the board. On the next line, assign to curS the result of dividing curMS by 1000 (converting it to seconds).
  5. Use the following code to convert curS to a string. The function sprintf is a standard C library function that allows you to create formatted strings. The first argument is the string variable to receive the data. The second argument is the format string, potentially with some placeholders for data. The remaining arguments are the data to go into the placeholders.

    In the following example, the expression %04d tells sprintf that at the location marked by the % it should expect an integer (d) and print it out with 4 digits (4), padded with zeros in front if there are not enough digits (0).

      sprintf( timestring, "%04d", curS );

    After the sprintf, set the cursor location to (0, 0) and then use lcd.write with timestring as the argument. Finally, put a delay for 100ms at the end of your loop.

    The whole structure of your code should look like the following. Within the loop, each comment line corresponds to one code line.

    #include <LiquidCrystal.h>
    // initialize the library by associating any needed LCD interface pin
    // with the arduino pin number it is connected to
    const int rs = 7, en = 8, d4 = 9, d5 = 10, d6 = 11, d7 = 12;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
    // main function
    int main() {
      // init the Arduino
      // set up our LCD with 16 characters and 2 rows
      lcd.begin(16, 2);
      // loop forever
      for(;;) {
        // declare two variables, curMS and curS, of type unsigned long (32 bits)
        // declare a variable timestring to be an array of 16 characters
        // assign to curMS the result of calling millis()    
        // assign to curS the result of dividing curMS by 1000
        // use sprintf to write a formatted string to timestring
        // call lcd.setCursor to set the cursor to location (0, 0)
        // call lcd.write with the argument timestring
        // delay 100 ms
  6. Compile, upload, and test your timer.

When you are done with the lab exercises, you may start on the rest of the project.