Problema recogiendo datos de un anemometro con sensores

Hola buenas,

Esta es mi primer post en este foro. Mis conocimientos son bastante reducidos en este tema, pero intentaré explicar cual es mi problema.

Mi idea es hacer un estación meteorológica y para ello me compré un anemometro de repuesto para la estación WS1080/3080. Por lo que he descubierto, el arduino tiene dos interruptores o relés y por cada "2 pulsos" da una vuelta.
El caso es que cada vez que el rotor toca o cierra alguno de los interruptores se "crea" una tensión no constante y recibo mucho datos de ese sensor. Entonces lo que yo hago es tener en cuenta la diferencia con el dato anterior:

void loop() {

// Lee el estado del sensor

int valor_sensor = analogRead(A0);
Serial.print("valor sensor ");
Serial.println(valor_sensor);
diferencia=valor_sensor-ultimovalor;
diferenciabs=abs(diferencia);
Serial.print("diferencias");
Serial.println(diferencia);
// Compara el estado del rele con el estado previo
if (diferenciabs>100) {
// Si el estado ha cambiado incrementa el contador
if (valor_sensor>0)
{
pulsos++;
vueltas=pulsos/2;
tiempo_ahora =millis();
tiempo_media_rev = tiempo_ahora - tiempo_anterior;
rpm = 60000*0.5 / tiempo_una_rev; // 1 minuto = 60000 ms y 0,5 por media vuelta
Serial.print("RELEON ");
// Serial.println(pulsos);
Serial.print("vuelta ");
Serial.println(vueltas);
Serial.print("Tiempo media revolucion: ");
Serial.println(tiempo_media_rev);
Serial.print("Revoluciones por minuto: ");
Serial.println(rpm);

}
else {
// Si el estado actual es LOW pasa de ON a OFF
Serial.println("Rele OFF");

tiempo_anterior = tiempo_ahora;
}
}
}

El problema es que los datos que recogo no son nada fiables porque las diferencias de tensión son muy variables y aveces cuenta vueltas cuando no las da. Por ejemplo, estos son los datos que recibo:

valor sensor 0
diferencias0
valor sensor 285
diferencias285
RELEON vuelta 8
Tiempo media revolucion: 2514
Revoluciones por minuto: 11
valor sensor 124
diferencias124
RELEON vuelta 8
Tiempo media revolucion: 2629
Revoluciones por minuto: 11
valor sensor 0
diferencias0
valor sensor 0
diferencias0

He pensado que quizás poniendo un serial.begin más bajo recibiré menos datos y tendré menos problemas, pero no lo creo. ¿A alguno se le ocurre alguna otra solución?

Creo que no he conseguido explicarme muy bien y no sé si alguno habrá entendido mi duda.

De todas formas, gracias por la atención.

Por lo que he descubierto, el arduino tiene dos interruptores o relés y por cada "2 pulsos" da una vuelta.
El caso es que cada vez que el rotor toca o cierra alguno de los interruptores se "crea" una tensión no constante y recibo mucho datos de ese sensor. Entonces lo que yo hago es tener en cuenta la diferencia con el dato anterior:

Que dices willies??????

Que es eso de que el arduino tiene 2 interruptores? Cuales, donde? Tu usas anlogRead(A0) de manera que todo lo que entra por A0 es tu preocupación.
Ahora tu anemómetro entre una señal analógica o una digital?
Si es analógica no deberias tener semejante diferencia, pero luce como que tienes una salida de pulsos y estas queriendo leer pulsos como si fuera una bateria variable o un potenciometro conectado entre 5v y 0V.

Me comprendes?

surbyte:
Que dices willies??????

Que es eso de que el arduino tiene 2 interruptores? Cuales, donde? Tu usas anlogRead(A0) de manera que todo lo que entra por A0 es tu preocupación.
Ahora tu anemómetro entre una señal analógica o una digital?
Si es analógica no deberias tener semejante diferencia, pero luce como que tienes una salida de pulsos y estas queriendo leer pulsos como si fuera una bateria variable o un potenciometro conectado entre 5v y 0V.

Me comprendes?

Me expliqué bastante mal. Quise decir que el anemometro tiene algun tipo de relé que cuando "se cierra" induce o envía una señal variable al arduino como por ejemplo esta:
valor del sensor0
valor del sensor0
valor del sensor157
valor del sensor77
valor del sensor32
valor del sensor0
valor del sensor5
valor del sensor15
valor del sensor0
valor del sensor0
valor del sensor0

Y no sé cómo controlar eso. Eso es una salida digital o analógica? Estoy un poco perdido.

