Home»Desarrollos»Receptor para sensores meteorlógicos Oregon

Receptor para sensores meteorlógicos Oregon

1
Shares
Pinterest WhatsApp

Para los aficionados a la meteorología el fabricante Oregon Scientific tiene una serie de dispositivos formados por sensores y receptores que permite saber la temperatura, humedad, velocidad y dirección del viento, cantidad de lluvia, sensor rayos UV … En el siguiente enlace podéis ver los dispositivos comercializados por Oregon: http://store.oregonscientific.com/es/estaciones-meteorologicas.htmlWMR88conjunto

Aunque Oregon si que dispone de diversas estaciones que recogen la información de todos sus sensores y permite volcarlos a un PC, la idea de este proyecto es poder publicar en tiempo real estos valores en Internet.

Los sensores de este fabricante son inalámbricos y emiten en la frecuencia de 433Mhz y una codificación Manchester. Nuestra pequeña estación meteorológica se encargará de estar escuchando la banda de 433Mhz y en cuanto se reciba una emisión de un sensor de Oregon, decodificarlo y enviarlo a un servidor en Internet.

Como servicio para recoger nuestra información utilizaremos https://data.sparkfun.com/, muy sencillo de configurar, utilizar y que conecta directamente con https://analog.io/

Listado de componentes de nuestro receptor

 Imagen3 Arduino Mega 2560: Para el proyecto vamos a usar uno de los arduinos más potentes con microcontrolador ATmel. No tanto por su cantidad de I/O o su tamaño de memoria, si no por su velocidad de procesamiento.
Imagen2 LCD Keypad Shield: Formado por una pantalla LCD 16×2 y una serie de botones nos va a permitir mostrar información tanto de la inicialización de nuestro receptor como de los datos recibidos de los sensores.
Ethernetmodule1  Interfaz Ethernet: Emplearemos la barata y fácil de utilizar ENC28J60. Existe otro tipo de hardware, como el Ethernet Shield o Wifi Shield, más caros y con características que no necesitamos en este proyecto, pero también se podría utilizar.
 Imagen1  Receptor 433MHz: Será el encargado de recibir la señal emitida por los sensores Oregon en la frecuencia de 433MHz
Imagen4 Pequeña antena para aumentar el alcance de nuestro receptor.
220v-a-9v-1a-fuente-de-alimentacion-conmutada-para-arduino  Transformador 9v: Será el encargado de alimentar al Arduino de forma estable.
cablesArduino  Cables preparados para conectar de forma sencilla los diferentes componentes con el Arduino

Montaje del receptor

  • LCD Shield

En un primer momento se utilizó para el montaje una pantalla LCD 16×2 I2C pero esto entraba en conflicto con el receptor de 433MHz con lo que se optó por un LCD 16×2 normal. El montaje del shield es bastante sencillo y solo tenemos que hacer coincidir las patillas del shield con el zócalo de nuestro Arduino Mega. Además nos proporciona unos botones que nos serán de utilidad para poder encender la luz de fondo del LCD.

  • Interfaz Ethernet

En este proyecto utilizamos la gran conocida interfaz ENC28J60 de la que ya hemos hablado en el proyecto de medidor de consumo: http://www.gonzalogalvan.es/medidor-de-consumo-conectamos-a-internet/

Al utilizar un Arduino Mega, deberemos conectar nuestra interfaz a los pines SPI siguientes:

ENC28J60 Arduino
CS D53
SI D51
SO D50
SCK D52
5v 5v
GND GND
ArduinoMega2560_SPI_pins
  • Receptor 433Mhz

El receptor deberemos conectarlo a una de las entradas digitales con interrupción de nuestro Arduino.

Nº Interrupción int.0 int.1 int.2 int.3 int.4 int.5
Pin Mega2560 2 3 21 20 19 18

 

Aquí una foto del receptor ya conectado con la antena puesta:

