Saturday, November 26, 2022

MCP33151 14 bit ADC breakout board--Inexpensive High resolution ADC for embedded C Projects

I'm trying to better understand volt per octave circuitry.  

To that end I built a RP2040 based circuit that used V/Oct input to create a voltage controlled oscillator, based around an AD9833 function generator IC--previous post is here

Can the VCO be improved by implementing higher resolution analog to digital conversion? Let's find out.

For this post I built a simple breakout board (abbeviated as "BoB") using Microchip's MCP33151 analog to digital converter (ADC).  Data sheet for this IC is here

Let's get right into it.

The MCP33151 BoB has 100mil edge connectors and will drop into a DIP-14 IC socket. 


DESIGN

I went to Digikey and looked at a whole bunch of their SPI 14 and 16 bit ADC's. Many had features I didn't need, such as registers to store the last ADC read when the chip was powered cycled.  

And: most of the >12 bit ADCs in their catalog were quite expensive--anywhere from $8USD each to over $40 per chip and beyond.

The MCP33151 however was quite affordable ($2.83 USD each for the 1Mhz samples per second version); great! 

It had another feature I thought would be good for us makers: you can power the chip with 3.3V and ground, but use 5VDC as the reference voltage for its analog to digital conversion. Event better: MCP33151's SPI logic voltage follows Vdd so you don't blow up your MCU when sampling 5V sources. 

A complication: the MCP33151 requires a 1.8V source in addition to Vref and Vdd, for "analog power".  From its datasheet: the maximum and minimum voltages permissible for this input were +/- .1V. Deviate from that and you might blow up the IC.  

A low dropout 1.8V regulator is needed. Fortunately I had some MCP1700CM's (TO92--1.8V) from another project. 50c US each...again, affordable! 

I used 100mil connectors and a DIP14 layout, with 4 "NC" pins, to make the BoB easy to insert into a standard 14 pin DIP IC socket. 

 I laid it out in Eagle, added 1206 sized SMD filter caps, and sent it off to the blog's patient sponsor, PCBWAY.

Wham bam, the boards are back:

top to bottom: gnat-ass-tiny MCP33151 chips, MCP1700CM regulators, a US quarter for reference, and the unpopulated BoB's. Thanks as always to PCBWAY for helping out this blog.

BUILDING OUR DOG BoB

The MCP33151 is an MSOP-10 surface mount device (SMD). These are really really small. SMD work intimidated me at first, but after buying a decent stereo bench microscope, working with parts this small has been--managable?  

I reviewed a SMD how-to video and got to work. Once I got everything set up on the bench and took a chill pill soldering the parts to the BoB was not that difficult.

You can get gerbers, eagle files, PDFs etc for the BOB from Github: here.  Or from the PCBWAY community: here.

Ready to program and test....

PROGRAMMING

The 33151 acquires its samples very quickly, at a speed that cannot be changed programmatically.

With SDI pin tied low: after a chip select (CS) logic low the IC quickly samples the voltage at input. 

On CS down (or, when the sampling is done, whichever comes last) the IC also puts 15 bits of sampled data onto the SPI bus. The least significant 14 bits--0 to 13--are sample data.  Bit 15/MSB--which oddly is never mentioned in the datasheet anywhere I could find--is put onto the SPI bus as well as a "don't care" bit.  Bit 14 is always zero when SDI is held low.

The datasheet calls this "without busy mode". 

However there is a slightly more advanced "busy mode." 

I found its description in the datasheet hard to follow at first but figured it out (well, I think I did....)

Busy mode works like this:

Tie SDI high. Now, bit 14 can be zero or one. In "busy mode" a one located at bit 14 means the CS interrupted the sample process; otherwise it's a 0.  

The idea: detect if CS high-to-low stepped on the sample process; read the value of bit 14 and if it's a 1, take action--for instance, go to the Hotsy Totsy and talk embedded C with the fellow geeks.

I drew up a lab note about this:



However, JOY! I wasn't working with fast SPI speeds, so I forgot about all the chip "busy" crapola and tied SDI to ground:

 




Next I wired it up to a Raspberry Pi Pico--the affordable and highly capable 16 bit dev board I've been experimenting with lately:


I took a break, came back, and double-checked my work--building the BoB was a bit tricky and I didn't want to smoke the little turd.



For signal IN I used an no name/made in China bench power supply. I put either 5V or 3.3V into the IC's "REF" pin. 

I used my usual embedded C coding computer--an Ubuntu VM running VSCODE and a Raspberry Pi 4 for receiving/sending serial data--to write a loop that read the SPI output and threw the RP4's minicom app.

After fixing a few dumb mistakes my code worked...I could see 14 bit values from my serial monitor.  

But! There was a lot of variation in each read and an unacceptable amount of slop in the ADC conversion process. 

Was it my layout, the cheap power supply I whose output I was sampling, or something else?  

I solved this pretty quickly. I used a second MCP1700 reference voltage IC as the voltage source to re-test the analog to digital conversion process. 

The MCP1700's output, when sampled, was not jumping all over the place. Better still, if I threw away the 3 LSB's (x >> 3) the signal was pretty steady:


 

I am not sure yet but this is probably good enough for volt/octave DCO's.

Next, I need to use the MCP33151 as the A to D for the V-octave DCO currently on the bench and see if it helps make the VCO's output acceptly steady. 

I will cover the result in a future post....update: the V/octave DCO worked fine with 12 bit ADC.  But, i am sure I will find uses for an inexpensive 14 bit ADC in the future.

In the meantime, you can get the MCP33151LIB embedded C code from my github repo here.

Coda: ARDUINO and MCP33151

I didn't try to port my code to Arduino Sketch, but this BoB would be useful for that development environment--however, since Arduinos are mostly 8 bit and this is a 14 bit ADC, you have to do some slicing and dicing. I found this Sketch code snippet that looks like it will work--here

it's time to move on.  

Until next time, don't breathe the fumes.

No comments:

Post a Comment

A guy OK with C tries to learn C++. Bjane me Up, Stroustruppy!

Why no posts so far for 3-2024?  I have been woodshedding, brushing up on C++ skills.  What got me to finally start digging into C++? I was ...