Friday, October 16, 2015

Surface Mount DigiPot with an Arduino Uno

For an upcoming modification to my Korg Polysix, I need to be able to attenuate an analog signal in response to the user's inputs.  This is a perfect task for a a digital potentiometer.  If I can, I'd like to control the digipot from an Arduino, because an Arduino is so easy to program.  There are two challenges with this plan, however.  First, my preferred digipot is only available as a surface mount device.  Second, I'm worried that the Arduino is too slow to drive the digipot quickly.  Well, I do like challenges, so let's just dive in and see where we can get!

Driving my digipot with an Arduino Uno.  How fast can it go?

Choosing my Digipot:  There are many digital potentiometers on the market.  For use inside my Polysix, I might need to put digipot in a place where it would need to control voltages ranging from -5V to +5V.  Most digipots cannot handle this kind of bipolar voltage range (most are just 0-5V).  Of the choices that I saw on Digikey for bipolar digipots, I chose to buy an Analog Devices AD5260 (link).  As you can see it in the picture below, it's a tiny little surface-mount device.  Scary!  (actually, don't be'll be fine)

Analog Devices AD5260 Digital Potentiometer.  Surface Mount!  Tiny!

Surface-Mount Adapter Board:  Because I'm usually just hacking stuff together, and because through-hole components are much easier to hack with, I don't have nearly zero experience soldering surface-mount components.  If I made my own circuit boards, I would certainly use more surface mount components because they save so much space.  For this hack, however, I need flexibility to plug, unplug, and reconfigure my circuit.  Therefore, I'm going to put my surface mount device onto a an adapter board that gives it legs like a through-hole component.  My digipot is a TSSOP-14 package, so I bought a TSSOP-14 adapter board from Adafruit.  It comes as a pack of 6, so I have spares in case I make a mistake.  :)

Mounting my surface-mount digipot to a through-hole adapter board.

Soldering Surface Mount ICs:  How do I actually do the soldering?  I talked with a co-worker who is extremely experienced in this area and he gave me a pile of good advice.  Two parts of that advice were: (1) use very fine (thin) solder and (2) use lots of flux.  Unfortunately, by the time I got around to soldering (days later), I had forgotten these two important details.  As a result, using my too-thick solder and using no extra flux, I created many solder bridges between the tiny legs of this tiny IC.  This is not what you want to do.  But, through perseverance, and through extensive use of solder wick to remove excess solder, I finally got the IC soldered no shorts or bridges.

Magnification (Or, How to Look Cool):  One piece of my colleague's advice that I did follow was to use some magnification.  He let me borrow an "OptiVisor" (see picture below).  It doesn't feel like it provides much magnification, but it is enough to give a clear view.  And, I'm learning that if you can *see* it, you can solder it.  The OptiVisor provides that.  They're also quite fashionable (that would be sarcasm).  

It definitely helps to use some magnification so that you can see what you're soldering.

Add Legs for Breadboarding:  The Adafruit adapter board has through-holes on either side for attaching pin headers.  As you can see below, I used a regular piece of 0.1" break-away pin header.  I broke off two seven-pin segments, temporarily placed them into my solderless breadboard, put the digipot board on top, and soldered the pins on.  This through-hole stuff is easy!

Soldering the pins to the breakout board so that I can easily prototype with the digipot.
Using a solderless breadboard keeps everything aligned while you solder.

Deciding How to Connect:  With the digipot's adapter board finished, I had to figure out how to wire up the device.  Below is a picture from the digipot's datasheet with my own labels added to show what I would connect to each pin.  All connections were going to my Arduino.  As you can see, there are a bunch of 5V and Gnd connections.  Commands are sent via the SPI bus, so there are also the three SPI connections (theSDO line is not needed as there is no communication needed back to the Arduino).  Finally, for the pot's input, I'll simply apply 5V, which means that my output will be a DC voltage that is scaled between 0-5V.

Signals to use for testing the digipot with an Arduino, which uses 5V logic.

Wiring to the Arduino:  The wiring plan shown above requires 12 connections.  Since I am usually prone to error when doing my wiring, I choose to draw up a little picture to fully illustrate to myself how I should use my solderless breadboard to make all of these connections.  This extra "design" effort really made the wiring process much easier.  It also made the wiring process more reliable.  Once I got the Arduino software working, the wiring of the hardware worked on the first try!

Wiring an Arduino Uno to the my digipot via a solderless breadboard.

Writing the Arduino Software:  To change the value of the digipot, I had to write some Arduino code to send commands to the digipot via the Arduino's SPI pins.  I started with the Arduino's built-in example called "DigitalPotControl".  While that code is simple and easy to understand, I wasn't sure if it runs the SPI bus as the fastest possible setting.  Speed is critical for using this in my Polysix, so this detail was worth a little effort.  After Googling around, I found the correct Arduino commands to control the SPI bus speed and I wrote my test program (SPI mode is zero!).  My program is shared on my GitHub here.

Initial Test:  My test program steps through a range of the digipot values.  It stops at each step for three seconds, which gives me enough time to confirm that its output is correct.  Because the input of my digipot is connected to +5V, my output will be between 0V and 5V.  For the picture below, the digipot was at a value of 125 (out of 255), which resulted in an output voltage being 2.47V.  Given that I expected (125/255*5) = 2.45V, I got pretty decent agreement.  In other words, it works!

First test.  It successfully created a voltage half-way between 0-5V. 

Testing for Speed:  Now for the full speed test.  I commented out the delay() and println() commands and restarted the system.  If used in my Polysix, there will only be 15-20 microseconds (usec) to change value of the digipot.  This means that the Arduino + digipot must support an update rate of 50-67 kHz, which seems pretty fast for an Arduino.  To see how fast my system was actually running, I connected the output of the digipot to an oscilloscope.  The full setup is shown at the picture at the top of this post.  A screenshot from the oscilloscope is shown below.

The Uno is changing the digipot as fast as it can.  It takes 16 usec per step, which results in an update rate of 62.5 kHz.

How Fast is It?  The picture above shows that the digipot is only being updated every 16 usec, which means it has an update rate of 62.5 kHz.  This is within my 50-67 kHz requirement.  So that's good, right?  Well, no, not exactly.  I am a little uncomfortable with the fact that there is no margin.

The Need for Margin:  In achieving this 62.5 kHz result, the Arduino is doing nothing but updating the value of the pot over and over endlessly.  That is all that the Arduino is doing.  In my envisioned hack for Polysix, however, my Arduino would need to do a few other tasks, as well.  For example, the Arduino will need to listen to its Serial port so that it can receive commands as to what values to use for the pot.  If the Arduino is running flat-out just to maintain a high update rate, it probably wouldn't have enough spare cycles to service the serial port.  That would be unacceptable.  So, while it is exciting that I got the system to operate this well, I think that the that the Arduino Uno isn't quite fast enough.  I need to try something else

Trying a Teensy:  My next step is to try a faster Arduino.  Or, an even better plan would be to step up to the fastest Arduino-like board that I know: Teensy 3.  But I think that'll have to wait until my next post.

Update:  My results with the Teensy are here.  The Teensy is *really* fast!


  1. Hi chipaudette,

    Very cool stuff! I'm definitely interested to see a guide with a teensy 3!

    Thanks for explaining the steps,


    1. Hey, Thanks for reading! I posted my findings with the Teensy. You can check it out here:


  2. Thanks for providing the detailed setup and working Arduino code! This will help me get up and running ASAP which will save me much headache!