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.
Yellow line is the key press, green is the output of the Scmitt inverter.  Notice that the yellow line doesn't go all the way to ground due to the diode in line with each key.  The green line however is rail to rail, and nice and square.
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.
Leads soldered to flex circuit.
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.
Synaptics track pad packet format
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.
Communication between the PIC and track pad
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:

Friday, November 27, 2015

MIDI Keyboard Controller, Part 1

Some time ago I acquired an old Korg DW-6000 synthesizer from a friend's dad.  This thing was at least a couple decades old, and showed it.  But it was a true synth with programmable sounds, and I was interested in playing around with it.
Image pulled from www.MatrixSynth.com
As someone who plays music regularly with various groups, it was not really worth lugging around.  It was big, rather heavy (35 lbs), and didn't have very good piano sounds.  Newer keyboards that people had were full of high quality orchestral sounds, lighter, and also had velocity sensitive keys (hitting the keys harder makes a louder note).  However, it's synthy sounds were nice, as well as could be customized.  So what to do?  Well I decided to rip the guts out and make a rack mounted synth from it.  Then I could install it with the mixer and PA, and people (including myself) could bring their nicer keyboards, and when wanting to use the DW-6000 sounds, plug into it via MIDI.  That however is another project.  For this one, I'm going to use the existing keys and make my own MIDI controller.

Most of the devices you would consider to be a keyboard or synth are actually a combo of two elements: a controller and a synthesizer.  The controller is generally the thing that allows user input (though arpeggiators, drum machines, and playback devices also count).  Most often it is in the form of a piano keyboard and includes the foot pedals and expression wheel.  But there are other forms they can take, from digital drum kits to electronic clarinets and keytars, or even my Virtual Whammy Bar.  These devices all capture the performance and create MIDI commands to send to other devices.  The synth is what you'd expect: it makes the sound.  A controller will tell it to turn notes and and off, or how much vibrato, or a variety of other pieces of info that can affect how the music will be produced.  Again, the controller and synth are often combined into a single package, but can still be used independently most of the time.  A keyboard with MIDI OUT can control another synth, and if it has MIDI IN, there is a good chance another controller manipulate it.
So really, I'm dividing the Korg into its separate functions.  Except, I can capture the performance in more ways than the original DW-6000 could.  I can add a few modern features and a couple more inputs:
  • The ability to divide the keyboard up into zones (3 or 4 max).  This means you could control more than one instrument from the same controller.  The lower octave or two could be used to control a bass and the rest of the keyboard could control strings for example.  Of course you need a receiving synth capable of performing different patches simultaneously, which is not uncommon.  A PC would do.  Or most modern synths.
  • The ability to set octaves for each zone independently.  If you were doing trumpet and clarinet at the same time, you wouldn't want to only be able to play low notes on the trumpet simply because it's using the lower part of the keyboard, nor only high notes on the clarinet because it lies on the upper portion.  The instruments tonally overlap, and by adjusting their octaves this can be achieved.
  • Transposition.  Ever learned a song in an easy key like G, but then been asked to play down half a step because the singer can't hit the high notes (I'm usually that singer, and it's usually more than half a step)?  A transposing feature allows you to adjust the note you're playing by any number of semitones so that you can keep playing it the way you learned.  It is very similar to a guitar capo.
  • Patches for different keyboard layouts.  You might have a variety of zone arrangements, each with octave, channel, or even volume settings which you would want to recall whenever you play a specific song.  A store and recall function would prevent having to redo setup work every time.
  • Additional input.  The keyboard current has a sustain pedal input, and a joystick which does pitch bend, modulation, and VCF.  I'm adding input connectors for an additional on/off function as well as one more analog input.
  • Assignable functions to all pedal and analog inputs.  Depending on the synth, there are a ton of parameters that can be varied in real-time to affect the sound.  This can help achieve more techno sounds, or control more traditional things such as sustain, damper, volume, or whether a chorus effect is on or off.
  • A character LCD and some buttons for a UI.  Users will need to be able to do tasks like load up patches, set the keyboard octave, transposition, or channel on the fly.  Maybe not everything can be done at the keyboard, but at least all the things you may need to do while jamming with others.
  • A PC program for advanced configuration.  Configuring zones and inputs is going to be a much easier process on a computer than thru the limited inputs on the keyboard itself.  MIDI can be used for dumping and editing patches.
