My Stoopid Stuff
  • Home
  • Projects
  • Blog
  • Lec'tronics
  • Links
  • CNC
  • Quick Recipes
  • 3D Printer Tips
  • Voron 2.4

ESP32 Fan Control

7/29/2026

0 Comments

 
I've been working a few projects that require controlling a PC 4-wire (PWM) fan from an esp32 running ESPHome.  One of them is an exhaust fan for my Bambu H2C, which I want to automate based on the printer state.  This is all stuff that is working on my Bento style filter (v2 - yet to be released), so I know it can be done.  The exhaust fan is not however an apples to apples design compared to the working Bento style filter v2, since the exhaust fan will use a 4 wire PWM fan, while the Bento style filter uses 2 wire fans (and controls their speed using  MOSFETs).

It turns out, the PWM control of a fan from an ESP32 is a bit more difficult than just turning a 2 wire fan on or off (or even controlling the speed on a 2 wire fan).  PWM fans should be more efficient than switching a MOSFET to control a 2 wire fan though.  What I've run into are several problems related to the PWM and tach for a 4 wire fan, controlled from an ESP32.  These problems (that I know of so far) are the following:

1. Not all PWM fans shut off completely based on the PWM signal alone.

2. The tach readings can be off by quite a bit.

3. On one of my fans, I noticed that there was a small current backfeeding through the tach line, with the fan's ground disconnected.

I am no electronics expert, but here is what I did to work through each of these issues.  For the first problem of the PWM signal not fully shutting down a fan, that seems like a known aspect of how PWM fans operate.  I learned that most fans will not fully turn off based on a zero duty cycle PWM signal, and will continue to run at some very low speed instead.  There is probably a reason why most of the Arduino or ESP32 fan control tutorials use Noctura fans too.  It's because most Noctura fans do actually shut off completely when the PWM goes to a zeroed out duty cycle, so they're almost like a cheat code if using fans with ESP32's or Arduinos.  I think if I were able to use a Noctura fan for this project, I'd just do that and save myself some headaches.  But I need to use an Arctic 8038 12v fan for the exhuast system, and it does not fully shut off when the PWM signal goes to zero.  

I decided to use an n-channel MOSFET board to control the fan's ground (low side switch), and add a control pin to the ESP32 to cut the fan's ground when it was "off" according to the program.  This is not the best fix, since I learned that fans are tricky, and can suck power from other places if they really want to.  While the MOSFET worked on my Arctic 8038 fan to shut it down, it did not work on another 120mm fan I used to bench test the setup.  I use a 120mm fan to test since the 8030 is a scary finger eating monster at 10k, while the 120mm fan is relatively a kitten at full speed.  The 120mm fan however was pulling a small current through the tach line, which was resolved when the tach line was cleaned up a bit in the next part.
​So the fully shutting off problem was mostly fixed, except for the 120mm bench testing fan which I didn't really care to much about, but the tach readings were still off.  My understanding is that the PWM fans use a tach which is an "open collector" so they only pull the line low to signal.  Without adding a pull up resistor to some voltage like 3.3v or 5v, the tach is just waving a white flag to signal, on a snow covered mountain.  The additional voltage gives the background some color, so the ESP32 can read a signal off the fan's tach line.  I was originally using a 10kOhm resistor to 5v (pull up) off the ESP32's GPIO 7 to read the fan's tach line, but that was not working well.  I then found the following helpful post which explained that using a voltage divider network to limit current and drop the tach line to around 3v at the ESP solved some odd tach readings that author was getting:
https://www.paulkeeble.co.uk/posts/tachometer/

I followed that post and added a similar resistor network as follows:
12v ---- 4.7kohm ----- TACH pin from fan ----10Kohm ----- GPIO 7 (tach read pin pn ESP32) ---- 4.7kohm ---- GND

The tach values still bounce a bit, but they are very close to what I expected, and reasonably stable.

Finally, the last issue was the tach line backfeeding on the 120mm bench testing fan, which was also solved by adding the resistor divider network, so two birds with one stone there.  Here is an image of the backfeeding current before the resistor divider network was added.  This is with the fan ground disconnected (via the n-channel mosfet cutting the fan ground), and zero pwm signal being sent to the fan.  The fan in this test should have been off but was spinning slowly.  In this config, the tach line was connected to the ESP32 on GPIO 7, and there was a 10kOhm resistor to 5v as a pull up so the tach signal can be read by the ESP32.  The ESP was registering 0 RPM as displayed on the OLED in the background (it did show an rpm value when it should be on high or low, but not when "off", though the fan did still spin slowly when "off").  The fan was pulling just a tiny current from the ESP32 while spinning slowly, though it did show the max was 27.4mA! (which I didn't actually catch when it happened so I'm not really sure about that value).  In any case not good.  In contrast, the 8038 monster fan which I intend to use for the project was only showing 0.0003mA (so nothing), when I ran this same test.  I think this would have been OK in the specific case of using the 8038 fan, but not so great in the general case of just using any PWM fan.

I didn't re-test this setup after the resistor divider network was added, but the 120mm fan stops when it should be off now (and that is with the MOSFET cutting the fan ground when "off", along with zero PWM signal).
Picture

That's all I have right now for this project, but the fan control is working much better after the changes mentioned here.  I'm adding this here as much for myself to review, in case I hit this problem again.  A big thanks goes out to https://www.paulkeeble.co.uk/ for sharing the tip on tweaking the tach line for better values.  

