I'm controlling a 4-pin PWM PC fan from a PIC16F684 with the fan speed driven from an ADC reading of a proximity sensor. This all works ok.

I wasn't originally planning to use the tachometer output from the fan, but as it's available I been monitoring it with my 'scope just to see that my mapping between proximity and fan speed is working.

Now, what I've noticed is that when the PWM is running the fan at 100%, the tach signal (which is an open drain pulled up via a 10K resistor) is nice and clean:


However, when I run at less than 100%, it's noisy:


Zooming in on that noise:


I'm guessing it's being affected by the PWM signal but I would like to understand why and how so that I could clean it up if necessary in future. Really I'm interested in what you should do when you see noise like this, how you find the cause and how you "fix" it. The scope manages to trigger ok so I'm wondering if I just feed it to the external interrupt pin on the PIC (RA2), which is a Schmitt Trigger input with CMOS levels, then I won't "see" the noise and I could e.g. echo a clean signal out of another pin to fade an LED or something.

So can someone explain in general terms how to go about recognising and correcting noisy signals? Or if that's too broad maybe just this particular problem? Also if there's anything wrong with my circuit it would be nice to know too. In the schematic below, the signal I'm displaying is the TACH input at the left of the circuit:


After helpful suggestions from both @MichaelKaras and @techydude, I've ruled out Q2 as the source of any problem by removing it from the circuit completely and grounding the fan directly. No significant effect on the noise.

So I then coded the external interrupt on RA2 to echo a "cleaned" signal out of a spare pin (RA1 in this case), which helped a lot but was still flickering due to false interrupts. (So I'd set the interrupt to trap rising edge then switched to falling edge when triggered and vice versa, setting/resetting RA1 accordingly).

But, after also adding a 100nF capacitor across R3 (as part of @techydude's suggestion), I now get a much more stable output. The screenshot below is the TACH signal after cleaning via the Schmitt Triggered RA2 input and re-output on RA1:


  • 1
    \$\begingroup\$ Why do you have the need for the IRF510 FET to switch the power to the fan? Driving the PWM to 0% duty cycle should put the fan either off or to its minimum operating speed. \$\endgroup\$ Jun 21, 2015 at 11:59
  • 1
    \$\begingroup\$ @MichaelKaras Yes, the fan has a minimum speed, so it doesn't stop unless you cut the power. By design it ignores any PWM less than ~10% and runs at 400RPM. So I use that FET to kill it completely when necessary. \$\endgroup\$ Jun 21, 2015 at 12:00
  • 2
    \$\begingroup\$ I see. But it does mean that when you intend to re-start the fan from a +12V off state you may need to start it up with a higher than minimum PWM duty cycle. I've experienced this with a few types of fans in that they need a kick start to get them to reliably startup at power on. The fan control algorithms on many server type computers will run at 100% duty cycle for the first 10 to 20 seconds at startup to ensure that the fans all start properly. \$\endgroup\$ Jun 21, 2015 at 12:07
  • 2
    \$\begingroup\$ On almost all the fan subsystems I have worked on I've had the TACH signal tied into a resistor network that biases the signal from the +12V rail and then has a pair of divider resistors in addition that bring the TACH signal down to the +5 or +3.3V levels needed for the monitoring system. A small cap across the lower resistor of the divider can help to filter any noise spikes on the TACH signal. \$\endgroup\$ Jun 21, 2015 at 12:13
  • 1
    \$\begingroup\$ The main usage of using the +12V rail to bias the TACH signal is that it provides isolation between the +12V and the low level digital voltage signals of the control system. Three considerations are: 1) Fan wires can get pinched between chassis parts and shorts between the four wires become possible. 2) Fans in a dusty environment could get static charge buildup and the resistors can help keep any ESD discharge out of the TACH detector input. 3) The RC time constant of the divider with stray capacitance or with added cap act as a filter for the TACH signal. \$\endgroup\$ Jun 21, 2015 at 12:30

4 Answers 4


About your schematic:

