Wednesday, March 30, 2016

DIY MIDI Ribbon Controller

In a previous age of the world (2011), I built myself a ribbon controller.  I used it to drive my Korg Mono/Poly via CV.  And it was good.  But, that was before "synthhacker" first awoke under the stars on the shores of Cuivienen.  Has its glory been forever lost?  No!  The ribbon lives again!  And it has been updated!  Behold:


The Overall Setup:  This ribbon is just a controller -- it controls a synthesizer.  It doesn't make noise itself.  Those black-and-white keys that are built into the synthesizer are also just a controller.  They tell the brain of the synth to make noise at fixed pitches.  My ribbon controller uses the synth's MIDI interface to tell the synth to make noise across a continuous spectrum of pitches.  More bendy.  More swoopy.  Fun!  My controller has two parts: the ribbon itself, and some electronics (Arduino +  MIDI Shield) to do the ribbon-to-MIDI conversion.



The Ribbon Parts:  The ribbon itself, I built a long time ago.  But, as stores on the internet never forget what you've ordered, I easily went back and looked it up.  The core of the ribbon controller is a 500mm-long "soft pot" (Sparkfun).  This is the part that senses where you touch.  Since it is soft and floppy, however, I also bought a 2-ft long strip of plastic (McMaster) to act as a backbone.  For the electrical connection to the ribbon, I used a headphone jack (Sparkfun) and a small perfboard (Sparkfun).  The only real innovation with my ribbon controller (there are lots of DIY ribbons out there) is that I also added a magnetic strip along its back (McMaster).  Since most of my synths  have a metal front panel, the magnetic strip is a great way of keeping the ribbon in place!

Components of the Ribbon Controller

The soft pot is on the top.  The magnetic strip (partly unrolled) is in my hand.

