Autor Tema: Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20  (Leído 30863 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado mielmari

  • Newbie
  • *
  • Mensajes: 43
    • Ver Perfil
  • Estación: En proyecto
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #15 en: 21 de Enero del 2018, 09:45:16 am »

Este el código en Arduino que calcula la dirección

Código: [Seleccionar]
int ADCvalue;  // lectura de la tension

static int ADCvalues[]           = {66,    84,   92,   127,   184,   244,   287,   406,  461,  600,   631,   702,   786,  827,   889,   946  };
static float vaneDirections[] = {112.5, 67.5, 90.0, 157.5, 135.0, 202.5, 180.0, 22.5, 45.0, 247.5, 225.0, 337.5, 0.0,  292.5, 315.0, 270.0};


float ADCtoDirection(int ADCvalue)
{
  for(int n=0; n<16;n++)
  {
    // valor intermedio
    if(ADCvalue < ( ADCvalues[n] + ( (ADCvalues[n+1] - ADCvalues[n]) / 2) ) )
       return vaneDirections[n];
  }
  Serial.print("ADCtoDirection error, ADCvalue: ");
  Serial.println( ADCvalue);

  return -1.0;
}

Desconectado mielmari

  • Newbie
  • *
  • Mensajes: 43
    • Ver Perfil
  • Estación: En proyecto
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #16 en: 27 de Enero del 2018, 06:01:46 am »
Hola,
he conseguido establecer comunicación serie entre Arduino y PC linux (Mint 18), porque todavía no he he recibido la RPi. L RPi envía a Arduino códigos de un carácter, 't' para temperatura, 'r' para lluvia...  Arduino responde envíando una línea de texto con el valor del sensor a la RPi

Código lado Arduino:
Código: [Seleccionar]
void loop()
{
    if (Serial.available() > 0)
    {
        bme.readSensor();
        s = Serial.read();
       
        // inicio dia, poner a cero contadores de lluvia y viento
if (s == '0')
        {
    dailyrainin = 0;
            windturns = 0;
        }
       // temperatura
else if (s == 't') 
    Serial.println(bme.getTemperature_C());
        // humedad
        else if (s == 'h')
           Serial.println(bme.getHumidity());
        // presion
        else if (s == 'p') 
   Serial.println(bme.getPressure_MB());
        // lluvia
        else if (s == 'r')
   Serial.println(dailyrainin);
        // velocidad viento   
        else if (s == 'v')
   Serial.println(windturns);
        // direccion viento
        else if (s == 'd')
        {       
            ADCvalue = analogRead(A0);
            gradosRosa = ADCtoDirection(ADCvalue);
    Serial.println(gradosRosa);
        }
    }
}

El código en lado RPi me ha dado algún problemilla. Estoy usando python3. Se trata de convertir valores ascii a unicode y viceversa. Además hay qye eliminar el final de línea.

Código: [Seleccionar]
                    arduinoPort.write("t".encode('ascii') )
                    getTenperatura = arduinoPort.readline()
                    getTenperatura = getTenperatura.decode('ascii')
                    getTenperatura = getTenperatura.rstrip('\r\n')
                           
                    arduinoPort.write("h".encode('ascii') )
                    getHumedad = arduinoPort.readline()
                    getHumedad = getHumedad.decode('ascii')
                    getHumedad = getHumedad.rstrip('\r\n')
                                     
                    arduinoPort.write("p".encode('ascii') )
                    getPresion = arduinoPort.readline()
                    getPresion = getPresion.decode('ascii')
                    getPresion = getPresion.rstrip('\r\n')
                 
                    arduinoPort.write("r".encode('ascii') )
                    getLluvia = arduinoPort.readline()
                    getLluvia = getLluvia.decode('ascii')
                    getLluvia = getLluvia.rstrip('\r\n')
   
                   # etc.

Luego se abre un fichero en modo 'a'a (append) y se van guardando los valores

Código: [Seleccionar]
 
                    file = open("/home/pi/weather/weather3_log.txt","a+")
                    file.write(orain.strftime('%Y-%m-%d %H:%M:%S\t'))   
                    file.write('%.1f\t' % float(getTenperatura) )
                    file.write('%.0f\t' % float(getHumedad) )
                    file.write('%.0f\t' % float(getPresion) )
                    file.write('%d\t' % int(getLluvia) )
                    file.write('%d\t' % int(getVelocidadViento) )
                    file.write('%.0f\t' % float(getDireccion) )
                    file.write('%s\n' % getRosa)
                    file.flush()
                    file.close()







Desconectado mielmari

  • Newbie
  • *
  • Mensajes: 43
    • Ver Perfil
  • Estación: En proyecto
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #17 en: 27 de Enero del 2018, 06:06:57 am »
Otro día comentaré otros puntos:

- cómo hacer que el programa python se cargue  al encenderse la RPi, y se ejecute como un proceso en segundo plano.
- cómo hacer que la RPi detecte automáticamente el puerto Arduino, que cada vez que se enchufa el usb puede variar, en mi caso a veces es ttyUSB0, otras veces es ttyUSB1, ttyUSB2...

Desconectado jmviper

  • Investigación
  • Hero Member
  • ******
  • Mensajes: 4.403
  • "Vortex Complex"
    • Ver Perfil
    • www.meteoarchena.es
  • Estación: Archena - ESMUR3000000030600B
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #18 en: 27 de Enero del 2018, 12:21:55 pm »
Un apunte por si te sirve de utilidad con el buen trabajo que estás haciendo....

los logs supongo que los harás en la RPi cada minuto con crontab y en ese caso sería bueno para la organización de los mismos que fuesen llamados por el nombre o número del mes. Por ejemplo el de este mes se podría llamar 012018log.txt, 022018log.txt el de febrero etc etc, por ejemplo con open('/home/pi/weather/logfiles/' + time.strftime("%m%Y") + 'log.txt','a+')

Para las máx/mín podrías hacer como en Cumulus un today.ini en que se guardasen las del día en curso con sus tiempos, un month.ini para las del mes y para las del año un year.ini (los nombres los que tú quieras claro está). Así podrías editarlos fácilmente en caso de algún valor erróneo aunque también tendrías que ver en el log correspondiente ese valor erróneo y corregirlo. También un dayfile.txt que te grabase las máx/mín del día al final del mismo en un fichero con todos los días del que podrías extraer los valores fácilmente.

Recurro a Cumulus porque tiene un sistema interesante al respecto, fácilmente editable y de consultar.

Poco a poco va tomando cuerpo la cosa.

Enhorabuena  :)