Everything seems fine, you can increase the R2 to 10k or even 100k, the capacitance of the MOST is so small, the FAN will have much more spinning inertia than the turn off delay in the MOST, probably even with 1M. That way the location of your 100R is irrelevant and while on you don't waste any mA's. If you never hold de uC in reset it's technically not even required at all, since your uC will actively pull it high or low.

For the PWM signal, you could see if the datasheet allows an external pull-up to 12V, though I doubt it will make much of a difference either way.

About the noise:

EDIT: I misread your plot for kHz, which is stupid if you think of it, where it's Hz. Some of my story will change a little (such as the talk about needing MHz for digital work), but the general idea remains.

I will leave the entire post as-is, but for a 100Hz signal with 30kHz noise, in stead of 100kHz with >5MHz noise (also didn't really make sense, did it?), you might increase the resistors that interact with capacitors by a factor of 10, and also increase the capacitors by a factor of 50 to 100. That'll get you a factor 1000 lower filtering frequency in all the examples. But it's also okay to just increase the capacitors by a factor of 10 to 20, for sharper edges or faster response on your signal of interest, since 30kHz is very far from 100Hz.

So consider this post as written for high frequencies and scale down the ideas, making them much easier to implement too! (Especially the digital rejection in 3.)

End of Edit

Since you make such a nice use-case for working through methods of noise reduction, I'll try to make one that applies to your situation.

To anyone reading, be aware:

This is only about noise on a digital signal

In a digital signal you can make an assumption that there's only two voltages you are interested in "on" and "off". Anything in between is pointless and belongs to noise or wrong. In an analogue signal, you need to know about every voltage level and you need to do some actual filtering with loads of C's, L's, etc.

A problem in your signal is that the negative noise spikes on the high level and the positive noise spikes in the low level come very close to each other, so a simple standard trigger, even with adjustable level cannot absolutely guarantee you that you will never get confused.

Your options:

  1. Change the Bias
  2. Change the Voltage Levels
  3. Add "slow" Hysteresis
  4. Filter out the Noise

1. Change the Bias:

The positive has very low negative spikes, that's because your pull-up cannot win from the noise. The easiest thing you can try is decreasing that resistance. There is a risk this will just increase the spikes on the off signal as well, so that may not always work. But it is very possible that it will give you some head-room between the spikes to set a simple hysteresis.

2. Change the Voltage Levels

You can easily, if the fan allows it, change the Tacho to a higher voltage level and add an intermediate state:


simulate this circuit – Schematic created using CircuitLab

Now there might just be enough space between the high and low spikes to make sure the MOST is always on, even when there's negative spikes and always off, even if there's positive spikes. It may take some diodes, zeners, or resistors to get the set-point in the new situation, but if the spikes on the negative signal stay what they are, they shouldn't be triggering the MOSFET, as long as you don't replace it with one that has a gate-threshold below 2V.

3. Add "slow" Hysteresis:

This is a trick that's commonly used when you know a spiky noise signal is of at least an order of magnitude larger than the signal you are interested in. It will delay the signal a little, so it cannot be used in situations where the exact moment of a on/off change is important.

But for a signal where you only want to know the shape or frequency of it, this is a very robust method. It basically starts to trigger when there's a voltage crossing the threshold, but only completes that action when it stays there. There are many ways to build one.

You can do it in the controller (which is easiest in component count): You can trigger on a flank, then sample some more values at enough speed to see the high between noise spikes, but not confuse about missing a whole period of low. Then you make a predefined judgement based on the knowledge of your signal and noise. For example, if you could sample at 10MHz, you could capture 50 samples and be certain that a 100kHz highest frequency will not be ignored if you go with majority rule. I.e.: at least 25 need to be low for it to actually be low. Your spikes are only very thin and the most time it is the original signal, so that could work, but the number of a majority can be adjusted. This will work with 1MHz and 6 or 7 samples as well, but it'll be less of an actual majority, so there may be some risks again there. 1MHz at the least should be feasible with most modern day uCs.

You can also do it externally: But it's already MUCH more complicated than adding a simple filter, especially when you look at the result with a uC with some hysteresis in its input already. But it's fun to think about, so let's:


simulate this circuit

U1 is any suitable Op-Amp or Comperator. Comperators are better switchers, often with better swing, but for sub-MHz an OpAmp with decent rail/rail swing will easily do.

While this type of hysteresis can be built with at least one resistor less, this one is easier to explain and as such easier to modify.

First imagine it without the capacitor:

First, see that the resistor divider is influenced by the output of U1, it will pull it a bit lower of higher through the 20kOhm apparent resistance. Let's say on the positive input of U1 is a voltage of 1.1V rounded down when its output is 0, and 3.9V rounded up when its output is 5V.

If the steady-state start-up Tacho Input is high, U1's output will be low, due to the inverting nature of the input to the Tacho. So the negative input will be, again due to the extra pull-up resistor, about 2.3V. Since the positive input is only 1.1V the input needs to drop to below 2.2V to make the negative input see a voltage lower and make the output flip over.

When the output flips over, the negative input will see 3.6V (because at this instant the input signal is 2.2V, the output of U1 is 5V, so their middle, made by the 10k resistors is about 3.6V), but the positive input will have flipped from 1.1V to 3.9V, so the negative is still below the positive input and the output will stay 5V.

If the signal now quickly "aborts" and flips back up, the output of U1 will quickly go back again, but then the spike has already had to drop below 2.2V, so that's better than nothing.

If the signal goes further down to 0, the stable situation will only become stronger, the negative input will drop to 2.5V (since we assume the FAN's tacho to be strong enough of a pull-down) and the positive will rest at about 3.9V.

Now the signal needs to raise above 2.7V for the output to flip the other way. Very likely 95% of your spikes will get ignored already.

Adding the capacitor:

With the capacitor, the incoming signal needs to supply enough energy for enough time to charge or discharge the capacitor. In effect that is already an R-C filter. Any spike that quickly dips and then recovers will not be able to discharge the capacitor.

The value of C of course depends on the source signal and the noise signal. I have ball-parked 510pF for a 100kHz source signal vs 1us spike duration at most, but I didn't really do much maths, it's just a R-C-time based gut feeling that this might be close to what will work.

4. Filter out the Noise

This is a bit like just filtering an analogue signal. You can use a simple R-C network, like discussed in the previous section:


simulate this circuit

Since the noise spikes are at or less than 1us, they cannot make a very significant change in the voltage on the capacitor, since its R-C-time is 5us. This means that the energy in the spikes is flattened out down to an average. Since you see high tops and low dips on the spikes it's even possible the averages will be very close to 0V and 5V, but that can only be said with either better pictures, or just an experiment. Since you feed it to a uC pin, the R-C-time will probably be enough to see it as high or low. This will give a small distortion due to the slower charging than discharging, caused by the pull-up resistor. Some tweaking of values may yield a result in which that is negligible.

If that's not enough you could add some more components, but you're very quickly overdoing it when your dominant noise is at least 10 times "faster" than your signal.

You could add a 4.7uH inductor in series with the resistor to smooth out some more high-frequency flanks, maybe even 10uH.

But to be honest, in the case of "feeding it to a uC" the only reason to experiment with L's in a signal of your kind is to find a balance in which the R is large, C is small and L just helps smoothing out some flanks, so that R2/R1 will be small enough to ignore the difference in rise and fall time. such as an R1 of 33k, C of 150pF and an L in series with R1 of 56uH. Or maybe a ferrite bead in stead of the inductor, depends a bit on the sharpness of your spikes.

But already over-thinking it, I would say.

  • 1
    \$\begingroup\$ I'm speechless! What a fantastic, well explained, comprehensive and useful answer. I can't thank you enough, this is exactly the sort of response I was hoping for. So much to learn here and very grateful. I need to read through this a few times but at first sight I can see the options more clearly now and you've really opened my eyes. Excellent, just excellent. \$\endgroup\$ Jun 21, 2015 at 16:00
  • 2
    \$\begingroup\$ @RogerRowland That's the main point of a site like this. Happy to help. Any further complications/mathsifications can be had in Chat. I'm there regularly. Only need to add a note that I misread your plot as kHz rather than Hz \$\endgroup\$
    – Asmyldof
    Jun 21, 2015 at 17:33

Noise like this from a fan tacho is common, because the circuitry (that usually includes a Hall Effect sensor) in the fan that's generating the tacho output is itself being chopped on/off at your PWM freq (when your PWM output is at anything other than 100%-On), not just the supply to the motor itself. Sure they'll have some capacitance to smooth the supply to that circuitry, but given, say, a 12V fan power supply, so long as there's enough capacitance to maintain several volts between minimum PWM off periods, that's enough to both drive the Hall-Effect sensor & pull-up the tacho output (if the fan includes its own pull-up on the tacho output), to provide a recoverable output signal. Yes, fans are messy when you PWM their supply. Some fans offer a PWM speed input that's separate to their +12V supply.

Your PWM appears to be about 27kHz. So the good thing in this specific situation is that your tacho output @ 100% output appears to be about 800Hz, which is < 1/30th the frequency of your PWM, so filtering this tacho output to get rid of most of the PWM noise is easy & worth doing. It's late here so I CBF'd working through the calcs, but because it's open-drain & it's your pull-up supply voltage (in the fan) that's being molested by PWM, a cap between tacho & +12V rail (not the PWM output from your fan drive circuit) will probably be a better option than a cap on the tacho to ground. Try both & see. Start with a 100n ceramic cap of appropriate voltage & see how it looks.

With a Schmigger input on the PIC, you might even be able to get away without doing any filtering of this tacho output before putting it into your PIC, but you have that freq differential that will easily allow you to go a long way towards cleaning it up.

One possible problem with your handling of the tacho signal from the fan tho: if the fan is pulling it up to +12 with a 10k internally (some do, some don't) & you're also pulling up the tacho signal to your +5V rail, then you're actually pulling it down! There are various circuit configurations to deal with this, depending on the fan supply voltage, how strong the pull-up is, etc. Try to measure it with your multimeter & let us know.

  • \$\begingroup\$ "Some fans offer a PWM speed input that's separate to their +12V supply" - Yes, that's what I've got :-) This 4-pin fan has a PWM control that's separate from the 12V/GND, so that's the line I'm driving. The other FET (Q2) is only there so I can switch the fan off completely because it has a minimum speed. So I'm not PWM'ing Q2, only Q1. \$\endgroup\$ Jun 21, 2015 at 12:37
  • \$\begingroup\$ Generally for a 4-wire fan, if it is given a constant 12V supply and the PWM input wire is used to control speed you would not see PWM switching frequency in the TACH output. Only would be the case of trying to apply the PWM to the fan power leads. \$\endgroup\$ Jun 21, 2015 at 12:37
  • \$\begingroup\$ " if the fan is pulling it up to +12 with a 10k internally" - Hmmm, it's not pulled up to +12, but if I remove my pullup it seems to be pulled up by the fan to about 2V. Seems strange to me, but maybe explains why my noisy signals is around 6V rather than 5V. Not sure what to do now! \$\endgroup\$ Jun 21, 2015 at 12:44
  • \$\begingroup\$ D'oh! So sorry, I didn't even notice on your sch that it's a 4-wire fan. And now I remember your other questions :). OK, having now reviewed the IRF510 datasheet, I think @Michael Karas is more likely right, that Q2 might not be fully on (and not helped by R1 & R2 being a 1:10 divider, so you'll get no more than Vgs=4.5V, so your +12 to the fan may be sagging (too hard to be certain from your scope shots, need to see within the PWM period). Change R2 to 100k (more than enough to keep of off when in tri-state) & see if that helps. If so, choose a lower Vgs-threshold MOSFET. \$\endgroup\$
    – Techydude
    Jun 21, 2015 at 13:05
  • 1
    \$\begingroup\$ @Techydude lol, never mind, it's still a puzzle though. As I said to Michael, I've now removed Q2 and grounded the fan directly, and I still see the same noise. I've also tried echoing the TACH to another pin via INT but the Schmitt doesn't clean it enough on its own and the echoed output is still ragged. Maybe it's because this is all still on a breadboard? Actually 100nF between TACH and Vcc has helped. \$\endgroup\$ Jun 21, 2015 at 13:29

A possible source of the noise on the TACH signal may be due to the IRF150 FET not being a low enough ON impedance. This could be due to the FET RdsON being fairly high or the FET not being fully ON at the provided gate drive voltage.

As the FAN current switches on and off with the PWM signal there will be a drop across the FET resistance the causes the "GND" reference of the fan to bump up and down and translate to the noise seen on the TACH signal.

You can check this to see if the effect I describe is the case by putting the scope GND lead on the FET drain and then look at the TACH signal. The signal would look a lot cleaner.

The solution would be to select a FET with much lower RdsON when supplied with a gate drive that your system provides.

Another possible idea is to use a P-FET to switch the fan's +12V lead instead of the GND lead.

Do note that the gate resistor arrangement you are using does cause you to lose some of your potential gate drive. Move the 1K resistor to the other side of the 100ohm.

  • \$\begingroup\$ Thanks Michael, I really appreciate your advice. I've now unhooked Q2 completely and grounded the fan directly but I still see the same TACH noise at everything below 100% PWM. Good point about the placement of the 1K resistor though! \$\endgroup\$ Jun 21, 2015 at 12:57

This sounds like a job for a low-pass filter. You need to keep the useful signal with f1 around 1 kHz and remove the offending signal with f2 near 25 kHz. The cut-off frequency can be chosen as geometric mean of f1 and f2 (suboptimal but simple):

fc=sqrt(1*25) = 5 kHz.

Assuming a simple RC-filter will be sufficient, and you already have the resistance in TACH circuit (R3 = 10 kOhm), the appropriate capacitor value should be calculated to match the 5 kHz time costant:

enter image description here

C = 1/(2 * pi * fc * R)=1/(6.28 * 5000 * 10000)=3.2*10-9 F.

So all you need to do is to solder a 3nF capacitor between the TACH line and the ground. It will attenuate the high-frequency noise by a factor of 20 or more, which should be sufficient for your application.

  • \$\begingroup\$ Thanks, that's similar to what @techydude suggested (although your calculation is obviously better than a guesstimate), but do you know why I find better noise suppression with the cap between TACH and 5V rather than TACH and GND? Does that choice affect where the noise is suppressed (i.e. on the high part of the pulse or the low part) or should it suppress it equally? \$\endgroup\$ Jun 21, 2015 at 19:52
  • \$\begingroup\$ The fact that a cap between TACH and 5V works better that a cap between TACH and GND surprises me. Normally, you're supposed to connect the filter to the voltage level which is used as a reference in your system, and in 99% of the cases it's GND. Also, VCC and GND are connected via a voltage source with close-to-zero internal resistance (compared to 10k resistor), so it shouldn't really matter. \$\endgroup\$ Jun 22, 2015 at 9:55
  • \$\begingroup\$ After a closer look on the schematic, I think it's related to the fact that your input is open-drain, which produces noise with asymmetric edges (fast falls and smoothed rises). If you use the schematic from @Asmildof's answer, the noisy signal will be applied to the input of the RC filter rather than in the middle of it, and it should work as expected for any kind of noise. \$\endgroup\$ Jun 22, 2015 at 10:03
  • \$\begingroup\$ Thanks @Dmitry, the asymmetric noise you describe seems to match my zoomed trace so that makes sense to me. I'll do some more work on the circuit based on all the good advice I've received here. Your input is much appreciated. \$\endgroup\$ Jun 22, 2015 at 10:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.