I am controlling a 12v 4pin fan using arduino uno pwm.
I didnt do anything regarding frequency change, only coneected the 12v power source and the arduino to the same ground and the PWM control worked fine, tough with one problem.
70% is the minimum i can get. Below that, the fan stays at 70%, doesnt go down more thant this.
I wish i could shutdown the fan using 0% pwm and make it turn slowly to.
There is no strange noise caused by low frequency as some people report.
Not sure how you have everything connected. It's always nice to see a schematic, that's how we do stuff. (It's not been described verbally, but my eyes always glaze over when people try that.)
It's an electronic assembly, it's more than a motor with a fan blade. So, PWM has a limited effect.
You'll likely have to use one of those other wires (google research that} - "four lead fan control", "4 wire fan control", or similar.
Perhaps you could post the code you are using to generate the 21 kHz to 28 kHz PWM signal. I didn't know an Arduino could do that range. edit -now I know, I googled "25 khz pwm arduino" and saw lots of good stuff, including this Setting up arduino Pwm for 25khz at 50% duty cycle - SparkFun Electronics
dmjlambert:
Perhaps you could post the code you are using to generate the 21 kHz to 28 kHz PWM signal. I didn't know an Arduino could do that range. edit -now I know, I googled "25 khz pwm arduino" and saw lots of good stuff, including this Setting up arduino Pwm for 25khz at 50% duty cycle - SparkFun Electronics Forum
Thanks for the PWM library. Changing the frequency to 25khz didnt change anything.
I did an pulse response test code and it seems that when i set the PWM to 30% it goes to 50% the speed. I did the calculations wrongly before, its going to 50 minimum not 70 (i am getting the same output with or without the frequency change code).
Maybe my fan in particular is limited to 50% minimum, even if the datasheet says it should be 30%.
Code:
#include<PWM.h>
int fanPulse = 0;
int fanPin = 3;
unsigned long pulseDuration;
int32_t frequency = 25000;
void setup()
{
Serial.begin(9600);
pinMode(fanPulse, INPUT);
digitalWrite(fanPulse,HIGH);
bool success = SetPinFrequencySafe(fanPin, frequency);
if(success) {
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
}
}
void readPulse() {
pulseDuration = pulseIn(fanPulse, LOW);
double frequency = 1000000/pulseDuration;
Serial.print("RPM:");
Serial.println(frequency/2*60);
}
void loop()
{
int i = 0;
analogWrite(fanPin,80);
Serial.println("PWM SET TO 30%...");
delay(1000);
Serial.println("Set point speed: ");
readPulse();
delay(1000);
Serial.println("PWM set to 100%, GO!");
analogWrite(fanPin, 255);
for (i = 0; i <= 100 ;i++){
readPulse();
delay(10);
}
Serial.println("Test completed, restarting to 30%...");
analogWrite(fanPin,80);
delay(5000);
}
dmjlambert:
I think you're supposed to count the tach pulses over a period of time, at 2 pulses per revolution, not measure the pulse width.
Measuring the pulse width is more reliable in my understanding, shorter pulses mean more speed... (i got the rpm measuring code from top 1 result in google). And the RPM values make sense to the way these fans operate when they are in a Intel CPU.
When i put something in the way of the fan and it slows down or stops (i know i shouldnt do this but it for the sake of testing) the values measured go down accordigly.
The data sheet also mentions you need to pull the tach pin high. It says pull it to 12 V but I don't know if that would be critical. If you did pull it to 12 V then I guess you could make a voltage divider to read it. I am kind of wondering if you are reading noise and not getting an accurate RPM reading.
dmjlambert:
The data sheet also mentions you need to pull the tach pin high. It says pull it to 12 V but I don't know if that would be critical. If you did pull it to 12 V then I guess you could make a voltage divider to read it. I am kind of wondering if you are reading noise and not getting an accurate RPM reading.
I did the pull to 5v and it didnt change anything in speed readings. It only stabilizes the readings to 0 when the pin is disconnected.
Measuring the pulse width is more reliable in my understanding,
You understand incorrectly.
Measuring the pulse width means the measurement has to be more accurate to gain a sense of the speed than measuring a number of pulses over a period of time. You are also likely to see more variations.
That's guys math involving 1000000/pulseDuration and RPM=frequency/2*60 looks interesting. I'm not sure how long that pulse stays high when it goes high, and you're only measuring the time it is low. I think you would have to measure the beginning of pulse going low to the beginning of the next pulse going low, or count the pulses, to be accurate. But this math probably does tag a wag at it.
You could make some code which counts the pulses and get an RPM you know is accurate, then simplify the code by going back to using pulse width but calibrate the reading by adjusting the numerator from 100000 to a number which gives you the accurate frequency. For best results make sure the calibration is accurate at different RPMs.
Just an update for everybody that helped me (thanks), i managed to implement an PID control on the fan (thats what i wanted) from 50% of the speed to 100%. Thats enough i think, you can mark this as solved.
Just an update for everybody that helped me (thanks), i managed to implement an PID control on the fan (thats what i wanted) from 50% of the speed to 100%. Thats enough i think, you can mark this as solved.
FYI, it is customary on the forum to post your solution if you arrive at it by yourself as opposed to posting something like 'I tried the last suggestion and it worked".
A lot of people spent time trying to help you and I am sure they would like to know how you arrived at your solution. I understand you implemented PID control but could you please take the time to post your code and explanation as a courtesy to those who tried to help you ? (not to mention all those out there with a similar problem looking for a solution . Stating you managed to solve your problem isn't going to be much help to them.