Engineering Projects/Music projects/Howard Community College/fall2011/502 The Tin Can Band

Problem Statement
From the "Next Steps" section of Music Team:

"The next team must get a note to play based on the analogRead function. This should be done more accurately with a potentiometer at first, rather than just holding the arduino to your temple. A good place to start is with breaking down the code I provided, and figuring out why it does not play a note at any given time (which it should - the if statements just have the pitch of the note different from one another, rather than the presence of a note), and then reconstruct it so that it does play a note.

From there, using previous team's knowledge, it should be possible to connect the Hall Effect Probe to the arduino, pass a magnet through its sensor, and through MIDI shield to arduino to keyboard connections, play a note. At that point, it is fairly easy to get six Hall Effect Probes working on one arduino (using the 7 analog pins provided on the arduino board), and then setting up the the actual tin can to play the notes on a hand crank."

In essence, we were tasked with creating a basic system that plays a note based on the input that is external from the arduino - which the previous team wanted to do via the analogRead function. Additionally, we wanted to be construct a relatively system that plays a note on a keyboard when we pass a magnet through a sensor.

Team Members
Dominick Moreno

Summary
Over our time with this project, we managed to get a keyboard to interact with a potentiometer using an arduino board and a MIDI shield. There's a code written to do this, however it does have its problems (see the narrative). In order to better analyze these problems, we found a way to print values used by the arduino board in this code to the serial monitor - a window integrated with the arduino environment that allows you to see whatever you want.

Team Weekly Reports:
 * Dominick's Week 1 Activities
 * Dominick's Week 2 Activities
 * Dominick's Week 3 Activities

Poster
This is the apparatus used to analyze the resistance and voltage that should be read by the arduino. A digital multimeter was used to read the voltage on the potentiometer pins going into the analog inputs on the MIDI shield. Adjustments made to the potentiometer effect the voltage going into the arduino. This voltage is read as an input with the program, which then produces an output that we were trying to analyze.

Story
We updated code from the last project to make it a bit easier to adjust. This way we only have to adjust the int sensorThreshold to test different voltage values.



It's obvious just holding an arduino board to our temple isn't nearly an accurate enough way deliver an input for analogRead to interpret. The next logical step before tackling the Hall Effect Probe was to instead use a potentiometer to control the values read by the pin - and instead of having it control a note being played, just turn on the LED in pin 13. Our reasoning for this was because of a potential problem that was discussed with the last group: Using certain analog devices require a baud rate of 9600 bits per second (bps), whereas MIDI Protocol requires 31250 bps. I'm only trying to deal with one problem at a time, so we tried to get consistent results with this code first. We went on to study potentiometers.

What we learned about potentiometers and voltage:
 * With the Wikipedia page on Ohms we researched voltage. We found that:
 * P = (V^2)/R
 * Where P is power in Watts, V is voltage, and R is resistance.
 * The potentiometer is used to adjust the resistance, and therefore, the amount of voltage read by the analog pin. Resistance is changed by turning the rod clockwise or counterclockwise.
 * There are three wires on the potentiometer. As far as working them with the arduino is concerned, one wire goes to power supply, another ground, and the third to where you wish power to be supplied to.

The potentiometer we used was actually broken - the wire snapped off the first time we tried to put a wire into an arduino pin. It was soldered back on. In order to solder it back on, we had to have a soldering gun/iron, wet sponge, and soldering wire - more detail into the necessary items can be found here. The process of soldering can be fairly complex or simple, depending on the devices used in the process. A detailed explanation for soldering in general can be found here. Once the wire was re-attached, the potentiometer was tested with a multimeter, where it was determined that what we had on hand was a 1 mega-ohm potentiometer.

While looking for the best way to test the potentiometer on the arduino site, we came across a code specifically meant to be used in conjunction with the potentiometer. The code is as follows:

