Help with MOSFET

Hello everyone!

I'm making a 3D printer module for a CNC Mill and I'm using Arduino to control the heating of the nozzle. It's my first project so not much experience here. So, since I have to control a 12V 40W heater, I'm trying to use a MOSFET (IRLZ44 DATASHEET) to do that.

This is the circuit I made, the MOSFET is on the bottom left (nevermind the mess on the right side)

The problem is: the heater is on at all times!! (at least when switch SW2 is on).

I took some measurements with a multimeter, the results are shown in the blue boxes on the image below. The output on pin 10 (the one that goes to resistor R3) is calculated via PID Library, and is correctly varying between 0 and 5V. Between Gate and Source, the voltage seems to be the same at all times, completely ignoring the voltage before the resistor R3. Same thing between Drain and Source.

I'd appreciate if someone could please shed some light on this problem. It feels like I'm missing something obvious.

Here's my code:

#include <PID_v1.h>
#include <LiquidCrystal.h>
#include <Encoder.h>

double Setpoint, currentTemp, Output;
const int kP = 3;
const int kI = 1.5;
const int kD = 2;
PID myPID(&currentTemp, &Output, &Setpoint,kP,kI,kD, DIRECT);
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);

//pins
const int buttonPin = 8;
const int encoder1Pin = 2;
const int encoder2Pin = 3;
const int thermistorPin = A0;
const int transistorPin = 10;
const int ledPin = 9;

Encoder myEnc(encoder1Pin, encoder2Pin);

//Variables
long oldPosition = -999;
long newPosition;

boolean buttonPress;
int buttonState = 0;
int thermistorMax = 260;
int thermistorMin = 30;

#define resistorResistence 1000 //series resistor resistance
#define thermistorNominal 100000 //termistor nominal resistance
const int temperatureNominal = 25; //nominal temperature (C)
const int numSamples = 5;
int samples[numSamples];
const int SAMPLETIME = 1000;
int nextUpdate = 0;

