Hi!
I've found a code for reading RPM of a fan.
I see that in code, after the counter of RPM was reset, there are that snippet of code
sei()
delay()
cli()
Ok, it works either with or without sei/cli..so my question is: is necessary using those functions?
Here the test code.
void readFan() {
nTick = 0;
//sei();
delay(1000);
//cli();
Calc = (nTick* 60);
Serial.print (Calc);
}
void loop ()
{
for (int i = 255; i >= 80; i -= 10) {
//sei();
analogWrite(fanPin, i);
delay(1000); // Wait for stabilize RPM
readFan();
//cli();
}
Another question. I'm trying to read the RPM for some range of PWM value.
The actual code is working perfectly, but if inside readFan() I decomment sei/cli, the program stops and the loop doesn't continue (I hear the fan always the same speed).
Instead, if I decomment the sei/cli inside main "loop" routine it works..
I'm a bit confused about that..for reading the fan RPM and setting the PWM value, I should use those interrupt flag??
The formula assumes that NbTopsFan is counting up during exactly one second. They use sei() and cli() to ensure that NbTopsFan does not keep counting after that second of time is finished.
(I'd add a "volatile" to the declaration of the NbTopsFan variable since it is modified in an interrupt and read from the main loop)
(I also prefer using interrupts() and noInterrupts() instead of cli/sei because in the first assembly language I learned, 6502, the SEI and CLI instructions were also used to enable/disable interrupts, but with the opposite meaning of what they have on Atmel chips...)
Mmm ok for the meaning of SEI and CLI..but if I enable/disable interrupt in readFan() routine, all program stop...Why I can enable/disable only in the main loop?
For the formula, SEI - delay CLI is simple to learn, but the second formula:
rpm = 30*1000/(millis() - timeold)*NbTopsFan;
is another attempt to calc the RPM. That formula work also with interrupt (see the original example) but if I put in a polling function it won't work..
I think it's a maths problem :
That why I didn't understand that formula, why 30? The original formula for speed is (in the example is obviously adapted):
// WHEELCIRC = 2 * PI * radius (in meters)
// speed = rpmilli * WHEELCIRC * "milliseconds per hour" / "meters per kilometer"
// simplify the equation to reduce the number of floating point operations
// speed = rpmilli * WHEELCIRC * 3600000 / 1000
// speed = rpmilli * WHEELCIRC * 3600
via - http://chiphacker.com/questions/89/how-do-i-use-a-hall-effect-sensor-to-measure-the-rpm-of-a-wheel
but a computer software (like speed fan) cannot know the exactly size of a fan, so where is the equation for getting the value of 30?
I try to modify the question in a more comprensive English
How I can measure the RPM of a fan using polling instead interrupt?
Why I want to use a more complex method if the interrupt method is more easy and accurate? Because on Arduino I have only 2 or 4 interrupt PIN (Arduino Mini/Mega).
What is generating the interrupts now? The interrupt handler is triggered on a rising edge, a falling edge, or both. That is a transition from LOW to HIGH, from HIGH to LOW, or from HIGH to LOW and from LOW to HIGH.
Connect those signals to digital pins and use digitalRead to determine the state (HIGH or LOW) of the pin. You then need to keep track of the previous state, and compare that to the current state, to detect when an edge has been encountered. You then decide whether to to do anything about that edge, depending on it's type (rising or falling).
If all you are doing is measuring the speed of a fan, why does it matter if it uses all the external interrupts?
Infact, in my previous post I put the code for reading that info, but the value is wrong..
I think that the formula for calculating the RPM is wrong...but I'm not sure if I don't know exactly if I can calculate the RPM using a polling on digitalRead
void readFan(int pwmValue) {
NbTopsFan = 0;
int val2 = 0;
while (true) {
val2 = digitalRead(pinOfFanRPM);
if (val2 == 1) NbTopsFan +=1;
if (NbTopsFan >= 20) {
rpm = 30*1000/(millis() - timeold)*NbTopsFan;
timeold = millis();
break;
}
}
I need to use the digital pins because I need to know the fan speed of 8 or more fans.