Moses Huang (email@example.com)
Brian Cheng (firstname.lastname@example.org)
Our project is a self-contained system that helps people develop the musical skills of perfect pitch and relative pitch. Push buttons allow the user to navigate a graphical user interface (GUI) on a liquid crystal display (LCD). In perfect pitch training mode, a note is played and the user tries to identify the note on an animated keyboard. In relative pitch training mode, an interval is played, and the user selects the correct interval name from a list of possible intervals. A musical instrument digital interface (MIDI) input is implemented so users can simply press a key on a MIDI keyboard instead of navigating the animated one. Musical notes are generated using direct digital synthesis (DDS).
High Level Design top
I played piano growing up and I was always envious of those who can play by ear or transpose music on the spot. Then I learned the concepts of "perfect pitch" and "relative pitch." Perfect pitch is the ability to identify musical notes without an external reference and relative pitch is the ability to hear the interval between notes. Perfect pitch allows musicians to play by ear and relative pitch allows musicians to transpose musical pieces. They are separate abilities that can be trained contrary to popular belief. To train myself, I often sit next to a piano and test myself. The drawback is that I need a piano and that even while not looking at the keys, the position of my hand often give the notes away. Then I thought to myself, wouldn't it be nice to be able to train myself without a piano? Our project "Ear Trainer" develop one's perfect and relative pitch by generating random note(s) for users to identify the note(s) or the interval using an Atmel ATmega644 microcontroller (MCU). For users that want to answer using a piano, we allowed a MIDI input into the microcontroller.
Our project consists of two sources of input that control two outputs. The software is governed by a state machine that controls DDS and the LCD. The inputs are push buttons that are debounced by the state machine to control the GUI on the LCD and a MIDI input so that a user can hook up a keyboard. The MIDI is interfaced to the MCU via the universal asynchronous receiver/transmitter (UART). The MCU communicates with the LCD via serial peripheral interface (SPI). The direct digital synthesis creates a pulse width modulated (PWM) waveform that is filtered to create the sinusoidal waveforms for the speakers.
We use the ISO standard for the frequencies of our musical notes. We also adhere to the IEEE Code of Ethics.
Direct Digital Synthesis
To generate musical notes from the microcontroller (MCU), we use direct digital synthesis (DDS). The duty cycle of a pulse width modulated (PWM) signal is changed according to a table of sine values. The frequency of the sine wave is controlled by how quickly one iterates through the sine table. A low pass filter acts as an averager, converting the digital signal into an analog one that can be played by a speaker. Multiple notes can be generated at once by summing sine waves.
MIDI is a protocol that allows asynchronous serial communication between electronic musical instruments and computers. Data is transmitted serially using event messages that contain information about pitch, intensity, and other parameters. Event messages consist of at least two bytes. The first byte is always a status byte that inform the receiver how to interpret subsequent bytes. In our case, we are only interested in the NOTE_ON status, which is sent when the user presses a key. When that status is detected, we can determine which key was pressed from the rest of the message. The baud rate is 31,250 bits per second, with a start bit, a stop bit, and no parity bits.
Musical Note Frequencies
Serial Peripheral Interface
Serial Peripheral Interface (SPI) is a synchronous serial data transfer scheme for communication between a master device and a slave device. The SPI bus consists of four lines. The serial clock (SCLK) line is a clock signal provided by the master device to keep things synchornized. The master out slave in (MISO) line carries data that is transferred from master device to slave device. The master in slave out (MOSI) lines carries data that is transferred from slave device to master device. The chip select (CS) line selects the slave device to which the master device is sending or receiving data.
First, we had to pick a LCD display. The LCD used in previous labs could only display 2 lines of 16 characters each, which was not enough for our needs. One of our friends had a Playstation Portable screen that we could use, but after looking into it, we concluded that a more powerful MCU was needed to run it, especially with our plans to run direct digital synthesis and take in MIDI input. We settled on a color LCD that is a knockoff of a Nokia cell phone screen. The screen resolution and the cost were both satisfactory.
We sacrificed some precision with direct digital synthesis (DDS) because we wanted to generate three notes at once. The 32-bit accumulators used in the DTMF dialer lab work for generating two notes simultaneously, but they take a relatively long time to perform addition and shift operations. We ran into trouble when we tried to generate three notes, so we changed the accumulators to be 16-bit. The frequencies generated were still close to the desired frequencies.
Keypad vs Push buttons
We considered whether to use a keypad or make our own input interface with push buttons. Both could have worked. The buttons on the keypad would have needed to represent things other than the keys 0-9 and A-D. Once we decided that we were going to draw a keyboard on the LCD, it made more sense to make our own push button interface with four arrow keys and an enter key. We thing moving around the keyboard with arrows is more intuitive than pressing alphanumeric keys on a keypad.
We used a custom printed circuit board designed by Bruce Land and Nathan Chun for the ATMega644. We did not solder on the parts necessary for RS-232 communication due to cost constraints. We ended up soldering a different switch on a solder board to allow users to turn our project on and off without having to open the packaging. We also added a voltage regulator after the switch to provide current for the backlight since the regulator on the board is not rated for the amount of current we needed. Protoboard
We used a color LCD that is a knock-off of a Nokia cell phone LCD. The screen is 132x132 pixels on an area of about 3.5x3.5cm. It is capable of displaying up to 16-bit color, but we decided to use 12-bit color because it requires less data transfer and we only use a few colors. We chose this LCD because it is a cheap color LCD with good enough resolution for our purposes. The availability of a breakout board and the fact that many people have interfaced to it with MCUs before were also a plus.
The LCD has a controller chip that holds the information for each pixel. We communicate with the controller via SPI. The SPI is not a normal 8-bit SPI, but rather a 9-bit SPI, so could not use the built in SPI on the MCU. The extra bit is used to signify whether a transmitted byte is a command or data. The LCD controller only receives data, so we did not need a MISO line. We successfully run the SPI at 16MHz even though the datasheet for the controller says the period of the serial clock should not be less than 150ns, which corresponds to operating at around 6MHz.
The LCD controller operates at 3.3V, so we could not directly hook it up to the MCU. We used a buffer as a level shifter for our SPI lines. By providing 3.3V to the VCC of the buffer chip, the maximum output of the buffer is limited to 3.3V, which is acceptable for the LCD controller.
The backlight of the LCD requires 7V. The breakout board has circuitry to step up voltages, so we hooked up 5V to it. However, this drew too much current for the voltage regulator on the custom PCB to handle, so we got an additional voltage regulator that is rated for up to 950mA. The backlight circuit draws about 120mA when it is given 5V. We moved the switch on the custom PCB onto a solder board so we could put in the voltage regulator and also so we can have an on/off switch on the outside of our box. The voltage regulator gets warm, so we put a heat sink on it.
Overall, the hardware aspect of the LCD was not difficult. The breakout board helped us bypass the issue of soldering the connector of the LCD, which seems to be fragile and hard to solder. The level shifter idea came from reading forums of people who had worked with this LCD before. The software aspect of the LCD took much more time.
Some circuitry is needed before the MCU can read MIDI data. Our circuit is based on circuits from previous ECE4760 projects that used MIDI. The grounds of the MIDI device and the MCU are different, so we isolated the two circuits with an optocoupler. We used the 6N138 because the rise/fall time is important. At 31,250 bits per second, each bit is only lasts 32 microseconds, so a fast rise/fall time is desirable. We put in an extra diode to protect against accidentally hooking up the MIDI leads backwards. The output is connected to the UART receive pin (D.0) on the MCU to be read at a baud rate of 31,250 bits per second.
We used five push buttons for user input. There are four arrow keys and an enter key. The MCU reads logic high when the buttons are unpressed because of pull-up resistors and logic low when the buttons are pressed. The button debounce is done in software.
Sound is produced by direct digital synthesis (DDS). A PWM waveform is produced on pin B.3. By passing the waveform through a lowpass filter, a sinusoidal waveform results because the filter acts as an averager. The resistor and capacitor values are 2k ohms and 100nF. They were chosen to give a cutoff frequency of about 800Hz, which is larger than our largest frequency. The resistor needed to be large enough so as not to load the port pin and smaller than the input impedance of the speaker.
We decided to make our project more presentable by putting the circuit in a box. We super glued the audio jack and midi adapter to the solder board. Then we cut out slots so the user can turn the system on and off, plug in a MIDI cable, and plug in headphones/speakers. A cutout was made so the LCD can be seen. The keypad is placed on top of the box with a slot for wires to enter the box. We cover the wires and resistors for a more pleasant look. The circuit boards inside the box are secured so users can plug into and unplug from the MIDI adapter and audio jack without opening the box. However, the MIDI adapter is too tight to connect or disconnect without additional support for the connector from the inside. We also put in a few ventilation holes near the voltage regulator, but this could probably be improved.
Our software is spread over three files:
EarTrainer.c - contains the main logic of our program.
lcd_driver.h - contains the LCD functions + UART inititialization
lcd.h - contains all the definitions and constant variables and the bitmap.
The most difficult part of our project was figuring out how to communicate with the LCD using software. We found sample code online, but we could only get the LCD to display shapes with no color control. The pixels of characters showed up as garbage. Reading the datasheet of the LCD controller did not help us make much progress. Then we found a tutorial to help guide us. We discovered that our early troubles could be attributed to trying to display 8-bit color on the LCD. For some reason, 8-bit colors cannot be displayed on the LCD even though theoretically it should be possible. We could sort of tell different colors apart, but they were more like different shades of gray. Once we switched to 12-bit color, our problems were solved.
The LCD controller requires a 9-bit SPI to communicate with it. The extra bit is used to distinguish between commands and data. The built-in SPI on the MCU is only 8 bits, so we could not use that. Fortunately, there was some code on the vendor webpage that had a method written in assembly langauge to send 9-bit SPI. This provided a foundation for our LCD code.
We found a tutorial by Jim Lynch to be very helpful. Even though the code he wrote was not for ATMega MCUs, we were able to convert the LCD driver methods to work on the ATMega644. The only modification to his code was to use the aforementioned assembly language method for sending 9 bits over the SPI. By using these LCD driver methods, we were able to display shapes and characters of varying colors, allowing us to move forward with the project.
We used the LCD orientation given in the tutorial so that the connector is in the upper right instead of the bottom left. Then we set the origin to be the bottom left corner with x (rows) increasing upwards and y (columns) increasing to the right.
Drawing the Keyboard on the LCD
We wrote our MIDI interface by consulting lab4 and a previous project "MCU MIDI synthesizer." We enabled the UART to receive and trigger an interrupt, so every time it receives an input, an interrupt service routine (ISR) is called. We had to set UBRR0L to 31. This is done based off the equation found on the data sheet: (16000000 / (16UL * UART_BAUD)) - 1 where UART_BAUD is equal to 31250. In the ISR the received byte is checked to see if it starts with 0x9(note on) or 0x8 (note off). By printing out the byte that follows a note onto to the LCD, we found that the key (without considering different octaves) can be determined by modding the byte by 12, since the range of the keys is 0-11. The key can now be used to check whether the user has guessed the notes correctly. Though the basic functionality works, there was some trouble with the MIDI. Quickly pressing keys multiple times may cause the screen to flicker and distort. We think the ISR is occurring too often and is affecting the SPI. (Talk about two note, three note functionality, even if it didn't work)
For using MIDI to answer multiple notes questions, the program stores each note user pressed and checks to see if it is correct when the required number of notes is played. Pressing the notes simultaneously on the MIDI generator will yield the correct result, but will cause the screen problem mentioned in the last paragraph.
Direct Digital Synthesis
We create our sound by using DDS. We keep a table of 256 values corresponding to one period of a sine wave. By iterating through the sine table at different speeds, different frequencies can be produced. An accumulator is used to keep track of the position in the sine table. The amount the accumulator increments by each PWM cycle dictates what frequency will be produced. We used timer0 to time our PWM. Each time timer0 overflows, an ISR is called to increment the accumulators and set the new PWM duty cycle. Our PWM frequency is 62.5kHz.
At first, a 32-bit accumulator was used to keep track of the position within the sine table. Using this many bits allows for precise generation of frequencies because essentially the unit circle is quantized into 232 points, so the increment can be more precise. The 8 most significant bits of the accumulator represent which of the 256 stored values is to be used.
When we tried to play three notes simultaneously, however, the microcontroller was not able to finish calculations before the interrupt service routine for the next PWM cycle was called. We considered decreasing the PWM frequency to give more calculation time for the ISR, but decided against it because it would limit the maximum frequency we could generate in case we wanted to expand to other octaves. We decided to sacrifice some precision by decreasing the size of the accumulator to 16 bits. The new increment values are then found by the equation 216*256*Fout/16e6. This was sufficient to allow us to play three notes simultaneously. When we measured our generated sine waves, the frequencies were still very close to what we wanted.
We used a state machine to debounce button presses and control our program. The state machine is updated every 30 milliseconds. It is based closely off of the state machine from Lab 2. The scanning code for the five push buttons checks to see if any of the input is 0 and stores the corresponding push button into a variable called butnum. If multiple buttons are pushed, then butnum becomes invalid. We also set it so that if more than three buttons are pressed, the answers will be displayed on the screen in case the player gives up. The state machine, according to the buttons pressed, will navigate the GUI based on user commands by highlighting different buttons/keys, play notes, start a question or enter/exit a training program.
When our system is turned on, it takes the user to a title screen where the user can select which training to do. There are three choices: perfect pitch, relative pitch, and synthesizer. The synthesizer just plays notes when a user presses them. In each of the three modes, we animate a keyboard along the bottom of the screen. To navigate the keyboard, the left and right buttons can be pressed. To access the exit or play buttons, the up and down buttons can be used. To confirm a selection, press the enter button.
In the upper left quadrant of the screen, the level and amount of progress is displayed. Giving incorrect answers decreases progress, while getting consecutive correct answers builds up progress quickly. The LCD displays whether the user is correct or incorrect when answers are entered.
Perfect Pitch/ Relative Pitch
For the two training methods, we had to generate random questions. We chose to use a linear feedback shift register for random numbers. This is a pseudorandom number generator, but we store the last used random number in the EEPROM and obtain the seed from EEPROM every time it is turned on. We chose a seed that has a period of about 4000 which we deemed to be good enough.
For perfect pitch, the training is separated into three levels, one note, two notes, and three notes. The user has to identify all the notes being played for each level on the keyboard. A score is given, and when the user reaches a certain score, the level increases. For relative pitch, the question is answered in a multiple choice format. There are 13 choices in total which ranges from 0 half-steps to 12 half-steps between the two notes being played. There are musical notations used for the choices. m-minor, M - major, P - Perfect, - Diminished, + Augmented. For example: +2 means Augmented second. Since an interval can be given multiple names, we show multiple names per option. We noticed that the quality of sound wasn't good enough to discern notes that are whole octave apart (harmonics).
Speed of Execution
Our program executes without flicker on the LCD screen. In certain cases with the MIDI, the LCD can become distorted. The animations and user interface are smooth. Overall, timing constraints in our software are met.
We measured the frequencies produced by our direct digital synthesis. The frequencies we measured were very close to the frequencies as set by the (ISO standard). The table below shows our measurements. Measurements have an accuracy of +/- .1Hz, so the frequencies we produced were within 0.5% of the desired frequencies. In theory, without the measurement error, the frequencies produced should be even more accurate.
|Musical Note||Frequency (Hz)||Measured Freq. (Hz)|
Our project is safe. There are no moving parts. The circuit is packaged inside a box, so the user only needs to plug in a power adapter, speakers, perhaps a MIDI cable, and press push buttons. Users need to be careful when trying to unplug the MIDI cable since the connector is very tight. Another possibility is the system could overheat if left on for a very extended period of time because the voltage regulators are dissipating heat and the ventilation system is not the best.
Our project does not transmit interference, nor is it affected by interference from other groups.
The system is usable. Users will need speakers/headphones, and a 9-12V DC adapter that is rated for at least 300mA. People of all ages can train themselves in perfect pitch and relative pitch. Relative pitch requires a basic knowledge of the naming conventions of intervals. The game can be frustrating for people who have not had much exposure to musical training, but over time it should become easier. Ear Trainer has not been implemented for the visually-impaired and is not suitable for the hearing-impaired.
On the piano, Moses is able to identify 4 notes played simulaneously. When we finished this project, the first thing we did was to use it ourselves. Surprisingly, Moses was having trouble identifying single notes on the Ear Trainer. We concluded that the timbre between the piano and the Ear Trainer is quite different. For one thing, sound generated from pure sine waves have less information than the sound generated by a piano. After using the ear trainer a few times, we showed improvement and were able to identify single notes on the ear trainer.
Our project met our basic expectations of being able to train someone in perfect pitch and relative pitch. We were able to incorporate MIDI input into our system so people can press keys on a MIDI keyboard to answer questions during perfect pitch training. Originally, we would've also liked to incorporate a vocal input so one could train to sing a pitch on cue. However, it took longer than expected to interface to the LCD at first.
Intellectual property considerations:
We used code from previous labs. We used code snippets for the LCD that were available on the vendor website. They were provided by other electronics enthusiasts. Some of our hardware considerations were also guided by these people. For the MIDI aspect of our project, a couple of previous projects were helpful to us. We have no intention of patenting this project.
Some combinations of notes are difficult to hear clearly. For example, some people will not be able to distinguish a perfect octave interval from a perfect unison interval. Another drawback is the need to press a push button to play the question when using MIDI to answer them. It would be nice the user could control that from the keyboard. Also, sometimes when the MIDI is pressed quickly, the LCD can become a little distorted.
One possible improvement is to extend the MIDI input to be able to answer questions in relative pitch training. Perhaps a modification could be made so a user can navigate the GUI from just the keyboard rather than having to press a button to play the question. Another improvement could be to implement a vocal training program so people can train to sing a note on cue. A microphone can be used to pick up a user's singing/humming/whistling. Then the pitch can be determine by the MCU.
Ethical and Legal Considerations
This project adheres to the IEEE Code of Ethics.
During the development of our project, we always kept safety in mind. We kept our speakers tuned to a low volume during lab so as not to be disruptive to other groups. Our end product does not have significant safety risks. Users need to be careful not to turn up the volume control on their speakers/headphones. Directly plugging in headphones into the audio jack should produce a reasonable volume level. The packaging keeps user from direct contact with the circuit. The voltages are at reasonable levels. Our system does not interfere with other devices.
This report was written in a clear and informative manner so that anyone interested can reproduce this project. We have attached the commented code in the appendices. We have discussed the results of our efforts in an unbiased way and suggested possible improvements. We have mentioned the contributions of others to this project.
There are no legal considerations for our project. Our project does not communicate with or interfere with other devices. The project was done for fun with no intention of commercialization. We aimed to complete a project that would be beneficial to anyone with an interest in music.
Appendix A: Commented Code
Appendix B: References
Epson LCD controller: http://www.sparkfun.com/datasheets/LCD/S1D15G10D08BE_TM_MF1493_03.pdf
LCD Breakout Board:
Previous 4760 Projects:
Appendix C: Cost
|Small Solder Board||Lab||2||$2.00|
|Custom PC Board||Lab||1||$4.00|
|LCD Breakout Board (Sparkfun: LCD-08600)||Sparkfun||1||$34.95|
|CD74HC4050E Level Shifter (Digikey: 296-9213-5-ND)||Digikey||1||$0.52|
|LD1117V33 Voltage Regulator (Digikey: 497-1491-5-ND)||Digikey||1||$0.68|
|LD1117V50 Voltage Regulator (Digikey: 497-7311-5-ND)||Digikey||1||$0.65|
|40-pin DIP socket||Lab||1||$0.50|
|MIDI Connector (Sparkfun: PRT-09536)||Sparkfun||1||$1.95|
|MIDI Cable||Own it||1||-|
|Resistors, Capacitors, Wires, Audio Connector, Push Buttons, Heat Sink, Diodes, Switch||Lab||-||-|
Appendix D: Task Division
|Push Button Interface||Brian|
|Direct Digital Synthesis||Moses|
|Ear Training Software||Moses|