IMG_20160724_191144

 

Programando nuestra estación meteorológica

Los sensores de Oregon emiten en 2 versiones de un protocolo propietario denominadas OSV2 y OSV3. Hay multitud de páginas comentando estos protocolos e implementaciones de su decodificación para Arduino. Algunos enlaces de interés sobre la codificación de Oregon:

Como el código es bastante extenso, solo voy a detallar ciertas partes interesantes que se deben entender. Al final del post tendréis un enlace para descargar el código fuente completo.

  • Inicialización del pin con interrupción

Para mi montaje he elegido la interrupción 1 para conectar el receptor RF, así que para esa interrupción asociaremos la función ext_int_1 que será lanzada ante la detección de un cambio.

	attachInterrupt(1, ext_int_1, CHANGE);

La función ext_int_1 queda definida de la siguiente forma:

	volatile word pulse;
 
	void ext_int_1(void)
	{
		static word last;
		// determine the pulse length in microseconds, for either polarity
		pulse = micros() - last;
		last += pulse;
	}
  • Captura de la emisión de los sensores mediante interrupción

Ya en el método loop() del programa, desactivaremos primero cualquier interrupción para coger el valor pulse recibido por el pin digital. Una vez guardado en una nueva variable, volveremos a activar las interrupciones. Para ello emplearemos las funciones cli() y sei(). Una web interesante sobre este tema http://www.allaboutcircuits.com/technical-articles/using-interrupts-on-arduino/

	cli();
	word p = pulse;
	pulse = 0;
	sei();
 
	if (p != 0)
	{
	  if (orscV2.nextPulse(p))
            reportSerial("OSV2", orscV2);  
          if (orscV3.nextPulse(p))
             reportSerial("OSV3", orscV3);
	}
  • Decodificación de la información

Si revisáis el código , veréis que en la función reportSerial se realiza la detección del tipo de sensor y la decodificación de los datos. Será en esta función donde tendremos que ir añadiendo cada uno de los sensores que queramos tratar.

Para el caso del THGR228N, sensor utilizado en el proyecto, podéis ver como se prepara la información para mostrarlo en las dos lineas del LCD y la cadena para el envío al servidor de Internet.

	// Inside Temp-Hygro : THGR228N,...
	if(data[0] == 0x1A && data[1] == 0x2D)
	{
		Serial.print("[THGR228N,...] Id:");
		Serial.print(data[3], HEX);
		Serial.print(" ,Channel:");
		Serial.print(channel(data));
		Serial.print(" ,temp:");
		Serial.print(temperature(data));
		Serial.print(" ,hum:");
		Serial.print(humidity(data));
		Serial.print(" ,bat:");
		Serial.print(battery(data));
 
		float temperatureRec = temperature(data);
		byte channelRec = channel(data);
		byte humidityRec = humidity(data);
		byte batteryRec = battery(data);
 
		String(temperatureRec, 1).toCharArray(tempChar, 10);
		sprintf(lcdLine1, "%02X DI:%02X C:%02X    ", data[0], data[3], channelRec);
		sprintf(lcdLine2, "T:%s H:%d B:%d     ", tempChar, humidityRec, batteryRec);
		sprintf(postData, "type=%02X&id=%02X&channel=%02X&temp=%s&humidity=%d&battery=%d", data[0], data[3], channelRec, tempChar, humidityRec, batteryRec);
 
		if (millis() > timerRead + READ_RATE) {
			timerRead = millis();
			pendienteEnvio = true;
		}
	}

Para formatear los datos utilizó la función sprintf, que permite fácilmente trabajar con distintos tipos de variables.

  • Envío al servidor y visualización en LCD

