Tuesday, September 3, 2013

First PCB - MCP4922 DAC

I've done it.  I've made the leap.  I've designed my first PCB.  Yay!

Top and Bottom Illustrations of my PCB (from OSH Park)
The purpose of my new PCB is to be a breakout board for the MCP4922 DAC.  This is a 2-channel, 12-bit DAC that I've used for previous projects including: (1) a pitch CV quantizer for my theremin, (2) a pitch CV corrector for my ribbon controller, (3) a CV recorder/looper for my Korg Mono/Poly, and (4) an Arduino wavetable oscillator.  It's this latter project -- the wavetable oscillator -- that I'm looking to resurrect.

I'm eventually looking to make six of these wavetable oscillators -- one for each voice of my Korg Polysix.  On my previous projects, I just wired up each DAC individually by hand on some proto-board.  But, when making six, that's just too full of error possibilities.  So, I designed my first PCB to simplify the construction of six units.  This simple first board will be a stepping stone to my actual goal, which is to build a bigger board that includes two of these DACs (permitting 4 channels of audio and/or CV outputs) along with an Arduino-compatible AVR microcontroller to drive the DACs.  All of this will be on one PCB.  For a guy who has never designed a PCB before, I figured that it would be better to start smaller...such as with this MCP4922 breakout board.

Schematic that I Created in Eagle 6.5
For software to do the PCB design, I chose to use CadSoft Eagle.  I hear that Design Spark might be a better choice (also free, but with fewer constraints than Eagle), but most of the bigger DIY electronics sites (Sparkfun, Adafruit) seem to provide their designs and models in Eagle, so I went with that.

Any PCB design starts with defining the schematic for the circuit that you want to turn into a PCB.  Since I'm just doing a breakout board, the schematic ought to be very simple since their are so few components.  The primary elements are just the IC in the middle and some connectors (or through-hole solder points) around the periphery.  As you can see in the schematic above, I all the input signals to the DAC come in via an 8-pin header on the bottom left (I only needed 7 pins, but the PCB model for the 8-pin looked better).  As for the outputs of the DAC, I brought its two outputs to separate 2-pin headers, as shown on the right side of the schematic.   Pretty straight-forward.

In addition to the connectors around the periphery, it is common for a breakout board to include those supporting components (capacitors and resistors) that are necessary for every likely usage of the chip.  Looking at the chip's datasheet, I see that it always suggests that you use a couple of caps for power supply decoupling, so I included 0.1 uF and 10 uF capacitors in my design.  Also, after looking through the datasheet, I decided that I was never going to want to change the reference voltages applied to the chip, so I just tied those pins to the power supply, which the datasheet said was fine.

The centerpiece of this design is, of course, the MCP4922 chip itself.  Note that labeling on its symbol is poor ("REFDES TYPE", what is that?).  The problem is either that I don't know how to use Eagle (which is true) or that the device model itself is poor because it was robo-translated to Eagle format from the generic format provided by Microchip.  When I was done, I found a model for the MCP4922 in the Adafruit Eagle library.  I should have used that version of the model instead.  But, what's done is done.

2-Layer PCB Design as Performed in Eagle.  Red traces are on the top layer.  Blue are on the bottom.
After completing the schematic, I switched Eagle over to its PCB layout mode.  With a friend's help on how to use the program, I whipped out the design above.  Note that the traces use a few different widths...some are fat and some are skinny.  The inconsistency is my fault and it is only partly by design.  The default trace size is very thin.  I thought it important that the power and ground traces be thicker, especially between the IC and the decoupling caps.  So, I thickened those particular traces by hand.  I did not do a great job.  In the future, I'll try Eagle's "nets" feature so that the trace thickness is more automated.

You'll also note that everything on the PCB is through-hole, except for the two caps, which are SMT (surface mount).  This will be my first time soldering SMT.  Caps are pretty easy, so this should be good training for me.  If it goes well, maybe I'll use more SMT for my future, bigger circuits.

After completing the PCB layout, I had to choose where to get the board manufactured.  Being a fan of Sparkfun, I remembered one of their blog posts that talked about their BatchPCB service being merged with OSH Park.  So, I checked out OSH Park and it looked like a pretty good deal (2-layer board for $5 per square inch, and you get three copies).  A key benefit for me was that OSH Park allows you to upload your Eagle file directly, without going through the error-prone process of exporting Gerber files.  For a newbie like me, that's outstanding.