void setup() {
  analogReference(EXTERNAL);
  pinMode(transistorPin, OUTPUT);
  pinMode(thermistorPin, INPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(encoder1Pin, INPUT_PULLUP);
  pinMode(encoder2Pin, INPUT_PULLUP);
  Setpoint = 95;
  myPID.SetMode(AUTOMATIC);
  myPID.SetSampleTime(SAMPLETIME);

  lcd.begin(16, 2);
  lcd.home();
  lcd.print("Controlador");
  lcd.setCursor(5,1);
  lcd.print("Temperatura");
  delay(2000);
  lcd.clear();

  Serial.begin(9600);

  delay(200);
  lcd.setCursor(0,0);
  lcd.print("SetPoint:");
  lcd.setCursor(0,1);
  lcd.print("Extrusor:");
  delay(200);
 
}

void loop() {
  //routine for detecting one of two encoder button states
  buttonPress = digitalRead(buttonPin);
  if (buttonPress == 0) {
    if (buttonState == 0) {
      buttonState = 1;
      while (buttonPress == 0) {
        buttonPress = digitalRead(buttonPin);
        delay(100);
      }
    }
    else {
      buttonState = 0;
      while (buttonPress == 0) {
        buttonPress = digitalRead(buttonPin);
        delay(100);
      }
    }
  }
  newPosition = myEnc.read();
  if (newPosition > oldPosition) {
    if (Setpoint >= thermistorMax) {
      lcd.setCursor(11,0);
      lcd.print(" MAX ");
        delay(1000);
      Setpoint = thermistorMax;
    }
    else {
      if (buttonState == 0) {
        Setpoint += 5;
      }
      else {
        Setpoint += 1;
      }
    }
    delay(100);
    oldPosition = myEnc.read();
    lcd.setCursor(11,0);
    if (Setpoint < 99.5) {
      lcd.print(" ");
    }
    lcd.print(Setpoint);
    lcd.setCursor(14,0);
    lcd.print(char(223));
    lcd.println("C");
  }
  else if (newPosition < oldPosition) {
    if (Setpoint <= thermistorMin) {
      lcd.setCursor(11,0);
      lcd.print(" MIN ");
        delay(1000);
      Setpoint = thermistorMin;
    }
    else {
      if (buttonState == 0) {
        Setpoint -= 5;
      }
      else {
        Setpoint -= 1;
      }
    }
    delay(100);
    oldPosition = myEnc.read();
    lcd.setCursor(11,0);
    if (Setpoint < 99.5) {
      lcd.print(" ");
    }
    lcd.print(Setpoint);
    lcd.setCursor(14,0);
    lcd.print(char(223));
    lcd.println("C");
  }
  currentTemp = getThermistor();
  lcd.setCursor(11,1);
  if (currentTemp < 99.5) {
    lcd.print(" ");
  }
  lcd.print(round(currentTemp));
  lcd.setCursor(14,1);
  lcd.print(char(223));
  lcd.println("C");
  myPID.Compute();
  analogWrite(transistorPin, Output);
  if (Output > 0) {
    digitalWrite(ledPin, HIGH);
   }
   else {
    digitalWrite(ledPin, LOW);
   }
}

float getThermistor() {   
  uint8_t i;
  float average;
  int ms = millis();
  if (ms >= nextUpdate) { //repeats routine after a certain time period (500 ms)
    for (i=0; i<numSamples; i++) {
      samples[i] = analogRead(thermistorPin);
      delay(10);
    }
      average = 0;
    for (i=0; i<numSamples; i++) {
      average += samples[i];
    }
    average /= numSamples;

    //Calculate thermistor resistance:
    // [Thermistor Resistance] = [Series Resistor] / (1023/ADC - 1)
    float average = 1023 / average - 1;                           // (1023/ADC - 1)
    float average = resistorResistence / average;               // 1000 / (1023/ADC - 1)

    //Steinhart-Hart equation:
    // 1/T = A + B * ln(R) + C * ln(R)^3
    
    const float Acoef = 0.00069881617;
    const float Bcoef = 0.00021539301;
    const float Ccoef = 0.00000011493814;

    float steinhart;
    float lnR = log(average);
    steinhart = Ccoef * pow(lnR, 3);
    steinhart += Bcoef * lnR;
    steinhart += Acoef;
    steinhart = 1.0 / steinhart;
    steinhart -= 273.15;
    
    Serial.print(average);
    Serial.print(" ");
    Serial.print(steinhart);
    Serial.print(" ");
    Serial.print(Setpoint);
    Serial.print(" ");
    Serial.println(Output);
   
    nextUpdate = ms + 500;
    
    return steinhart;
  }
}

Switching the source is a weird and maybe dangerous setup for the mosfet.
If you want to keep the switch there, then at least connect R1 to gate and source, not to gate and ground.
Wise to move the switch to the 12volt supply of the heating element.

The mosfet should be off with 0volt (< 1volt) between gate and source.
Mosfets are ESD sensitive devices. You might have damaged it with handling/soldering.
An old trick is to weave a thin bare wire through the pins, close to the body, and leave it there until the mosfet and the rest of the parts are mounted/soldered.
Leo..

The “on all the time” and ~0.5 voltage drop sounds like the heater is being powered via the mosfer body diode, which would indicate a wiring error (although I’m sure you would have checked that). Odd is also that the voltage at the middle of a potential divider appears to be independent of the voltage across it, whether 0 or 5 volts.
Maybe for testing, use a simple sketch which explicitly sets D10 to either high or low instead of sketch you have posted.

Wawa:
Switching the source is a weird and maybe dangerous setup for the mosfet.
If you want to keep the switch there, then at least connect R1 to gate and source, not to gate and ground.
Wise to move the switch to the 12volt supply of the heating element.

The mosfet should be off with 0volt (< 1volt) between gate and source.
Mosfets are ESD sensitive devices. You might have damaged it with handling/soldering.
An old trick is to weave a thin bare wire through the pins, close to the body, and leave it there until the mosfet and the rest of the parts are mounted/soldered.
Leo..

Thank you Wawa, I'll move the switch. I might have damaged it with soldering then, I guess it was a bit to much. Could you clarify this old trick you mentioned? Is the bare wire supposed to dissipate the heat from the soldering?

6v6gt:
The “on all the time” and ~0.5 voltage drop sounds like the heater is being powered via the mosfer body diode, which would indicate a wiring error (although I’m sure you would have checked that). Odd is also that the voltage at the middle of a potential divider appears to be independent of the voltage across it, whether 0 or 5 volts.
Maybe for testing, use a simple sketch which explicitly sets D10 to either high or low instead of sketch you have posted.

I'll do the testing, thank you 6v6gt!

gian_nichele:
Is the bare wire supposed to dissipate the heat from the soldering?

No.
The wire shorts all pins together, so any electrostatic charges from you or the soldering iron can't damage the very sensitive gate.

Ever wondered why ESD sensitive parts come in conductive pink or black foam, or in a conductive gray plastic bag.
Google ESD.
Leo..

6v6gt:
Maybe for testing, use a simple sketch which explicitly sets D10 to either high or low instead of sketch you have posted.

Blink is a great one for such tests. One second on, one second off. Very easy to follow with your multimeter.

If indeed you power through the body diode, you switched the drain and source. Carefully check the pinout against the data sheet (and mind that sometimes you get top views, sometimes bottom views!)

Look at the printing on the TO-220 package with the pins pointing down.

Most devices are from left to right: Gate, Drain, Source.
Or for BJT transistors: Base, Collector, Emitter.

The middle pin is usually electrically connected to the flange/heatsink.

But always double-check against the datasheet.
Leo..

Thank you guys, apparently I actually damaged the transistor. I tested blinking an LED as you guys suggested and it just switched from bright to slightly dimmer. I tested again with a new transistor (no soldering yet) and it blinked as it should!

Wawa:
Switching the source is a weird and maybe dangerous setup for the mosfet.
If you want to keep the switch there, then at least connect R1 to gate and source, not to gate and ground.

I actually need to keep that switch there now, oops. So you're saying I should wire R1 like this?

Not really!

Use your original diagram. Short out SW2. Add a switch between D10 and R3.

6v6gt:
Not really!

Use your original diagram. Short out SW2. Add a switch between D10 and R3.

I see, that could work for me. But I also wanted to hook up an LED, so it shows when the heater is heating up, but turns off when the switch is turned off (the point of the switch is to turn the heater off but still keep the LCD and all the rest on). Would this work?

I know the parallel circuit divides the current, would that be a problem?

Thank you guys again for the great help.

EDIT: Never mind that. Instead, I'll connect the switch to 5V and an input pin, digitalRead that pin and use that value to turn on both heater and LED. That should do it.

OK. But if in principle, the function of the led is to indicate that the heater is active, rather than simply the position of a switch, it would be nicer to have the led (together with its current limiting resistor) in parallel with the heater. Since the heater is 12v, you'd need a higher value current limiting resistor (say 1k).