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:
XS1N05PA310Lo 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:
#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

).
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