Tuesday, August 2, 2016
MIDI Keyboard Controller, Part 4
So, I was supposed to be continuing on with the MIDI keyboard, but I've had to press the big red button. Turns out I want this to be a USB keyboard now (still MIDI, but plug right into the PC). So that means a new microcontroller, somewhat new layout, using USB power, and a bunch of firmware redesign. I'm going to do a PCB spin this time around to hopefully speed up prototyping. Now its the USB-MIDI Keyboard Controller!
Monday, August 1, 2016
The Disalarmer! (Part 2)
I'm just going to dive right in. Be sure to have read Part 1, and maybe even have it open for reference. So continuing the discussion where we left off, I mentioned there is a potential issue of feeding 5V into the 3,3V power rail.
Now normally this wouldn't be a huge deal. Perhaps isn't even in this case. When one of the buttons is pushed, current flows into the 1K resistor, thru ESD1 and into the 3.3V power rail. So you'd expect that current (without D1 or R2) to to be something like: $\frac{V_{B+}-V_{ESD1}-V_{CC}}{1K} = \frac{5V-.3V-3.3V}{1K} = 1.4mA$. Not a lot, right? But that 3.3V supply isn't magic. Let's take a look at the output of our regulator:
It only lets current into the circuit, it doesn't let any out. Those two resistors between the output and ground measure out to about $125K\Omega$. Without D1 & R2, I was finding the 3.3V rail would rise above 4V whenever a button was pressed. The only current paths were back into the regulator and whatever draw the microcontroller had.
So by adding a 3.3V zener and a small resistor (so it wouldn't really turn on in normal operation), I'm able to keep the voltage from rising too much. Interestingly though, the fact that the voltage was above the "safe" operating voltage may not have been too dangerous for the MCU. The 1K resistor between the button and the input limits any current into the circuit to 5mA, and that's if the microcontroller tried to short anything to ground.
Also, there was probably an easier solution had I not already soldered things and had better tools to undo my work: just use diodes on the outputs instead of resistors (I was expecting active low, not high). They'd block the 5V from feeding into the 3.3V circuit and ultimately reduce idle current (the zener draws a couple mA all the time, so sleeping the micro doesn't even buy much). The only drawback might be the diode drop means you're only supply 2.6V to the input of the clock's processor, which is expecting 5V, and I don't know the logic type of those inputs.
But anyhow, that's not a super exciting discussion. It is however, all that's needed for this project to work. There's a little bit of firmware involved:
It only lets current into the circuit, it doesn't let any out. Those two resistors between the output and ground measure out to about $125K\Omega$. Without D1 & R2, I was finding the 3.3V rail would rise above 4V whenever a button was pressed. The only current paths were back into the regulator and whatever draw the microcontroller had.
![]() |
| The circuit without D1 & R2 |
Also, there was probably an easier solution had I not already soldered things and had better tools to undo my work: just use diodes on the outputs instead of resistors (I was expecting active low, not high). They'd block the 5V from feeding into the 3.3V circuit and ultimately reduce idle current (the zener draws a couple mA all the time, so sleeping the micro doesn't even buy much). The only drawback might be the diode drop means you're only supply 2.6V to the input of the clock's processor, which is expecting 5V, and I don't know the logic type of those inputs.
But anyhow, that's not a super exciting discussion. It is however, all that's needed for this project to work. There's a little bit of firmware involved:
- It has to monitor the UART for a "snooze\r\n" or a "off\r\n" from the bluetooth module and act accordingly. Throw away all other messages.
- It has a timer set for about 9 minutes (the sleep time of the clock is 8 minutes). This allows disabling the alarm between snoozes. Whenever the buzzer goes, the timer is reset.
- After the timer is up, turn off the bluetooth and go to sleep.
That's almost the last thing. We need a phone app. While I've used the various incarnations of the Android studio or SDK's in the past, I actually did this one in Visual Studio. Nothing too fancy. A giant "snooze" button that's easy to hit. A smaller "off" button that requires a long press to activate, and a sort of "reset" button. The app stores the address of a paired bluetooth device so there is no need to fumble thru choices everytime you launch it. It recalls the stored device and opens a socket, no questions asked. Should the need to use a new paired address arise, then the "reset" button just clears it, and the app will then ask.
At this time, I've had this working in the alarm clock for a few months now, pretty much trouble free. Not the most important project I've ever done, or necessary, or all that worthwhile, but still a lot of fun. It was a small and compact project that spanned embedded to Android. Here's a little clip of it in action:
(the app loads slow because.... well I was filming, so something had to not work normally. The blinking on the alarm clock shows that the alarm is still active, after long pressing the "off" button, the blinking stops as the alarm is disabled)
Sunday, June 5, 2016
The Disalarmer! (Part 1)
Occasionally you get an idea that is way too much work and complication to justify going thru with it. This is one such idea, but a good learning experience. It should also lead to another, hopefully more worthwhile project.
I have an old Sony alarm clock from maybe junior high that I still use to this day as it has a nice loud and obnoxious alarm that is guaranteed to wake you up. But it has a drawback... it's loud and obnoxious. Due to it having a combo CD-player it actually has a decent pair of speakers and a some amplification. So, what is there to fix?
Well truly, not that often. Again, this idea is not worth the effort. I'm typically the person who hits the snooze a few times in the morning. On occasion, I'll get up with the intent to start my day, but ultimately end up on the couch.... And then the alarm goes off from the bedroom. What to do?
Let's Bluetooth the alarm clock.
I have an old Sony alarm clock from maybe junior high that I still use to this day as it has a nice loud and obnoxious alarm that is guaranteed to wake you up. But it has a drawback... it's loud and obnoxious. Due to it having a combo CD-player it actually has a decent pair of speakers and a some amplification. So, what is there to fix?
Well truly, not that often. Again, this idea is not worth the effort. I'm typically the person who hits the snooze a few times in the morning. On occasion, I'll get up with the intent to start my day, but ultimately end up on the couch.... And then the alarm goes off from the bedroom. What to do?
Let's Bluetooth the alarm clock.
The Plan
First we should define our main objectives:- Emulate the "snooze" button
- Emulate the "off" button
- The circuit should sleep while the alarm is not going off
- The Bluetooth module should be easily removable, so that I can use it for other projects if I need it.
Like most things we'll probably need a microcontroller (I've chosen the PIC12F1572). Nothing fancy, just a few I/O. We're gonna want to tie into the physical buttons, and mimic a button press.We're also gonna want to listen to some signal indicating that the alarm is currently sounding.
The button inputs to the processor for the alarm clock are pulled low thru 100K resistors to the ground. Pushing the button puts 5V across the 10K and 100K voltage divider (essentially 5V goes to the clock input).
Connection to the Clock
So where to start? Well, fortunately, there is a service manual, complete with schematics and drawings. Shown below is how the circuitry for the buttons on the alarm clock.The button inputs to the processor for the alarm clock are pulled low thru 100K resistors to the ground. Pushing the button puts 5V across the 10K and 100K voltage divider (essentially 5V goes to the clock input).
$V_{IN} = V_{cc}\frac{R445}{R445+R456}=5V\frac{100K}{100K+10K}=4.55V$
The capacitor is just there for debouncing, it smooths out the transition from low to high and back down as the mechanical button is pushed. We can more or less ignore it for our intuitive analysis.
Controlling the input ourselves is as simple as emulating the button. Just make one of our microcontroller lines drive high.
A 1K resistor is added just to protect the output driver of the MCU. I actually should have done something different... but we'll get into that a little later.
The buzzer signal is also going to be an easy tie-in (although tough to solder to such a small area). I hooked it up to the scope to get a look at it, a series of 5V pulses at the frequency of the alarm. Perfect for triggering an interrupt on change pin. Instead of a 1K resistor like the buttons, I threw in a 10K. Shown below is the buzzer portion of the clock schematic, where I soldered in after R428. And that is all our signal connetions. 5V was picked up near the buttons above, and ground was everywhere.
![]() |
| Buzzer 5V square pulses |
![]() |
| Buzzer has five quick beeps followed by a long pause. |
Other bits
We still need to incorporate a Bluetooth serial module. The particular module I have is some kind of BC04 variant (same pinouts). All it really needs is power and serial connections. That's it. And in our case we only need to receive data from the Bluetooth module. On power up it goes right into pairing, and defaults to 9600 baud. You can literally just connect with your phone and start sending serial data. However, it does run off of 3.3V, and is the most power hungry part of the Disalarmer. We'll need a voltage regulator, and some way of switching power to it.
Before I show the finished circuit, I just wanted to bring up a minor hiccup. The microcontroller I had turns out to be a PIC12LF1572; that 'L' indicating low voltage. Not a huge deal as we already need a 3.3V regulator. But the 5V clock signals present a little bit of a challenge. But first, the schematic.
Switching the Bluetooth module on and off is as simple as a PNP transistor. Pull the base to ground and you've got power. Outputs to the buttons are just thru series resistors R4 & R7. Drive high to "push" the snooze or off buttons, and tri-state them otherwise.
You may also have noticed D1 and R2. These are my mediocre solution to the 5V input problem. But this is enough for now. We'll look at interfacing the 3.3V and 5V circuits in the next post.
You may also have noticed D1 and R2. These are my mediocre solution to the 5V input problem. But this is enough for now. We'll look at interfacing the 3.3V and 5V circuits in the next post.
Friday, December 11, 2015
Midi Keyboard Controller, More I/O - Part 3
So last time we went over how to read all 61 piano keys into a 28 pin micro, but we still have a few more I/O signals to worry about:
In a later post I will show the circuit in its entirety for the sake of putting all the pieces together. For instance, I'm excluding the debounce components for the footswitches as well as the specific circuitry for the MIDI interface (which I've already discussed in the Virtual Whammy Bar project). Really what we're concerned about right now is allocating the microcontroller I/O.
Now what about those three "system" buttons? We actually already have what we need for these. Going back to the piano keys we have eight banks, each capable of reading eight inputs. But we only have 61 physical keys. The last bank only reads in five, meaning we have room for another three. By using the same diode configuration the keyboard does, we can add the system buttons to the last bank. It will require the firmware to differentiate them, but that's not a problem. No more I/O's used. We have the eleven pins used for the keyboard and the six we just figured out above for a total of 17. There are only the analog inputs left.
The literature for the PIC16F916 says that it has 8 ADC channels. However, it really only has one actual ADC. They just allow you the option of hooking eight analog sources directly to the chip if desired, and can perform one conversion at a time. Although we only need four, and I kinda have the pins available to do so, I'm gonna multiplex again (also, it's already soldered in place). I may in the future decide to add more features to the keyboard, don't want to eat up all the I/O.
Using a 74HC4051, we can actually borrow from Bank Select circuit. The 4051 will give us eight possible analog inputs, for which we already have three signals set aside to select with. Granted, this will go thru X4 to X7, but these we can simply ignore in software. We have the potential of adding four more analog inputs with very little work.
The remaining I/O actually turned out to be rather painless. Everything is accounted for, and there is still a little room for future need.
- 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
In a later post I will show the circuit in its entirety for the sake of putting all the pieces together. For instance, I'm excluding the debounce components for the footswitches as well as the specific circuitry for the MIDI interface (which I've already discussed in the Virtual Whammy Bar project). Really what we're concerned about right now is allocating the microcontroller I/O.
Now what about those three "system" buttons? We actually already have what we need for these. Going back to the piano keys we have eight banks, each capable of reading eight inputs. But we only have 61 physical keys. The last bank only reads in five, meaning we have room for another three. By using the same diode configuration the keyboard does, we can add the system buttons to the last bank. It will require the firmware to differentiate them, but that's not a problem. No more I/O's used. We have the eleven pins used for the keyboard and the six we just figured out above for a total of 17. There are only the analog inputs left.
The literature for the PIC16F916 says that it has 8 ADC channels. However, it really only has one actual ADC. They just allow you the option of hooking eight analog sources directly to the chip if desired, and can perform one conversion at a time. Although we only need four, and I kinda have the pins available to do so, I'm gonna multiplex again (also, it's already soldered in place). I may in the future decide to add more features to the keyboard, don't want to eat up all the I/O.
Using a 74HC4051, we can actually borrow from Bank Select circuit. The 4051 will give us eight possible analog inputs, for which we already have three signals set aside to select with. Granted, this will go thru X4 to X7, but these we can simply ignore in software. We have the potential of adding four more analog inputs with very little work.
The remaining I/O actually turned out to be rather painless. Everything is accounted for, and there is still a little room for future need.
Monday, November 30, 2015
MIDI Keyboard Controller Part 2
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.
Virtual Whammy Bar Sidetrack (PWM Motor Driver)
While I was breadboarding the Virtual Whammy Bar I decided I could do more than just send some MIDI messages. So I grabbed a little MOSFET and a small motor, used a PWM output on the PIC16F916, and wrote a bit of code. Nothing more than just an experiment. I drew a red dot on the output pulley of the motor (not that it helps much in the video) to see the movement. It's probably easier to hear the change in speed. Also, I believe I did this before I gave the light sensor more of a log response (in code, via a lookup table), so after a certain point, the speed changes rapidly with very little movement of my hand. But this was just for the sake of doing it.
Saturday, November 28, 2015
Fun with a Track Pad
For some reason or another, I was tearing into a couple of laptops that didn't need reassembling. Or maybe they weren't worth reassembling. But either way, I ended up plucking the track pad out of one of them. I noticed that the module only connected to the rest of the computer via only a few contacts. At least have to be power and ground, meaning it's likely a serial interface. After a little bit of research on the Synaptics chip at the heart of things, turns out it's PS/2.
I had always assumed that PS/2 was more or less obsolesced, only continuing to be supported because so much consumer hardware is out there, and for industrial settings. If I had to guess, a track pad would have been internally tied into USB. In any case, it's a serial protocol, I can probably talk to it from a microcontroller.
PS/2 is a bit odd, almost like I2C in reverse. I never actually found a definitive resource on the protocol, just gleaned a few things from various websites and from the Synaptics literature. There is a data and a clock line, which require pull-ups, but the device controls the clock. The host must create a start condition to get the device to begin clocking, and have the data available on rising edges. Unfortunately, I couldn't see a way to use the peripherals of a PIC16F916 to emulate the protocol, so I had to bit bang it in software. The micro didn't have to do much else though, as I just wanted to output MIDI (I know it seems like all I do, but it's just a fast way to make a device talk to other existing devices and accomplish something).
I definitely learned a lot going thru the Synaptics implementation guide. For instance, the pad has both a relative and absolute mode, as well as a polling mode. It was much easier to use absolute positioning, and since I was emulating the protocol in software, the polling mode meant I didn't have to constantly keep track of the clock pin. I would know when to expect data. I can choose my own update rate and just grab the track pad data as needed.
Once configured, whenever my host requests data, it receives the packet above. An interesting piece of information is that "Z pressure." Maybe I can play with that. You'll see in the video later in this post where I enable Z interaction while holding down one of the buttons.
As this is merely an anecdotal post, I won't go into much detail. I wrote up a small bit of code to setup the track pad and talk to my PC over MIDI and experimented a bit. I just wanted to know I could. Perhaps I'll come up with a good use for the track pad, but until then, here's some footage of it in action:
I had always assumed that PS/2 was more or less obsolesced, only continuing to be supported because so much consumer hardware is out there, and for industrial settings. If I had to guess, a track pad would have been internally tied into USB. In any case, it's a serial protocol, I can probably talk to it from a microcontroller.
![]() |
| Leads soldered to flex circuit. |
I definitely learned a lot going thru the Synaptics implementation guide. For instance, the pad has both a relative and absolute mode, as well as a polling mode. It was much easier to use absolute positioning, and since I was emulating the protocol in software, the polling mode meant I didn't have to constantly keep track of the clock pin. I would know when to expect data. I can choose my own update rate and just grab the track pad data as needed.
![]() |
| Synaptics track pad packet format |
![]() |
| Communication between the PIC and track pad |
Subscribe to:
Posts (Atom)






















