CS 153: Project 4

Title image Fall 2018

Project 4: Digital Piano

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 more complex musical instrument that acts like a digital keyboard.


Part 1: Board Setup

You will need the following components for your board setup.

Part 2: LED

Create a new file, caplight.ino. You can probably copy over your code form the last task in the lab and modify that to include the LED. Make sure your name/date/project are at the top of the file.

  1. Wire up an LED with a 560 Ohm resistor, driven by one of the digital pins.
  2. In your code, set up the LED control pin as an OUTPUT. In the setup code, make sure you write a 0 to that output pin.
  3. In your main loop, if any of the capacitors is touched, light up the LED. If all of the capacitors have been released, make it dark. If none of the capacitors is being touched, what is the value of curtouched?
  4. Test that your circuit lights up an LED whenever you are touching one of the capacitive sensors.
  5. Required images (include in your wiki): a picture of you touching a pad and the LED lighting up, and a follow-up picture of your finger off the pad and the LED off.

Part 3: Digital Keyboard

Create a new file keyboard.ino. Copy over your code from part 1. The prior state of the sensors will always be in lasttouched, and the current state will be in curtouched.

  1. Write a function that takes in one int value (possibly a second with the octave), which is a note in the range [1, 12] and returns the proper frequency. By default, use octave 4. You can re-use your code from last week if you wish.

    If you put the function in a separate file (not a bad idea) make sure you put a prototype of the function in your main file at the top. A prototype is the function signature followed by a semi-color. For example, the code snippet below shows a function and its prototype.

    // prototype for the function porcupine
    // this should go at the top of the main file
    int porcupine( int a, float b );
    // actual function
    int porcupine( int a, float b ) {
      int c = a * b;
  2. As the tone function will play only a single note at a time, we have to choose which note to play if multiple sensors are touched at once. One possible rule is to specify the tone by the most recent touch, and to use the last new touch in the search order. This algorithm could be implemented as follows.
    1. Initialize a variable curtone to -1
    2. Inside the loop polling the sensors, inside the if-statement looking for new touches, assign curtone the index i if there is a new touch
    3. After the loop over all of the sensors, if curtone is >=0 then call the tone function with the appropriate note.
    4. If curtouched == 0, then call notone.

    Add this algorithm to your code and test it out. The system should respond as though it were a digital keyboard.

  3. Required video one: a video of your digital keyboard working.

Part 4: Digital Keyboard with Memory

The goal of this part is to add the capability to remember what the user plays and then play it back. The program should start up, wait 3s, then turn on an LED and start recording the state of the touch sensors. After 10s of recording, it should stop recording and turn off the LED. After a 1s pause, it should continuously repeat the data that was recorded. At any time, the user should be able to stop the program.

  1. Start a new file, recorder.ino, and copy over the code from the prior task. The overall structure of the code for this task is as follows.
    main function
        setup code and variable definitions, including an array of 100 ints
        pause for 3s
        turn on LED
        for 100 steps
            get the current state of the touchpads
            store the current state in the next location in an array
            delay 100ms (take 10 samples per second for 10s)
        turn off the LED
        delay for 1s 
        initialize quit to 0
        while( !quit ) 
            for 100 steps
                analyze the current state (as though reading it from the sensor)
                start or stop tones as according to the saved array
                get the state of the quit button/sensor
                if the user activated quit then set quit to 1 and break
    end main function

    There are two methods of recording the information to play. The first is to simply record the state of the touchpads directly. If you do that, then in your second loop you need to analyze that state to figure out what action to take, similar to the digital keyboard program when it analyzes the currenttouch state.

    The second method is to analyze the current state in the first loop and store the current tone being played (or 0 if a rest). This approach makes the second loop easier, because it simply calls tone (or noTone if a 0) with the stored value.

  2. Test your circuit.
  3. Required video two: a video of your recording keyboard working.

Follow-up Questions

  1. What is a loop variable, and how do we use it with arrays?
  2. How do you keep track of how many items you have entered into an array?
  3. In C, how do you know how long an array is?
  4. If you have one switch, it allows you to play 2 octaves with only 12 keys (0 = lower octave, 1 = upper octave). How many octaves could you play if you had 2 switches?



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 cs153f18project4


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.