Hi,
Could some one help to understand tachometer issue.
I complied a debug sketch to see tachometers data, and Can’t get real rmp of 3 fans PWM 4pin.
All fans connected:
1pin - Ground to PS
2pin - 12V to PS
3pin - Tach with PullUp resitor 5,1kOm to 5V Nano
4pin - PWM to Nano
So, I tried more than 10 different options to get real rmp data of coolers that I Can found. I tried digital pins (5, 6, 7) in different Ports and many other.
But I reached a dead end. I understand that such RPM readings are presumably related to an increase in frequency 25kHz, but I can’t figure it out further.
The PWM of 3 fans is excellent, a rise every 10% is clearly audible. However, at 100% the speed starts to float.
Below is the rpm data, first column is PWM in %
Pulse counter started on A1(A)/A2(B)/A3(C)
0 | fan1: 81 | fan2: 91 | fan3: 83
0 | fan1: 54 | fan2: 55 | fan3: 50
0 | fan1: 26 | fan2: 23 | fan3: 22
0 | fan1: 15 | fan2: 14 | fan3: 14
0 | fan1: 14 | fan2: 14 | fan3: 14
0 | fan1: 13 | fan2: 14 | fan3: 14
0 | fan1: 14 | fan2: 14 | fan3: 13
0 | fan1: 14 | fan2: 13 | fan3: 14
0 | fan1: 14 | fan2: 15 | fan3: 15
10 | fan1: 15 | fan2: 15 | fan3: 15
10 | fan1: 2738 | fan2: 2260 | fan3: 2753
10 | fan1: 4439 | fan2: 3733 | fan3: 4465
10 | fan1: 1136 | fan2: 940 | fan3: 1158
10 | fan1: 669 | fan2: 540 | fan3: 686
10 | fan1: 1161 | fan2: 957 | fan3: 1178
10 | fan1: 219 | fan2: 198 | fan3: 220
10 | fan1: 548 | fan2: 461 | fan3: 568
10 | fan1: 2552 | fan2: 2125 | fan3: 2649
10 | fan1: 2058 | fan2: 1720 | fan3: 2153
20 | fan1: 1946 | fan2: 1639 | fan3: 2027
20 | fan1: 1497 | fan2: 1396 | fan3: 1506
20 | fan1: 2285 | fan2: 2158 | fan3: 2307
20 | fan1: 3260 | fan2: 3071 | fan3: 3276
20 | fan1: 3554 | fan2: 3357 | fan3: 3561
20 | fan1: 4041 | fan2: 3830 | fan3: 4031
20 | fan1: 4166 | fan2: 3899 | fan3: 4185
20 | fan1: 4610 | fan2: 4315 | fan3: 4577
20 | fan1: 4506 | fan2: 4236 | fan3: 4483
20 | fan1: 3727 | fan2: 3494 | fan3: 3728
20 | fan1: 3625 | fan2: 3435 | fan3: 3653
30 | fan1: 4946 | fan2: 4876 | fan3: 4936
30 | fan1: 5012 | fan2: 4971 | fan3: 5016
30 | fan1: 4373 | fan2: 4304 | fan3: 4360
30 | fan1: 3615 | fan2: 3578 | fan3: 3624
30 | fan1: 3741 | fan2: 3664 | fan3: 3710
30 | fan1: 5087 | fan2: 5010 | fan3: 5084
30 | fan1: 3965 | fan2: 3893 | fan3: 3940
30 | fan1: 2691 | fan2: 2643 | fan3: 2694
30 | fan1: 4813 | fan2: 4739 | fan3: 4788
30 | fan1: 4653 | fan2: 4594 | fan3: 4661
40 | fan1: 11047 | fan2: 3605 | fan3: 3604
40 | fan1: 10975 | fan2: 4000 | fan3: 4000
40 | fan1: 9822 | fan2: 4378 | fan3: 4377
40 | fan1: 11245 | fan2: 3571 | fan3: 3571
40 | fan1: 11094 | fan2: 4365 | fan3: 4363
40 | fan1: 10525 | fan2: 4081 | fan3: 4093
40 | fan1: 10226 | fan2: 4104 | fan3: 4094
40 | fan1: 11082 | fan2: 4268 | fan3: 4285
40 | fan1: 10353 | fan2: 3764 | fan3: 3756
40 | fan1: 11194 | fan2: 4331 | fan3: 4328
50 | fan1: 11071 | fan2: 3878 | fan3: 3891
50 | fan1: 11573 | fan2: 4220 | fan3: 4203
50 | fan1: 10240 | fan2: 5047 | fan3: 5043
50 | fan1: 10955 | fan2: 4093 | fan3: 4095
50 | fan1: 11432 | fan2: 3886 | fan3: 3875
50 | fan1: 11215 | fan2: 4769 | fan3: 4757
50 | fan1: 10778 | fan2: 4317 | fan3: 4318
50 | fan1: 11070 | fan2: 4569 | fan3: 4567
50 | fan1: 11177 | fan2: 4325 | fan3: 4310
50 | fan1: 11204 | fan2: 4110 | fan3: 4125
60 | fan1: 8351 | fan2: 11587 | fan3: 10952
60 | fan1: 8367 | fan2: 10749 | fan3: 11358
60 | fan1: 7892 | fan2: 10636 | fan3: 11264
60 | fan1: 7729 | fan2: 10807 | fan3: 10744
60 | fan1: 7784 | fan2: 11085 | fan3: 11318
60 | fan1: 8397 | fan2: 11097 | fan3: 11439
60 | fan1: 8283 | fan2: 11143 | fan3: 11698
60 | fan1: 8759 | fan2: 10646 | fan3: 11089
60 | fan1: 8039 | fan2: 10955 | fan3: 10721
60 | fan1: 7169 | fan2: 10855 | fan3: 11174
70 | fan1: 8419 | fan2: 9882 | fan3: 10153
70 | fan1: 8413 | fan2: 10011 | fan3: 11372
70 | fan1: 8349 | fan2: 9717 | fan3: 10555
70 | fan1: 9456 | fan2: 10336 | fan3: 10732
70 | fan1: 8013 | fan2: 9416 | fan3: 10709
70 | fan1: 8651 | fan2: 10115 | fan3: 11081
70 | fan1: 8108 | fan2: 10409 | fan3: 10475
70 | fan1: 8583 | fan2: 9428 | fan3: 10745
70 | fan1: 9088 | fan2: 10158 | fan3: 10841
70 | fan1: 8025 | fan2: 10094 | fan3: 10484
80 | fan1: 4656 | fan2: 8076 | fan3: 9300
80 | fan1: 5084 | fan2: 8798 | fan3: 9327
80 | fan1: 4474 | fan2: 7345 | fan3: 8516
80 | fan1: 4897 | fan2: 8613 | fan3: 9499
80 | fan1: 4903 | fan2: 8196 | fan3: 8989
80 | fan1: 4698 | fan2: 8530 | fan3: 9434
80 | fan1: 4556 | fan2: 7607 | fan3: 8713
80 | fan1: 5007 | fan2: 8629 | fan3: 9385
80 | fan1: 4920 | fan2: 8121 | fan3: 9018
80 | fan1: 4505 | fan2: 8237 | fan3: 9392
90 | fan1: 3969 | fan2: 4771 | fan3: 6373
90 | fan1: 3333 | fan2: 5422 | fan3: 7817
90 | fan1: 3387 | fan2: 5032 | fan3: 7058
90 | fan1: 3659 | fan2: 5486 | fan3: 6288
90 | fan1: 3280 | fan2: 5418 | fan3: 7209
90 | fan1: 3850 | fan2: 5053 | fan3: 6347
90 | fan1: 3875 | fan2: 5254 | fan3: 6600
90 | fan1: 2938 | fan2: 5745 | fan3: 7366
90 | fan1: 3793 | fan2: 5253 | fan3: 6597
90 | fan1: 3751 | fan2: 5106 | fan3: 6311
100 | fan1: 0 | fan2: 0 | fan3: 2
100 | fan1: 0 | fan2: 0 | fan3: 0
100 | fan1: 0 | fan2: 0 | fan3: 0
100 | fan1: 0 | fan2: 0 | fan3: 0
100 | fan1: 0 | fan2: 0 | fan3: 0
100 | fan1: 0 | fan2: 0 | fan3: 0
100 | fan1: 0 | fan2: 0 | fan3: 0
100 | fan1: 0 | fan2: 0 | fan3: 0
100 | fan1: 1 | fan2: 0 | fan3: 0
100 | fan1: 0 | fan2: 0 | fan3: 0
Below a debug sketch:
(I apologize for the dirt in the sketch, I just chose the Tachometer functionality for debugging.)
const int fanPwmPins[] = {3, 9, 10}; // PWM Pins (D3, D9, D10) (25kHz)
unsigned long Millis_current;
unsigned long Millis_fan;
unsigned long Millis_cooler;
const unsigned long period_cooler = 10000;
const unsigned long period_fan = 1000;
const int power_ps24v = 7 ;
const int power_cooler = 11;
const int power_rpi4 = 12;
const int button_sw = 2;
const int button_led = 8;
int rpm_value = 100;
int rpm_change = 10;
unsigned long a1;
unsigned long a2;
unsigned long a3;
// Pulse counter on A1, A2, A3 for Arduino Nano (ATmega328P)
// A1 -> PC1 (PCINT9), A2 -> PC2 (PCINT10), A3 -> PC3 (PCINT11)
volatile unsigned long countA1 = 0;
volatile unsigned long countA2 = 0;
volatile unsigned long countA3 = 0;
// store previous states to detect edges
volatile uint8_t prevPortC;
void setPWM(int fanIdx, int duty) {
duty = constrain(duty, 0, 100);
if (fanIdx == 0) { // Pin 3
OCR2B = (duty * 79) / 100;
} else if (fanIdx == 1) { // Pin 9
OCR1A = (duty * 320) / 100;
} else if (fanIdx == 2) { // Pin 10
OCR1B = (duty * 320) / 100;
}
}
void setup() {
pinMode(button_sw, INPUT);
pinMode(button_led, OUTPUT);
pinMode(power_ps24v, OUTPUT);
pinMode(power_cooler, OUTPUT);
pinMode(power_rpi4, OUTPUT);
digitalWrite(power_ps24v, HIGH);
digitalWrite(power_cooler, HIGH);
digitalWrite(power_rpi4, HIGH);
// Configure PWM Timers for 25kHz PWM
// Timer 1 (Pins 9, 10) and Timer 2 (Pin 3)
TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM11); // Phase Correct PWM
TCCR1B = _BV(WGM13) | _BV(CS10); // Prescaler 1
ICR1 = 320; // 16MHz / (2 * 1 * 25000) = 320
TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); // Fast PWM Pin 3
TCCR2B = _BV(WGM22) | _BV(CS21); // Prescaler 8
OCR2A = 79; // 16MHz / (8 * 25000) - 1 = 79
// Initialize Pins PWN and Tach
for (int i = 0; i < 3; i++) {
pinMode(fanPwmPins[i], OUTPUT);
}
// Start fans at 100% at starting
for (int i = 0; i < 3; i++) { setPWM(i, 100); }
// Configure pins as inputs (analog pins default to input)
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
// Optional pullups - enable if you need defined low/high when open
// digitalWrite(A1, HIGH);
// digitalWrite(A2, HIGH);
// digitalWrite(A3, HIGH);
// Read initial PORTC state
prevPortC = PINC;
// Enable pin change interrupts for PCINT9,10,11 (PC1,PC2,PC3)
// PCMSK1 corresponds to PCINT[14:8]; set bits 9-11 -> mask bits 1-3
PCMSK1 |= (1 << PCINT9) | (1 << PCINT10) | (1 << PCINT11); // same as (1<<PC1)|(1<<PC2)|(1<<PC3)
// Enable PCINT1 group
PCICR |= (1 << PCIE1);
Serial.begin(9600);
while (!Serial) ; // wait for Serial on some boards (safe)
Serial.println("Pulse counter started on A1(A)/A2(B)/A3(C)");
digitalWrite(power_cooler, LOW);
Millis_fan = millis();
}
ISR(PCINT1_vect) {
uint8_t curr = PINC;
uint8_t changed = curr ^ prevPortC;
// Check PC1 (A1) rising edge: bit 1 changed and now high
if (changed & (1 << PC1)) {
if (curr & (1 << PC1)) {
countA1++;
}
}
// Check PC2 (A2)
if (changed & (1 << PC2)) {
if (curr & (1 << PC2)) {
countA2++;
}
}
// Check PC3 (A3)
if (changed & (1 << PC3)) {
if (curr & (1 << PC3)) {
countA3++;
}
}
prevPortC = curr;
}
unsigned long lastReport = 0;
unsigned long lastA1 = 0, lastA2 = 0, lastA3 = 0;
void loop() {
Millis_current = millis();
if (Millis_current - Millis_cooler >= period_cooler) {
Millis_cooler = Millis_current;
rpm_value = rpm_value + rpm_change;
if (rpm_value > 100) { rpm_value = 0; }
for (int i = 0; i < 3; i++) { setPWM(i, rpm_value); }
Serial.println(" ");
}
unsigned long now = millis();
if (now - lastReport >= 1000) { // report every 1 second
Serial.print(rpm_value); Serial.print(" ");
Serial.print(" | fan1: "); Serial.print(countA1); countA1 = 0;
Serial.print(" | fan2: "); Serial.print(countA2); countA2 = 0;
Serial.print(" | fan3: "); Serial.println(countA3); countA3 = 0;
lastReport = now;
}
//
}
Any suggestions to solve the problem?
In any case thanks in advance!