Y porque no investigas lo que compraste y donde lo compraste? No es lo mas facil.
Anemometro marca, modelo, salida analogica o digital, de tanto a tanto.
tantos km/h por volt o
tanta km/hora x Hz de velocidad de viento

Bueno si el que tiene algun rele es el anemómetro entonces la salida es digital.
Tenemos que contar los pulsos.
mira esta instrucción para comenzar,
Supongamos que conectas el anemometro al pin7
No se como esta alimentado... sería bueno que nos informes. Algo va a GND del arduino.
Algo debe ir a +5V y algo debe ser tu salida que deberia ir al pin 7.
Alimenta el anemótro de esta manera y luego mide con un tester la salida y gira las paletas, en algun momento leerás algo proximo a 5v y luego algo proximo a 0v.
Si es asi usa este codigo.

int pin = 7;
unsigned long duration;

void setup()
{
  pinMode(pin, INPUT);
  Serial.begin(9600);
  Serial.println("Medición de anemómetro 1ra fase");
}

void loop()
{
  duration = pulseIn(pin, HIGH);
  Serial.println("T en mseg =");
  Serial.print(duracion);
}

surbyte:
Bueno si el que tiene algun rele es el anemómetro entonces la salida es digital.
Tenemos que contar los pulsos.
mira esta instrucción para comenzar,
Supongamos que conectas el anemometro al pin7
No se como esta alimentado... sería bueno que nos informes. Algo va a GND del arduino.
Algo debe ir a +5V y algo debe ser tu salida que deberia ir al pin 7.
Alimenta el anemótro de esta manera y luego mide con un tester la salida y gira las paletas, en algun momento leerás algo proximo a 5v y luego algo proximo a 0v.
Si es asi usa este codigo.

int pin = 7;

unsigned long duration;

void setup()
{
  pinMode(pin, INPUT);
  Serial.begin(9600);
  Serial.println("Medición de anemómetro 1ra fase");
}

void loop()
{
  duration = pulseIn(pin, HIGH);
  Serial.println("T en mseg =");
  Serial.print(duracion);
}

Ante todo muchas gracias por las respuestas surbyte.

He estado buscando información por internet y la verdad es que no encuentro mucha respecto a mi anemometro ya que al ser de recambio para una comercial, supongo que no querrán dar demasiadas pistas.
Lo poco que he encontrado, es que tiene una especie de interruptor magnético que se cierra cada vuelta.
El cable que usa es un RJ11 y no puedo contar mucho más.
Diría que la salida es analógica, pero es simple intuición.
He intentado utilizar tú script pero el valor me daba siempre nulo. Encima sólo tiene dos cables.

Quizás lo mejor sea desmontar el anemometro y ver lo que hay o poner un iman y un relé reed por separado.

Bueno si cierra por cada vuelta tienes una salida digital.
A ver... Ti tiene dos contactos es porque actua como un interruptor.
Entonces haz esto.
Siempre con el pin 7 pero da igual, le cambias el número y usas otro.
Ahora, un cable a masa, y el otro al pin 7, okay? No alimentes el anemótro con nada mas.

Ahora modifica esto en el sketch solo esto

pinMode(pin, INPUT_PULLUP);

Aproximadamente esta será tu conexión, lo que se lee como switch es tu anemótro.

Acá esta al pin 2, que si quieres lo cambias tambien en el sketch. Funciona con 2, 7 o cualquiera.

Vamos que ya lo tienes

Un detalle, importante.. no sabes la equivalencia de 1 vuelta con los m/seg del viento.. y ahi estamos mal.
El programa anterior mide el ancho del pulso pero ahora no se si sirva o no, medir el ancho del pulso o contar vueltas y luego con alguna ecuación tener los m/seg del viento.

Al final he encontrado un script que fuciona. El problema es que no lo entiendo del todo. Es el siguiente:

#define uint unsigned int
#define ulong unsigned long

#define PIN_ANEMOMETER 2 // Digital 2
#define PIN_VANE 5 // Analog 5

// How often we want to calculate wind speed or direction
#define MSECS_CALC_WIND_SPEED 5000

volatile int numRevsAnemometer = 0; // Incremented in the interrupt
ulong nextCalcSpeed; // When we next calc the wind speed
ulong time; // Millis() at each start of loop().

//=======================================================
// Initialize
//=======================================================
void setup() {
Serial.begin(9600);
pinMode(PIN_ANEMOMETER, INPUT);
digitalWrite(PIN_ANEMOMETER, HIGH);
attachInterrupt(0, countAnemometer, FALLING);
nextCalcSpeed = millis() + MSECS_CALC_WIND_SPEED;

}

//=======================================================
// Main loop.
//=======================================================
void loop() {
time = millis();

if (time >= nextCalcSpeed) {
calcWindSpeed();
nextCalcSpeed = time + MSECS_CALC_WIND_SPEED;

}

}

