Microcontroller Based BJT/JFET Curve Tracer

GroupDIY Audio Forum

Help Support GroupDIY Audio Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.

Matador

Well-known member
Joined
Feb 25, 2011
Messages
3,063
Location
Bay Area, California
So I decided that I wanted to do a micro controller-based curve tracer project to really exercise my acquisition of the following device:

lpcxpresso_board.jpg


It's an LPCXpresso board with an integrated JTAG end-point and an LPC1769 target MCU.  It runs at 120MHz and has the normal plethora of embodied peripherals like I2C and SPI.  Most importably, it has support on-board for a LAN8720 ethernet phy, but more on that later.  It's a great bargain for about $25!

So what I wanted to do is glue on to this board a basic ADC and DAC block, controlled over SPI.  The DAC's would be used to provide test voltages to a Device Under Test (DUT), and then the ADC section would take voltage and current measurements which could then be displayed.

I selected the following chips for their simplicity, and given the fact that I have used them in previous designs so I know some of their quirks:
1) DAC - TI DAC7614:  a quad, 12-bit voltage output DAC with SPI control
2) ADC - TI TLC2543:  an 11 channel successive approximation ADC with SPI control

However the DAC chip can only source about 2mA of current, so I need a way to boost the current up to acceptable levels for small and medium signal BJT's and JFET's.  I figure I need at least 100mA of output current in order to be useful.

I settled on the following circuit to take the DAC voltage output and buffer it for driving the device:

buffer.jpg


This is essentially a quad precision op-amp wired with three of it's active devices driving in parallel in a voltage follower configuration.  According to the data sheet, this should be capable of driving 100mA before pooping out.

At the end of the feedback loop is a 1 ohm current sense resistor, the two terminals of which is taken to the following current sense circuit:

current_sense.jpg


So this circuit is an INA2134 precision difference amplifier, followed by a bipolar to unipolar conversion stage.  So the output of the difference amp is proportional to the current through the sense resistor (and negative for sink currents, positive for source currents), and the second stage afterwards level shifts this signal into a range of 0V to 5V (which is the VREF for the ADC stage).  This voltage (along with the terminal voltage) is sampled by the ADC and should allow me to plot voltage and current for all channels as a function of input voltage.

So in order to control all of this:  since this board contains an on-board ethernet PHY, all that's needed in the target schematic is an RJ-45 connector and magnetics.  I'm planning on using a regular Magjack from Pulse.

I'm planning on using the FreeRTOS port of EasyWeb which contains support for a simple TCP/IP stack to have this all controlled via a web interface.  Basically you can load a device into the board, load up the embedded server to control what kind of device is loaded, select the tests to run, then start the tests and display the results as a web page.

Since this MCU contains 512kB of code storage (as well as 64kB of SRAM), if I can, I'll port one of the open sources graphics libraries and generate bitmaps in real time (perhaps something like libgd).  Any suggestions on this are welcome!  This is so I can plot the IDS/VGS/VDS curves right on the web page.  Barring that, I can export in Excel comma delimited format and make the curves that way, but if the web page can display the traces that would be even cooler.

Here's my prototype board layout (measures 4.5" x 6"):

ct_board_layout_v1.jpg


I have not broken up the ground planes yet, however given I won't be sampling at light speed I may be able to get away without breaking them up.  I'll have to bread board it up and see how well it performs.

So I'll try to document all of this here in case anyone is interested in leveraging this MCU for other audio related projects like DAC's, ADC's, or perhaps preamp controllers or MIDI hosts/interpreters. 

Suggestions and comments are always welcome!
 
If this is still active (it's been more than 120days since you last posted Matador), I have a current need for something like this, and a lot of very detailed suggestions about it.
Else, I hope it went well for you.
 
Yes, I've been monkeying around with it.

First off, I ran into 3.3V vs. 5V interfacing problems.  The original DAC chips I wanted to use weren't compatible with 3.3V signalizing, so I needed to switch over to a 3.3V part.

I landed on the MCP4922 DAC part, as it was 12-bit and dual channel (what I needed).  I got it successfully working with my NXP micro controller, and I can control the output voltage of each channel independently.

I also abandoned the idea of paralleling op-amps for current drive capability, and just used a BJT stage in the feedback loop of a precision op-amp.  The input is fed from the buffered output of the MCP4922, and I sized the emitter resistors to give a maximum current drive of 100mA per channel.  I've proved that I can put a 150ohm resistor on the buffer output and drive from 0 to 15V without having the output voltage collapse.

Of course another complication is moving between the bi-polar and unipolar domains:  the original chip was bipolar so interfacing to the current buffer was trivial.  Using a unipolar DAC means I have to convert the 0 to 3.3V output to -2.5V to 2.5V by scaling through a differential amp.  I have some differential amps with on-board laser-trimmed gain resistors to try to make this work (since I don't need much gain).

I'll publish the latest schematics for my prototype if you are (or anyone else is) interested.
 
There are no GUI's or fancy curves yet. ;)

I had to re-write a UART driver and hook it through the __sys_write() provision of NewLIB in order to get data out of the controller.  So I have some curves taken from resistors where the code calculates the average resistance.  It seems pretty accurate so far.

Another thing:  I found out that due to INL and DNL I had to implement a SW feedback loop to continually sample and adjust the DAC value until the output analog voltage was the closest.  So now I multisample and average, and then bump the output code up and down a few steps in both directions until I find the closest match.

Here is the output of a 1K resistor, where one channel holds it's control node at 0V, and the other side does the sweep.  It sweeps all 4096 codes so I didn't list all of them here:

Ideal 0.000 1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 9.000 10.000
Channel 1 Code 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
Channel 1 V 0.000 0.001 0.001 0.000 0.001 0.000 0.000 0.001 0.001 0.001 0.000
Channel 1 A 0.000 0.001 0.002 0.003 0.004 0.005 0.006 0.007 0.008 0.009 0.010
Channel 2 Code 0         273         546         819         1092         1365         1638         1911         2185         2458         2731
Channel 2 V 0.004 1.003 1.992 3.007 4.010 4.999 6.006 6.998 8.002 8.990 9.998
Channel 2 A 0.000 0.001 0.002 0.003 0.004 0.005 0.006 0.007 0.008 0.009 0.010

So you can see that the voltage vs. current curve is consistent with a 1K resistor.  The output calculates the resistor as 1004.93 ohms average. ;)

I plan on porting EasyWEB to this application, so it can plug in via Ethernet and have a control screen that interfaces via a regular web browser.
 
Back
Top