int NbTopsFan;
int Calc;
int hallsensor = 2;
int Pin = 9;
int temp = 0;
float tempC;
typedef struct{ //Defines the structure for multiple fans and their dividers
char fantype;
unsigned int fandiv;
}fanspec;
//Definitions of the fans
fanspec fanspace[3]={{0,1},{1,2},{2,8}};
char fan = 1; //This is the varible used to select the fan and it's divider, set 1 for unipole hall effect sensor
//and 2 for bipole hall effect sensor
void rpm () //This is the function that the interupt calls
{
NbTopsFan++;
}
void setup() {
pinMode(hallsensor, INPUT);
pinMode(Pin, OUTPUT);
Serial.begin(9600);
attachInterrupt(0, rpm, RISING);
}
void lp ()
{
NbTopsFan = 0; //Set NbTops to 0 ready for calculations
sei(); //Enables interrupts
delay (1000); //Wait 1 second
cli(); //Disable interrupts
Calc = ((NbTopsFan * 60)/fanspace[fan].fandiv); //Times NbTopsFan (which is apprioxiamately the fequency the fan is spinning at) by 60 seconds before dividing by the fan's divider
Serial.print (Calc, DEC); //Prints the number calculated above
Serial.print (" rpm\r\n"); //Prints " rpm" and a new line
}
void loop ()
{
tempC = analogRead(temp);
tempC = (5.0 * tempC * 100.0)/1024.0;
Serial.println(tempC);
if (tempC < 30)
{
analogWrite(Pin, 127);
lp();
}
else
{
analogWrite(Pin , 255);
lp();
}
}
here is my code, which i want to control the fan speed depend on the temperature reading from LM35 sensor
the code just work great without the rpm.
i make the rpm reading in another function and i call it when i need it.
if i turn on my hardware with temperature higher than 30C it works fine, but when the temperature falls under 30C here start the wrong reading for RPM
i read about it and i find some guy has solved this problem using pulse stretching method .. he is using PIC microcontroller, here is the article
wazeer91:
hi there,,
i am really new in using arduino and i am trying to build a small project that read the RPM from PC fan and control the speed by using PWM.
wazeer91:
The problem start when i am trying to join these two codes together. The RPM reading goes wrong
Of course it does. PWM switches the motor on and off at a high frequency. Well the "tacho" wire from the fan is powered from the motor (winding) so every time the PWM switches the motor off, it switches off the tacho wire as well.
The best way to do this is to start with a 4-wire PC fan. These fans have a separate PWM input, which you can drive from an Arduno PWM output using just a resistor or diode, or even directly. No need to use a transistor to switch the power to the fan, and no problems reading the RPM.
Paul__B: Of course it does. PWM switches the motor on and off at a high frequency. Well the "tacho" wire from the fan is powered from the motor (winding) so every time the PWM switches the motor off, it switches off the tacho wire as well.
Correct. Two strategies can cope with this problem:
Low-pass filter to smooth the PWM into a steady voltage. May require a substantial filter for fan that draws a lot of current.
PWM at a low frequency and only count tacho pulses when the output is high. You'll need to set the frequency low enough and the RPM high enough that you can count at least two pulses per high interval, but this may put the fan into the range of audio frequencies so you may hear a "whine".
dc42:
The best way to do this is to start with a 4-wire PC fan. These fans have a separate PWM input, which you can drive from an Arduno PWM output using just a resistor or diode, or even directly. No need to use a transistor to switch the power to the fan, and no problems reading the RPM.
dc42, please could you take a look at my code? I'm trying to control my Arctic Cooling PWM F12 Fan.
You are using timer 1 to define a gate in which to count RPM pulses. But timer 1 is used to control PWM on pin 9, which is the one you are using to control the fan speed. Either use a different PWM pin (but not pin 10 either), or see here Frequency Counter Library - #36 by dc42 - Science and Measurement - Arduino Forum for a way to measure frequency (and hence RPM) without taking over one of the timers.
rpmPin should be declared const but not volatile.
You are PWMing the fan at the default frequency of 490Hz, whereas the Intel PWM fan specification calls for 25kHz. But 490Hz may work OK.
What do you have connected to all the other pins? A standard character LCD need to be connected to 6 pins, but 5 of those pins (all except the Enable input to the LCD) can often be shared with other devices.
Just before reading the fan speed put he fan to the max, then read the tacho, then put it back to your speed, you need only to read the tacho for maybe 1/10 of a sec or lower, and every N seconds, so this trick doesn't change your fan speed, nor you'll notice it in any way (sound)
dc42:
What do you have connected to all the other pins? A standard character LCD need to be connected to 6 pins, but 5 of those pins (all except the Enable input to the LCD) can often be shared with other devices.
At the moment I'm using pins 12, 11, 7, 6, 5, 4 for LCD.
zYxMa:
Great, but the problem I'm facing now is that I have no more pins left.
zYxMa:
At the moment I'm using pins 12, 11, 7, 6, 5, 4 for LCD.
...
I use 1 analog pin and pwm pin 13 and that's it.
I'm confused. You say you're out of pins, but you have 0, 1, 2, 3, 8, 9, 10, and 5 analog pins available?
Out of PWM pins, that's what I mean, but in future I'd like to control more PWM devices and yet have the LCD connected. Also dc42 suggested that I don't use pin 9 and 10 for what I wanted. Now I'm confused.