Essentially, what this code does, is it causes the LED on pin 13 to stay lit up, and then turned off, for the value found by the analog pin reading the voltage. It is a very simple way to see how resistance effects the interpreted voltage. The code we refined from the last team's work is similar in this ultimate objective, but goes about it in a different manner; rather, it simply causes the light to turn on once a certain voltage is reached. Initial testing with this code made us realize that our potentiometer, as it currently stood, needed one more wire. We found an old broken one, cut off the wire on that, and soldered it on to our potentiometer. We then hooked it up to the arduino and ran this code. Our results were as follows:


 * Our first time testing different resistances, we noticed a kind of electronic burning smell we've only experienced when trying to put together an old computer. Both the board and potentiometer were fine. The smell disappeared after our first attempt.
 * Turning the pot fully counterclockwise resulted in a dimly lit LED light that was always on, never blinking.
 * Turning the pot fully clockwise resulted in the LED light just being off altogether. Additionally, the power LED would dim and then turn off as well.
 * When turning the potentiometer from fully clockwise to counterclockwise, the light still (generally) blinks at a seemingly constant rate, until a certain threshold is reached approximately 1/3rd of the way to fully counterclockwise, at which point the LED light just remains dim, never blinking, like when it's turned fully counterclockwise.



From this test we drew the conclusion that when turned fully clockwise, all power is being diverted from the arduino into the 5v pin, through the unrestricted potentiometer, and into the analog pin, leaving insufficient power for the power LED pin to be used, meaning that resistance is at its lowest when the potentiometer is rotated fully clockwise. Additionally, after the potentiometer is turned counterclockwise past a certain point, the arduino has difficulty reading the voltage in the analog pin because of how little voltage is getting through the potentiometer, and as a result, the light just dims.

We then tried using the Potentiometer Light Code with the arduino, expecting it to stay off when turned fully counterclockwise. As it was turned clockwise, the LED pin should have turned on, and stayed on. Instead, it just remained off at any given position. When fully clockwise, the power LED turned off again, and when it was turned counterclockwise from this position even just a hair, it would come back on. Additionally, the LED pin would blink rapidly for a short length of time, before remaining off. That blink was consistent, and was for a length of time after the potentiometer was moved - how much it was moved, or where it was moved to, had absolutely no discernible effect on the blinking.

To try and get results more similar to what we expected, we tested several solutions:

'''Note: one wire snapped off while we were trying different combinations. As a result, from here on out, we were only able to test solutions with one wire in the 5v, and one in analog pin 0, and none in grounding.''' The light just continued to stay on, no matter what we did. Fully clockwise and fully counterclockwise did not dim the LED pin, nor did the power LED turn off when turned fully clockwise.
 * Wiring the potentiometer into the arduino differently. We tried several different combinations, but they had no effect.
 * We analyzed the code we refined. We found no theoretical problems, but a second opinion is something we're still searching for. Just to try something, we added a delay of 200 milliseconds after the "if" parameters to give the code enough time to reasonable display that the LED is in fact on. This had no effect, so we removed it in all future iterations of testing.




 * We checked that our code was reading the right pin number, and that the wires were in the correct pins - they were.
 * We experimented with different threshold values. We saw no change in the LED pin.
 * 512 - the "halfway" point, or 2.5V
 * 1023 - the "maximum" point, or 5v
 * 1 - the "minimum" point that could still be interpreted with this code, or 0v
 * 736 - an arbitrary value
 * 316 - an arbitrary value
 * 493 - an arbitrary value
 * We tried setting the LED pin to "off" using "digitalWrite(13, LOW);" before any of the if parameters in the void loop. We saw no change in the LED pin, which is strange, because if the analog pin just weren't reading anything, the light should have just been off.

The conclusion we drew was that we would need to re-sodder the wire on that potentiometer before we could continue to test solutions (we did not have the tools necessary at home). What throws us off, however, is the fact that apparently some kind of voltage is being read that causes the LED to turn on, or else the bit of code we threw in to make the default status of the LED pin be "off" would have just kept it off.

