Reading different RPM values with Arduino R4 minima

Hi,

I'm trying to use PID and PWM to control a fan rpm for college project. At first, I was using an Arduino R3 Uno for the project but opted for R4 minima because I was intersted in using a higher PWM frequency for better control. After changing the boards, the value of rpm got wrong and I really don't know why and how to change!
I'll put both of my codes, first is the working one for the Arduino R3 and the second is the new one for the R4 minima.

FIRST:

// HYDRO-K PROJECT
// TURBINES ARRANGEMET V2.1
// DATE:27/04/2015
// DATE V2.0: 28/03/2016
// DATE V2.1: 25/11/2024
// DEVELOPER: Rafael Mendes & Arthur Giolo

#include <HX711.h>
#include <PID_v1.h>
#define DT A5
#define SCK A4
//----------------------------------------------------------------
//                        Extensômetro
//----------------------------------------------------------------

HX711 scale;
float torque               = 0;

//----------------------------------------------------------------
//                         Sensor RPM
//----------------------------------------------------------------

const float fator_conv     = 10000000.0 ;
volatile long n_pulso      = 0;
volatile float freq        = 0;
int pin                    = 3;
float rot;

//----------------------------------------------------------------
//                            PWM
//----------------------------------------------------------------

const int PWM           = 5;
int relay11             = 6;
int relay12             = 7;

//----------------------------------------------------------------
//                           PID 
//----------------------------------------------------------------

double Alvo, Entrada, Saida, Caixa_texto;
double Kp = 0.9, Ki = 2, Kd = 0;
PID myPID(&Entrada, &Saida, &Alvo, Kp, Ki, Kd, REVERSE);

//----------------------------------------------------------------
//                  Impressão de valores
//----------------------------------------------------------------

long int tempo_atual, tempo_anterior;
int intervalo = 100;       

void setup() {
  Serial.begin(115200);

  //----------------------------------------------------------------
  //                            PWM
  //----------------------------------------------------------------

  pinMode(relay11, OUTPUT);
  pinMode(relay12, OUTPUT);

  //----------------------------------------------------------------
  //                        Extensômetro
  //----------------------------------------------------------------

  scale.begin(DT, SCK);
  scale.read_average(20);
  scale.set_scale(-86);
  scale.tare();

  //----------------------------------------------------------------
  //                           RPM
  //----------------------------------------------------------------

  while (!Serial) {
    ;
  };

  pinMode(pin, INPUT);
  digitalWrite(pin, HIGH);
  attachInterrupt(digitalPinToInterrupt(3), le_rpm, RISING);

  //----------------------------------------------------------------
  //                           PID 
  //----------------------------------------------------------------

  Entrada = freq;
  myPID.SetSampleTime(1);
  myPID.SetMode(AUTOMATIC);
  
}

void loop() {
  //----------------------------------------------------------------
  //                           Controle
  //----------------------------------------------------------------

  if (Serial.available()) {
    Caixa_texto = Serial.parseInt();
    Alvo = Caixa_texto; 
  }

  //----------------------------------------------------------------
  //                            PID
  //----------------------------------------------------------------

  Entrada = freq;
  myPID.Compute();
  analogWrite(PWM, Saida);

  //----------------------------------------------------------------
  //                     Valores de saída
  //----------------------------------------------------------------
 
  tempo_atual = millis();
  if (tempo_atual - tempo_anterior >= intervalo){
    tempo_anterior = tempo_atual; 
    torque = scale.get_units();
    String output = String("w \t") + freq           + \
                      "\t pwm% \t" + (Saida / 2.55) + \
                      "\t set \t"  + Alvo           + \
                      "\t T \t"    + torque; 
   Serial.println(output);

  } 
}

//----------------------------------------------------------------
//                        FUNÇÃO RPM
//----------------------------------------------------------------

inline void le_rpm() {
  volatile long n2_pulso = micros();
  freq = fator_conv / (n2_pulso - n_pulso);
  n_pulso = n2_pulso;
}

SECOND:

// HYDRO-K PROJECT
// TURBINES ARRANGEMET V2.1
// DATE:27/04/2015
// DATE V2.0: 28/03/2016
// DATE V2.1: 25/11/2024
// DEVELOPER: Rafael Mendes & Arthur Giolo

#include <HX711.h>
#include <PID_v1.h>
#include <pwm.h>
#define DT A5
#define SCK A4
#define PWM_D5_PIN D5