Archena, Valle de Ricote (Murcia). 120 msnm. 19.622 hab.
Davis Vantage Pro2 Plus

www.meteoarchena.es

Desconectado mielmari

  • Newbie
  • *
  • Mensajes: 43
    • Ver Perfil
  • Estación: En proyecto
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #19 en: 28 de Enero del 2018, 07:53:52 am »
Hola
no utilizo crontab, lo que hago es mirar la hora, dividir los minutos  por 5 (se podría hacerlo por otro número como 1 o 2 o 5) y cuando el resto es igual a 0 y los segundos son 0, guardo los datos. divmod() da dos datos: r[0] es el cociente y r[1] es el resto. Así funciona exacto.

Código: [Seleccionar]
while True:

    try:

        ahora = datetime.now()
        # cada 5 min
        r = divmod(ahora.minute, 5)
        resto = r[1]

        if resto == 0 and ahora.second == 0:
        file = open("/home/pi/eguraldi/eguraldi3_log.txt","a+")
   
        # leer datos de Arduino...

        # guardar datos en un fichero                 
        file.write(orain.strftime('%Y-%m-%d %H:%M:%S\t'))   
        file.write('%.1f\t' % float(getTenperatura) )
        file.write('%.0f\t' % float(getHumedad) )
        file.write('%.0f\t' % float(getPresion) )
        file.write('%d\t' % int(getLluvia) )
        file.write('%d\t' % int(getVelocidadViento) )
        file.write('%.0f\n' % float(getDireccion) )

        file.flush()
        file.close()
        time.sleep(40)

 

Como el primer dato que guardo es fecha y hora en la forma "2018-01-27 07:48:00", todo va a un fichero. Es buena idea renovar el nombre del fichero cada mes, utilizaré tu fórmula.

(nota: veréis que en algún lugar utilizo "eguraldi", es una palabra en euskera que equivale exactamente a "weather")

Por ahora no hago ningún tratamiento de datos (por ejemplo, máximos o mínimos diarios). Simplemente quiero recogerlos. La elaboración la dejo para más tarde.

