When driving high-current loads like a 10A DC motor or a 150W cartridge heater with an ESP32 and a power MOSFET, guessing the heatsink size inevitably leads to melted silicon. You need a closed-loop thermal management system. The core of this is calculating the thermal path and monitoring it with an NTC (Negative Temperature Coefficient) thermistor. An accurate ntc sensor temperature reading gives you the real-time case temperature, allowing your microcontroller to throttle the PWM duty cycle before the semiconductor junction exceeds its absolute limits.

Sizing the Heatsink: Rtheta Math and Real Part Numbers

Before you can monitor temperature, you must define the thermal path. Let's look at a real-world scenario: an IRFZ44N MOSFET in a TO-220 package driving a 12V, 10A resistive load (120W). The IRFZ44N has an $R_{DS(on)}$ of 17.5mΩ at 25°C, but silicon resistance increases with heat. At 100°C, $R_{DS(on)}$ roughly doubles to 35mΩ. The steady-state power dissipation ($P_D$) in the MOSFET is: $P_D = I^2 \times R_{DS(on)} = 10^2 \times 0.035 = 3.5W$ To select a heatsink, we calculate the total thermal resistance from junction to ambient ($R_{\theta JA}$). The maximum junction temperature ($T_{J(max)}$) is 175°C, but for long-term reliability, we cap our target junction temperature ($T_J$) at 125°C. Assuming a worst-case ambient temperature ($T_A$) of 40°C inside an enclosure: $R_{\theta JA} = (T_J - T_A) / P_D = (125 - 40) / 3.5 = 24.28 \text{ °C/W}$ The total $R_{\theta JA}$ is the sum of three thermal resistances in series: 1. Junction-to-Case ($R_{\theta JC}$): 1.0 °C/W (from the IRFZ44N datasheet). 2. Case-to-Sink ($R_{\theta CS}$): 0.5 °C/W (using a Bergquist Sil-Pad 400VOS thermal interface material). 3. Sink-to-Ambient ($R_{\theta SA}$): This is the heatsink's rating, which we must solve for. $R_{\theta SA} = R_{\theta JA} - R_{\theta JC} - R_{\theta CS} = 24.28 - 1.0 - 0.5 = 22.78 \text{ °C/W}$ We need a heatsink with an $R_{\theta SA}$ of 22.78 °C/W or lower. A real-world part that fits this is the Aavid Thermalloy 577102B00000G, an extruded aluminum TO-220 heatsink rated at roughly 14.5 °C/W in natural convection. This provides an 8 °C/W safety margin, which is critical when accounting for enclosure heat trapping.
Warning: Never size a heatsink based solely on the 25°C $R_{DS(on)}$ value. Always use the temperature-derated resistance at your expected operating temperature, or your thermal math will underestimate dissipation by up to 100%.

NTC Sensor Temperature Tables and Derating Curves

With the heatsink sized, we mount a 10kΩ NTC thermistor (B-parameter = 3950K, such as the Vishay NTCLE100E3103) directly to the heatsink tab using thermally conductive epoxy. To translate the ESP32's 12-bit ADC readings into actionable thermal data, we use a voltage divider with a 10kΩ pull-up resistor to 3.3V.
10kΩ NTC Thermistor (B=3950) Thermal & ADC Lookup Table
Heatsink Temp (°C) NTC Resistance (Ω) ESP32 ADC Raw (12-bit) Derated Max Continuous Current (A)
25 10,000 2047 43 (Absolute Max)
50 3,590 1081 38
75 1,495 532 31
100 699 267 22 (Throttle Threshold)
125 361 142 11 (Critical Shutdown)

This table directly maps to the MOSFET's power derating curve. On the datasheet, the Safe Operating Area (SOA) and power derating graph show that above 25°C, the allowable power drops linearly to zero at 175°C. By reading the ADC values above, the ESP32 knows exactly where the system sits on that derating curve.

How Hot is Too Hot?

The silicon limit is 175°C, but 125°C is the practical ceiling. Beyond 125°C, the $R_{DS(on)}$ increases so rapidly that the MOSFET generates more heat than the heatsink can dissipate, triggering thermal runaway. Our code must initiate PWM throttling at 100°C and a hard shutdown at 125°C.

Airflow, Enclosures, and Thermal Stress Signatures

Thermal resistance is not static; it changes based on your mechanical design. Understanding what airflow and enclosure changes buy you is essential for passing edge-case stress tests.

What Airflow Buys You

Adding a standard 40mm x 10mm brushless DC fan (like the Noctua NF-A4x10) pushing 5 CFM across the Aavid heatsink drops the $R_{\theta SA}$ from 14.5 °C/W to approximately 5.0 °C/W. This allows you to double your continuous current without changing the silicon. However, fans introduce a mechanical point of failure; your ntc sensor temperature loop must detect fan failure (via a tachometer pin or simply by observing unexpected temperature rise rates) and throttle the load accordingly.

