CS 153: Project 3

Title image Fall 2018

Project 3: Digital Instrument

The purpose of this lab is to give you practice in creating more sophisticated code. We'll make more use of functions, loops, conditionals, and arrays this week.

Our application for the project will be a musical instrument. The pitch (note) of the instrument will be determined by the distance measured using the distance sensor. In addition, we'll give ourselves the equivalent of a piano pedal that holds the current note until you let up on the pedal.


Part 1: Board Setup

You will need the following components for your board setup.

  1. Connect the IR sensor as we did in the lab: red wire to 5V, black wire to ground, yellow wire to the breadboard and a wire from there to an analog input pin.
  2. Connect the speaker to your breadboard. One end should be connected to ground, the other end should connect to a digital pin with a * on your Metro board. Pin 5 works.
  3. Connect your push button as you did in lab 2. One side of the push button should connect to both a digital input pin on the Metro board and a 10k resistor to ground. The other side of the push button can be connected to either 5V or 3.3V.
  4. The force sensor is a small flat circular pad with a straight set of wires coming off it. Carefully push the wires into your breadboard, putting them on two different rows. One side of the sensor should be connected to 5V. The other side of the sensor should be connected to both an analog pin and a 10k resistor to ground.

Part 2: Board Testing

Write a program that shows four pieces of information on the LCD display: the raw value from the IR distance sensor, the estimated distance as generated by the function you wrote in lab, the raw value from the force sensor, and the state of the push button. Your program should also make the speaker play a tone if the push button is pressed.

Test all of the components of your board using this program. Required video one: a short video showing the three components working properly.

Part 3: Instrument

The purpose of this section is to create an electronic instrument. As noted above, the pitch of the instrument will be controlled by the distance sensor data. If the distance is too far, then the instrument should turn off the speaker. If the user is pressing the force sensor, the instrument should hold the last note played until the force sensor is released. If the user presses the push button, the program should terminate (you can restart it by clicking the reset button on the Metro board).

  1. Create a new code file and save it as instrument. Create a second file within the same project and name it instlib. Put the genTone function from lab into your instlib file.
  2. In your instlib file, write a new function int avg( int d[], int N ) that takes in an array of integers d and the number of values N and computes the average of the array. The algorithm is (1) declare a local function variable avg and initialize it to zero, (2) loop over the values of the array, adding each value to avg, and (3) divide avg by N and return the result.

    If you want to test your avg function, create an array of five numbers in your main program, pass the array and a 5 to avg and assign its return value to a variable. Then print the value on the LCD.

  3. In your instlib file, Write a function int dist2note(int value) that converts raw distance sensor readings into values from 1 to 12. An easy way to do this is to use something similar to the distance conversion function you wrote before, adjusting it so the values will get down to 1. You need to test the return value so it is guaranteed to lie in the range [1, 12]. If it would be less than 1 make it 1. If it would be greater than 12, make it 12.
  4. The outline of a suggested main function is below. Each comment marked with "code" is one line of code unless otherwise specified. You are free to write your own version of this program. The only requirements are that (1) the speaker's output is a function of the distance and force sensors, (2) you have a function that generates the frequency passed to the tone function, (3) intermediate information is displayed on the LCD screen, and (4) the push button terminates the program.
  5. int main() {
      // variable declarations
      // code: declare an int variable to hold the pushbutton pin #
      // code: declare an int variable to hold the speaker pin #
      // code: declare an int variable to hold the IR sensor analog pin #
      // code: declare an int variable to hold the force sensor analog pin #
      // code: declare a char array of length 20
      // code: declare an int array of length 5 with the name dqueue, initialized to all 0s.
      // code: declare an int variable with the name marker, initialized to 0.
      // set up your LCD with 16 characters and 2 rows and the input and output pins
      // code: set up the lcd
      // code: set the push-button pin to be an input.
      // code: set the speaker pin to be an output.
      // code (2 lines): set the LCD cursor to the upper left and write four zeros
      // main for loop
      for(;;) {
        // code: assign to an int variable (e.g. halt) the result of calling digitalRead on the right push button.
        // code (2 lines): if halt is equal to 1, then break;
        // code: assign to an int variable (e.g. force) the result of calling analogRead on the force pin.
        // code (3 lines): write the value of force to the LCD
        // check if the force sensor is being pressed
        // code: if force is greater than 300 
        //    code: delay for 10ms
        //    code: continue;  // don't change the note
        // react to the distance sensor
        // code: assign to an int variable (e.g. distance) the result of calling analogRead on the ir sensor pin
        // code: if the value is less than 200
        //    code: call noTone with the speaker pin as the argument
        //    code: delay for 10ms
        //    code: continue;  // don't play anything
        // keep track of the last five distance readings and average them
        // code: assign to the position in dqueue specified by marker the distance value
        // code: assign to marker, the expression (marker + 1) % 5
        // code: assign to distance the result of calling your avg function with dqueue and 5 as arguments
        // code: assign to an int variable (e.g. note) the result of calling dist2note on the distance value
        // code (3 lines): write the distance value and the note to the LCD screen
        // code: assign to an int variable (e.g. freq) the result of calling genNote with note and 4 as the arguments.
        // code: call the tone function with the speaker pin and freq as arguments
        // delay for 10 ms
      } // end main for loop
      // call noTone with the speaker pin as the argument
  6. Test your program, using the LCD outputs to debug as necessary. Required video two: a short video of you playing your instrument.
  7. Create a second function that translates distance to notes, similar to dist2note, but which does not use a simple linear transformation. It should create noticeably different notes for the same behavior. Describe the difference in your report. You should also feel free to submit a short video demonstrating the difference.

Follow-up Questions



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 cs153f18project3


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.