Mi pregunta: ¿cada cuánto tiempo conviene tomar los datos? En otros ámbitoss he visto que a menudo lo hacen cada 10 minutos. En el mensaje anterior insinúas cada minuto. ¿Hay algún criterio aceptado de forma general en meteorología?





Desconectado jmviper

  • Investigación
  • Hero Member
  • ******
  • Mensajes: 4.403
  • "Vortex Complex"
    • Ver Perfil
    • www.meteoarchena.es
  • Estación: Archena - ESMUR3000000030600B
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #20 en: 28 de Enero del 2018, 10:15:19 am »
Yo lo tengo cada minuto en los diversos programas para crear los logs. No sé si habrá algún criterio al respecto.

Para tomar datos en el loop infinito en el segundo 0 de cada minuto se puede poner también time.sleep(60 - time.time() % 60)


Archena, Valle de Ricote (Murcia). 120 msnm. 19.622 hab.
Davis Vantage Pro2 Plus

www.meteoarchena.es

Desconectado mielmari

  • Newbie
  • *
  • Mensajes: 43
    • Ver Perfil
  • Estación: En proyecto
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #21 en: 29 de Enero del 2018, 05:32:21 am »
Gracias, jmviper
Paso a otro tema.

Ejecutar el programa python en segundo plano como un proceso

Hay varias formas de ejecutar en segundo plano una aplicación python. Llámese proceso, daemon (demonio), no llego a las pequeñas diferencias entre esos coceptos.

A mí me va muy bien un método sencillo, que consiste en editar "rc.local". Desde la consola ejecuto

sudo gedit /etc/rc.local (yo uso 'gedit' como editor, habría que poner  el editor que use cada uno)

y añadir esta línea:

sudo python3 /home/pi/eguraldi/eguraldi.py &
La dirección completa y el nombre del script. Es importante añadir ese ampersand ('&') al final de la línea, le indica al sistema que es un proceso en segundo plano.

Luego hay que hacer:

reboot

Al encender la Raspberry el programa se carga automáticamente y empieza a ejecutarse. Cada vez que se cambia algo del script, hay que volver a hacer "reboot"

P.D. Debo confesar que todavía estoy probando en Linux Mint 18, la RPI creo que llegará esta semana ...

Desconectado mielmari

  • Newbie
  • *
  • Mensajes: 43
    • Ver Perfil
  • Estación: En proyecto
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #22 en: 29 de Enero del 2018, 05:43:16 am »

Pregunta de 'bricolaje': tengo pensado en poner la RPI y el arduino en el exterior dentro de una caja estanca de las que se usan para conexiones eléctricas en intemperie. MI duda es ¿se producirá alguna condensación debido al calor que producen los chips? Si alguien tenéis experiencia en este punto, agradecería compartir. También iría en ella  el alimentador 220V AC  -5V DC.