Again though, I'm no electronics expert, I'm just working my way though the problems as I see them with this project, and thought I'd share what I've done so far.  Do your own research, and use your best judgement if you try anything similar.
8/3/2026:  After further pondering, I think I need to drop the low side switching and instead switch the 12v for the fan. Switching the ground may work for my particular fan, but it could be problematic in a more general case.  I decided to try a relay instead of the MOSFET, which I settled on due to the complete lack of good P-channel MOSFET modules for the ESP32.  I have several of these 3.3-6v relay boards ordered from AliExpress, which will take a week or so to arrive, and then I can get testing again.  I've already designed a rough footprint of that relay board, and it should fit inside the existing in-line exhaust fan housing, which is a plus.  Using a relay over a MOSFET is kind'a a bummer, but I don't really see a better choice unless I want to roll my own board (which I don't).  The relay should be OK though for this project, since it only needs to switch on and off few times to disconnect the fan after a print, or turn it back on before one.  The PWM will be handled separately using the fan's own internals.  
8/12/2026:  Well, good news, bad news.  I received the relay module, and it looks like it will fit well into the design for the exhaust fan.  I also received an ESP32-C3 board which I had hoped to use for the project, however it was not set up to use an external antenna (see the above post).  I have another ESP32-C3 board on order though, and this one should be set up correctly to use an external antenna, and then I can get the project back on track.  In the mean time I've been tweaking the ESPHome config for the project, and it seems to be coming along well.

In the image below I bent the input pins vertical on the board, since I will either need to do that or re-solder them so they fit the enclosure.  This was something I had planned for, since the space it will fit is a bit tight, but I am still testing to see if I can avoid bending the pins.
Picture
8/15/2026:  I decided that instead of making a voltage divider for the fan tach in the "dead bug" style, that a PCB would be cleaner.  I just need 4 resistors, but I really hate wiring them onto wires since they are pretty fragile.  It took about an hour to whip up a small PCB that will use three 4.7kΩ and one 10kΩ 1/8 watt resistors, and fan header to simplify the adaption of the signals from the 12v PWM fan to my ESP32.  It's just the same voltage divider as was described above, with an additional resistor on the PWM line to limit the current (though that is probably not really necessary).  The board should be small enough that a bit of heat shrink will make it almost disappear when it's connected to the fan connector.  I used a KiCAD footprint for a 4 pin fan header by MartinPu (@Thingiverse), which I modified slightly to reduce the length of the board.

Now I have to wait for the parts, which seems to be typical of my projects.
0 Comments



Leave a Reply.

    Picture

    Stoopid Me

    Welcome to my Stoopid corner of teh Internet.  It's mostly gonna be 3D printing stuff, but I also post some recipes, projects, and the occasional rant here as well.  More Stoopid stuff is updated regularly.

    I recently joined the Amazon Associate program, so some of the links on this site are Amazon affiliate links. This means that, at zero cost to you, I will earn an affiliate commission if you click through the link and finalize a purchase.  This will help to support this site, and pay for more Stoopid Stuff.

    Currently, there are no active authorized sellers of my designs.  If you see my stuff (such as my Dummy 13 Weapons) for sale on Amazon, Etsy or AliExpress, the seller is using my designs without permission.

    If you want to help out with my parts and filament budget, you can also "Buy Me A Coffee" using the link below.
    ​​

    Buy Me A Coffee

    Archives

    August 2025
    July 2025
    June 2025
    May 2025
    April 2025
    March 2025
    February 2025
    January 2025
    December 2024
    November 2024
    October 2024
    September 2024
    August 2024
    July 2024
    June 2024
    May 2024
    April 2024
    March 2024
    February 2024
    January 2024
    December 2023
    November 2023
    October 2023
    September 2023
    August 2023
    July 2023
    June 2023
    May 2023
    April 2023
    March 2023
    February 2023
    January 2023
    November 2022
    October 2022
    September 2022
    August 2022
    July 2022
    April 2022
    February 2022
    January 2022
    December 2021
    November 2021
    October 2021
    September 2021
    August 2021
    July 2021
    June 2021
    May 2021
    April 2021
    March 2021
    February 2021
    January 2021
    December 2020
    November 2020
    October 2020
    September 2020
    August 2020
    July 2020
    June 2020
    May 2020
    April 2020
    March 2020
    February 2020
    January 2020
    December 2019
    November 2019
    October 2019
    September 2019
    August 2019
    July 2019
    June 2019
    May 2019
    April 2019
    March 2019
    February 2019
    January 2019
    December 2018
    November 2018
    October 2018
    September 2018
    August 2018
    July 2018
    June 2018
    May 2018
    April 2018
    March 2018
    February 2018
    November 2017
    September 2017
    August 2017
    June 2017
    December 2016
    October 2016
    September 2016
    July 2016
    March 2016
    February 2016
    September 2015
    August 2015
    June 2015
    May 2015
    April 2015
    March 2015
    February 2015
    January 2015
    December 2014
    November 2014
    October 2014
    September 2014
    July 2014
    June 2014
    May 2014
    April 2014
    March 2014
    February 2014
    November 2013
    August 2013
    July 2013
    June 2013
    May 2013
    April 2013
    March 2013
    January 2013
    December 2012
    November 2012
    October 2012
    September 2012
    August 2012

    Categories

    All

    RSS Feed

Powered by Create your own unique website with customizable templates.