CS 153: Project 2

Title image Fall 2018

Project 2: Time and Temperature

The purpose of this lab time is to give you more experience with using the LCD display, push buttons, the temperature sensor, and coding loops and conditionals in C.


Tasks


Part 1: Stopwatch

The goal of the first main task is to build a simple stopwatch with two buttons: Reset/Start and Stop.

  1. Find the two push-buttons in your bag of goodies (left side in the picture below). You may have to adjust the position of the pot for the LCD in order to fit them on your breadboard. Position them on the board as shown.

    The circuit for the push buttons is shown below. If the push button is sitting across the divide on the breadboard, then the two pins that are on the same row of the five connected pins are connected (green lines). When the push button is down, the red line is activated, connecting the two sides. Therefore, when you push the button, the value going to the board should be HIGH (or 1). When you let up on the button, the value going to the board should be LOW (or 0). Use pins 2 and 3 for the board connections to the push buttons.

  2. The first task is to write code that watches the push buttons and sends messages to the LCD to indicate if each button is low or high. The structure of your code should follow the outline below. Each comment specified by code corresponds to one line of code.
    /*
     * Your name
     * Class and Project
     * Date
     */
    #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();
      int pushLeft = 2;
      int pushRight = 3;
    
      // set up our LCD with 16 characters and 2 rows
      lcd.begin(16, 2);
    
      // set the pushbutton inputs to be INPUT
      pinMode( pushLeft, INPUT );
      pinMode( pushRight, INPUT );
    
      // code: position the cursor to the first position on row 0 (top row)
      // code: write "Left" to the LCD
    
      // code: position the cursor to the 11th column on the top row
      // code: write "Right" to the LCD
    
      // main loop
      for(;;) {
        // code: declare and assign to a variable of type int the result of digitalRead( pushLeft )
        // code: declare and assign to a variable of type int the result of digitalRead( pushRight )
        // code: declare an array of type char with 16 elements
    
        // code: if the left push button is equal to 0
        //   code: set the cursor to the 0 position on the bottom row (row 1)
        //   code: write "Up  " to the LCD (note the extra spaces)
        // code: else
        //   code: set the cursor to the 0 position on the bottom row
        //   code: write "Down" to the LCD
    
        // block of code: repeat the above for the right push button, but write to column 11
    
        // delay 10ms
      }
    
      return(0);
    }	

    You might want to write yourself a function like writeToLCD( int col, int row, char message[] ) that combines the two step process of setting the cursor position and writing the message.

    Required video 1: Take a video showing your LCD changing in response to pushing buttons

  3. Write a program to create a simple stopwatch using the two push buttons. One button should reset and start the timer. The second button should stop the timer, leaving the time value visible. When the timer is running, it should ignore the start button. When the timer is stopped it should ignore the stop button.

    The easiest way to implement the logic for this program is to have a variable that keeps track of whether the timer should be running or stopped. You can use an int variable and specify that if the variable's value is 0 it is stopped and if it is 1 it is counting. We often call this a state variable.

    If the state variable is 0 (stopped) and the user hits the start button, your program should store the current millis() value into a variable (this saves when the timer started). It should then set the state to 1.

    Else, if the state variable is 1 (counting), the program should capture the current millis() value and subtract the start time to get the time elapsed since the user hit start. It should then calculate the number of seconds (divide by 1000) and the number of hundredths of a second. To calculate the latter value, first divide the milliseconds by 10, then apply modulo 100 to keep the range in [0, 99]. Finally, use sprintf to generate a string of the form SS:HH where SS are two seconds digits and HH are two hundredths digits.

    In the counting state, the program should also check the value of the stop button. If the stop button is high, then the program should set the state back to 0 (stopped).

    You can use the following outline to implement the stopwatch.

    /*
     * name
     * project
     * date
    */
    #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();
      int pushLeft = 2;
      int pushRight = 3;
    
      // code: declare a variable startTime of time unsigned long and assign it 0
      // code: declare a variable state of type int and assign it 0
    
      // set up the LCD and push button inputs
      lcd.begin(16, 2);
      pinMode( pushLeft, INPUT );
      pinMode( pushRight, INPUT );
    
      // code: set the cursor to column 0 row 1
      // code: write "Stop" to the LCD
    
      // code: set the cursor to column 11 row 1
      // code: write "Start" to the LCD
    
      // code: set the cursor to column 0 row 1
      // code: write the string "00:00" to the LCD
    
      // main loop
      for(;;) {
        // code: declare and assign to a variable of type int the result of digitalRead( pushLeft )
        // code: declare and assign to a variable of type int the result of digitalRead( pushRight )
        // code: declare three variables of type unsigned long: curMS, curS, and curHS
        // code: declare an array of type char with 16 elements
    
        // code: if state is equal to 0
        //   code: if the right push button is 1 (high)
        //     code: assign to startTime the result of calling millis()
        //     code: assign to state the value 1
        // code: else
        //   code: assign to curMS the difference between millis() and startTime
        //   code: assign to curS the value of curMS / 1000
        //   code: assign to curHS the value of curMS  / 10
        //   code: assign to curHS the value of curHS % 100 (% is the modulo operator)
        //   code: use sprintf to generate the proper string, you can use the format string "%02ld:%02ld"
        //   code: position the LCD cursor to 0, 0
        //   code: write the message to the LCD
        //   code: if the left push button is 1 (high)
        //     code: set state to 0
    
        // delay for 5 ms    
      }
    
      return(0);
    } 
  4. Download and test your program.

    Required video 2: a video of your stopwatch working.