After speaking with the instructor, we realized our potentiometer, as it was when we received it, had a connection between the middle and top node (red and blue wires). As a result, they essentially acted as one node, and thus skewed the results of our testing last week in a way we hadn't accounted for. We cut this connection with a pair of wire cutters. Additionally, we decided to just cut off the remaining two wires on the potentiometer - one wire was like the one that had snapped off (brittle), and we weren't sure how much longer it would last, while the other one was fraying and relatively difficult to manage. We snapped these off with wire cutters as well.

We found a "thing" that appeared to be some kind of computer component. The wires were relatively long (~4 in), and the ends were crimped with some kind of metal holding. The ends of them fit perfectly into the arduino pins. We cut a red, green, and blue wire off that, stripped the opposite end of them, and twisted the frayed ends tightly so none were loose. We soldered these three wires to the potentiometer (much better than we did the first time), and they became securely fastened.



The next step was to hook up a digital multimeter to the poteniometer, and analyze the way it would interact with voltage. By hooking up the alligator clips (the multimeter) to two nodes that were not connected yielded a maximum resistance of 1,000,000 ohms - or 1 mega-ohm, which confirmed what was previously found when we first received the potentiometer. By switching the multimeter to read volts, and attaching the alligator clips to the crimped ends of the wires, we found we were able to read the level of voltage going through the potentiometer and into the arduino - essentially being able to see what voltage reading should be read by the arduino.

We attached the red wire to ground, blue wire to analog input pin #0, and the green wire to 5v, one alligator clip to the green wire, the other to blue. Additionally, we uploaded the "Reading a Potentiometer Sample" code into the arduino. The multimeter read ~5.0v while the light blinked incredibly quickly. This is the opposite of what we expected - when the arduino recognizes a higher voltage, it should have a value close to 1023 from analogRead, which was used in the delay timer, and as such should have a slower blinking rate. Despite this, we found these results to be quite consistent. As we adjusted the resistance with the potentiometer, we found that as voltage increased (up to ~5.0v), so did the rate at which the LED pin blinked. The opposite was true as well, ~0.0v had a (relatively) incredibly slow blinking rate whereas we predicted it would have a fast one. We switched which alligator clip was on which wire to see if we somehow gave the wires an inverse relationship with our apparatus, but the multimeter instead read the same values as they originally did, only they were negative. Because the magnitude of the values were not changed, and we weren't sure if voltage was even a scalar quantity, so we put it back the way we originally had it.



This table displays the general trend of voltage vs blinking rate. When the voltage was 2.0, the resistance wasn't being read properly by the multimeter.

Despite the fact that this wasn't precisely what we originally predicted, this was, generally, what we expected to happen - by using the potentiometer to alter resistances (and therefore the voltage read by the analog pin), we were able to change the rate at which the light blinked. The next step for us was to use a code that we had written instead of one we were given. We uploaded the "Potentiometer Light" code into the arduino. We had the sensorThreshold at 1023. Only voltage values interpreted as 1023 should turn the light on; originally we thought that would have been 5.0v, but in light of recent events, we changed our prediction to having the light turn on at ~0.0v. We were right, and went on to test this with a different sensor Threshold value (511).

We loaded this into the arduino, and it loaded fine. At ~3.0v the light was off, however, seemingly arbitrarily, the arduino board just powered off as we were writing down data. The multimeter read ~0.0v, and the power LED was off as well as the LED pin. No matter how qw changed resistance with the potentiometer, none of the lights would come on, and the multimeter continued to read ~0.0v. We started taking parts off the arduino (the clips and potentiometer) to load just the blinking light code to see if we broke the board, but the moment we took one alligator clip off, the board powered back on. It then behaved accordingly, the LED pin turning off at approximately where we predicted, and turning on in a similar manner (We were unable to look at the voltage, as we decided to leave the multimeter disconnected for a little while). After playing with turning the light on/off for a time, we put the alligator clips back on, and everything resumed working as normal. Our theory is that the multimeter was somehow sapping a reserve power from the arduino, but we really have no idea, and had no way to test this theory, as we were unable to reproduce this anomaly; the board worked fine from here on out.

