Our system performs accurately under the following constraints.  The keys must be pressed one a time without extreme pressure or speed.  These limits account for the fact that the midi protocol allows many different functionalities whose implementations vary from keyboard to keyboard and instrument to instrument.  Implementing these functions require a thorough knowledge of the MIDI protocol and the keyboard MIDI protocol implementation, and are unrelated to the understanding of the MCU.


Our system is affordable and easy to use since it uses plug and play technology, i.e. things don’t need to be configured or installed.  However, it can be improved by sending the MIDI output of the instrument to a synthesizer, either that of the PC or that of the TV.  In addition to adding sound, which shouldn’t be too difficult, if all the special functionalities of the instruments are implemented, our system can be mass produced for the market.  The special functionalities would require one or more additional MCUs for extra memory and processing power.  Nevertheless, most of the cost will probably be due to packaging.




Inputting a clean signal to the UART


We first used a 4N35 optoisolator manufactured by Fairchild.  We found that using a resistor value of 2kΩ for R2 - the resistor at the input of the UART- we were unable to get a voltage level greater than 2.5V at the UART input.  While, when we used a 280Ω, the voltage level was close to 5V but the signal was very distorted.  We found that using a different optoisolator, in particular HP6N138, with a R2 resistor value of 2 kΩ fixed the clean input signal problem.




Reinitializing the note_counter properly is critical to determining the note type since this variable keeps track of the duration of a note.  The variable should be reset to 0 when a note starts playing and, once the contents have been stored, when a note stops playing.


Stack Space


Function calls are expensive operations since they require stack space, a limited resource.  We ran into many problems all based on the stack space limit.  The biggest problem was auto scrolling.  We initially wrote an auto scrolling function which was called in draw_note( ).  Using this function caused many random visual artifacts on the TV screen.  This problem was fixed once we just inserted auto scrolling code wherever we needed to auto scroll. 




We encountered a second instance of a stack limit problem when clearing the screen.  We have a clear_screen( ) function which draws an empty sheet music by first clearing the screen and then redrawing the staffs and G-clefs.  We found that we can call this function in initialize( ) but not in other functions since it would cause visual artifacts on the screen.  This was because the function was too slow to call when the television refresh code was running.  Cycling through the entire screen array was too expensive.  Also, calling video_line() several times in order to draw staff lines took quite a bit of time.  This is because using this routine requires a function call to video_line() which subsequently calls video_pt().  Nested function calls are very time and stack expensive. We fixed this problem by in-lining code to clear the screen and by optimizing our screen clearing code.  Optimizations included direct memory copies when possible as opposed to call to the note drawing functions.