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.
Tasks
Part 1: Board Setup
You will need the following components for your board setup.
- Capacitive Sensor and associated wires, alligator clips, and copper tape
- The piezo speaker
- The small round sensor pad and a 10k resistor
- An LED with a 560 Ohm resistor
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.
- Wire up an LED with a 560 Ohm resistor, driven by one of the digital pins.
- 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.
- 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?
- Test that your circuit lights up an LED whenever you are touching one of the capacitive sensors.
- 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.
-
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; return(c); }
-
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.
- Initialize a variable curtone to -1
- 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
- After the loop over all of the sensors, if curtone is >=0 then call the tone function with the appropriate note.
- 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.
- 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.
- 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.
- Test your circuit.
- Required video two: a video of your recording keyboard working.
Follow-up Questions
- What is a loop variable, and how do we use it with arrays?
- How do you keep track of how many items you have entered into an array?
- In C, how do you know how long an array is?
- 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?
Extensions
- Make modifications to your instrument. Some possibilities include:
- Add a switch or two to enable more octaves.
- Add the force sensor as a hold pedal.
- Use the force sensor to "bend" your note by adding or subtracting to the frequency
- Try out materials other than the copper tape as sensors.
- Make your keyboard do percussion sounds instead of tones.
- Lay down a percussion beat while you play notes.
- Be creative...
- Try out other sensors as part of your instrument (there is at least one light sensor we haven't used yet).
- See if there is some way you could generate a percussion line without using the speaker (throwing this one out there).
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 cs153f18project4
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.