Desconectado B.Santiago

  • Moderador Global
  • Hero Member
  • ******
  • Mensajes: 1.979
    • Ver Perfil
  • Estación: Ávila- La Colilla [ESCYL0500000005192A]
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #23 en: 29 de Enero del 2018, 08:52:41 am »
Si temes que eso llegue a ocurrir, pon dentro uno o dos  sobrecillos de desecante, silicagel.
[img width=180

Desconectado mielmari

  • Newbie
  • *
  • Mensajes: 43
    • Ver Perfil
  • Estación: En proyecto
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #24 en: 30 de Enero del 2018, 05:22:11 am »
Hola,

Detectar auomáticamente el puerto Arduino

Otro asuntillo que he tenido que solucionar ha sido el de detectar el puerto USB de Arduino. Porque a veces era el "ttyUSB0", otras veces "ttyUSB1", "ttyUSB2"... (esto en el caso de Linux Mint, tal vez cambie algo en RPI, lo comentaré cuando lo pruebe)

Se utiliza una función para detectar el puerto (encontrada por la red):

Código: [Seleccionar]
def findArduinoUnoPort():
    portList = list(serial.tools.list_ports.comports())
    for port in portList:
        if "ttyUSB" in port[0] or "ttyUSB" in port[1] or "ttyUSB" in port[2]:
            print("\n")
            print(port)

            #print(port[0])
            #print(port[1])
            #print(port[2])

            #please note: it is not sure [0]
            #returned port[] is no particular order
            #so, may be [1], [2]
            return port[0]

def doAtExit():
    if arduinoPort.isOpen():
        arduinoPort.close()
        #print("Close serial")
        #print("arduinoPort.isOpen() = " + str(arduinoPort.isOpen()))


El programa principal llama a esa función, y si el puerto se abre, sigue la ejecución:

Código: [Seleccionar]
        if resto == 0 and ahora.second == 0:
            #buscar puerto Arduino tal como '/dev/ttyUSB1'
            atexit.register(doAtExit)
            unoPort = findArduinoUnoPort()
            while not unoPort:
                print("\nNo Arduino Uno found")
                unoPort = findArduinoUnoPort()
                time.sleep(5)
   
            arduinoPort = serial.Serial(unoPort, 9600, timeout=1)
            if arduinoPort.isOpen():
 
                try:

Desconectado mielmari

  • Newbie
  • *
  • Mensajes: 43
    • Ver Perfil
  • Estación: En proyecto
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #25 en: 06 de Febrero del 2018, 06:19:53 am »
Hola,
por fin, recibí la Raspberry. Le instalé raspbian con un instalador muy cómodo llamado NOOBS. Le puse IP fija, y le instalé un servidor VNC para poder prescindir de la tele y demás periféricos,  y poderle controlar desde el PC. Le he conectado el Arduino Uno con un cable usb, igual que lo hago al PC, he copiado a la RPi el programa python que estaba probando en Linux, y eureka! Funciona, porque los puertos usb tiene el mismo formato: ttyUSB0, ttyUSB1...

Tuve algún contratiempo que me costó un par días en aclararme: en el lado Arduino, en la función setup(), suele ser normal que cuando se activa algún sensor (en mi caso el BME280), se envíe a la consola un mensaje de confirmación, por ejemplo

Código: [Seleccionar]
Serial.println("Bosch BME280 Barometric Pressure - Humidity - Temp Sensor ok");
Este mensaje interfería con la lectura que hacía python... Conclusión: en un programa Arduino que se comunica por serie con python, no debe haber ningún mensaje del tipo Serial.print() que no sea estrictamente el que se envía a python.

He editado 'rc.local' para que cargue el programa python al arrancar y está guardando en un fichero log los datos de fecha, hora, temperatura, humedad y presión.

En este momento estoy esperando a los RJ11 hembra, para poder preparar una placa perforada, y hacer lecturas reales.

P.D. Creo que Cristobal Colón sintió algo parecido a lo que yo estoy sintiendo al descubrir un nuevo mundo, en mi caso el de la Raspberry.

Continuará.

Desconectado mielmari

  • Newbie
  • *
  • Mensajes: 43
    • Ver Perfil
  • Estación: En proyecto
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #26 en: 10 de Febrero del 2018, 07:26:39 am »
Hola,
anduve indagando normativa o directrices sobre la toma de datos en estaciones automáticas, sobre todo, me intersaba la frecuencia de muestreo.
Gracias a un amable meteorólogo, he conseguido la información que buscaba.

El documento de la Organización Meteorológica Mundial se titula:
Guide to Meteorological Instruments and Methods of Observation (WMO, updated 2017)

Se puede bajar de aquí:
https://library.wmo.int/opac/doc_num.php?explnum_id=4147

La versión española:
Guía de Instrumentos y Métodos de Observación Meteorológicos
https://library.wmo.int/opac/doc_num.php?explnum_id=3664

PARTE 2, CAPITULO 1. trata de MEDICIONES DE ESTACIONES METEOROLÓGICAS AUTOMÁTICAS

Esplica la diferencia entre muestra,  valor instantáneo, observación.

En la pag. 593 dice:
Con el fin de normalizar los algoritmos de promediado se recomienda
a)  que la presión atmosférica, la temperatura del aire, la humedad del aire, la temperatura  de la superficie del mar y la visibilidad, entre otras, sean comunicadas como medias de 1 a  10 minutos, obtenidas después de la linealización de la salida del sensor;
b)  que el viento, exceptuando las ráfagas de viento, sea comunicado como media de 2 o de  10 minutos, obtenida después de la linealización de la salida del sensor.
Como valores instantáneos adecuados se sugieren para la mayoría de las variables promedios de 1 minuto, siempre que sean aplicables. Se exceptúan las mediciones del viento (véase el apartado b) anterior) y de las olas (promedios de 10 o 20 minutos)