From here we decided that, now that we can effectively use the analogRead to alter an output with the arduino, we went to try and use the Potentiometer Tone Code from the previous team's work. We decided to streamline it a bit, and came up with:

We just tidied up this code by replacing the pin numbers and delay values with integers. Additionally, we changed the delay in both "if" tests to a constant 100 milliseconds. We tried uploading this, and attaching everything together to play notes on the keyboard. We were met by a constant thumping at a rate of ~0.1 seconds. The light, however, continued to work the way we expected it to, turning on/off after turning the potentiometer approximately halfway (at this point we didn't have access to a digital multimeter).

Solutions we tested that contributed towards playing proper notes:
 * We just wanted to see if the board and midi shield were working correctly at all - we tried uploading a code that we knew worked with the keyboard (the "Mary Had a Little Lamb" code), and went to see if that still played properly - it did, so we knew the problem was one with our code, and not the hardware
 * We knew that we had the right kind of format for "if" tests in our code because the blinking light test we had just been working on worked fine. However, we weren't sure if keeping the part of the code that effected the LED pin was creating a problem with the note playing, so we just removed that - it didn't do anything noticeable to the code.
 * W tried changing the timeDelay in the second "if" test, just to see if we could at least augment the rate at which the keyboard was thumping - and we was succesful. After turning the potentiometer ~halfway, we found a difference in the timing of the thumping. However, it did not play a note.
 * We tried removing the "silent" note (the one after the delay with a velocity of 0x00), to no effect.
 * We tried implementing a default "else" block instead of the second "if" test, and removing the note in that else block, instead replacing it with turning the LED light on. After initial testing, we realized we needed to have the light actually turn off in case the "if" test were successful so we could appropriately interpret results. The code appeared as such:


 * It worked as we predicted, the thumping would continue until we turned the potentiometer a certain amount, at which point it would stop and the light would come on. This lead me to believe the problem was in the way the note was being played in the first place.
 * We looked at the values we had inside the noteOn function. Command and pitch were fine, however, we looked at velocity - 0x100 is equal to 256 decimal. The range of midi protocol values is [0, 127] (decimal). 256 is way above that, and never would have worked at all. We tried using a hexadecimal value inside this range - 0x40 (64 decimal) - instead of the 0x100 we had just used in our previous code. It worked wonderfully, the note playing at the rate of the timeDelay value we had set until we turned the potentiometer ~halfway, at which point the note would stop, and the light would turn on.

From this point on we kind of just built our code back up, adding new components that we had either stripped it of in trying to get it to function properly, and adding new ones to try and test how far we could take this.

We tried breaking the analogRead value range [0, 1023] into 3 different segments along the intervals: [0, 341), [341, 682), [682, 1023]. Each interval corresponds to its own different note, and which note is chosen is dependent upon the value that analogRead returns from interpreting the voltage. Our end result was this:

This code was met with a moderate amount of success. 3 different notes would in fact play throughout the entire [0, 1023] interval, however they would overlap seemingly random. Further testing into why this occurred is necessary.

After giving a presentation, we were informed of what is called a "serial monitor". It's a way to, with proper coding, look at the actual values specified in the arduino (like the sensorValue I've been using so often). It was our belief that, if we could actually see those values in real time, we'd be able to look at what the arduino was actually producing, and what it should be producing (say it's playing note A when we think it should be playing note B), and would be able to more precisely view any problems.

We looked through the example codes provided for the arduino, and came across the one for use in conjunction with an accelerometer. It used within it, something called "Serial.print", and we were told this had something to do with printing values to the serial monitor. This made sense, so we searched for the function on the arduino site, and found this code:

