Archive for March 14th, 2012

Peltier PWM Temperature Control: Noise Blanking

The MOSFET tester I’m building controls the MOSFET’s gate voltage and drain current, while measuring the drain voltage. That, however, puts the drain terminal at a relatively high-impedance node between two current sources: the limiter and the MOSFET-under-test. When they’re both set to nearly the same value, the drain terminal picks up a generous helping of 32 kHz noise from the 3 A PWM Peltier module current. When either current source is set much larger than the other, the higher one serves as a relatively low impedance path that reduces the pickup.

I thought about grounding the thermal block, but that means adding an insulating washer under every MOSFET-under-test, which means an even greater thermal control problem. So the easiest solution is to just turn off the PWM during measurements:

Peltier Noise - VDS - PWM Shutdown

Peltier Noise - VDS - PWM Shutdown

The lower trace (at 5 V/div, not 500 mV as shown) is a digital output marking the duration of the three analog reads: temperature, drain voltage, and drain current. The upper trace shows the absolute worst case for the noise, which looks rather awful.

The Peltier PWM comes from Arduino digital output 10, which is lashed to hardware Timer 1. Turning off the PWM requires setting the corresponding clock prescaler to “no input”, then setting it back to select the appropriate clock input after the measurement.

Just on general principles, I average three successive analog inputs, so the Arduino source code for the analog reads looks like this:

#define TCCRxB                  0x01        // set prescaler to 1:1 for 32 kHz PWM
#define NUM_T_SAMPLES    3

float ReadAI(byte PinNum) {
word RawAverage;

    digitalWrite(PIN_SYNC,HIGH);                // scope sync
    TCCR1B = 0x00;                              // turn off Peltier module PWM

    RawAverage = analogRead(PinNum);            // prime the averaging pump

    for (int i=2; i <= NUM_T_SAMPLES; i++) {
        RawAverage += (word)analogRead(PinNum);
    }

    TCCR1B = TCCRxB;                            // restart Peltier PWM
    digitalWrite(PIN_SYNC,LOW);

    RawAverage /= NUM_T_SAMPLES;

    return (float)RawAverage;
}
About these ads

3 Comments