Go Down

Topic: Valores muy altos con AttachInterrupt(), RPM (creo que es un tema eléctrico) (Read 768 times) previous topic - next topic

Adolfito121

Muy buenas tardes a todos.

Estoy haciendo una aplicación de PC para poder tomar datos de unas máquinas mecánicas que tenemos en mi trabajo.

De estas máquinas sólo necesito saber la velocidad de ciclos por hora que hacen (cúantas piezas a la hora hacen) y si la velocidad es cero varias veces ya en el programa del pc me encargaré de saber a qué hora se ha parado la máquina si no hay nadie delante.

El problema es que estos datos necesito pasarlos por bluetooth para la prueba piloto, ya que la aplicación de PC que estoy haciendo correrá en una tablet que sólo tiene un puerto USB (y es el mismo que hará falta para cargarla )

El sensor que escogimos para medir la velocidad a la que trabajan las máquinas es uno de estos sensores inductivos de continuidad:


Supongo que los hay mejores o más adecuados para lo que nosotros necesitamos (leeremos valores que estarán entre los 1.000 piezas/hora a 35.000 piezas hora). El modelo que nosotros escogimos era este: XS1N05PA310

Lo escogimos porque permitía trabajar a 5V, y al ser un ignorante total en temas de resistencias y divisores de tensiones, pensamos que sería lo más adecuado para trabajar directamente con una Arduino.

Al principio intentamos trabajar con una BLEduino, pero al encontrar poca documentación, tiramos directamente por una Arduino Uno y un módulo Bluetoth.

El cableado que hemos hecho pinta tal que así:


El sketch que hemos subido a la placa (uno de muchos) era este:
Code: [Select]
#include <SoftwareSerial.h>
int arx = 8;
int atx = 12;
SoftwareSerial bluetooth(arx,atx);

// read RPM and calculate average every then readings.
const int numreadings = 10;
int readings[numreadings];
unsigned long average = 0;
int index = 0;
unsigned long total;
#define BOUNCE_DURATION 10   // esta parte del código era para evitar activaciones erróneas del sensor
volatile unsigned long bounceTime=0; // variable to hold ms count to debounce a pressed switch



volatile int rpmcount = 0;
unsigned long rpm = 0;
unsigned long lastmillis = 0;

void setup(){
 //Serial.begin(115200);
 attachInterrupt(1, rpm_fan, RISING);

bluetooth.begin(9600);
bluetooth.print("$$$");
}

void loop(){
  
 if (millis() - lastmillis >= 1000){  /*Uptade every one second, this will be equal to reading frecuency (Hz).*/
 
 detachInterrupt(1);    //Disable interrupt when calculating
 total = 0;  
 readings[index] = rpmcount * 36000; //* Convert frecuency to pieces per hour
 
 for (int x=0; x<=9; x++){
   total = total + readings[x];
 }
 
 average = total / numreadings;
 rpm = average;
 
 rpmcount = 0; // Restart the RPM counter
 index++;
 if(index >= numreadings){
  index=0;
 }
 
 
if (millis() > 11000){  // wait for RPMs average to get stable

 //Serial.println(rpm);
  bluetooth.println(rpm);
}
 
 lastmillis = millis(); // Uptade lasmillis
  attachInterrupt(1, rpm_fan, RISING); //enable interrupt
  }
}


void rpm_fan(){
   {  
// this is the interrupt handler for button presses
// it ignores presses that occur in intervals less then the bounce time
 if (abs(millis() - bounceTime) > BOUNCE_DURATION)  
 {
     rpmcount++;
    bounceTime = millis();  // set whatever bounce time in ms is appropriate
}
}
 
}


Con este código me he encontrado desde obtener valores correctos (poniendo el sensor en una máquina trabajando a una velocidad conocida) hasta barbaridades del tipo:


Una cosa que me ha llamado mucho la atención es que los valores cambian dependiendo de cómo alimento la placa:  con un usb directo al pc, funciona bastante bien. Si ese mismo pc está conectado a la corriente eléctrica (sin tirar de batería) los valores son del orden de 430 millones de piezas por hora (y mi jefe encantado  :smiley-money: ).

Cualquier combinación que represente alimentar la placa por el jack siempre lleva a valores anormalmente altos.

Ya en el código he intentado incluir una rutina para evitar los rebotes del sensor, pero no ha variado en nada las medidas.

Cualquier tipo de ayuda o orientación será muy agradecida.

Saludos

surbyte

Bueno veamos las cosas por partes.
Tus valores 429477XXX son valores x overflow... o sea se desborda alguna cuenta.

Veamos cual. Vi que total es unsigned long asi que esta bien.
Dices que no tendras mas de 35000 interrupciones pero no has visto esos valores.
Evidentemente tienes ruido en la linea.
El debounce presente en tu ISR esta bien pero acá esta tu error


Code: [Select]
volatile int rpmcount = 0;
int readings[numreadings];
readings[index] = rpmcount * 36000; //* Convert frecuency to pieces per hour

36000 x 2 = 72000 y da overflow a un int como has designado a int reading[numradings]
Definelos como unsigned long tambien.
Y resuelto ese problema

36000 x 2 Con esto quiero decir que basta que rpmcount valga 2 para que ya te de overflow.
Asi que imagina la de errores que acumulas.

Go Up