chipKIT® Development Platform

Inspired by Arduino™

chipKIT FET Tester

Created Sat, 16 Apr 2016 14:51:09 +0000 by majenko


majenko

Sat, 16 Apr 2016 14:51:09 +0000

I have salvaged a bunch of unknown power MOSFETs from an old motherboard. They formed part of the somewhat complex power circuitry driving the main AMD CPU.

Interested in knowing what they and how they perform I decided to build a little FET tester out of bits I had lying around.

Ingredients:

  • chipKIT Board (I used the forthcoming Lenny that I am just about to release)
  • Combined ADC/DAC board - it's nothing more than an MCP4822 dual 12-bit DAC and MCP3553 22-bit Sigma-Delta ADC
  • Small TFT screen (ILI9341)
  • 470Ω Resistor

[attachment=0]2016-04-16 15.34.10.jpg[/attachment] On the DAC/ADC board one output of the DAC feeds the voltage reference input of the ADC and set to 4095mV. The other output is swept from 0 to 4095mV.

The resistor connects between +5V and Vin+ of the ADC, and Vin- connects to ground.

Connect the gate of the unknown MOSFET to the second output voltage of the DAC, the source to GND, and the drain to Vin+. Sweep the output voltage, and graph the ADC readings against that voltage, and bob's your uncle. One FET tester. [attachment=1]2016-04-16 15.34.21.jpg[/attachment] Code:

#include <DSPI.h>

// This is part of DisplayCore. 
// https://github.com/MajenkoLibraries/DisplayCore
#include <ILI9341.h>

// Available from: 
// https://github.com/MajenkoLibraries/PrecisionADC
#include <PrecisionADC.h>

// My screen is an ILI9341 with the almost standard shield pinout.
ILI9341 tft(PINS_8BIT_SHIELD);
// On the Lenny the 6-pin SPI port is DSPI1
DSPI1 spi;
// Pins 28 and 29 are the SCL/SDA pins on the Lenny
PrecisionADC tester(spi, 28, 29);

int readings[320];

void setup() {
    spi.begin();
    spi.setSpeed(20000000UL);
    tester.begin();
    tft.initializeDevice();
    tft.fillScreen(Color::Black);
    tft.setRotation(1);
    tester.setReference(4095);

}

const int hscale = 12;

void loop() {
    int ly = 0;
    int satmv = 0;
    int thresh = 0;

    for (int x = 0; x < 320; x++) {

        tester.setVOut(x * hscale);
        readings[x] = tester.readMV();        
    
        int sum = readings[x] / 20;
        bool tag = false;
        if (satmv == 0 && sum == 0) {
            satmv = x * hscale;
            tag = true;
        }
        if (thresh == 0 && sum != 204) {
            thresh = x * hscale;
            tag = true;
        }
        
        tft.drawLine(x, 30, x, 240, tag ? Color::Red : Color::Black);

        if (x < 318) {
            tft.drawLine(x+1, 239 - sum - 5 , x+1, 239 - sum + 5, Color::Green);

        }
        
        if (x > 0) {
            tft.drawLine(x - 1, 239 - ly, x, 239 - sum, Color::White);
        } else {
            tft.setPixel(x, 239 - sum, Color::White);        
        }
        ly = sum;
    }
    tft.setCursor(0, 0);
    tft.printf("Threshold between %dmv and %dmv         \r\n", thresh, satmv);
}

majenko

Sat, 16 Apr 2016 21:00:39 +0000

Now with autoranging:

[attachment=0]2016-04-16 21.54.43.jpg[/attachment]

I only wish the ADC I had on that board was faster. I'm only using it because I'm working with voltages between 3.3V and 5V that the on-board ADC of the PIC32 can't cope with. I could faff around scaling it to the internal ACD, but that's more than I can be bothered with right now. And since this has such a nice resolution ADC already on-board that's what I am using.

It would be nice to build a proper tester one day. One using a constant current source instead of a simple voltage divider, and the ability to test with a greater range of gate voltages (up to 10V for instance) and even test P-channel FETS. But for now this will suffice.

#include <DSPI.h>

// This is part of DisplayCore. 
// https://github.com/MajenkoLibraries/DisplayCore
#include <ILI9341.h>

// Available from: 
// https://github.com/MajenkoLibraries/PrecisionADC
#include <PrecisionADC.h>

// My screen is an ILI9341 with the almost standard shield pinout.
ILI9341 tft(PINS_8BIT_SHIELD);
// On the Lenny the 6-pin SPI port is DSPI1
DSPI1 spi;
// Pins 28 and 29 are the SCL/SDA pins on the Lenny
PrecisionADC tester(spi, 28, 29);

void setup() {
    spi.begin();
    spi.setSpeed(20000000UL);
    tester.begin();
    tft.initializeDevice();
    tft.fillScreen(Color::Black);
    tft.setRotation(1);
    tester.setReference(4095);
}


void loop() {
    static int start = 0;
    static int end = 4095;
    static int ly = 0;
    static int satmv = 0;
    static int thresh = 0;

    if ((thresh <= 0) || (satmv <= 0) || (satmv <= thresh)) {
        tft.fillRectangle(0, 0, 320, 20, Color::Black);
        tft.setCursor(0, 0);
        tft.print("Scanning for threshold...");
        start = 0;
        end = 4095;
    } else {
        tft.fillRectangle(0, 0, 320, 20, Color::Black);
        tft.setCursor(0, 0);
        tft.printf("Threshold between %dmv and %dmv", thresh, satmv);
        start = thresh - 20;
        end = satmv + 20;
    }
    
    satmv = 0;
    thresh = 0;

    for (int x = 0; x < 320; x++) {

        float mul = (end - start) / 320.0;
        tester.setVOut(start + (x * mul));
        int sample = tester.readMV() / 20;
        bool tag = false;
        if (satmv == 0 && sample == 0) {
            satmv = start + (x * mul);
            tag = true;
        }
        if (thresh == 0 && sample != 204) {
            thresh = start + (x * mul);
            tag = true;
        }
        
        tft.drawLine(x, 30, x, 240, tag ? Color::Red : Color::Black);
        tft.drawLine(x+1, 239 - sample - 5 , x+1, 239 - sample + 5, Color::Green);
        
        if (x > 0) {
            tft.drawLine(x - 1, 239 - ly, x, 239 - sample, Color::White);
        } else {
            tft.setPixel(x, 239 - sample, Color::White);        
        }
        ly = sample;
    }
}

majenko

Sat, 16 Apr 2016 22:28:32 +0000

To clarify the wiring a little, here's a block diagram of the test circuit:

[attachment=0]FETTest.png[/attachment]