//=======================================================
// Interrupt handler for anemometer. Called each time the reed
// switch triggers (one revolution).
//=======================================================
void countAnemometer() {
numRevsAnemometer++;

}

//=======================================================
// Calculate the wind speed, and display it (or log it, whatever).
// 1 rev/sec = 1.492 mph->2.4km/h
//=======================================================
void calcWindSpeed() {
int x, iSpeed,y;
// This will produce mph * 10
// (didn't calc right when done as one statement)
long speed = 14920;
speed *= numRevsAnemometer;
speed /= MSECS_CALC_WIND_SPEED;
iSpeed = speed; // Need this for formatting below

Serial.print("Velocidad(km/h): ");
x = iSpeed / 10;
y=x1,609344 ; //para pasar a km/h
Serial.print(y);
Serial.print('.');
x = iSpeed % 10;
y=x
1,609344 ;
Serial.print(y);

numRevsAnemometer = 0; // Reset counter

}

Ahora me toca comprobar si los datos son fiables con otro anemometro. Y otra duda, por qué me aparecen los datos en horizontal?

bueno para que te vayas poniendo en tema. No se le dice script sino sketch
Luego los códigos deben insertarse usando los tags del editor. El Nro 19 es el de código.

#define uint  unsigned int
#define ulong unsigned long

#define PIN_ANEMOMETER  2     // Digital 2
#define PIN_VANE        5     // Analog 5

// How often we want to calculate wind speed or direction
#define MSECS_CALC_WIND_SPEED 5000

volatile int numRevsAnemometer = 0; // Incremented in the interrupt
ulong nextCalcSpeed;                // When we next calc the wind speed
ulong time;                         // Millis() at each start of loop().


//=======================================================
// Initialize
//=======================================================
void setup() {
   Serial.begin(9600);
   pinMode(PIN_ANEMOMETER, INPUT);
   digitalWrite(PIN_ANEMOMETER, HIGH);
   attachInterrupt(0, countAnemometer, FALLING);
   nextCalcSpeed = millis() + MSECS_CALC_WIND_SPEED;
 
}

//=======================================================
// Main loop.
//=======================================================
void loop() {
   time = millis();

   if (time >= nextCalcSpeed) {
      calcWindSpeed();
      nextCalcSpeed = time + MSECS_CALC_WIND_SPEED;
     
   }

}

//=======================================================
// Interrupt handler for anemometer. Called each time the reed
// switch triggers (one revolution).
//=======================================================
void countAnemometer() {
   numRevsAnemometer++;
   
}

//=======================================================
// Calculate the wind speed, and display it (or log it, whatever).
// 1 rev/sec = 1.492 mph->2.4km/h
//=======================================================
void calcWindSpeed() {
   int x, iSpeed,y;
   // This will produce mph * 10
   // (didn't calc right when done as one statement)
   long speed = 14920;
   speed *= numRevsAnemometer;
   speed /= MSECS_CALC_WIND_SPEED;
   iSpeed = speed;         // Need this for formatting below
   

   Serial.print("Velocidad(km/h): ");
   x = iSpeed / 10;
   y=x*1,609344 ;        //para pasar a km/h
   Serial.print(y);
   Serial.print('.');
   x = iSpeed % 10;
   y=x*1,609344 ;
   Serial.print(y);


   numRevsAnemometer = 0;        // Reset counter
   
}

Tu codigo conecta el anemétro al PIN 2 como yo te habia sugerido. Pero resulta que el PIN2 es una interrupción externa, entonces cada vez que se cierre el interruptor ejecuta esto

//=======================================================
// Interrupt handler for anemometer. Called each time the reed
// switch triggers (one revolution).
//=======================================================
void countAnemometer() {
   numRevsAnemometer++;
   
}

o sea incrementa en 1 numRevsAnemometer
en el loop tienes un if que dice
if (time >= nextCalcSpeed) {

si se supera nextCalcSpeed entonces se cambia los parametros de comparación y se presenta el valor de la velocidad delviento.

Muchas gracias Surbyte. Últimas dudas, por qué me aparecen los valores en horizontal y por último, cual sería la manera más económica de almacenar y pasar los datos a un excel?

ahh por horizontal quieres decir que se pega uno junto al otro.
Bueno eso es porque tienes un Serial.print(blabla) que no le dice nunca que cambie de linea.
Lo haces con Serial.println(blablabla)

Cambie este

Serial.print("Velocidad(km/h): ");

por este

Serial.println("Velocidad(km/h): ");

Hola, estoy interesado en realizar un proyecto con arduino relacionado con esto, si alguien esta interesado: reg@informaticaautonomos.com Gracias