That's more or less the things I want to do.  I have pretty much a set of plastic keys and a joystick to start with.  We'll start blocking it out next time.

Bare piano key assembly


A Completed Headphone Amplifier, Part 5

With a working amp design and a suitable power supply, I was able to make the device.  Just a bit of soldering, drilling, and hand filing (a 15/16 bit is hard to come by) I had a final product.  

Whiteboarding, with random calculations to try and explain circuit to a
non-math person (including how to ruin an LED)
Blank Canvas
Solder Side
Component Side, nearly done



It assembled nice and cleanly, and worked well.  Should get installed soon, and that's that.


Thursday, November 26, 2015

A Maybe Not That Complicated Either Headphone Amp (Part 4)

Now we're on to the power circuit.  The result is disappointingly boring, but I wanted to look at the circuit I tried first.  Let's look at how we're getting power.
The phantom power (+48V) is applied to both the "HOT" and "COLD" lines, which are what carry the audio.  Whatever we do, it needs to affect both of those lines equally.  Anything we do to one signal and not to the other will be amplified by the input of the mixer.  And we don't want the actual microphone signal either, just the DC that it's riding on.

So here's my initial layout:
After drawing this up I felt pretty proud of my somewhat involved circuit.  Here's how it breaks down: it's just a zener voltage regulator.  If we just look at R1, D2, and Q1 we see that zener regulator.  Ideally, the base of Q1 will always be 5.1V.  Subtract $V_{BE}$ and we see the emitter (and effectively VCC if we establish R15 and R16 as small) as 4.5V.  Q1 will draw as much current as needed to maintain that emitter voltage.  So when that kick drum hits, it'll turn on more to keep Vcc from sagging.  Now I said before we have to affect both audio lines equally.  Well, we can just add R2 and Q2 as a current mirror.  With the bases tied together, and R1=R2, both transistors should pull half the required current needed to power the amplifier.
In reality though, Q1 and Q2 will always vary slightly, and you need ballast resistors (R15 & R16) to balance them out.  Their gains and actual $V_{BE}$ values will differ, and you can get thermal runaway.  This is a phenomenon where if one transistor pulls a bit more current than the other, it will get warmer and start conducting even more of the shared load ($V_{BE}$ will decrease as temperature increases).  The ballast resistors try to counteract that.  As one of the transistors conductors more current, the resistor tied to it will have a greater voltage drop (simple V=I*R).  This prevents thermal runaway from... well running away.
The last little bit, being R3, R4, and D1 are soley there because I only had 2N3904's on hand.  The max $V_{CE}$ of these transistors is spec'd at 40V.  If the amp is drawing little or almost no current, then Q1 and Q2 will seem like large resistances, dropping the majority of the phantom P\power across them.  Worst case being $V_{Phantom}-V_{Vcc}=V_{CE}$ or $48V - 4.5V = 43.5V$.  Normally, as the amplifier draws power, the "HOT" and "COLD" line DC voltages will be pulled lower because the 6.8K$\Omega$ resistors in the mixer drop some of the voltage.  So as the voltages on those lines start to get close to 40V, D1 starts to conduct, keeping them around 38V max.  Even though D1 is rated at 27V, any current it draws will drop a voltage over R3 and R4, which are large enough not to load down the audio, but small enough to let D1 operate.

CMRR, What CMRR?

So how did this design fare?  Not so awesome actually.  Unfortunately, even a few millivolts difference across Q1 and Q2 shows up in the mixer.  While playing music through the amplifier, you could actually hear the songs thru the mic input.  It was lower than the microphone level, but still audible, and distorted to boot.  R15 and R16 can only get so big before they start causing problems, and they couldn't get big enough.  So I ended up going to a simpler, proven design:


Many less parts, and in the end, it does work.  It draws a more or less constant current, either thru the zener diode or the load.  Even so,  there is still enough juice for a powered microphone.  After much testing, there was no observable bleed from the amplifier into the mic signal.  Nor was there bleed of the mic into the amp, if R1 and R2 are equal, any audio cancels itself out at the Vcc node (which is the intent of phantom power).  Not nearly as interesting as my first circuit, but still the best solution.  We can wrap this project up in the next post.

Monday, November 23, 2015

A Not So Simple Headphone Amp Part 3