The Enclosure Penalty

Sealing your project in an IP65 polycarbonate enclosure traps heat. A sealed box typically raises the internal ambient temperature ($T_A$) by 10°C to 15°C above room temperature. If your room is 25°C, your internal $T_A$ is 40°C. If you mount the enclosure in direct sunlight or near another heat source, $T_A$ can easily hit 55°C, invalidating your heatsink math. Always design for the worst-case internal ambient, not the laboratory bench temperature.

Failure Signatures of Thermal Stress

When thermal management fails, the MOSFET doesn't always just pop. Look for these specific failure signatures on the bench:

  • Gate Oxide Breakdown: The gate pin shorts to the source or drain. The silicon die overheated, degrading the microscopic gate oxide layer. The ESP32 GPIO pin driving the gate may also be destroyed by the high-voltage feedback.
  • Die Attach Melt (Thermal Runaway): The solder bonding the silicon die to the copper tab melts. The die physically detaches, causing an immediate open circuit or a massive short. This happens when $T_J$ exceeds 175°C for extended periods.
  • Solder Joint Fatigue: Repeated thermal cycling (heating to 100°C, cooling to 30°C) causes the TO-220 leads to expand and contract at a different rate than the FR4 PCB (Coefficient of Thermal Expansion mismatch). Over months, the through-hole solder joints develop micro-cracks, leading to intermittent high-resistance connections and arcing.

Closing the Loop: ESP32 Thermal Throttling Logic

To utilize the ntc sensor temperature data, the ESP32 must convert the ADC reading into Celsius using the Beta parameter equation. For a detailed breakdown of the math, refer to the Ametherm Beta Parameter guide or standard heatsink selection methodologies. Below is the core C++ logic for the ESP32 to read the thermistor, calculate the temperature, and dynamically throttle a PWM-driven load. This code assumes the ESP32 DevKit V1 and uses the 12-bit ADC.
#include <math.h>

const int THERMISTOR_PIN = 34; // ADC1_CH6, no PWM conflicts
const int PWM_PIN = 18;        // MOSFET gate driver pin
const int PWM_FREQ = 1000;     // 1kHz for MOSFET switching
const int PWM_RESOLUTION = 10; // 0-1023 duty cycle

// NTC Parameters (Vishay 10k, B=3950)
const float NOMINAL_RESISTANCE = 10000.0;
const float NOMINAL_TEMPERATURE = 298.15; // 25°C in Kelvin
const float B_COEFFICIENT = 3950.0;
const float PULLUP_RESISTANCE = 10000.0;

float readNTCTemperature() {
  // Average 16 samples to reduce ESP32 ADC noise
  float adcSum = 0;
  for(int i=0; i<16; i++) {
    adcSum += analogRead(THERMISTOR_PIN);
    delay(2);
  }
  float adcAvg = adcSum / 16.0;
  
  if (adcAvg < 10) return 200.0; // Open circuit / sensor disconnected failsafe

  // Convert ADC to resistance
  float resistance = PULLUP_RESISTANCE * adcAvg / (4095.0 - adcAvg);
  
  // Beta Parameter Equation
  float steinhart = resistance / NOMINAL_RESISTANCE;
  steinhart = log(steinhart);
  steinhart /= B_COEFFICIENT;
  steinhart += 1.0 / NOMINAL_TEMPERATURE;
  steinhart = 1.0 / steinhart;
  steinhart -= 273.15; // Convert Kelvin to Celsius
  
  return steinhart;
}

void setup() {
  Serial.begin(115200);
  ledcSetup(0, PWM_FREQ, PWM_RESOLUTION);
  ledcAttachPin(PWM_PIN, 0);
}

void loop() {
  float tempC = readNTCTemperature();
  int targetDuty = 1023; // 100% duty cycle baseline

  // Thermal Throttling Logic
  if (tempC > 125.0) {
    targetDuty = 0; // Hard shutdown: Critical thermal limit
    Serial.println("CRITICAL: Thermal Shutdown!");
  } else if (tempC > 100.0) {
    // Linear derating between 100°C and 125°C
    float derateFactor = (125.0 - tempC) / 25.0; 
    targetDuty = (int)(1023.0 * derateFactor * 0.5); // Cap at 50% max when hot
    Serial.printf("WARNING: Throttling to %d. Temp: %.1fC\n", targetDuty, tempC);
  }

  ledcWrite(0, targetDuty);
  delay(500); // Thermal mass requires slow polling; 500ms is sufficient
}
By combining rigorous $R_{\theta}$ math with real-time ntc sensor temperature monitoring, you transform a fragile high-power circuit into a robust, self-protecting system capable of surviving the worst-case ambient conditions your enclosure can throw at it.