What this code does is it just has a loop of values, ascending from 0 to 63, and prints those values in decimal, hexadecimal, octal, binary, and as a raw byte value. Essentially all of these are useless for our purposes except for decimal, but it's handy information to know that we can print them as things other than decimal.

The way it works is it prints the "titles" ("No Format", "Dec", "Hex", "Oct", "Byte") in a single row, spacing them with a tab ("\t"). The last line for "Byte" uses "Serial.printin", which essentially does the exact same thing as "Serial.print", except, among other things (which are useless for our purposes), creates a new row, ensuring that all values that follow are now on the second row. It then creates a conditional loop with the "for" statement, which just causes the values go from 0 to 63 in ascending order, and the code lists the values in their respective formats (decimal, hexadecimal, etc), creating a new line after the byte value is displayed. Once all 64 values have been displayed, the conditional loop ends, the void loop ends, and the process repeats.

Note: viewing the serial monitor requires setting a baud rate of 9600, meaning it can't be used in conjunction with the MIDI protocol with any of the arduino boards we currently have access to. However, an arduino mega board would sidestep this issue by allowing me to set multiple baud rates.

Wanting to better learn the format, we wrote our own code to be used in conjunction with a potentiometer:



We used "Serial.print("\n")" instead of "Serial.printin" simply because everything else that comes with Serial.printin is unnecessary. What this code does is it reads the analog pin 0 for a voltage with analogRead, assigns it a value in the range of [0, 1023], and then prints that value in the serial monitor at a rate of two values printed every second. This means that we can see the analog read values in real time. We wanted to test this, so we hooked the potentiometer up to the arduino and loaded the code.

It worked as intended initially - values would change as we changed the resistance with the potentiometer, though we came across some complications. They, along with some basic properties, are listed below:
 * Fully clockwise yields a value of 1023, consistently
 * Fully counterclockwise yields a value of 0, consistently
 * Turning the potentiometer clockwise from fully counterclockwise will still result in values of 0 for a time; at approximately 1/3 of the way turned, it starts returning positive integers that ascend proportionally as it's turned clockwise. We refer to this point as the resistance threshold. A multimeter should be used to analyze why this occurs, but it is consistent, and therefore easy to account for.
 * Initial testing of these values resulted in a seemingly random spike as we turned it counterclockwise from fully clockwise. As it descended from 1023, it would randomly spike up to 1023 and stay there as we turned the potentiometer (when we would otherwise expect a value of, for example, 780 that is descending). Our ability to reproduce this was inconsistent, though it was more likely to happen when we turned the potentiometer counterclockwise rapidly.
 * Occasionally turning the pot fully counterclockwise resulted in values no longer being returned in the serial monitor (it would just stop), and an error code from the arduino environment. It wouldn't un-"freeze" itself unless we re-uploaded the code altogether. Just closing and then re-opening the serial monitor was insufficient. This error was generally inconsistent, but was more likely to happen when we turned the potentiometer to fully counterclockwise rapidly.

Our method of finding solutions to these problems were, originally, just trying to reproduce the errors, both the one that caused the random spike to 1023, and the "freezing" error. Our results were sporadic and inconsistent, and googling the error yielded nothing useful. However, while the potentiometer was fully counterclockwise, consistently producing a value of 0, we accidentally knocked it and the arduino off the desk, and we saw that we the freezing error had occured. This led us to believe perhaps the error was a hardware one, and when we went to pick it up, we noticed the green and blue wires (which go to the 5v and ground pin in the arduino, respectively), where exposed, were touching. We knew from our understanding that this wouldn't lead to anything good, and that due to the way they were soldered, it would be all too easy for them to touch without us noticing.

We turned the potentiometer fully clockwise (where it should yield a value of 1023), and reset the code. We turned it counterclockwise (very slowly), and the values began to descend, we touched the two wires together, and suddenly they would read only 1023, no matter how we turned the potentiometer. The moment we let go they returned to whatever value they should have been. We tried this below the resistance threshold, and it would still read 1023 when the wires touched. However, most importantly, we turned the potentiometer fully counterclockwise and touched the wires - immediately we were given the "freezing" error. We tested this a few times with the same exact result, but we were afraid of somehow doing damage to the arduino board if we kept it up.