I realized that it may be helpful to give a basic layout of what is trying to be accomplished before moving on.
Conceptually this is very simple.  The important parts of the project are coming up with a solution that is clean for frequent use.  By removing the power supply from the amplifier, there will be less wires and parts involved, and it's operation becomes dictated by the mixer, which is ideal.  Also, the amp as well as mic and headphone connectors will apart be part of a single unit that mounts in an electrical gang box of the wall in the office where it will be used.  Let's get back to the design.

No More Op Amp
I previously said that the op amp didn't work well under phantom power.  There were issues that I might investigate later, but occasionally the supply voltage would dip, and the op amp would straight up shut off, resulting in some choppy sound.  My final design is really quite un-unique.  I actually saw it while looking into crossover distortion on Wikipedia.  When I did see it, I realized there was no reason to reinvent the wheel, just modify it to my needs.

Quite a bit different looking that the previous layout.  But nothing here that hasn't been around since the beginning of electronics.

Some of you may notice that the output is still very similar to the previous design.  However, instead of driving the point between diodes D3 & D4 we're driving transistor Q3 which is in a common emitter configuration.  This will accomplish the same thing in the end, be we get the advantage of Q3's gain to help keep the front end from being loaded down.

Others of you may have noticed that the "front end" is the basic "long tailed pair" (R6, R7, R12, Q5 and Q6).  It's a building block of your garden variety op amp.  Fancier versions replace the resistors with current mirrors and constant current sources, but that is not necessary for what we're doing.  The base of Q5 is our non-inverting input and the base of Q6 is the inverting input.  Incoming audio still goes thru a similar DC biasing scheme as the previous design.  The feedback (for those familiar with simple op amp circuits) is done the same way as an op amp.  The output of the amplifier is fed to Q6 thru R9, allowing our input to track the output.  The gain is given by $A_V = 1+\frac{R9}{R8||R13}=4$.  If you do a little more math you find gain in dB to be $20*log{\frac{4}{1}}\approx12dB$.  Put that on top of 18dB lost by plugging directly into the mixer and we're ahead 30dB.  Not a ton, but it doesn't need to be.

C4 might seem kind of random.  While listening to music thru the amp I was noticing distortion at lower volumes.  Almost like crossover distortion, which we already solved.  Except now, it would go away if the volume was turned down further (with crossover distortion, the audio would be distorted all the way down to zero).
This should be a nice sin wave....
Looking at the scope there appears to be some high frequency ringing oscillations.  The fix?  Capacitance.  Rather than analyze the circuit, I just used my finger as a test capacitor.  This only works for low voltage circuits, by the way.  By touching the various circuit nodes I could listen to any changes to find the problem.  And C4 came into being.  I could have done it to ground as well, but Vcc was easier to solder to as I already had everything built up.  When it comes to AC signals, DC sources act as AC grounds.... something about ideal DC sources having zero internal impedance.... and superposition of voltages... and I don't want to get into it.  But it does make sense that the problem is related to the feedback.  Anytime you have an amplifier, there is a potential for instability.

All said and done, this new circuit is essentially the same as the previous one.  Our "op amp" is just much simpler and it's operation more in our control (and it will work under 2.7V).  We still need power though.....

Monday, November 16, 2015

A Not So Simple Headphone Amplifier (Part 2)

So I had previously started to lay out a bit of background information in order to begin designing a simple amplifier for a pair of headphones.  Well.... the requirements changed a little.  Now I'm going to power it via Phantom Power.  Most, if not all of the things I brought up in the previous article still apply; but now there's a small catch.  Here's the story:

Someone needs to be able to sit in a room listening to a live speaker in an auditorium and translate for an audio feed for non-native listeners.  The translator person will need both a microphone and a way to listen to the speaker.  And if they have a mic, they can have Phantom Power.  Now it is not typically good practice to use that mixer power for anything other than the mic it's connected to, but I'll make an exception for myself.  I have a good understanding of their scenario, existing sound equipment, and their procedures.  So the trick here is going to be making an amp that has some a small amount of gain, can pump of few mW of power into some headphones, and pulls its power from a mic signal without affecting that mic signal.

Why an Amplifier?

Back to the main problem at hand.  Why do this at all?  Why not plug headphones into whatever aux out and go with it?

