Loading...

Anemómetro leer velocidad del viento

Pablo Durán
Comparte el post:

Teoría

El anemómetro es un sensor que nos mide la velocidad del viento, es uno de los sensores principales que debe tener una estación meteorológica. Envía los datos de forma analógica y aquí vamos a explicar como funciona y como leeremos sus datos.

Su funcionamiento es increíblemente básico. En este caso en la parte rotatoria del anemómetro nos podemos encontrar con un imán que levantará un relé cada vez que pase por encima haciendo que se cree un pulso eléctrico. La Raspberry Pi leerá este pulso eléctrico y cada dos pulsos será una vuelta por lo que solo nos faltaría calcular la velocidad del viento con el tiempo y la cantidad de vueltas dadas por el sensor.

Este tipo de sensores son muy sensibles al rozamiento por lo que es necesario calibrarlo teniendo encueta esta variable en los cálculos. Después de muchas búsquedas la comunidad ha estipulado la calibración en 1.18 conforme la velocidad dada por el sensor. Este cálculo se ha hecho mediante calibraciones de este modelo de anemómetro específicamente por lo que si se usa otro modelo sería necesario hacer las pruebas uno mismo.

Por último, en el caso de este sensor no se toma una única medida del sensor, sino que tiene medición continúa devolviéndonos a cada hora la media de viento leído y las rachas de viento. Esto le suma cierta complejidad al código como veremos más adelante.

Cableado

El orden de los cables en un conector RJ11 es el siguiente.

Orden de los cables rj11

Hay que tener en cuenta que nuestro anemómetro solo tiene dos cables en las posicines 3 y 4. En mi caso utilizaré un adaptador RJ11 para poder conectar los cables a la placa sin cortarlo.

  • Cable 3: este se conecta a un pin GND de la placa.
  • Cable 4: este se conecta al pin GPIO6 de la placa.
Cableado del rj11 a la raspberry

Si prefieres verlo en su esquema te la dejo justo aquí.

Cableado del anemómetro

Funcionamiento

Se importarán las siguientes librerías:

  • import math: Nos servirá para hacer los cálculos para saber la velocidad del viento en km/h.
  • from gpiozero import Button: Con esta librería conseguiremos leer los puertos GPIO en nuestro caso queremos leer el GPIO6.
  • from apscheduler.schedulers.background import BackgroundScheduler: Con esto creamos las rutinas de ejecución para leer las rachas de viento.

Los parámetros que nos devolverá esta clase son velocidad media del viento el cual se obtiene sabiendo cuantas vueltas ha dado el anemómetro en un tiempo determinado. También nos devolverá velocidad de racha máxima en el que se mira la velocidad máxima registrada en un ciclo. Las rachas de viento se miden en intervalos de 5 segundo y solo guardamos la que tenga el valor más alto.

La clase tiene que ser llamada desde que se inicia el programa principal ya que hace una medición continua durante todo el ciclo y no solo la recogida del dato instantáneo como hemos visto en los anteriores sensores. Para medir las rachas cada 5 segundos tenemos que iniciar un subproceso en el programa con apscheduler el cual calcula la cantidad de pulsos recibidos en 5 segundos.

Para detectar la cantidad de vueltas dadas por el anemómetro tenemos que recurrir al método when_pressed de gpiozero el cual tiene la comunicación directa con el sensor mediante el pin GPIO 6 de la Raspberry pi. Cada vez que se detenta un pulso este método ejecuta el método pulso de nuestra clase VelocidadViento para sumar +1 al contador de vueltas.

El programa principal finaliza el ciclo haciendo la llamada a finalizar_ciclo que llama a los métodos necesarios para procesar la velocidad del viento en km/h y reiniciar los contadores para el siguiente ciclo.

Al ser una lectura totalmente analógica no puede haber errores de lectura. Simplemente ha hecho falta que al calcular la velocidad media de viento se ponga un condicional de que se debe haber ejecutado al menos una vez el método de medición de racha de viento para evitar que la división sea entre cero y se bloquee el programa. Esta situación es muy improbable que pase ya que debe de ejecutarse el programa en los últimos 5 segundos de la hora y solo hay una posibilidad del 0.14% de que ocurra esa situación, pero como ya me ha pasado una vez y el inicio del programa es automático es mejor tener esa situación cubierta.

Cableado del anemómetro

Código

Test

En este apartado puedes obtener el código básico para poder leer los pulsos del anemómetro.

from gpiozero import Button

wind_speed_sensor = Button(6)
wind_count = 0

# Se ejecutará cada vez que reciba una señal del sensor
def spin():
    global wind_count
    wind_count = wind_count + 1
    print("spin" + str(wind_count))


wind_speed_sensor.when_pressed = spin
    

Clase

