Flyback diode on PWM fan?

I am having some unexplained problems and have burned out a couple of photons in the last few weeks and was wondering if anyone can tell me what I am doing wrong.

I have a project where I am creating a controller for a cold frame. Basically pair of electrical valvles ( and a pair of PWM fans at the business end. One set for intake and one for exhaust. The idea is that when it gets too hot in the cold frame relative to outside temps (a couple of ds18b20 temp sensors). I can open the valves accordingly and operate the fans as needed. You can see my code and some notes in my repo here: There is a lux sensor too but that is not important.

I have done some testing and it is working ok except the valve is only 1/2 is too small and takes too long to cool off but I have some ideas to improve that.

I am occasionally killing PWM pins and one photon gets up to 125C in 3 minutes. I am wondering if I need a flyback diode between PWM fan pins and ground? Here is the setup:

My board has a 12V rail at the top ( and the 3.3V control rail at the bottom. I have some NPN MOSFETS to provide the +12 and ground to the FANS and I am using TX and RX pins as PWM outputs. I have 4 wire fans and I am not using the third pin (tachometer). I use the MOSFET so I can complete turn off the FANS since most pwm fans will run at slow speed even if the PWM pin is set to 0

I bought two sets of Fans. The “good set” Noctura only run at a low speed and is not responsive to the analogWrite. I can measure on DMM and the voltage gets “Stuck” at different voltages (I burned out three pins and all stick on a different voltages). However the cheap fans ( worked great.

However I was creating a wire harness and decided to give the fan 12V off the rail and I burned out another PWM pin using the cheap fan that was working great. Now I just get 850mv constant on that. I removed the fan and hooked up both PWM pins to to my oscilloscope and I can see the one I did not hook up is behaving like I want and I can see the square wave where as the other one is just steady at 850mv not matter what analog write value I use.

I was think of this PWM control pin to the fan like a digital signal and assumed that I did not need to protect this pin but now I am wondering if I got something wrong in my head and I should try a flyback diode across it.

Please note I am powering the fan via the MOSFET but not like you think. I am using it as a relay and giving it full 12V, I am using the PWM control pin of the fan to control the speed.

Also I am coming off the 12V rail into a buck convert to drop it down to 5V and currently going into a spark fun battery shield (which is dumb since I already and coming off a 7AH 12V batter). But I think I will go straight into VIN. While researching my issue I saw @peekay123 say “don’t forget the decoupling capacitor across vin and ground” onthis post and it blew my mind. It seems like a 0.1uF decoupling capacitor between the Vin pin and GND is just going to short VIN to ground. Can someone help explain why this isn’t the case.



This setup worked for me numerous times. Just also add a resistor to the pin running to the FET gate.

Thanks @RWB, I saw your post too but it looks like you are using a 2wire fan and controlling the speed by sending PWM signals over the load. I am trying to use the dedicated speed control pin of the fan. But maybe this is a dumb idea and I should just use your approach. And I do have a 1k R on my MOSFET.

Did you end up keeping in the diode? None of my MOSFET rigs have flyback diodes but none of them (except this one) run motors.

I’ve done it both ways, with 2 wire fans and with fans with dedicated speed control wires.

I did use the Flyback Diode on the 2 wire fan project.

I used a regular Arduino Uno to control speed on the fans with the speed control wires. I had to use a FET on the power lines to these fans because even at the lowest speed setting the fan would not stop, just run slow.

My Arduino code for that is below, the prescaler code was taken from an example I found online to get the correct pulse output for the fans. :

#include <Adafruit_SHT31.h>
#include <Arduino.h>
#include <Wire.h>

Adafruit_SHT31 sht31 = Adafruit_SHT31();

word VentPin = 3;
int FanEnable = 8;

float temp;
float tempMin = 95;   // the temperature to start the fan
float tempMax = 120;   // the maximum temperature when fan is at 100%
int fanSpeed;

void setup() {
  Serial.println("SHT31 test");
  if (! sht31.begin(0x44)) {   // Set to 0x45 for alternate i2c addr
    Serial.println("Couldn't find SHT31");
    while (1) delay(1);
  pinMode(VentPin, OUTPUT);
  pinMode(FanEnable, OUTPUT);
  digitalWrite(FanEnable, LOW);

void loop() {

  float t = sht31.readTemperature();
  float tF = (t* 9) /5 + 32;

 // if (! isnan(t)) {  // check if 'is not a number'
    //Serial.print("Temp *C = "); Serial.println(t);
 //   Serial.print("Temp F = "); Serial.println(tF);
 // } else { 
  //  Serial.println("Failed to read temperature");
 // }

     temp = tF;     // get the temperature
   if(temp  < tempMin) { // if temp is lower than minimum temp 
      fanSpeed = 0; // fan is not spinning 
      digitalWrite(FanEnable, LOW); 
   if((temp  >= tempMin) && (temp <= tempMax)) { // if temperature is higher than minimum temp and lower than max temp. 
      fanSpeed = map(temp, tempMin, tempMax, 0, 120); // the actual speed of fan 
      pwmDuty(fanSpeed); //  (range = 0-79 = 1.25-100%)
      digitalWrite(FanEnable, HIGH); 
   if(temp  > tempMax) {        // if temp is higher than tempMax
      pwmDuty(100); // Fan On Highest Speed. 
      digitalWrite(FanEnable, HIGH); 

   Serial.print("Temp F = "); Serial.println(tF);
   Serial.print("Fan PWM = "); Serial.println(fanSpeed);


void pwm25kHzBegin() {
  TCCR2A = 0;                               // TC2 Control Register A
  TCCR2B = 0;                               // TC2 Control Register B
  TIMSK2 = 0;                               // TC2 Interrupt Mask Register
  TIFR2 = 0;                                // TC2 Interrupt Flag Register
  TCCR2A |= (1 << COM2B1) | (1 << WGM21) | (1 << WGM20);  // OC2B cleared/set on match when up/down counting, fast PWM
  TCCR2B |= (1 << WGM22) | (1 << CS21);     // prescaler 8
  OCR2A = 79;                               // TOP overflow value (Hz)
  OCR2B = 0;

void pwmDuty(byte ocrb) {
  OCR2B = ocrb;                             // PWM Width (duty)

Great thanks @RWB . so when you use the control wire of the Fan did you isolated it in any way from the MCU? With a diode of optocoupler? Or did you wire straight to a gpio pin

I wired it directly to the GPIO pin but did put a 1K resistor in between.

The FET I used to control power to the Fans was this which is optoisolated.

Capacitors exhert a (near) infinite resistance for low frequency signals and low resistance for high frequencies.
That's why placing it between Vin and GND won't short anything as DC is the lowest frequency you can get :wink:

Providing a schema rather than assuming what we may or may not think might be the better way to go.

And what about the fourth pin? :wink:

Why would that be? To me that would indicate some issue with your wiring.

What made you assume this?

You may need to read up on capcitors and inductors and how they work and react when presented with DC and/or high/low frequency PWM.

Or look at videos like this

1 Like

I posted that part.

The wiring was correct but my assumption that the fan still ran very slow and did not completely stop from spinning had something to do with the PWM signal the Arduino was generating went set to 0.

I preferred the mosfet controlling power to fan because it was a battery based application and keeping the small amount of power the fans circuits consumed when not needed was eliminated by not supplying it power until it was needed.

I didn't put the output of the Arduino PWM pin on a scope to see what it actually was when set to zero, it didn't matter to me since cutting power to fan did the same thing.