If it's an unbalanced output, the first thing you'll notice is you only get one ear's worth of sound.  But ignoring that you'll also find that the volume is rather lacking.  If you recall, we looked at the output impedance of the mixer as well as the impedance of the headphones last time.  I'm showing the basic circuit above.  Calculating voltages we can see that for a 100mV of audio signal, only 21mV is dropped across the headphones ($V_{HEADPHONE}=\frac{R_{HEADPHONE}}{R_{HEADPHONE}+R_{MIXER}}*V_{MIXER}$).  That's a 13.5dB loss ($20*log{\frac{V_{HEADPHONES}}{V_{MIXER}}}$).  If you do manage to parallel each ear of the phones, we're looking at another 5dB down from there as the load will total $16\Omega$ instead of $32\Omega$.

While you will be able to hear the audio, it may only be "loud enough" when the mixer output is really dialed up.  For a number of reasons, the mixed audio will never be near the top of the mixer's abilities.  We're gonna want the ability to add extra volume.

Initial Design

Originally I was going to power the amplifier with a typical wall wort.  This would have provided "unlimited" power for the application and made life easy.  And as such, I was simply going to use the good ol' op amp.

Not a ton of parts really.  You may notice that this layout has no gain, and that was because I thought that just dealing with the impedance mismatch would be good enough at first.  Let's look at the individual sections: the input, amplification, and output driver.

Input

This part includes everything left of the op amp.  Those diodes are provide some input protection.  For both the listener and the op amp(I don't necessarily know that the op amp needs any protection, but it's still best to keep the signal within the rails).  Any input swing above or below 0.7V of ground gets trimmed off.  The potentiometer should be obvious, it's the volume control.  Rather than alter the gain or output, it's more advantageous to affect this input.  If the signal is clipping, the input is the only place to fix that.  R3 I only had to add to protect the mixer output.  If the signal is clipping quite a bit, and the pot is turned all the way up, there isn't much to limit current thru the D3 and D4.

R2, R7, and C2 form a DC bias for the incoming audio.  This is point I've always been a little bitter about.  In no point during my college career were we shown any single supply op amp circuits.  Never.  And since college, I've never used an op amp with dual supplies.  The differences are minimal and not complicated, but only in retrospect.  I just wish they would have pointed us in the right direction.....

But anyhow, the bias circuit.  C2 allows the audio signal, which is AC, thru, while blocking our DC from feeding into the mixer output.  R2 & R7 set the bias at half our supply voltage to allow for the most voltage swing.

Amplification

Very little to say here.  Just the op amp really(a Microchip MCP601).  The feedback comes from the audio output, so the op amp will try to make that voltage match the input voltage, giving us a gain of one.  So why use it?  Well, it has very high input impedance.  The only other input impedance comes from R2, R7, and the potentiometer, which are all large compared to the output of the mixer.  Most of the signal will be seen at the op amp input.  Since it will adjust it's output from the voltage seen over the headphones, it's like there is little or no output impedance.  This gives us direct control over the voltage over the headphones.

Output Driver

I first drove the headphones directly from the op amp.  For reasons I haven't fully sussed out, it didn't quite have enough oomph (likely the headphones were too low an impedance).  So I added Q1, Q2, and all the related components which comprise push-pull driver.  Q1 pushes the top half of the signal and Q2 pulls the lower half of the signal.  Because these transistors are tied directly to the power rails, they can supply a lot of current and achieve a wide voltage swing.  R4 & R6 are small enough to not limit the desired output voltage range, but large enough to safely limit the current thru the transistors if the output is shorted directly to ground.

I had to add diodes D1 & D2 because I noticed there was some distortion on the output, especially at lower volumes.  As it was most noticeable at low audio levels, i.e. near the zero crossing of the signal, I was able to recall back to a college lecture and pluck out the phrase "crossover distortion".  We typically say that a bipolar junction transistor turns on when $V_{BE}$ is greater than 0.6V or 0.7V.  In reality they do turn on a little bit before that, but the operation in that area is very non-linear.  In any case, around what we could consider the middle of the signal (where it would cross zero), the transistors don't quite turn on creating distortion.  The diodes pre-bias the transistors by that 0.6-ish volts we need to turn them on.  With the op amp trying to track the output, it'll adjust for that bias and smooth things out.
An exaggerated example of crossover distortion
Although this circuit worked plenty well with an ample power supply, it struggled when using the phantom power.  I'll show how it was done in the next post.