So we're gonna make a MIDI controller, what exactly does that mean? At the very least we can say it's an embedded system, there is some digital communication. It's also going to be rather I/O intensive. Let's do a basic layout:
Even without any pretty pictures, it's already easier to grasp. I'm using the Microchip PIC16F916 as the microcontroller, which comes in a 28 pin dip package. However, between power, ground, and reset five pins are used up right off the bat, leaving us only with 23 available for I/O. How about we take a look at some more in depth requirements:- I2C Data and Clock lines for LCD display and EEPROM
- Three system buttons for UI
- RX and TX for MIDI
- Two analog inputs for both joystick axes, another for volume, and one more for an external input
- Two footswitches
- 61 Piano keys
I/O Design
By my count, that's a total of 75 total signals. Way more than we have room for. What do we do? We employ and key matrix. Rather than reading every key all the time, we look at them in groups at a time. For convenience, and because the fine people at Korg already added in diodes to make it so, we will look at them in groups of 8. That's one byte's worth per read. We'll call each group a bank, and we'll need a minimum of 8 banks for our 61 keys.I'm showing the first two banks of keys above. The keys are all connected to an 8-bit wide bus thru diodes. These diodes prevent a pressed key from an inactive bank affecting the reading of a key within an active one. To read the keys, you pull the appropriate "Bank Select" low and read the bus. A pressed key will read as a '0', and an unpressed key will read as '1'. I should point out that Key 0-Key 7 need to have pull-up resistors somewhere in the circuit.
Now that we can read the keys in, we still need to be able to select the banks individually. We could simply commit another eight I/O pins, but we could improve on that. By using a 74HCT138, we only need three. A 3-bit number has eight different possible values, exactly what we need.
If you are familiar with reading schematics, you'll notice that the outputs are inverted. This means our active line is low. Just what we want. Where we started with 61 I/O, we now have 11. Not too bad. Almost done here.
Rather than tie directly into the microcontroller, I shoved a Schmitt inverting buffer in the middle. Initially I did this with the intent of using the output enables, but that ended up not being a thing. It does invert our logic though. Pressed keys are now a '1', and unpressed are '0'. You can see the pull-up resistors I mentioned earlier, but also take note of the caps. These help in debouncing our switches. Any high frequency jitter is shunted to ground.
I soldered most of circuit together before thoroughly testing each section with the general knowledge that it would work. And for the most part it did. With the MIDI hooked up to my computer I was able to play normally and everything appeared to work great. Then, while showing it to my girlfriend, she pressed three adjacent keys simultaneously and the notes all stopped playing. This caught me by surprise as I had been able to play chords using all of my fingers with no problem up until then. But not all combinations of three adjacent notes caused this problem, and I had had the foresight to write the number of each key within its bank on each key just for debugging. Any three keys within a bank was the problem. It's surprising how rarely that happens during regular playing.
My first thought after checking all my soldering was dig into the firmware. I looked at all my code for any logic that could cause this anomaly and saw none. Then I started running with breakpoints, and sure enough, it was reading in all the notes as off if I played more than two in a bank. Time to pull out the scope. Using the oscilloscope I was able to watch the outputs from the Schmitt inverter. Curiously, as I pressed a third note, the outputs would jump low. What was going on?
The cause was subtle. If you look at the yellow line in the scope capture above, it sits about one diode drop above 0V. As you press more notes in the same bank something interesting happens: that line moves a tiny bit further away from 0V, until it triggers the Schmitt input high. How? Why?
Turns out this one was kinda my bad. All the current going thru the pressed keys is sunk into the output of the 74HCT138. That output is a semiconductor with non ideal characteristics. If you read the datasheet, as the current increases, so does the offset between the output and ground. Looking at my design (and ignoring the diode) each key is going to source about 5mA ($5V/1K\Omega$). That's actually kind of a lot for this circumstance. Three keys would be 15mA. The combination of the output error plus the diode drop was enough fake out the inverter.
So how do we solve this? Everything is already soldered in place, it would be a huge hassle to put larger resistors in place. Let's rethink the problem Our pull-ups are all in parallel, meaning that each additional key press makes matters worse as the total resistance between Vcc and the 74HCT138 output gets smaller. If all eight keys are pressed, the eight 1K resistors in parallel total 125$\Omega$. That's a huge 40mA at 5V. I don't even think it's supposed to be able to handle that much current....
We do know that two keys works just fine though. The trick is to make that our worst case scenario. The total resistance of two key presses is 500$\Omega$. If we just add a resistor in series between Vcc and the pull-ups, we can guarantee that the total resistance will never be less than 500$\Omega$, even if we could press an infinite number of keys. And this fix requires very little rework. Much harder to track down than to fix.
We'll continue the design in the next post. I've added a clip above of me testing the software and hardware for your enjoyment.

































