I recently bought a few somewhat expensive fans from Digikey, and they turn out to not work well with PWM control, no matter what the speed is set to. Some fans spin at 100% up until 50% PWM, and then stop completely, or others have unpredictable speeds (going from 0 to 50% is resulting in a very different speed to going from 100% to 50%).
Pretty much all fans used in 3D printers are brushless, so they are not meant to be used with PWM control, even though a lot of them work decently with it.
For the rest of the post, I will assume a 24V Supply, since this is what I have and I think it is the most common voltage nowadays.
I came across this thread from 2 years ago exploring a fix, but the best fix they came up with was not only not effective, but actually slightly dangerous for the fan.
Using the LC filter suggested resulted in transient spikes reaching 26V, which might potentially damage some fans. Also changing the PWM ratio does not change the average voltage, so I can't see how that would affect the speed of the fan. The problem with this circuit is that the fan (modelled as a resistor), affects the filter. To fix it using only passive components we would need a very large capacitor that would cause large currents, which can damage the mosfet on board.
Instead, we will need a high impedance input from the filter, and a low impedance output to the fan. Cheapest way with the lowest amount of components is using a high power op amp wired as a voltage follower.
With a few more components, it is possible to use a more basic op amp and a mosfet as an emitter follower to achieve a higher current, but a £0.40 L272M can do 0.7A per channel and my fans only use about 0.07A on max speed at 24V, so I went for the easier option.
I played around slightly with the values for my LPF, and I came up with this as my final solution, except with a L272M as the opamp instead of the LT1677 (LTspice doesnt have it in its library). The R3 is there as a pull up resistor, so the lower node on the diagram becomes 24V when the onpoard mosfet is off, so we get a proper square wave.
The overall cost is about £2 for two channel (as a L272M is a dual opamp). I have built it and it does work very well. My cheap DSO oscilloscope can't even measure the noise, and all the fans I have tried adjust their speed smoothly from barely spinning to full speed. Also some fans that work fine with PWM, such as the Pengda blower from Trianglelab, seem to run even quieter at roughly the same airflow using the adjusted DC.
I will add photos of the scope output at a later date since I am currently printing stuff using the module.
Here is a photo of the module itself. (excuse my messy wiring)
Only very small issue is that the voltage will only go to ~0.9V lower than the output. I guess with an emitter follower circuit and a rail to rail opamp it would be possible to get closer, but in my use case this is not really noticeable and does not matter. Also of course you will have to readjust your fan profiles.
At even 10+ quantities with a custom small PCB, it would be possible to get the BOM to about £1 each. There aren't any specialised modules for this currently, so I think there's definitely a market for this. I think this might be something for Duet3D team to consider making as an addon. I got plenty of spares for all the parts that I might never use again, so if an Admin wants to test it too I can send parts to build a module for free (I'm in UK).