Ruido en lectura de RPM motores DC con sensor FC-03

Buenas tardes,

Tengo un motor DC alimentado mediante PWM hasta 7V, al ir variando el PWM para leer las RPM del motor, se me genera una especie de ruido a mayores RPM, he navegado en foros y he intentado varias soluciones y no he sido capaz de corregir esto, comparto mi codigo, adicional a esto, el tiempo de muestreo debe ser obligatoriamente menor a 10ms. Quedo atento a sus respuestas:

/*

  LABORATORIO 1 CONTROL 202360

*/


#include <Time.h>  //Incluimos la librería Time


#define encoder_pin 2  //Encoder Signal Input = D2
#define inputH1 3
#define inputH2 4
#define enableA 5


float dynamoVolt;
float filterAVolt;
float radsVel;
int userPWM;
int arduinoPWM;
unsigned int rpmGen;
volatile byte pulses;
unsigned long TIME;
unsigned int pulse_per_turn = 1;  //Encoder Disc Resolution = 1 slots
bool autoincrement;
int secondsH;

void setup() {

  Serial.begin(19200);
  //Con entrada 1 y entrada 2 se envian dos señales al puente H para controlar el sentido de giro del motor
  pinMode(inputH1, OUTPUT);
  pinMode(inputH2, OUTPUT);
  pinMode(enableA, OUTPUT);  //Salida analoga, equivalente a %PWM
  pinMode(encoder_pin, INPUT);

  digitalWrite(inputH1, LOW);
  digitalWrite(inputH2, HIGH);

  rpmGen = 0;
  pulses = 0;
  secondsH = 0;
  TIME = 0;

  autoincrement = false;

  attachInterrupt(digitalPinToInterrupt(encoder_pin), count, RISING);
}

void loop() {

  if (Serial.available()) {       // Verificar si hay datos disponibles en el puerto serial
    userPWM = Serial.parseInt();  // Leer el valor entero enviado por el puerto serial

    // Verificar si el valor recibido está dentro del rango válido (0-100)
    if (userPWM >= 1 && userPWM <= 101) {
      if (userPWM == 1) userPWM = 0;
      arduinoPWM = userPWM;

      if (userPWM == 101) {
        autoincrement = true;
        arduinoPWM = 10;
        secondsH = 0;
      }
    }
  }
  analogWrite(enableA, map(arduinoPWM, 0, 100, 0, 127));
  filterAVolt = analogRead(A0) * (5.0 / 1023.0);
  dynamoVolt = analogRead(A1) * (5.0 / 1023.0);





  if (millis() - TIME >= 1 && arduinoPWM >= 10) {

    // detachInterrupt(digitalPinToInterrupt(encoder_pin));



    // Serial.println(arduinoPWM);

    // Serial.print("RPM: ");
    // Serial.print(", RADS  ");
    // Serial.print(radsVel);
    // Serial.print(", PWM  ");

    // Serial.println(arduinoPWM);
    // Serial.println(dynamoVolt);
    // Serial.println(filterAVolt);

    // Serial.print(", VOLTAGE  ");
    // Serial.print(dynamoVolt);
    // Serial.println(",");
    if (arduinoPWM <= 100 && autoincrement == true) {
      if (secondsH == 10000) {
        arduinoPWM = arduinoPWM + 10;
        secondsH = 0;
      }
    } else autoincrement = false;


    secondsH++;
    // attachInterrupt(digitalPinToInterrupt(encoder_pin), count, RISING);
  }
}

void count() {
  
  pulses++;
  if (millis() - TIME >= 10 && arduinoPWM >= 10) {
  rpmGen = (60 * 1000 / pulse_per_turn) / (millis() - TIME) * pulses;
  if(rpmGen < 15000)Serial.println(rpmGen);
  TIME = millis();
  radsVel = rpmGen * (2 * 3.141659 / 60);
  pulses = 0;
  }
  
}


Fuente: Propia

En la anterior imagen pase de 50% a 70% aproximadamente.

Tu problema es que no puedes usar Serial dentro de una rutina de servicio de interrupción.

Saludos

Del codigo que mostre principalmente, lo unico que saque de la interrupción fue el serial, tome datos y los tabule en excel, me digo lo siguiente:


Fuente: Propia.

El transitorio de las RPM se ve bien, es lo que mas me interesa, pero esa variación cuando entra en estado estable es normal?.

Gracias por tu respuesta.

Desde mi punto de vista, tu ISR (rutina de servicio de interrupción) tarda demasiado y es lo que genera esas variaciones (picos).
Solo debería actualizar el contador y lo demás hacerlo en loop().

Además algunos detalles...

La operación

2 * 3.141659 / 60

puedes guardarla en una constante y no hacer el cálculo 5000 veces por segundo de una operación que siempre dará el mismo resultado.
Por ej. puedes declarar una constante global

const float K = 2 * 3.141659 / 60;

y luego aplicarla así

radsVel = rpmGen * K; 

Lo mismo puedes hacer con

60 * 1000 / pulse_per_turn

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.