//----------------------------------------------------------------
//                        Extensômetro
//----------------------------------------------------------------

HX711 scale;
float torque               = 0;

//----------------------------------------------------------------
//                         Sensor RPM
//----------------------------------------------------------------

const float fator_conv     = 10000000.0 ;
volatile long n_pulso      = 0;
volatile float freq        = 0;
int pin                    = 3;
float rot;

//----------------------------------------------------------------
//                            PWM
//----------------------------------------------------------------

PwmOut objPWMD5(PWM_D5_PIN);
int relay11             = 6;
int relay12             = 7;

//----------------------------------------------------------------
//                           PID 
//----------------------------------------------------------------

double Alvo, Entrada, Saida, Caixa_texto;
double Kp = 0.9, Ki = 2, Kd = 0;
PID myPID(&Entrada, &Saida, &Alvo, Kp, Ki, Kd, REVERSE);

//----------------------------------------------------------------
//                  Impressão de valores
//----------------------------------------------------------------

long int tempo_atual, tempo_anterior;
int intervalo = 100;       

void setup() {
  Serial.begin(115200);

  //----------------------------------------------------------------
  //                            PWM
  //----------------------------------------------------------------

  pinMode(relay11, OUTPUT);
  pinMode(relay12, OUTPUT);
  pinMode(PWM_D5_PIN, OUTPUT);
  objPWMD5.begin(8000.0f, 0.0f);

  //----------------------------------------------------------------
  //                        Extensômetro
  //----------------------------------------------------------------

  scale.begin(DT, SCK);
  scale.read_average(20);
  scale.set_scale(-86);
  scale.tare();

  //----------------------------------------------------------------
  //                           RPM
  //----------------------------------------------------------------

  while (!Serial) {
    ;
  };

  pinMode(pin, INPUT);
  digitalWrite(pin, HIGH);
  attachInterrupt(digitalPinToInterrupt(3), le_rpm, RISING);

  //----------------------------------------------------------------
  //                           PID 
  //----------------------------------------------------------------

  Entrada = freq;
  myPID.SetSampleTime(1);
  myPID.SetMode(AUTOMATIC);
  
}

void loop() {
  //----------------------------------------------------------------
  //                           Controle
  //----------------------------------------------------------------

  if (Serial.available()) {
    Caixa_texto = Serial.parseInt();
    Alvo = Caixa_texto; 
  }

  //----------------------------------------------------------------
  //                            PID
  //----------------------------------------------------------------

  Entrada = freq;
  myPID.Compute();
  objPWMD5.pulse_perc(Saida);

  //----------------------------------------------------------------
  //                     Valores de saída
  //----------------------------------------------------------------
 
  tempo_atual = millis();
  if (tempo_atual - tempo_anterior >= intervalo){
    tempo_anterior = tempo_atual; 
    torque = scale.get_units();
    String output = String("w \t") + freq           + \
                      "\t pwm% \t" + (Saida / 2.55) + \
                      "\t set \t"  + Alvo           + \
                      "\t T \t"    + torque; 
   Serial.println(output);

  } 
}

//----------------------------------------------------------------
//                        FUNÇÃO RPM
//----------------------------------------------------------------

inline void le_rpm() {
  volatile long n2_pulso = micros();
  freq = fator_conv / (n2_pulso - n_pulso);
  n_pulso = n2_pulso;
}

Hmm...

Did you investigate using a higher frequency on R3? Hint: the advantage of using higher frequency is to avoid the fan making ear-splitting, unpleasant noises. R3 can generate up to at least 31KHz which is way too high for humans to hear.

Please explain how higher frequency would give better control? Hint: better control needs higher precision control of duty cycle, not higher frequency.

Question: that is Durdle Door, isn't it?

Hint motors have an upper limit on PWM frequencies, check that to be sure you stay in range.

I already checked and the motor runs on 8 kHz. The problem now is rpm reading on 1800 rpm. The uno r3 reads normally, but the r4 bugs and can't give me values

What does INPUT_PULLUP do?

It will work much better than pinMode(…,INPUT);digitalWrite(…,HIGH);

The UNO R4 core does not emulate AVR pull-ups. digitalWrite() just calls the Renesas FSP(*) function R_IOPORT_PinWrite() which does not care about pin modes.

(*) Flexible Software Package