Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.


Mensajes - mielmari

Páginas: 1 [2] 3
16
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.








17
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á.

18
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:

19

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.


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

21
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?





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

23
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()







24

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;
}

25

Dirección del viento

Esta es la tabla donde he reunido los datos. Los que usaré en el programa serán dos series: grados vs valores ADC




26
Gracias por los enlaces.

27
Hola
Sobre la forma de leer el anemómetro, después de pensar un poco más, creo que lo mejor es contar todas las revoluciones del anemómetro en el día. En una variable long caben 4 billones. Es lo más sencillo en el lado Arduino. Poner a cero al empezar el día y contar revoluciones durante el mismo.

Raspberry puede leer el contador con la frecuencia que desee, por ejemplo, cada 10 segundos, y extraer los incrementos comparando con la lectura anterior.

28
Varias dudas:

- ¿Cómo se puede editar en el foro un mensaje ya enviado? A veces se ven erratas y cosas a corregir. No veo la forma de hacerlo.

- Sobre la frecuencia de las mediciones:
     - medición de la velocidad del viento: a) cada cuánto tiempo debería medirla? ¿Bastaría cada minuto?  b) cuanfo hago la medición, ¿durante cuánto tiempo debería contar las revoluciones? ¿Bastaría con contar durante 10 segundos? O es mejor contar todas las revoluciones y registrar el cómputo cada cierto tiempo?

    - medición dirección del viento: ¿cada cuánto tiempo debería medir?


29
Hola,

B.Santiago, ¿cómo se puede cambiar de subforo?

zapal, de las las dos dircciones I2C hay que elegir una para todo, conectando el terminal SD0  a GND o a 5V.

Debo confesar que todavía estoy esperando las placas perforadas, los terminales hembra RJ11, los diodos... Monataré 3 terminales RJ11 en una placa perforada, el estañado se me da bastante bien, menos en los casos en que los chips son muy pequeños jeje. Por ejemplo, los BAV99 vienen en un chip de dos diodos, formato SOT-23, que está un poco al límite de mis posibilidades. Espero soldarles unos hilitos a las patasi y pasar esos hilos por la placa. Si no,  irá sin diodos. Es la primera vez que uso estos diodos. Como ca a estar a la intemperie sobre un mástil, me pareceió interesante uso de diodos, que lo aprendí aquí:

http://www.thebox.myzen.co.uk/Tutorial/Protection.html

Sobre el grágico general, algunas puntualizaciones ( en las explicaciones y programas uso palabras en inglés, español y hasta en euskera... soy un poco anarco en este sentido, sabrán disculparme)

- los sensores de lluvia y velovidad del viento producen impulsos que se  tratan como entradas digitales por interrupciones en Arduino. El Arduino UNO posee dos entradas con interrupciones, la D2 y D3. Eso significa que esos valores se leen automáticamente, al margen de lo que esté haciendo en cada momento  el microcontrolador. Una vez que se activan las interrupciones, ellas van contando los pulsos de forma autónoma. Lo único que hace el programa es leer el valor o pner el contador a cero.

- la dirección del viento es el sensor más complicado: tiene 8 reed switch, conectados a 8 resistencias, y el imán puede activar dos de ellos a la vez, de suerte que el valor será el de las dos resistencias en paralelo. Así se obtienen 16 posicioes en la rosa de los vientos. Según el valor de las resitenncias, para 5V con resistencia  de 10K, se leen las tensiones en una entrada analógica aprovechando el ADC de 10 bit  que posee Arduino.




 


30

Diseño de estación con Arduino y Raspberry Pi con sensores tipo PCE FWS-20

La idea en resumen: un Raspberry Pi (RPi) utiliza un Arduino para leer sensores. La RPi está conectada a la wifi doméstica. He elegido Arduino para leer los sensores porque estoy muy familiarizado con él, y me siento cómodo programando en C. El programa en el lado de RPi va en Python.
Arduino y RPi se comunican por serie.

Este es el esquema general de los senosres, que lo iré detallando en mensajes siguientes:




Páginas: 1 [2] 3