Assembling the Ribbon:  I started with the plastic strip.  Its edges were surprisingly shart, so I got out some sandpaper to smooth the edges.  Now it's much nicer to touch.  After cleaning off the sandy bits, I spray-painted the whole thing black.  When fully dry, I attached the magnetic strip and the soft pot, both via their adhesive backing.  Then, I carefully soldered the ribbon's terminals (don't melt the soft pot!) to the perfboard and then to the audio connector.  I wired the connector so that the "top" of the pot was to the tip, "bottom" of the pot was to the sleeve, and the "wiper" of the pot was to the ring.  Once it was all soldered together, I epoxied the perfboard to the plastic strip to make it all nice and solid.

Headphone jack is connected to the perfboard, which is connected to the soft pot.  The whole thing is epoxied to the plastic strip, for strength.

Arduino-MIDI Electronics:  The ribbon is just a potentiometer -- it needs electronics to interface to a MIDI synth.  After my previous project making an MIDI-to-trigger converter, I realized that I could re-use that exact same hardware for this ribbon-to-MIDI converter.  Repeating the recipe list from that project, my parts include an Arduino Uno, a MIDI Shield* from Sparkfun, some stackable headers, and a 3.5 mm stereo headphone jack (or maybe one like this).

(* Note: I used the old Sparkfun MIDI Shield but, presumably, the new model linked above works well, too).

Components for the "Brain" of the Ribbon Controller

Assembling the Electronics:  I soldered together the MIDI shield, including soldering on the stackable headers.  I then soldered some wires to the audio jack and soldered those wires (being sneaky) to the header pins sticking down from the MIDI shield (detailed soldering pics here).  Once it was all assembled, I connected the ribbon to the MIDI shield using a standard 3.5 mm audio cable.  I also connected a USB cable to my laptop so that I could power it and program it.  The photo below also shows the MIDI cable connected, but we're not quite ready for that, yet.

Connecting my ribbon controller to the MIDI Shield (the Arduino is under the MIDI shield).

The Ribbon is a Potentiometer:  Touching the ribbon (the "soft pot") is like turning the knob on a potentiometer to a particular spot.  If I touch it near the low end, it'll show a low resistance.  If I touch it near the high end, it'll have a high resistance.  The job of the Arduino, therefore, is to sense the resistance of the ribbon so that it knows what note to play.  In theory, pretty easy.  But, to get some details on how this works, I hooked used my setup to collect some actual data.

The Ribbon's Response via Arduino:  To measure the response of the ribbon with an Arduino, I used the setup described above, which has the wiper of the pot connected to one of the Arduino's analog input pins (A3).  The bottom of the pot is tied to ground.  I activated the input pin's pullup resistor (via pinMode(A3, INPUT_PULLUP)) and started reading ribbon values via AnalogRead(A3).  I printed the values to the serial port so that I could see them on the P and log them to a file.  Sliding my finger to different octave points on the ribbon, I made the plot below,

The AnalogRead() Values Generated by the Arduino when Touching the Ribbon at Different Spots.

Values When Not Touching the Ribbon:  The first thing to notice is what happens when *not* touching the ribbon: the ribbon shows a very high value.  The high value results from the fact that the wiper is floating when you're not touching the ribbon.  As a result, the pull-up resistor on the analog input pin is able to pull the value all the way to the maximum value (which is 1023 on the Arduino Uno).  So, it's easy to know when you're touching the ribbon versus non touching the ribbon -- just look to see if the value is near 1023.

Values When Touching the Ribbon:  The middle of the graph shows the values when I touch the ribbon between its bottom (C1) and its top (C4), Looking at the detailed values, the lowest value seen in my ribbon (C1) is about 12 whereas the highest value (C4) is about 339.  So, I know that I have to program the Arduino to map values between 13-339 to musical notes between C1-C4.

Touching the Ribbon To Record the Arduino's AnalogRead() Value at Different Locations.

Software:  After seeing how the ribbon responds, I wrote my Arduino software.  It's basically a big loop that reads the ribbon value, converts it to a MIDI note number, and sends those MIDI commands to my synth.  While it seems conceptually simple to do an AnalogRead() for the ribbon followed by a Serial.write() to send the corresponding MIDI message, it does actually take some thought to get it to respond the way that you'd like.  Also, to make the ribbon pitches change continuously (and not be quantized like with the piano keys), you need to compute and transmit all the pitch bend commands.  It takes some work to get it right.  If you're interested, my Arduino code is available on my GitHub here.

Linearizing the Response:  One tricky spot is if you want the pitch to track linearly with your finger position on the ribbon.  In my case, I found that the notes were too closely-spaced at the top of the ribbon and too widely-spaced at the bottom.  I didn't like that.  The key to linearizing the response is to recognize that the ribbon and the Arduino's pull-up resistor actually form a voltage divider.  Once you do the math on that voltage divider, you program the Arduino to better deduce the note you want given the apparent voltage at the soft pot's wiper.  It's not perfect, but it's much better than before.

I was lucky at how well the ribbon fits on the face of the synth.  I took the extra effort to make the software fit well, too.
Bend Range:  The ribbon is fun because you can use your finger to sweep through all the pitches in between the normal notes.  Since the MIDI messages assume a piano-like keyboard, you do these "in between" pitches by commanding a note to one of the standard pitches followed by commanding a pitch bend to get the in-between pitch that you actually want.  Ideally, you could set the synth so that its allowable amount of bend would span the whole ribbon.  Unfortunately, on the Prophet 6, the max bend amount is +/- 1 octave.  As a result, with my setup, I get a brief note discontinuity when I try to continuously slide across more than 1 octave.  This is a limitation of the synth, not my ribbon controller. (If the synth's software were open source, I could fix that!)

Wobbling Pitch (ie, Pitch "Noise"):  Another subtlety that I uncovered is related to the fact that one's ear is very sensitive to changes in pitch.  The issue is that any noise in the measurement of the ribbon value will directly translate into wobble (instability) in the pitch commands sent to the synth.  When I was powering my system from the laptop and when the laptop was running on battery, my system sounded great.  But, when I plugged the computer into AC power, the pitch wobbled a lot.  It was quite unpleasant.  My solution was to add a 33 nF capacitor between the ribbon's analog input pin and ground and to add some filtering in software (revised code is here).

Future Work:  It's pretty fun to have my ribbon controller working with my MIDI synth.  Sure, I don't like that there is still a note discontinuity that happens when I try to exceed the 12-step max bend allowed by the Prophet 6, but it's still quite fun.  (Maybe I can sweet talk someone at Dave Smith Instruments to help me out on that one remaining issue :).  Looking for other ways to improve the ribbon, I'm considering adding a DAC so that the the Arduino (or Teensy!) can directly create its own audio without needing to command an external synthesizer.  That'd be fun.  How about a ribbon wavetable synth!  Or, how about a ribbon FM synth?  Fun!

Follow-Up:  I also made a version of this ribbon that outputs CV signals.  Now it can drive my old pre-MIDI synths like my Korg Mono/Poly.  Check it out here!

Saturday, February 27, 2016

Replacing Key Contacts on Korg Mono/Poly

When I first got my Korg Mono/Poly off eBay, quite a few of the keys didn't play.  After some searching around, I tried some CaiKote on the rubber key contacts (as I described here) and it worked great.  When I bought a Korg Polysix off eBay, it had the same problem...and CaiKote saved the day again.  But, now that it's been a few years, some of the keys on the Mono/Poly have stopped working again.  Let's fix this problem for-real.  Let's replace the key contacts!

New Key Contacts from LA Synth Co

When I first had my problem with dead keys, I couldn't find anyone who sold new key contacts for these old synths.  So, I had to use the CaiKote to restore the old ones.  That was pretty cheap and pretty easy.  I now know, however, that it's a fix that only lasts a few years.  In that time, LA Synth Co has started to sell brand new key contacts that fit a bunch of old synths from that era.  Fantastic!  So, $100 later, I've got a complete set to fit my Mono/Poly.  Let's take the old girl apart and swap in these new parts!

First, remove the five screws on the bottom of the synth to release the keybed.  Then, remove the screws holding on the metal panel so that you can get inside.  Finally, unplug the keybed from the Mono/Poly circuitry

Getting started is pretty easy.  As shown above, I unscrewed the keybed and the main front panel.  Then, I opened up the synth and disconnected the keybed from the circuitry.  At that point, I was able to pull out the keybed.

The keybed has been removed from the Mono/Poly.

With the keybed out of the synth, you can look at the side of the keybed and see how, when pressing a key, the key smashes down a gray rubber button (the "key contact") onto the circuit board underneath.  It is through this contact that the brains of the synth know that the human has pressed a key.

You can see how pressing a key acts to press down the gray rubber key contact.

On the underside of the keybed, you can see the brown circuit board.  The key contacts are attached to this board.  We need to remove this board to get access to the key contacts.

The underside of the keybed has a brown circuit board.  Remove the screws to release the board.

Removing the screws, the brown circuit board is easily removed.  Flipping it over, you can see all of the gray rubber key contacts.  They come off simply by tugging on them.

Removing the circuit board, the gray key contacts are revealed.

Pulling on the gray rubber strips, the key contacts are easily removed.

With the old key contact strips removed, now was a good opportunity to get out a little alcohol and clean the contacts on the circuit board.  I probably should have used higher quality alcohol (only 70%?), or something better than a cotton rag for my scrubber, but this is what I had.

Time to clean the circuit board.

With the board cleaned, I got out the new key contacts and lined them up to make sure that I had the correct assortment -- they're not all the same and I was worried that I might not have been sent the right ones.  Luckily, LA Synth Co know what they are doing.  I had what I needed.  They lined up great and I attached them simply by pushing them on.

Getting ready to attach the new key contacts
The new key contacts are attached simply by pushing them on.

With the key contacts attached, I start putting the synth back together again.  First, I have to re-attach the key contact circuit board to the bottom of the keybed.  The only trick is getting the key contacts to fit inside their respective holes in the bottom of the keybed.  It isn't hard, but you do have to pay attention.

These are the holes on the bottom of the keybed into which the key contacts must fit. 

After getting the board onto the keybed and screwed together, I did a visual inspection and saw that one key contact wasn't seated correctly (as shown below).  So, I unscrewed the board and was more careful in putting them together.  The second time, all the key contacts were seated nicely.

Here, after assembly, one of the key contacts didn't seat correctly.  I simply took it apart and was more careful when I put it together again.

That's it!  The key contacts are done!  The only thing left to do is to put the synth back together again.  I have to put the keybed back in, screw it in, and screw the front panel back down.

Time to put everything back together again!

Fully re-assembled, I also to this as an opportunity to clean the keys and the front surface.  Looks great!

The re-assembly went easily.  I also used my rag and alcohol to clean the tops of the keys and the control panel.  She looks great now!

Plugging her in, they keys all work.  The joy!  Not only is it a joy to play an instrument that works, it's a real satisfaction to have fixed it myself.  Fixes don't really come any easier than this one.  Thanks LA Synth Co!

Friday, January 1, 2016

PCB For Polysix OTA Overdrive

Before today, I had made exactly one PCB.  It was a very simple design, yet it was still a painful experience.  I am not an expert -- that's for sure.  Yet, here I'm going to give it another go.  I'm going to dive in and design myself a custom circuit board.  This PCB is going to host my OTA Overdrive Mod for my Korg Polysix.  It'll contain an Arduino-controlled digipot, including my own Arduino as part of the same PCB.  Given my inexperience, this is pretty bold stuff.  I'm nervous and I'm excited.  Can I make it work?

Here's the PCB design that I made using Fritzing.  It's only a two layer board, but it looks awfully complicated for a newbie such as myself.  Does it have any chance of working?

Laying the Groundwork:  Over the last several posts, I've been figuring out most of the elements of this modification, including the digipot and the Arduino.  I know that I want to put all of those elements onto one board and fit it inside my Polysix.  My biggest remaining unknown is how to physically attach my components to the Polysix's circuitry.

Use One of the Built-In DIP Sockets:  A good trick is to re-use one of the DIP sockets that a used throughout the Polysix circuitry.  This is the same trick that I used when installing my mod to add velocity sensitivity to my Polysix.  For this OTA Overdrive Mod, I'm going to use the DIP socket that the OTA itself lives in (ie, IC20 on the KLM-368 "Effects" PCB).

DIP Socket and DIP Connector:  As shown in the picture below, I'm going to pull IC20 out of its DIP socket and I'm going to insert a pinned DIP-style connector in its place.  My PCB will solder to this pinned connector.  To reconnect IC20 into the circuit, my PCB will include its own DIP socket (and associated wiring).  My PCB will include the wiring to connect IC20 back into the Polysix's circuitry via the pinned connector.

I'm going to attach my PCB via the DIP socket for IC20.  It's great that the Polysix came with so many socketed ICs to enable this kind of hack.

Circuit Block Diagram:  Before diving into PCB design, it's important that I understand what it is that I want to do.  The block diagram below shows my overall approach for this PCB.  It shows the DIP connector and DIP socket, it shows the digipot that controls the overdrive, and it shows the Arduino-style microcontroller that controls the digipot.  It also shows the headers that I'll used to program the Arduino ("ICSP" and "FTDI") as well as a bunch of pins and headers that'll let me be flexible in how I choose to connect the various audio and synth control signals that I might wish to manipulate.

Here's a block diagram of what I'm hoping to build.  I want to include lots of pin headers so that I have plenty of flexibility for modifying my own circuit once it's built.

Which PCB Layout Software?  In my previous attempt at a PCB design, I used CadSoft Eagle This is the PCB layout software common throughout the Maker community, probably because there is a free version that is pretty capable.  Both Sparkfun and Adafruit seem to think that it's a good choice for their open source designs.  I didn't like it, though.  I thought that it was hard to learn and didn't promote self-discovery.  I felt like trying a new tool instead.  I almost went for a cloud-based software tool like Autodesk's 123D Circuits, but at the last moment I ended up downloading and trying Fritzing.  I found Fritzing to be very approachable, and unlike 123D Circuits, it's been around long enough for the forums to have a good number of threads for me to learn from.

To layout my PCB, I tried Fritzing.  It seemed much more approachable than CadSoft Eagle.

Parts then Schematic then PCB:  One should only start a PCB design when you already have a good idea about what you want to build.  That's why I started with the block diagram shown earlier and that's why I spent so much time breadboarding the key elements of my circuit in previous posts.  Once you know what elements are going to be in your circuit, only then should you start with the PCB design software.  PCB design software generally follows a three-step process: (1) choose the parts for your design, (2) draw your schematic using your parts, (3) layout your PCB based on your schematic.  OK, here we go...

Step 1A: Choosing my Parts.  Looking back at my block diagram, my major parts are the LM13600 OTA, the AD5262 dual digipot, and the ATMega 328P microcontroller.  For minor parts, there will be a bunch of resistors and capacitors, some pin headers, and an oscillator/clock for the microcontroller.  Fritzing is already well stocked with parts for me to use for these minor components.  So, it's the major components that I need to focus on.  Lucikly, Fritzing already has the version of the ATMega 328P that I want to use (the surface mount TQFP package).  What Fritzing doesn't have is the LM13600 OTA or the AD5262 digipot.  I needed to make these two parts myself.

Step 1B: Creating the Missing Parts.  Making parts is often the hardest part of using PCB design software.  It's such a pain.  I figured it out through a combination of the Fritzing documentation plus lots of trial and error.  The key to making any progress is that Fritzing already had built-in components of the right size.  They weren't the correct part, but they were the correct size (they already had a TSSOP-16 like my digpot and they already had a DIP-16 like my OTA).  As a result, my task was simply to copy the existing parts and re-name the pins.  Through a combination of the built-in part editor (see screenshot below) and a text editor (to change the labels on the SVG graphics), I was able to create my two parts.  If you're interested, I've shared my Fritzing library on my GitHub here.

One of the hardest part of designing one's own PCB is creating models for the parts that don't come in the standard library. Here, I'm making a model for the AD5262 digipot, which is a TSSOP-16 package.  I also did this for the LM13600 OTA, which is a DIP-16.  This process always seems harder than it should be.

Step 2: Create the Schematic.  With my parts created (go me!), I started creating the schematic.  My final schematic is shown below.  In the upper left, you can see a block corresponding to the DIP connector that'll be used to connect this PCB to the Polysix's KLM-368 PCB.  You can see that most of the pins of the DIP connector get routed down to a DIP socket that I'll put on my board to host the LM13600 OTA chip itself.  You can also see that I've broken out few of the LM13600 pins so that I can manipulate the signals (ie, enable overdrive) with the other parts of my circuit.  The rest of the schematic shows the other elements of my circuit -- in particular, you can see the block for the digipot (bottom left) and the big block for the ATMega 328P microcontroller (center).  The critical connections for the 328P (such as the reset circuit) I copied from the Sparkfun Arduino Pro.  That Sparkfun design is also where I learned the layout for the two programming headers (the FTDI and the ICSP headers).

This is the schematic of all the elements that will go into my PCB.  This defines all the connections between the different circuit elements.

Make it Hackable.  As already mentioned, this design breaks out extra Arduino pins, includes some unconnected "spare pins", and includes a second set of pins for both pots in my digipot.  All of these extra access points are to enable future hacking of my own PCB.  I wanted to include flexibility the design of my PCB so that I can make different connections between the OTA, the digipot, and the Arduino.  Who knows what kind of mods I might dream of in the future?!?  With these extra pins, it'll be easier to have fun explorations.  You've got to be prepared to be spontaneous!

Step 3: Layout the PCB.  With the schematic complete, I started the PCB layout process.  I placed my components onto a notional PCB and started laying wires ("traces") between them.  Below is a screenshot showing all of the parts on a notional PCB outline.  I've got about 2/3rds of the traces complete.  To make a trace you simply choose which side of the PCB you want (top or bottom) and then right-click on one of the "air wires" to create the actual trace.  Because the default trace is pretty thick, I would click on the trace and, in the "Inspector" window pane on the bottom right, choose a thinner size like 12 mil.  Finally, click and drag points on the trace to manually route the trace where you want it.  If a trace needs to jump between layers to avoid existing traces, you create a "via" between the layers by right-clicking on the desired spot on the wire.  This is easy!

This is the PCB layout view in Fritzing.  I'm about 2/3rds complete in laying out the board.
Surface Mount vs Through Hole:  I'm not very experienced with surface mount parts (though I have soldered this TSSOP digipot before), so most of my parts in this design are through hole parts (PTH).  The only two surface mount parts (SMT) are the digipot and the ATMega 328P.  In laying out the PCB, the main issue with mixing PTT and SMT parts is that the grid size (which helps keep your traces orderly) really wants to be different for the PTT components vs the SMT components.  For the PTT parts, grid sizes of 0.1", 0.05" or 0.025" all work well.  By contrast, the TQFP package for the ATMega 328P works better with a 0.8 mm (0.0315") grid.  Annoyingly, for the TSSOP package for the digipot, the best grid size is yet a different value (0.0254").  It gets very tedious manually switching between the different grid sizes.

Finishing the PCB:  Once I got all the traces where I wanted them, I started adding text to the PCB so that I could know where to connect my different signals.  I also put a name and date on the board so that I could know which iteration of he board I was using (surely, I would need to iterate the board to fix errors).  Finally, on the bottom layer, I told Fritzing to do a "copper fill".  This is a common technique to try to reduce unwanted noise that may be transmitted between closely spaced circuit boards (such between this PCB and the Polysix KLM-368 that'll be right underneath it).  A screenshot with my final PCB is shown below.  I shared my Fritzing design files on GitHub here.

Still in Fritzing, I have finished my PCB design, including a big copper fill on the bottom for the ground plane.

Design Rule Check:  Throughout the PCB layout process, I would periodically use the software's built-in tool for confirming that my traces were not overlapping with anything else on the board.  The traces on a PCB can get pretty convoluted, so using an automated tool is a great benefit.  This tool is called the "design rule check" (DRC) and is included with almost any PCB design software.  In Fritzing, when I'd run the DRC, I'd get a big pile of error messages like shown in the window below.

The "design rule check" (DRC) gives lots of errors for my design when using the default DRC rules.

Shrinking the Keepout Distance:  When I would try to find these errors in my PCB, I often saw no issue.  The traces (especially around the SMT components) may have been close, but they were not interfering.  I was confused.  The answer is that the default rules used by the DRC algorithm were too tight for my small SMT components.  When I changed the DRC "keepout" distance from its default 0.01" value to a smaller 0.008" value (see screenshot below), almost all of my errors went away.  The remaining DRC errors were legitimate problems, which I found and fixed.

With such small SMT components, you need to reduce the "keepout", thereby telling the DRC algorithms that it is OK if the traces are close together.  I dropped the keepout from 0.01 inches to 0.008 inches.

Shrinking the keepout (plus fixing some actual errors in my PCB) eventually lets me pass the DRC.

Export for Production:  Once my design was complete and the DRC results came back clean (see screenshot above...I was so happy when I saw this message!), it's time to export the design so that it can be sent out to be printed.  The exported production files are often called "Gerber Files".  In Fritzing, I chose to export to "Extended Gerber Files".  It created a collection of files that define the top and bottom copper traces, the drill locations for the vias and the PTT components, the top and bottom solder mask, and the top and bottom silkscreen (ie, text and graphics).  These are the files that the printing company need to make the PCB.

Tailor for Your PCB Print Company:  Unfortunately, every PCB printing company is a little different in their requirements for the Gerber files.  As a result, the Gerbers may have to be tweaked specifically for different printing companies.  For me, I chose to use OSH Park to print my board.  Looking at their requirements, the Fritzing Gerber files were all fine, except I had to change my drill file to end with ".xln".  That's all I had to do!  My Gerber files are zipped up on my GitHub here.

Send to Printer:  I uploaded my zipped Gerber files to OSH Park.  Their automated system interprets the files and then shows you illustrations of your design so that you can confirm that they interpreted your files correctly.  In my case, the top and bottom views of my board are shown below.  They look pretty good.



Top and Bottom View of my PCB as Generated by OSH Park.  $21.75 for three.  Let's get it printed!

Order the PCB:  In general, the cost for PCBs is driven by the number of layers (a two-layer board is cheaper than a six-layer board) and by the area of the board (a smaller board is cheaper than a large board).  I tried to make my board pretty small.  I was hoping to get under $20, but I only got it down to $21.75.  Given that OSH Park sends you three copies of your board for that price (plus free shipping!), I'm still pretty happy.  Anyone can order my board from OSH Park here.

Waiting:  So, now I wait for the board to get printed and sent to me.  It generally takes 2-3 weeks.  I'm so excited to get it.  Waiting is agony!

Monday, December 28, 2015

Making a Breadboard Arduino

I'm still working on my OTA Overdrive modification.  My approach is to control the overdrive using an Arduino-controlled digipot.  But, if you saw the last picture from that post, you saw that my Arduino-digipot setup is a total mess.  To fit it inside my Polysix, I need to clean it up.  I think that means that I'm going to make my own custom PCB.  Exciting!  If I'm going to do that, I want to integrate the Arduino processor right onto the PCB.  Fully integrated!  But that's something that I don't know how to do.  Today is my first step in learning.  Today, I figure out how to build my own Arduino from parts.

Recipe for an Arduino: one Atmel 328P (foreground) along with one 16 MHz crystal and a couple of 22 pF caps (background)

Following Instructions:  My goal is to build an Arduino Uno on a breadboard.  Furthermore, I want to be able to program it from the Arduino IDE, just like a real Arduino.  Not surprisingly, the Arduino folks have a pretty good page on how to make a breadboard Arduino.  These are the instructions that I followed, though I'm bad at following directions, so you may see some differences here.

Buying Stuff:  You don't need many parts.  I already had basic stuff like a solderless breadboard, resistors, and jumper wires.  I did have to buy the Arduino processor (an Atmel AVR ATMega328P), a 16 MHz crystal, and a couple of 22 pF caps.  Easy.

Wiring Together my Breadboard Arduino:  Once I got the parts, I started wiring it up.  As shown in the picture below on the left, I started with the power (+5V) and ground connections, along with the 10K pull resistor for the reset line.  Then, as shown in the picture on the right, I added the crystal and its supporting caps.  That's it.  It's done.  [Note that some folks like to add a push button to make it easier to reset the chip.  It's not necessary and I never felt the desire to use it.  You don't need it.]

Wiring the Elements on a Breadboard.  Start with the Atmel chip and wire in the power (+5V and Gnd) along with the pull-up resistor for the reset line.  Then, add the oscillator elements (crystal plus caps).  That's it!

Is it now an Arduino?  No.  My breadboard circuit still is not quite an "Arduino" because it can't yet be programmed from the Arduino IDE.  The missing piece is that the processor has not been programmed with the Arduino "bootloader".  This is the software that tells the chip what to do upon startup, including how to listen to the Arduino IDE after being reset.  So, to turn my breadboard circuit into a breadboard Arduino, I have to put the bootloader on it.

Burning the Arduino Bootloader: Following the Arduino page on this topic, I put the bootloader on my breadboard Arduino using a real Arduino Uno.  I connected the Uno to my PC and (via the Arduino IDE) uploaded the "ArduinoISP" sketch.  Note that this is programming the real Arduino, not my breadboard one.  Once the Uno was programmed, I continued to follow the instructions and hooked up the Uno's SPI pins to my breadboard Arduino's SPI pins (see photo below).  Finally, in the IDE, I set "Programmer" to "Arduino as ISP" and then selected "Burn Bootloader".  I took just a second or two and it was done!

Using a real Arduino Uno (left) as a programmer for my breadboard circuit.  Here, I'm burning the Arduino bootloader onto my Atmel 328P so that it can be programmed as an Arduino.

Programming my Arduino:  Theoretically, my breadboard Arduino (it's an Uno, specifically) can now be programmed with regular Arduino programs straight from the Arduino IDE.  It has no USB jack, however, so how do I actually get the program onto the breadboard Arduino?  The Arduino instructions say that, if you've got the right kind of real Arduino, you can use your real Arduino to act as a USB-to-Serial converter.  Great!  Let's try!

From One Arduino to Another:  The key to doing this transfer is that you need the right kind of Arduino.  The "right" kind of real Ardiuno is one where the main chip is a big DIP, which will need to be pulled out for this trick.  Most of my Arduinos happen to be the SMT version, which won't work.  In my bin of spare electronics, I did find one Arduino that is DIP version (yay!).  So, following the Arduino page's instructions, I popped out the big DIP chip and then connected the board's TX and RX and Reset lines to my breadboard Arduino (see below).  Once connected, I told the Arduino IDE software to upload the "Blink" sketch and VOILA!  The light blinks!  It works!

Using an empty Arduino Uno to program my breadboard Arduino with the basic "Blink" sketch.  My breadboard Arduino lives!

Programming via FTDI:  After this exciting initial success, I found that this setup wasn't ideal.  It turns out that my DIP Arduino would sometimes fail to program my breadboard Arduino.  I then remembered that this unreliability was why this Arduino had sunk to the bottom of my box of electronics...I had seen problems with it previously.  Very annoying.  So, to avoid more annoyance, I purchased a stand-alone USB-to-serial converter.  There are a variety of these devices available.  I bought an "FTDI Friend" from Adafruit because they usually make good stuff.

Connections for using an Adafruit "FTDI Friend" to program my breadboard Arduino.  On the left, the figure shows the names of the connections as labeled on the FTDI friend itself.  On the right, the figure shows the name of the points on the breadboard Arduino where the wires should get connected.

Connecting the FTDI Friend:  While the Adafruit documentation is good on how get started with the FTDI Friend, it does not explicitly show how to connect it to a breadboard Arduino to transfer a program.  Instead, I found this thread on the Arduino forum, which was very helpful.  The picture above shows the connections that worked for me.  On the left are the names of the wires as labeled on the FTDI friend itself.  On the right are the names of where it should connect to a breadboard Arduino.

Don't Forget the Capacitor!  One key detail (as stated in the thread above) is that you have to use a capacitor between the RTS pin on the FTDI Friend and the Reset pin on the AVR chip.  The cap needs to be 0.1 uF or bigger.  If you don't have the cap in series, it doesn't work!  Once i did this, I could reprogram my breadboard Arduino from the Arduino IDE reliably and with ease.  It is very satisfying.

Can my Arduino Drive my Digipot?  The whole purpose of this experiment is to figure out how to build an Arduino to the digipot that's at the heart of my Overdrive Mod for my Polysix.  So, before I declare victory with my breadboard Arduino, I want to make sure that it worked like a real Arduino to drive my AD5260 digipot.

My breadboard Arduino controlling an AD5260 digipot.  It works!

Testing with the Digipot:  I wired up the digipot the same way as in my previous post, though I did need to reference the Arduino pin map to find which pins on my naked AVR chip corresponded to the SPI bus (answer: pins 19, 17, and 16).  Once I got it all connected (see picture above), I loaded my test code for the digipot, which steps through a few resistance values.  As you can see in the picture below, it works just fine...here I'm getting a resistance of 8.3 kOhm.  It was very satisfying to confirm that my breadboard Arduino was able to drive my digipot.

Measuring the resistance values produced by my Arduino-controlled digipot.

Adjusting CPU Speed:  Now that it all works, I'm thinking ahead to the PCB that I'll design to fit these elements within the Polysix.  I'm a bit concerned that the addition of this microcontroller, plus the others that I've already added, might be stressing the power supply of my old synth.  My old synth already gets pretty warm.  So, if possible, I'd like to minimize the power consumption of my added elements.  One easy way to reduce power is to slow down the clock speed of the processor on my breadboard Arduino.  Looking at this thread, you can change the CPU speed on an Arduino simply by adding a little code to your sketch.  That's easy!

Measured Current Draw:  Following the example code in the link above, I tested each speed from 16 MHz down to 1 MHz and recorded the current draw for each case.  My results are shown below.  In all cases, I confirmed that the digipot still works, which is great.  So, it appears that I can cut my power draw almost in half by running at 1 MHz.  Great!

Current Draw When Running the "Blink" Program.  The clock speed is changed by changing the clock divider setting.  No is LED connected.  

Lessons Learned:  The purpose of this whole experiment has been to learn what needs to be learned so that I can build my own Arduino-based modification for my Polysix.  Let's summarized the important lessons:
  • I am able to build my own Arduino from a raw Atmel AVR chip.  That is fantastic.  
  • To put the Arduino bootloader on the raw AVR chip, I need access to the chip's SPI pins.  So, on my custom PCB, I need to make those pins available.
  • To program the AVR chip from the Arduino IDE, I need access to the chip's TX, RX, and Reset pins.  So, I need to break those pins out, too.
  • To upload my programs to the AVR chip, I need a USB-to-serial converter.  My Adafruit FTDI Friend works great as long as I've got that in-line capacitor on the RTS line.
  • To save power, I can run my Arduino at 1 MHz instead of 16 MHz.  I confirmed that the digipot still works fine at the slower speed.
Whew!  What a great day of learning!  Now to start with the PCB design.  That'll be a lot more learning!

Follow-Up:  I designed a custom PCB, including a home-brew Arduino!  You can check out the story here.

Wednesday, December 23, 2015

Arduino-Controlled OTA Overdrive

I'm really enjoying playing my OTA Overdrive Mod for my Polysix.  I also enjoy how simple it is -- I just added one resistor.  If I want a different amount of overdrive (or none), I swap in a different resistor.  So simple.  The question now, however, is how to make this mod be robust and usable day-to-day?  Well, today, I start that process.  My goals are to make it controllable from the front panel *and* to save and recall its setting with the Polysix's patch memory.  It's this second goal that makes this mod a little tricky.  Let's figure it out!  (Not surprisingly, my solution involves an Arduino...)

Controlling my OTA Overdrive with an Arduino and a Digipot.  

Why Not Use a Pot?  As I said, my OTA overdrive is controlled by changing resistors.  So, the easiest solution is to mount a potentiometer (a "pot") to the Polysix face, to wire it as a variable resistor, and to connect it to the correct spot in front of the OTA.  Fit with a nice knob, a pot is easy to use, simple to install, and inexpensive.  Sound great!  The main problems with using a traditional pot are that (a) I don't want to drill a hole in my Polysix to mount the pot and (b) a pot is not programmable, which means that its setting can't be saved and recalled with the overall synth patch.  I'd like to find a way to overcome both issues.

Using a Digipot as a Variable Resistor for my OTA Overdrive Mod

Use a Digital Potentiometer:  While a traditional pot isn't quite satisfactory, I think that a digital potentiometer (a "digipot") would work great.  I first used a digipot to add velocity sensitivity to my Polysix and I found it to be very useful.  A digipot is like a regular pot in that it can be used as a variable resistor, but a digipot has an advantage in that it can be controlled by digital messages sent from a microcontroller.  As a result, I can use buttons and knobs that already exist on the synth to control the overdrive.  And, in theory, I can even change the overdrive settings with each synth patch.

Control by an Arduino:  You don't get something for nothing, however.  To use a digipot, you need a microcontroller to drive it.  Microcontrollers are pretty easy to add...in fact, I've already added two to my Polysix: (1) an Arduino Mega acting as my key assigner and (2) a Teensy 3.1 acting as my velocity processor.  I could use either of these existing devices to control my digipot, but neither is conveniently located to the KLM-368 Effect PCB where the overdrive mod lives.  I hate running long wires carrying noise-spewing digital signals, so I think that I will add yet another microcontroller to my synth.  This time, it'll be something small like an Arduino Micro.

Block Diagram of my Solution

User Control:  While the Arduino can control the digipot, how will the user tell the Arduino what overdrive level is desired?  Since I don't want to drill a hole to add a new dedicated knob, I looked at my Polysix control panel with fresh eyes.  Which knobs ore buttons could I re-purpose?  My eyes fell upon the "Attenuator" knob.  For me, I never use the knob below 0 dB, which means that the whole left half of the knob is basically unused.  I could totally re-purpose part of that knob for adding overdrive.   No drilling necessary!  But how do I sense the Attenuator's setting?

Re-Using the "Attenuator" Knob to Be My Overdrive Control

Look for the Signal, not the Knob Itself:  The key innovation is that I should not try to sense the knob itself.  Instead, I should sense the signal that the Polysix CPU generates in response to the knob.  The reason to sense the signal instead of the knob is because of patch memory.  To enable patch memory (even when patch memory isn't being used), the Polysix CPU scans all of the knobs and switchs on the panel and then generates control signals in response to those settings.  Then, if a patch is recalled from patch memory, the CPU ignores the switches and knobs and generates the control signals based on memory.  If I am successful in having my Arduino listen to the signal generated by the Polysix CPU in response to the Attenuator knob, my overdrive setting will respond to both the knob and to the patch memroy system.  This is what I want!  But which signal in the Polysix corresponds to the Attenuator knob?

"P-Vol" is the Attenuator Knob:  Looking around the schematic, I found that the Attenuator setting corresponds to a signal called "P-Vol", which presumably stands for "programmable volume".  It turns out that P-Vol is a simple analog voltage signal.  Therefore, via its Analog Inputs, my Arduino can listen to this signal and engage (and increase) the overdrive whenever the Attenuator knob is turned below 0 dB.  Great.  The P-Vol signal is also available on the KLM-368 Effect PCB (at R188), which makes it convenient to the overdrive mod itself, which is likely where I'll mount the Arduino.

The "P-Vol" signal reflects the setting on the Attenuator knob.  I'll control the amount of overdrive by sensing the value of this signal.  I can read the P-Vol signal at R188 on the KLM-368 Effect PCB.

Interpreting P-Vol:  Attaching a wire to the upstream side of R188, I read the voltage using my digital multi-meter for various settings of the Attenuator knob.  As you can see in the graph below, it's a nice, simple, straight line.  I can use this data as part of a lookup table on my Arduino to determine whether to engage the overdrive (if knob is set to less than 0 dB) and how much overdrive to apply (a lower knob setting will engage more overdrive).  Via this lookup table, the Arduino will command the digipot to actually induce the overdrive that I want.  This plan is coming together nicely.

Data that I measured relating the "P-Vol" voltage at R188 to the Value of the Attenuator Knob

The Wiring Plan:  Now I have to figure out how to wire up all of the pieces to put this plan into action.  Luckily, I already figured out how to connect and use a AD5260 digipot.  This time, however, instead of using a full-size Arduino Uno,  I'll use an Arduino Micro.  The pin mapping is the same, so the connection plan is still valid.  The image below shows my plan for wiring it up.

Wiring the Arduino Micro to the AD5260 Digipot.  Lots of signals are needed from the Polysix, including +5V, -5V, Gnd, P-Vol.  These are in addition to the input and output audio signals that'll be manipulated by the digipot to overdrive the OTA.

Both +5V and -5V:  There is one important difference in this new plan: the digipot needs to be supplied with both +5V and -5V.  The -5V is new.  The reason that it needs a bi-polar power supply is that the audio signal that I'm attenuating is a bi-polar signal.  The audio signal from the synth could span +5V to -5V, therefore the power supplied of the digipot needs to span +5V to -5V.  Lucikly, the Polysix makes -5V, so I can grab that voltage rail from the synth.  I had to pull it from the Polysix's power supply PCB (not the KLM-368 Effects PCB), but that's not really a problem, just a bit messy.

Wiring it Up:  I wired up the Arduino and digipot onto a solderless breadboard, as shown in the picture at the top of this post.  I then tacked in a bunch of wires to the KLM-368 PCB and grabbed the +/-5V from the main power supply PCB.  As you can see below, it's quite a mess.  I usually find that messiness is part of the discovery and invention process.  Things always seem to get messier before they get simpler.

Trying new things is a messy, messy business.

Software:  After wiring up the hardware, I need to write software for the Arduino to listen to the P-Vol signal and to drive the digipot.  For the digipot, I simply re-used my previous software that I wrote to drive the AD5260.  Then, I added the logic to read the analog "P-Vol" signal and decide what resistance level to set in the digipot.  It was nothing complicated, though it did take some trial and error to find the right voltages at which to transition between resistance levels.  My code is shared here on Github.

Success!  After firing up the system, and after fixing a bunch of bugs in my software, I found that this Arduino-digipot solution does successfully control the amount of overdrive based on the Attenuator knob setting.  Success!  And, yes, it also correctly respond via patch memory changes.  Yay!  It feels so good when stuff works.

Issues:  This setup does have one small problem, however -- the lowest setting of the Attenuator knob (-10 dB) isn't detected by the Arduino.  The -8 dB setting and the -10 dB setting give the same behavior.  The problem should have been obvious earlier.  As shown earlier in my graph of voltage vs knob setting, note that both the -8 dB and -10 dB knob settings yield a P-Vol voltage that is negative.  The Arduino can't measure negative values.  To the Arduino, they both look like zero volts.  As a result, the Arduino can't tell the difference between the two knob settings.  I totally should have realized that earlier.  Bummer!

Next Step:  There are two easy solutions here: (1) shift the DC level of P-Vol with an op-amp prior to sending it to the Arduino's analog input, or (2) abandon P-Vol and, instead, sample the four digital signals that the Polysix uses to generate the P-Vol.  The latter approach definitely looks easier.  Next time, I'll give that a try instead.

Follow-Up:  I'm thinking about doing a custom PCB with the digipot and Arduino integrated together onto a single board.  To help me learn how to do that, I created my own breadboard Arduino from raw parts.  You can check it out here!

Follow-Up:  I've completed the PCB design.  It was actually pretty fun!  You can check out the story here.

Thursday, December 10, 2015

Polysix OTA Overdrive

I still chase my dream -- to get a decent electric piano feeling from my Korg Polysix.  Adding velocity sensitivity got me a long way there, but the sound itself needs to be dirtier, with more compression, more grit.  I tried adding diodes to the signal path to generate some distortion, but it sounded bad.  Too fizzy.  Now, I've modified my Polysix to overdrive one of its OTA circuits.  Having a soft onset that eventually leads to a deep, warm saturation, I think that it worked out pretty well!


OTA Overdrive:  After the failure of my experiment with diodes, I looked for other places in the Polysix circuit where I could generate distortion in other ways.  I noticed that the Polysix has a number of LM13600 chips, which are operational transconductance amplifiers, or OTAs.  Seeing them there reminded that a number of newer synths (e.g. Moog Sub Phatty) say that they offer "OTA Overdrive" as a means of user-controllable distortion.   I don't know how these synths overdrive their OTAs, but I was certainly game to figure out how to overdrive mine.

Pre-OTA Attenuation:  A key requirement of the LM13600 is that the input signals have to be very small.  If the inputs are too strong, the out signal will become distorted.  Since I want distortion, this looks like a good place to make my modifications.  Looking at the Polysix schematic, I see voltage dividers in front of every LM13600 to cut the signal down.  One example is shown below, which shows the elements around IC20.  The signal comes in on the right and exits on the left.  The voltage divider in front of IC20 is formed by R155 (10 kOhm) and R163 (100 ohm).  This cuts the input signal voltage by a factor of 100.  That's 40 dB of pre-OTA attenuation!

Adding a resistor in parallel to R155 reduces the attenuation prior to IC20 enabling the LM13600 OTA to be overdriven

Reducting the Pre-OTA Attenuation:  If I modify the circuit to have less pre-OTA attenuation (ie, to allow the signal to be stronger), I will likely overdrive this OTA.  I can easily reduce the attenuation by adding a resistor in parallel with R155, which will reduce the effect of the voltage divider.  For example, putting a 1 kOhm resistor in parallel to R155 will result in the signal being cut down by only a factor of 10, instead of the factor of 100.  This means that the signal is attenuated by only 20 dB instead of the 40 dB.  In effect, I'm slamming the OTA with a 20 dB stronger signal.  This seems like an easy path to overdriving IC20.  That's what I want.

Connecting the Resistor:  Looking inside the synth, I first looked for IC20 on the KLM-368 PCB.  I found R155 nearby.  To easily try different resistors in parallel to R155, I attached clip leads on either side of R155.  See the pics below.  I also attached my oscilloscope to C75 so that I could visualize the output as well as hear it.

Clipping in on either side of R155.
Adding a resistor, via the clip leads, to be in parallel with R155.

Trying a Range of Resistors:  As you saw in the video at the top of the post, I tried a range of different resistor values.  For gritty electric piano sounds, I liked the 3.3K and 1.1K values the best because the effect was subtle...it simply warmed up the signal and only added some grit when I played hard.  At the other end of the spectrum of resistor values (ie, when I shorted across R155), I unexpectedly enjoyed the unpredictable chaos of the heavily saturated distortion.  It was really fun!

Seeing the Effect:  The video demonstrated what this modification sounds like.  The figure below shows what it *looked* like.  The figure shows the output of IC20 for different resistor values across R155.  As you can see, with no resistor (which is the same as a very large resistor), the output signal is a nice sawtooth, but it is relatively small.  Then, as I add a large resistor (3.3 kOhm) the signal gets quite a bit stronger due to the extra gain.  As I make the resistor smaller (1.1 kOhm), the signal gets stronger.  Continuing to make the resistor stronger (500 ohm and on), the shape of the waveform starts to deviate from a sawtooth -- the top and bottom are becoming rounded.  This is signature of the OTA being overdriven.  It's a softer, more rounded, distortion than seen in my diode mod from my last post.  Finally, when I short across R155, the distortion becomes so heavy that the signal is a square wave.  Under certain contditions, as seen in the video, that can be cool in its own way.

Output of IC20 recorded for different resistors placed in parallel with R155. Note that decreasing resistance results in increased gain, which eventually leads to overdriving IC20, causing the sawtooth to become distorted.  Note that, for these images, I played two notes at the same pitch and waited for the two voices to naturally phase into alignment.

More Than Just Gain:  Clearly, the main effect of changing the resistor is to boost the level of the signal going into the OTA, which then overloads the OTA and causes the output signal to be distorted,  But, gain and distortion is not the resistor's only effect.  Looking back at the Polysix schematic, I see that R156 and C80 are also in parallel with R155.  This resistor and capacitor act to boost the treble frequencies.  By adding my own resistor around R155, I will also be reducing the effect of this treble boost.  So, maybe the "warmth" that I felt was actually a result of changing the frequency response, and not necessarily due to overdriving the OTA.  To confirm this theory, let's analyze the circuit for different resistor values and see what happens.

Circuit Simulation:  To simulate this part of the circuit, I used 5Spice Analysis, which is a SPICE-based circuit simulation program with a nice graphical interface for Windows.  Like most graphical versions of SPICE, you start by drawing the schematic of the circuit that you want to simulate.  The screenshot below shows the schematic that I made to represent the elements leading into the IC20 OTA.  For this simulation, the input signal is generated by "SigIn" on the right.  "TPv1" on the left represents the output signal, which would normally go to IC20.  In between the elements of the Polysix's voltage divider, the R-C treble boost, and my added overdrive-inducing resistor.  Now I can run the simulation and see the expected frequency response.

Using "5Spice Analysis" to model the frequency response of the pre-OTA voltage divider network.

Expected Response, Unmodified Polysix:  The graph below shows the modeled response of the circuit.  On the bottom (in blue) is the the circuit response with no added resistor around R155.  As expected, the signal is 40 dB down, which is what we expect based on the 10 kOhm / 100 Ohm voltage divider.  Also note, however, that the treble frequencies are boosted due to the effect of R156 and C80.  At 5 kHz, the signal is boosted by about 5 dB.  While not a huge boost, this would definitely sharpen the sound.

Expected Response of the pre-OTA voltage divider network.  The different lines show the effect of different values for the resistor that I placed in parallel to R155.
Expected Response, Modified Polysix:  When the parallel resistor is added, I get the black traces shown in the figure above.  The primary effect is that the signal level goes up.  The 1.1 kOhm case, for example, shows that the signal is at -20 dB instead of at -40 dB.  This is the 20 dB gain that I mentioned earlier.  A secondary effect of adding the parallel resistor, however, is that the boost to treble frequencies becomes much less.  Perhaps this is the increased "warmth" that I perceived.  Hmm.  I think that this requires a little more exploration.  Maybe there are additional modifications that I can make to shape the frequency response to make the OTA overdrive sound even better!

Next Step:  I liked the sound and feel of this OTA overdrive much more than the diode distortion.  I think that, if I can figure out how to make this OTA overdrive controllable from the Polysix's front panel, I'll enjoy having this modification.  So, that's my next step: figure out how to have a controllable amount of overdrive for IC20.  Stay tuned!

Follow-Up:  How to make this mod controllable without clipping in new resistors?  In this follow-up post, I start designing this mod to use an Arduino and a digipot.