So most importantly we learned to make sure that the ground and 5v wires don't touch where they're exposed, and it'll be fine. Additionally, our sensorValues will return 0 for multiple resistances with this potentiometer.

With this new information, we wanted to test our code for playing a note with the potentiometer. This was however impossible with an arduino duemilanove, and will be until we can get an arduino mega, but we could write a code that is similar, and essentially does the same thing with a blinking light instead of playing a note. So what we wrote was:

This code behaves similar to the code we wrote earlier, the only difference is that instead of playing a note, it causes the LED light to blink at different rates. Additionally, it accounts for the fact that sensorValue will be equal to 0 for a relatively large section of values, and lets me see the actual values for it in the serial monitor.

Material List
Parts necessary to finish this project:
 * Arduino 2009 board - used to write code
 * MIDI shield - used to give code access to the MIDI protocol
 * Keyboard with a MIDI IN attachment - used to play notes
 * Tin can - device used to play notes over time
 * Several dozen magnets - objects used as "notes" in final product
 * 4-7 Hall Effect Probes - used to interpret the magnets as notes
 * Means to mount the tin can - used to hold the tin can in place
 * Legos to operate a hand crank to move the tin can once mounted - rotates the tin can at will to play music

Parts on hand:
 * Arduino 2009 board
 * MIDI shield
 * Keyboard with a MIDI IN attachment
 * Tin can and appropriate mounting/operating devices - Tin can is currently mounted
 * 4-7 Hall Effect Probes
 * 2 keyboards, one for working at home, the other in class

Parts ordered:
 * Arduino mega board, to interact with both the MIDI protocol and serial monitor

Software List
Used software:
 * Arduino programming environment

Absolutely essential to programming with an arduino. A link to their site can be found here. It's open source, so free to download.

Time

 * Time estimated to get a note playing based off of analogRead would have been estimated at approximately 5 hours, where in actuality it was closer to 7 or 8.
 * Time estimated to get a note playing with a magnet and a hall effect probe was estimated at around 10 hours (15 total) after getting a note to play from analogRead, where in actuality after approximately 18 hours total this still has not been accomplished.

These discrepancies in theoretical and actual time taken to complete projects is due to troubleshooting issues with the potentiometer and with our code. However, work towards getting the arduino to interact with the hall effect probe is now ready to be done after 18 hours work.

Tutorials
The story and team pages actually have a fairly good list of explaining everything, however, they are listed here for convenience.
 * The MIDI protocol
 * Hexadecimal Calculator
 * Arduino references
 * For those who need a stronger background in musical theory, this is not a horrible place to start.
 * Blinking Light Code, used throughout this project to test to see if the arduino board was properly talking to the computer.
 * "If" function, used to create conditional statements
 * "If... Else" function, used for greater control over conditional statements than just "if"
 * "Serial.begin" function, explains baud rate used for when the arduino interacts with various other devices
 * "int" function, explains the usage of integers
 * "analogRead" function, elaborates on how to read the voltage input from a device
 * This explanation gives details about the serial monitor used with the arduino environment
 * "Serial.print" function, talks about printing text or values to the serial monitor
 * "Serial.begin" with an arduino mega talks about using multiple baud rates in conjunction with the arduino mega board

Next Steps

 * Write a code based on the potentiometer tone code that allows for viewing in the serial monitor once the arduino mega board has arrived. Figure out why the notes were overlapping when played, and fix it.
 * Work on getting the hall effect probe to interact with the arduino in some elementary fashion - get it to turn on a light, or something easy like that.
 * Once the hall effect probe is interacting with the arduino, combine the potentiometer tone code with whatever code was used to get the hall effect probe talking to the board in order to play a note when a magnet passes through the sensor.