Part 2: Sensing Temperature

  1. Find your temperature sensor in the bag of goodies (TMP36). For more information on how to wire it up and use it, see the Adafruit TMP36 Instructions.

    Wiring the sensor is easy. When facing the flat side, connect the right pin to ground, the left pin to 3.3V and the center pin to one of the analog pins in your board (e.g. A0). I managed to squeeze it onto my board in the space between the push buttons and the LCD board. It's a tight fit.

  2. Write a program that runs continuously, reading the temperature and writing the result to the LCD. The setup portion of your code just needs to call init and then call lcd.begin. The main loop should have the following structure.
      for(;;) {
        // code: declare a variable (e.g. temp) of type int
        // code: declare a variable (e.g. tempstring) that is an array of 16 characters
        // code: declare a variable (e.g. celsius) of type int.
    
        // code: assign to temp the result of calling analogRead for the pin connected to the sensor
        // code: assign to celsius the value (temp*49/10 - 500) / 10  
    
        // code: use sprintf to write celsius to a string
        // code: set the cursor location to 0, 0
        // code: write tempstring to the LCD
    
        // code: delay 100ms
      }
  3. Download and test your program.

    Required video 3: a video of your LCD changing values when you touch or blow on the sensor.

  4. Update your code so that it remembers the minimum and maximum temperature values seen so far. Have the LCD write out the min and max values on the right side of the screen.

    Required image: show your LCD displaying the min and max values.

Follow-up Questions


Extensions


Report

Each week you will write a brief report about your project. In general, your intended audience for your write-up is your peers not in the class. From week to week you can assume your audience has read your prior reports. Your wiki report should explain to friends what you accomplished in this project and to give them a sense of how you did it.

Your project report should contain the following elements.

  1. Abstract: a brief summary (200 words or less) of the task, in your own words. give the reader context and identify the key purpose(s) of the project. You can assume the reader has read your prior assignments.

    Writing an effective abstract is an important skill. Consider the following questions while writing it.

    • Does it describe the CS concepts of the project (e.g. writing loops and conditionals)?
    • Does it describe the specific project application (e.g. creating applications with the LCD)?
    • Does it describe your the solution or how it was developed (e.g. what code did you write/circuits did you build)?
    • Does it describe the results or outputs (e.g. did your code and circuit work as expected)?
    • Is it concise?
    • Are all of the terms well-defined?
    • Does it read logically and in the proper order?

  2. A description of your solution to the tasks. This should be a description of the form and functionality of your final code and the design of your breadboard circuits. Try to describe your algorithm or code without including actual code in your report. Using 1-2 lines as an example is acceptable. Using simple diagrams or pictures of your board may be helpful when describing your circuits. Note any unique computational solutions or hardware circuits you developed.
  3. A description of any extensions you undertook, including images, videos, or diagrams demonstrating those extensions. If you added any functions, or other design components, note their structure and the algorithms you used.
  4. The answers to any follow-up questions.
  5. A brief description (1-3 sentences) of what you learned.
  6. A list of people you worked with, including TAs, and professors. Include in that list anyone whose code you may have seen, such as those of friends who have taken the course in a previous semester.
  7. Don't forget to label your writeup so that it is easy for others to find. For this lab, use cs153f18project2

Handin

Mount the Courses volume. Navigate to the Private sub-directory. Create a new folder called project01. (It's best to avoid spces in the directory name.) Each week, the following items should be submitted here.

Your report should be submitted as a wiki page with the appropriate label, as noted above.