Con los sensores analógicos es necesario programar muchas más cosas por lo que el código de estos sensores termina siendo bastante más largo que los anteriores. En este caso tiene que cumplir con los siguientes requisitos.

  • Se creará una clase para que sea más fácil trabar con el sensor.
  • Se leereán los datos cada vez que se cree un objeto de esta clase.
  • Se pasarán los datos al programa principal mediante metodos GET.
  • Leer durante toda la hora la velocidad del viento dividiendolo en intervalis de 5 segundos para saber la velocidad de racha.
  • Calcular la velocidad del viento teniendo encuenta el tiempo, las señales recibidas, circunferencia del sensor y su fricción.
  • Hacer media de la velocidad del viento sabiendo el número de pulsos y el tiempo trascurrido.
  • Reinicial los valores cuando se hayan leido los datos por el programa principal.

Teniendo todo lo anterior en cuenta esta parte del programa nos queda de la siguiente forma:

import math

from gpiozero import Button
from apscheduler.schedulers.background import BackgroundScheduler

PUERTO_SENSOR = Button(6)

contador_viento = 0
contador_viento_rafaga = 0


class VelocidadViento:
    '''Lee la velocidad del viento en racha y promedio en Km/h. No retorna decimales'''

    vel_med = 0
    vel_max_racha_comparar = 0
    vel_max_racha = 0
    contador_num_rafagas = 0

    def __init__(self):
        '''Inicia un scheduler para recoger las ráfagas de viento cada 5 segundos.'''

        # Mide las rafagas de viento cada 5 segundos
        sched = BackgroundScheduler()
        sched.add_job(self.medir_rafaga, 'interval', seconds=5)
        sched.start()

    def pulso(self):
        '''Suma 1 a los contadores de viento y viento_rafaga cada vez que se ejecuta'''

        global contador_viento
        global contador_viento_rafaga

        contador_viento += 1
        contador_viento_rafaga += 1

    def medir_rafaga(self):
        '''medirá la velocidad de la ráfaga de viento y lo comparará con la velocidad
        máxima registrada en racha y la cambiará si la actual es superior.'''

        global contador_viento_rafaga

        vel_rafaga = self.calcular_velocidad(contador_viento_rafaga, 5)

        if vel_rafaga > self.__class__.vel_max_racha_comparar:
            self.__class__.vel_max_racha_comparar = vel_rafaga

        contador_viento_rafaga = 0
        self.__class__.contador_num_rafagas += 1

    def calcular_velocidad(self, contador, intervalo):
        '''Calcula la velocidad del viento ya sea media o de racha.'''

        # Calcular la circunferencia del sensor de viento
        circunferencia_cm = (2 * math.pi) * 9.0

        # Dividimos los pulsos recibidos entre 2 ya que lanza dos pulsos por vuelta
        rotaciones = contador / 2

        # Calculamos la distancia en km
        dist_km = (circunferencia_cm * rotaciones) / 100000

        # calculamos la velocidad en Km/h
        velocidad = (dist_km / intervalo) * 3600

        # multiplicamos la velocidad por 1.18 que es la fuerza del viento perdida
        # por el rozamiento del sensor de viento
        velocidad_real = velocidad * 1.18

        # print("velocidad = " + str(velocidad_real) + "km/h")

        return velocidad_real

    def calcular_velocidad_media(self):
        '''Calcula la velocidad media registrada.'''

        # para saber cuanto tiempo lleva el programa recogiendo datos miramos
        # los ciclos de rachas hecho y los multiplicamos por 5 para obtener
        # los segundos.
        tiempo = self.__class__.contador_num_rafagas * 5

        # Evitamos que mida entre cero en el caso de que ejecute el comando antes de 5
        # segundos de haber iniciado el programa.
        if tiempo != 0:

            # Calculamos la velocidad del viento promedio en km/h
            self.__class__.vel_med = self.calcular_velocidad(
                contador_viento, tiempo)

        else:
            self.__class__.vel_med = 0

    def reiniciar_valores(self):
        '''Reiniciamos los valores de las variables para empezar de nuevo el siguiente
        ciclo.'''

        global contador_viento

        contador_viento = 0
        self.__class__.contador_num_rafagas = 0
        self.__class__.vel_max_racha = self.__class__.vel_max_racha_comparar
        self.__class__.vel_max_racha_comparar = 0

    def get_vel_media(self):
        '''Devuelve la velocidad media del viento sin decimales.'''

        return str(round(self.__class__.vel_med))

    def get_vel_max_racha(self):
        '''Devuelve la racha de viendo con mayor velocidad en el intervalo del
        tiempo sin decimales'''

        return str(round(self.__class__.vel_max_racha))

    # Envía un pulso cada vez que el anemómetro da media vuelta.
    PUERTO_SENSOR.when_pressed = pulso