El proceso de envío es muy similar al ya realizado para el medidor de consumo eléctrico. Realizaremos un POST sobre la URL con las claves que nos haya proporcionado sparkfun. Concatenaremos la cadena postData que ya hemos preparado con los datos a enviar en el método anterior.

	if (pendienteEnvio) {
 
		//Enviamos al servidor
		if (millis() > timerHttp + REQUEST_RATE) {
			timerHttp = millis();
			 Serial.println("\n REQ");
			ether.browseUrl(PSTR("/input/###tu_clave_publica###?private_key=###clave_privada###&"), postData, website, procesarRespuesta);
 
 
		}
		lcd.setCursor(0, 0);
		lcd.print(lcdLine1);
		lcd.setCursor(0, 1);
		lcd.print(lcdLine2);
	}
  • Lectura del botón del Shield

Los botones que se encuentran en el Shield junto al LCD se leen mediante una entrada analógica, en los que cada uno de los botones tendrán una resistencia diferente y por tanto una lectura diferente.

	uint8_t read_analog_buttons(void) {
	  //RIGHT: 0
	  //DOWN: 308
	  //UP: 132
	  //LEFT: 481
	  //SELECT: 723
	  uint16_t lectura = analogRead(0);
	  uint16_t k = (analogRead(0) - lectura); //gives the button a slight range to allow for a little contact resistance noise
	  if (5 < abs(k)) return KEY_NONE;  // double checks the keypress. If the two readings are not equal +/-k value after debounce delay, it tries again.
 
	  if (lectura < 104)  return KEY_RIGHT;  
	  if (lectura < 303)  return KEY_UP; 
	  if (lectura < 479)  return KEY_DOWN; 
	  if (lectura < 633)  return KEY_LEFT; 
	  if (lectura < 864)  return KEY_SELECT;   
 
	  return KEY_NONE;  // default
	}

Visualizando los datos recibidos

pantallazo1Si hemos creado bien nuestra cuenta en sparkfun, definiendo los campos que vamos a enviar desde el arduino y metiendo en nuestro programa la clave privada necesaria para que los datos queden registrados, empezaremos a ver en la web cada uno de los envíos realizados.

Podéis ver un ejemplo real en https://data.sparkfun.com/oregon, donde tenemos los datos del sensor THGR228N. En este caso se está recogiendo el estado de la batería, el canal en el que está emitiendo el sensor, la humedad, el Id del dispositivo, el tipo de dispositivo y la temperatura. El campo timestamp es incluido automáticamente con lo que evitamos necesitar tener un RTC en nuestro proyecto.

Desde la propia página podemos exportar la información en diversos formato y directamente conectar con AnalogIO para graficar nuestros datos de forma sencilla.

pantallazo2
Aquí podemos ver un pequeño video del montaje final funcionando:

 

Próximo pasos …

Como podéis comprobar, ahora mismo el programa cargado en el Arduino solo decodifica y trata la información de un sensor de Oregon, habría que ir analizando la información del resto de sensores para ir extrayendo su información y enviarlo al servidor.

También se puede trabajar en la representación de la información en el LCD aunque hay que tener cuidado en realizar demasiadas tareas y mantener ocupado al Arduino en otras tareas diferentes a la decodificación de los mensajes.

Descarga del código fuente.

Del siguiente enlace podréis descarga el fuente completo del receptor: OregonWeather.ino

Si os es de utilidad o realizáis alguna mejora interesante como añadir nuevos sensores, por favor, comentar sobre este post para irlo completando y así poder aprender todos.

 

Previous post

Medidor de consumo. Almacenar los datos

Next post

Medidor de consumo V2 - MQTT

1 Comment

  1. 6 junio, 2018 at 11:31 am — Responder

    Hola Gonzalo
    Muchas gracias por esta iformación que te has trabajado.
    Estoy interesado en ponerlo en práctica pero yo tengo una torre MISOL 1 wireless y no sé si también es compatible tu documentación aquí expuesta para esta torre que también utiliza una transmisión inalámbrica de 433Mhz, pero que desconozco si usa una codificación Manchester.

    Saludos

Leave a reply

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *