Hi All,
I'm a complete Arduino Newbie trying to do a project controlling a 120mm 4 pin case fan using an Arduino MEGA 2560. Reading this forum and some other links I found I have put together the following code:
// Declare variables
unsigned long previousRPMMillis;
unsigned long previousMillis;
float RPM;
int state = 0;
unsigned long interval = 3000;
volatile unsigned long pulses=0;
unsigned long lastRPMmillis = 0;
// Specify the input and output pins
const int readPin = 2; // Read the
const int fanPin = 8;
void countPulse() {
// just count each pulse we see
// ISRs should be short, not like
// these comments, which are long.
pulses++;
}
unsigned long calculateRPM() {
unsigned long RPM;
noInterrupts();
float elapsedMS = (millis() - lastRPMmillis)/1000.0;
unsigned long revolutions = pulses/2;
float revPerMS = revolutions / elapsedMS;
RPM = revPerMS * 60.0;
lastRPMmillis = millis();
pulses=0;
interrupts();
return RPM;
}
// Set the duty-cycle
void analogWrite25k(int value)
{
OCR4C = value;
}
// Set up the pins - first we want to set the duty-cycle to be at 25,000 Hz for PWM Control
// next we want to set up the RPM reading.
void setup()
{
TCCR4A = 0;
TCCR4B = 0;
TCNT4 = 0;
// Mode 10: phase correct PWM with ICR4 as Top (= F_CPU/2/25000)
// OC4C as Non-Inverted PWM output
ICR4 = (F_CPU/25000)/2;
OCR4C = ICR4/2; // default: about 50:50
TCCR4A = _BV(COM4C1) | _BV(WGM41);
TCCR4B = _BV(WGM43) | _BV(CS40);
Serial.begin(115200);
pinMode(readPin,INPUT_PULLUP); // Set pin to read the Hall Effect Sensor
attachInterrupt(digitalPinToInterrupt(readPin), countPulse, RISING); // Attach an interrupt to count
// Set the PWM pin as output.
pinMode( fanPin, OUTPUT);
}
void loop()
{
int w = Serial.parseInt();
if (w>0) {
analogWrite25k(w);
Serial.println(w);
state = w;
}
if (millis() - previousMillis > interval) {
Serial.print("RPM=");
Serial.print(calculateRPM());
Serial.print(F(" @ PWM="));
Serial.println(state);
previousMillis = millis();
}
}
So from this I have learned that I need to work with the low level timers of the board to achieve a 25kHz PWM control rate. I have also learned that each PWM has an attached timer, and that PWM pins have to be used to read the RPM.
My questions are as follows:
- Please help me to understand the following block of code. Also, how do I do this for 2 more fans at the same time - which timers and pins do I use?
TCCR4A = 0;
TCCR4B = 0;
TCNT4 = 0;
// Mode 10: phase correct PWM with ICR4 as Top (= F_CPU/2/25000)
// OC4C as Non-Inverted PWM output
ICR4 = (F_CPU/25000)/2;
OCR4C = ICR4/2; // default: about 50:50
TCCR4A = _BV(COM4C1) | _BV(WGM41);
TCCR4B = _BV(WGM43) | _BV(CS40);
-
How do I keep my RPM measurements from jumping around?
-
Do I really need to use PWM pins for measuring the RPM?
Thanks!!