Before sending my PCB design to OSH Park, I downloaded their DRU file for Eagle, which specifies all of the design limits used in their manufacturing process.  This is important to ensure that your design can actually be fabricated.  When I ran the DRU check on my PCB,Eagle reported some errors with my design.  Mainly it saw that all of my "text" was assigned to the wrong layer.  If I didn't change anything, my "text" was actually going to be printed copper traces on the same layers as the rest of my traces.  This would have shorted everything out!  Oops!  Thank you DRU check!  So, I corrected the problem by moving my text to the correct layer ("21" in Eagle) and re-ran the DRU check.  Now everything was good.

I uploaded my design to OSH Park.  After processing the Eagle file, the OSH Park page produces a bunch of images of my board (like the one at the top of this post) so that I could check the design.  I noticed that some text was written wrong, so I fixed that in my Eagle file and uploaded the design again.  I iterated like this 3 or 4 times before I was happy.  When I was eventually satisfied, I accepted the design.  It's going to be $5.85 for three copies and the shipping is free.  What a deal!

Now I wait for them to arrive.   And to see what design errors I made.  Isn't this hobby fun!?!

(Oh, I shared my PCB design on OSH Park.  If you're curious, you can see it here.)

Follow-Up: The PCB's have arrived!  Check it out here.
Follow-Up: I've assembled the PCB.  Check it out here.
Follow-Up: I've tested the PCB.  It works!  Yay!  Check it out here.

Follow-Up: I've designed my second PCB.  Much more complicated.  You can check out the story here.


  1. I'm curious about what you're doing with these?

    Recently I've been working on an audio shield for Teensy3 with the aim of brining CD quality audio projects to the Arduino world.

    1. Hey, Thanks for the comment!

      I'm mainly using this as a design exercise. I will be driving it from an Arduino. If it works, I'll consider the exercise a success and I'll go to the next step...I'll layout a new board with the MCP4922 DAC *and* with an AVR processor on the same PCB. I'll program the AVR like an Arduino, but it'll have a DAC there ready-to-use! Then, it can be either a wavetable oscillator or a CV generator.

      If you're interested in "CD Quality" the MCP4922 is only 12-bit, so it won't do the job. There's a really nice high-res high-sample-rate "Audio Codec Shield" available from Open Music Labs: http://www.openmusiclabs.com/projects/codec-shield/

      The problem with a regular Arduino is that it just can't feed data fast enough to the shield to keep up with 44.1 kHz CD Audio rate. You'll need to step up to a Maple to do that. A Due is fast enough, too, but I don't know if this shield will work with a Due.

      Good luck, and be sure to let me know which way you go for CD quality audio on the Arduino!

    2. It's been nearly a year, and so very much has happened, especially in the last several weeks.

      The audio library is still "beta", but now has quite a lot of functionality. There's now a GUI for designing the interconnection of audio objects that will run all internally (everything at 16 bit 44kHz), controlled by the arduino sketch.

  2. I'm using Teensy3, which is a board my company makes. It uses a 32 bit ARM chip similar in capability to Arduino Due, but sells at the price of a Leonardo. It has DMA for very efficiently moving audio data in and out of the chip.

    My current design has a SGTL5000 codec chip, which is very similar in capability to the WM8731 on the Open Music Labs codec shield. I added a SD card socket and SPI flash memory, for storing audio files or short clips. I've been playing .wav files which sound great, though the slowness of the SD library does hog the CPU a bit. I can stream stereo in to stereo out using only a few percent of the CPU time.

    Something I've been looking at recently is implementing wavetable synthesis, probably using soundfont files (likely converted to an intermediate format). The ARM chip is pretty fast, and the one I'm using is the M4 with lightweight DSP instructions. But the soundfont format has lots of CPU intensive options, like reverb, vibrato, and parameterized resonant filters. So far, it appears nobody has attempted this sort of thing on any Arduino compatible board.

    I'm working on the supporting library now, which is a LOT more work than just making the hardware. I'm building connection objects that automatically stream data from inputs to processing objects to outputs, all done in the background, so it will be Arduino-style easy to use (no callbacks to urgently create data or requirements to do things at extreme speed at the sketch programming level). So far, I've only created a few objects, other than input/output, but now that the basics are working I'm starting to focus on writing objects to do fun stuff like oscillators, modulators, mixers, etc.

    I'm keeping an eye out for people's audio projects. My big concern is making the library API able to do a wide range of things. Even if most is added later, the last thing I want to do have to change all the code in an incompatible way, only because there's some important classes of applications I didn't consider. You mentioned a few things that caught my eye. I have a pretty good idea of how to implement thing audio stuff I already understand..... but I'm curious about some of these things you're looking to do with controlling synths? Maybe it's things I haven't anticipated?

    1. Hi,

      I am aware of the Teensy3, which looks great. I've written my own wavetable synth and deployed it on Arduino and on Maple (an Ardiuno-like ARM board from Leaf Labs that came out well before the Due). For the analog output, I've used PWM, I've used the MCP4922, and I've used the Audio Codec Shield that you referenced from Open Music Labs.

      The highest-fidelity reproduction came from the Maple with the Audio Codec Shield. This had the highest fidelity because I could run the sample rate very high. I also could have high polyphony.

      The worst sounding was Arduino using PWM. The limited sample rate, PWM rate, and bit depth made it sound awful.

      The most engaging sounding configuration was the Arduino with the MCP4922. The key was to do the style of wavetable synthesis where you vary the sample rate to get the pitch that you want (like the PPG Wave and SCI Prophet VS). With the limited sample rate that the Arduino could handle, I got lots of aliasing effects. But, because the sample rate changed directly in relation to the pitch of the note, the aliasing was a function of pitch, too...so whole thing sounded like a weird but compelling instrument. I liked it. That's why I continue to pursue the MCP4922 with this breakout and why I'll be looking to put it and an AVR (with Arduino bootloader) on the same board. Then, I'll have a funky one-voice wavetable synth on a single little board. Fun!


  3. Paul, Chip,

    funny. Seems we're thinking alike, at about the same time.

    I've been working on a new V2 version of my Goldilocks board that puts a MCP4922 and a Brown-Burr 4134 on the board, to provide a dual DAC capability. There are some other nice things too.

    I'll send you the schematics (open hardware) if you're interested.

    Whilst I've designed Goldilocks V2 with both DC (level setting) and AC (audio) in mind, the challenge is getting enough processing time from an AVR, even when running at 22MHz.

    I'll be sampling some prototypes before Christmas, and will probably do another Pozible project in the New Year, to see if anyone else, besides me, wants one.

    One question that still worries me is, is the lack of true "analogue" projects in Arduino world an artefact of the lack of true analogue capabilities, or is it because there simply aren't analogue things left to do in this world?


    1. Hi Phillip,

      Thanks for your interest!

      Regarding analog and Arduino, I think that the "lack of true analogue projects" for the Arduino is true only if you're speaking of projects where the Arduino *outputs* an analog signal. If that's what you mean, yes, there is truly a lack of such projects. I think that the cause for that absence is likely due to the absence of interesting applications for analog outputs. Outside of the world of synthesizers and the world of audio, I can't really think of any other application that aren't adequately addressed using PWM.

      It is true that audio applications on the Arduino would be killer. There would be numerous analog projects for Arduino if the Arduino could do audio. Unfortunately, it can't. I see two reasons...

      First, PWM on the Arduino is not fast enough to get good audio...so you need a DAC, which is bit more difficult to add and code for than an LED or potentiometer. A pre-wired DAC shield would help. But, then you'd run in the second hurdle...

      The second hurdle is that the Arduino just isn't fast enough. You can kinda do audio...but the sample rate has to be really low. Or you have to go to a lot of coding in assembly language. That's not the Arduino way. Even to get a timer going so that you have a consistent sample rate...that requires digging into the AVR macros to setup the timer. That's not really the Arduino way, either.

      So, while some people are interested in forcing the Arduino to do audio (like me and you), it's not a natural platform for that application. We're spending lots of effort to make it happen. I like that challenge. Most people probably don't.

      A more natural platform for audio would be the Raspberry Pi...it's got the speed and the software libraries to make it so much easier.

      Back to the other reason for analog output on the Arduino...controlling synthesizers via Arduino-generated control voltages (CVs)...I think that the Arduino is OK for that application...once you get a DAC. Sadly, there just aren't that many CV synth / Arduio / DIY hobbyists out there.

      But, I know that I'm interested (hence my blog) and it sounds like you're interested. Let's make some cool stuff and share!


  4. Chip,

    I forgot to give some links to related stuff, for the lazy.

    The previous Goldilocks project on Pozible

    Some notes on using the OML Audio Codec Shield

    And AVRfreeRTOS

    I'm peer reviewing the Goldilocks V2 Prototype design at the moment, so things are a bit in flux. But, if you're interested and you want to drop me your email, I can send you the Eagle files.