Esp32 Fan Speed Random Noise

Hey yall, I am running a fan using an esp32 chip. I am properly able to get the fan speed by using an interrupt to count the number of ticks on the falling edge, and from that, I use a calculation to determine the speed of the fan at a given moment. It works well, however, I get random spontaneous noise after it runs and stops because the fan will send false falling edges pulses when voltage isn't sent to the fan. The calculations are done every 0.1 seconds and printed out to Serial.

I can give code, however, I don't think it is necessary. I basically grabbed the algorithm from this website if you're curious about the algorithm: Arduino Projects

This is the task that does the calculating:

// interrupt that counts the number of pulses from fan
void IRAM_ATTR fanPulseIn() {
  NumberOfPulses++;
}

void calcFanSpeed(void * parameter) {
  while(1) {
    noInterrupts();
    if(NumberOfPulses < 3) NumberOfPulses=0; // Fan still outputs 1 or 2 pulses each second even when stopped
    fanRPM = (NumberOfPulses + LastReading) / 2*30000 / (millis() - TimeStamp);
    LastReading=NumberOfPulses;
    NumberOfPulses=0;
    TimeStamp=millis();
    interrupts();
    if(fanRPM > 4600) fanRPM = 0; // fan should never go above ~4300
    delay(100); // task should run every 0.1 seconds
  }
}

Below is an example serial output of the fan speed, printed every 0.1 seconds. The ones in bold are the ones that is random noise.

Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 300
Fan Speed: 900
Fan Speed: 1200
Fan Speed: 1200
Fan Speed: 1500
Fan Speed: 1800
Fan Speed: 1800
Fan Speed: 2100
Fan Speed: 2100
Fan Speed: 2400
Fan Speed: 2400
Fan Speed: 3000
Fan Speed: 4200
Fan Speed: 4200
Fan Speed: 3000
Fan Speed: 1800
Fan Speed: 900
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
**Fan Speed: 1500**
**Fan Speed: 2100**
**Fan Speed: 300**
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 600
Fan Speed: 600
Fan Speed: 300
Fan Speed: 900
Fan Speed: 900
Fan Speed: 1200
Fan Speed: 1200
Fan Speed: 1500
Fan Speed: 1500
Fan Speed: 1500
Fan Speed: 1800
Fan Speed: 1800
Fan Speed: 2100
Fan Speed: 2100
Fan Speed: 2400
Fan Speed: 2400
Fan Speed: 2700
Fan Speed: 2700
Fan Speed: 3000
Fan Speed: 2700
Fan Speed: 2400
Fan Speed: 2400
Fan Speed: 3300
Fan Speed: 4200
Fan Speed: 4200
Fan Speed: 3000
Fan Speed: 1800
Fan Speed: 600
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
**Fan Speed: 1500**
**Fan Speed: 1500**
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0
Fan Speed: 0

The bolded section is what needs to be zeroed out. My idea was to grab the 3 latest values of fan speed and average them out, where if there is a zero, it will ignore the values. This will ignore real values though.

Another idea was to compare the fan speed values and zero out the ones with higher values.

But these all seem to give me some undesireable side-effects. Does anyone have any recommendation on how I should tackle this?

How is the speed of the fan controlled? Is there a pull-up resistor on the fan speed signal?

Information I forgot to provide, it is indeed a pull-up resistor. This is how I initialize it:

pinMode(FAN_PWM,OUTPUT);
pinMode(FAN_RPM,INPUT_PULLUP);

I use FAN_PWM pin to give the fan power, and FAN_RPM to count the pulses that the controller in the fan gives. It is also only a 3-wire fan.

Really? And why do you think so?

The built-in pull-up resistors are of high value and especially with longer wires you may have noise in the circuit. Try adding an external pull-up with lower resistance. In addition, you can only measure the fan speed when the fan is switched on (you have not published your entire program and real circuit and I'm trying to guess but I do not like this).

If the fan is controlled by the arduino which is also used to read its speed, it should be pretty straight forward to figure out which measurements are wrong.

@flashko
I didn't think the code was completely necessary because I was mainly asking if anyone knew of a method to ignore some values in data output, though I can see why that generally needs code to answer. I would modify the circuit, but it has been built out professionally and it is not my choice to modify the circuit. However, the coding is very simple and I've provided all the code that deals with the fan calculations. There is a task that does the calculations every 1/10th of a second and spits it out to Serial(for debugging), but there is no more extra code that talks to or manipulates the fan data. I don't think posting multiple hundreds of lines of code will help in the question I am asking. There is also sensitive data in there and would take too much time to change. I hope I don't come off as ignorant and assume strangers will fix my issues. I was just hoping someone would have some insight on maybe an algorithm or method to zero out some values in my output data.

The problem I am running into is that the tachometer is spitting out multiple pulses a second or two after ramping down. After that, it reads 0 the entire time perfectly. On top of that, the length of the fan cable is roughly 4 inches though. So I came to an assumption that noise in the circuit isn't the issue, since it also spits out the bad rpm speeds consistently after the last true rpm speed.

@Danois90
Are you trying to say to just zero out the fanRPM whenever there is no voltage? I would do that, but the algorithm I use calculates the speed of the fan after power stops being sent to the fan. I was hoping to keep that feature, even though technically the fan speed can't be calculated after it's turned off. It is close enough to be valuable data to me

As I understand, the (voltage to the) fan is controlled by the arduino. You could start to monitor fan speed when the fan is switched on, and when it is switched off and RPM reaches zero, you could stop the monitoring.

How about this: put an oscilloscope on the FAN_RPM input and have a look at what's actually coming in on that line. Then you will know what's causing the extra counts.

If it's short noise spikes - significantly shorter than the input pulses - you could use a "debounce" algorithm so it ignores pulses shorter than a certain duration.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.