En la PARTE 1, CAPITULO 1, ANEJO 1.E (PÁGINA 51)  da unos criterios sobre REQUISITOS DE INCERTIDUMBRE DE LAS MEDICIONES OPERATIVAS Y RENDIMIENTO DE LOS INSTRUMENTOS

Tal vez esta información sería de más ayuda a otros puesta en otro lugar. Dejo a criterio de los responsables.








Desconectado jmviper

  • Investigación
  • Hero Member
  • ******
  • Mensajes: 4.403
  • "Vortex Complex"
    • Ver Perfil
    • www.meteoarchena.es
  • Estación: Archena - ESMUR3000000030600B
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #27 en: 10 de Febrero del 2018, 10:57:04 am »
Gracias por esos enlaces... aunque sean un buen tocho valdrán la pena leerlos en un rato libre.


b)  que el viento, exceptuando las ráfagas de viento, sea comunicado como media de 2 o de  10 minutos, obtenida después de la linealización de la salida del sensor.
Como valores instantáneos adecuados se sugieren para la mayoría de las variables promedios de 1 minuto, siempre que sean aplicables. Se exceptúan las mediciones del viento (véase el apartado b) anterior) y de las olas (promedios de 10 o 20 minutos)


Esta es la parte que importa en cuanto a enviar los datos a meteoclimatic. Los valores de temperatura, humedad, presión, precipitación y radiación solar pueden ser instantáneos en ese mismo momento pero para la velocidad del viento se debe de dar el dato como velocidad media (y dirección media) de los últimos 10 minutos. Se hace así ya que el viento es la variable que más puede cambiar bruscamente y con la media se consigue un valor más homogéneo y no puntual de una determinada racha. De hecho en los METARS se informa de esa velocidad y dirección media de la velocidad del viento además de las direcciones extremas (entre las que ha soplado el viento) de esos 10 últimos minutos para unos determinados valores.


Archena, Valle de Ricote (Murcia). 120 msnm. 19.622 hab.
Davis Vantage Pro2 Plus

www.meteoarchena.es

Desconectado EA1AML

  • Full Member
  • ***
  • Mensajes: 102
    • Ver Perfil
  • Estación: ESCYL2400000024420A
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #28 en: 10 de Febrero del 2018, 14:31:02 pm »
Muchas gracias. Con el enlace que lo voy a imprimir y la wiki de meteoclimatic, como aficionado y estacion davis vantage pro2 plus, creo que ya los datos seran el 95% fiables. A leer y una, dos, .. hasta que sacque el maximo de calculos etc.
Aunque siempre suegen algunos problemas que no entiendo , pero tenemos el foro para preguntar y alguna alma buena, siempre me ayuda a solucionar.
Un saludo... 73´s

Desconectado mielmari

  • Newbie
  • *
  • Mensajes: 43
    • Ver Perfil
  • Estación: En proyecto
Re:Diseño de estación con Arduino y raspberry pi con sensores tipo PCE FWS-20
« Respuesta #29 en: 12 de Febrero del 2018, 07:04:55 am »
Hola,
me alegro de que les sirvan las citas.

Existe otro documento interesante titulado: Guidelines on Quality Control Procedures for Data fron Authomatic Weather Stations
https://www.wmo.int/pages/prog/www/IMOP/meetings/Surface/ET-STMT1_Geneva2004/Doc6.1(2).pdf

Donde se exponen criterios para evaluar la calidad de los datos. Hay criterios para depurar 'raw data' (lecturas de los sensores), y 'processed data' que serían las medias obtenidas de esos datos de lectura. Por ejemplo, simplificando, para que de unas muestras puntuales se pueda obtener un dato procesado (una observación), debe haber un 66% de muestras válidas. En caso contrario, el dato se considera inexistente.
Lo que comenta jmviper sobre el tratamiento especial del viento también está especificado.
En un ejemplo, plantea realizar mediciones cada 10 segundos (el viento se trata aparte), y obtener la media cada minuto, después de aplicarles el chequeo de validación. Es lo que voy a intentar en mi programa Python.

Continuará...