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.
- 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.
-
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
- 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); }
- Download and test your program.
Required video 2: a video of your stopwatch working.
Part 2: Sensing Temperature
- 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.
- 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 }
- Download and test your program.
Required video 3: a video of your LCD changing values when you touch or blow on the sensor.
- 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
- Are the variables you declare inside a loop part of the loop symbol table or part of the function symbol table?
- How could you figure out the answer to question 1 by writing and compiling code?
- Could you implement the tasks in this lab without a loop?
- Could you implement the tasks in this lab withou conditional statements?
Extensions
- Make a better timer that shows hours, minutes, and seconds. Think about using the modulo operator.
- Combine time and temperature.
- Make a timer that counts down to zero and flashes. You can write the time into your code or you can accept it through the serial port.
- Use the serial port to send information to the board and modify an aspect of your program.
- Can you make the setup an actual clock that tells the correct time? Can your set up your clock so it can accept the current time from a serial port message?
- Try out other sensors.
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.
- 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?
- 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.
- 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.
- The answers to any follow-up questions.
- A brief description (1-3 sentences) of what you learned.
- 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.
- 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.
- Code that should graded and any required supporting materials. This week, submit your code from all of the project tasks. Code from lab exercises will generally not be graded unless it is used as part of the project tasks.
- Videos of your work. You can also submit videos as part of your report on the wiki, but please put a copy of the video here.
Your report should be submitted as a wiki page with the appropriate label, as noted above.