Proyecto IoT: Sensor de temperatura wifi con Wifly y DHT11

DHT11

Hace tiempo que tengo un sensor de temperatura y humedad DTH11 dando vueltas por los cajones, así que ha llegado el momento de probarlo. Junto con un Arduino y un módulo Wifly, voy a mostraros un sensor de temperatura y humedad que envíe datos periódicamente por WiFi a un servidor. Es la base de cualquier proyecto enmarcado en el Internet de las cosas (IoT).

El sensor DHT11

Este sensor es muy barato y fácil de usar, así que es perfecto para un pequeño proyecto como éste. El siguiente esquema sacado del datasheet del fabricante muestra cómo ha de conectarse el sensor.

Conexión DHT11

Se puede encontrar en versión de tres y cuatro patillas. En la versión de cuatro, una simplemente está desconectada y no se utiliza. Además de los dos pines de alimentación (a 5V), la información se transmite por un único pin conectado al microcontrolador a través de una resistencia pull-up de 5K. En mi diseño he añadido un condensador entre VCC y GND para filtrar la entrada de alimentación. En la fotografía de la cabecera se ve el montaje completo en la protoboard.

Módulo Wifly

Para enviar los datos al servidor tenemos varias opciones como Bluetooth o GSM. Pero como tenía un módulo Wifly a mano, lo haremos por WiFi. Esta basado en el chip RN-171, que está muy probado y es bastante robusto. Además de tener una gran cantidad de funcionalidades. En este proyecto sólo vamos a mostrar su uso más básico, para el cuál sólo necesitamos cuatro conexiones, dos para la alimentación (a 3.3V) y otras dos para al comunicación serie (TX y RX). Si ya has trabajado con un módulo XBee, Wifly es totalmente compatible a nivel de conexiones, por lo que podrías sustituir uno por otro sin tener que modificar el resto del circuito.

Wifly

Montaje con Arduino

El montaje del sensor DHT11 y Wifly con Arduino se muestra en el siguiente esquema. Como ves no hay nada fuera de lo común, lo único más delicado es la conexión del módulo Wifly, cuyas patillas son más pequeñas y están más juntas de lo habitual, lo que es un poco problemático para conectarlo con cables dupont, pero forzando un poquito no hay mayor problema.

WiFly_DHT11_Arduino

El sensor se alimenta de la salida de 5V del Arduino, cuya patilla central por donde van los datos de temperatura he conectado al pin 7 del Arduino. El módulo Wifly lo he conectado al pin de 3.3V del Arduino (cuidado con no conectarlo al de 5V si no queréis freír el módulo Wifly). Los pines RX y TX del Wifly se pueden conectar directamente a los pines RX y TX de Arduino (pines 0 y 1), pero yo he preferido usar un puerto serie por software (pines 2 y 3) y dejar libre el puerto serie nativo para depurar la comunicación con el Wifly. El montaje completo queda así.

IoT Sensor Temperatura

Funcionamiento

El código encargado de de leer el sensor y enviar los datos por el puerto serie al Wifly es el siguiente.

#include "DHT.h"
#include 

#define DHTPIN 7     // Pin

// Tipo de sensor
#define DHTTYPE DHT11   // DHT 11

// Inicializar sensor
DHT dht(DHTPIN, DHTTYPE);

SoftwareSerial wifly(2, 3); // RX, TX

void setup() {
  Serial.begin(9600); // usamos serial normal para debug
  wifly.begin(9600);
  dht.begin();

  // Preparar Wifly
  delay(5000); // esperamos a que wifly esté listo
  wifly.print("$$$");  // entrar en modo comando
  delay(1000);
  wifly.println("join myssid");  // nos asociamos al ssid
  delay(2000);
  wifly.println("set com remote 0");  // evitar que se envíe la cadena HELLO al servidor
  delay(1000);
}

void loop() {
  float h = dht.readHumidity();
  float t = dht.readTemperature(); // por defecto en Celsius

  // Comprobar si hay error
  if (isnan(h) || isnan(t) ) {
    Serial.println("Error de lectura en el sensor");
    return;
  }

  // Calculo de la sensación térmica
  // float hic = dht.computeHeatIndex(t, h, false);

  wifly.println("open 172.26.0.9 8080");  // abrimos conexión al servidor web
  delay(1000);
  wifly.println("GET /readsensor?t="+String(t,2)+"&h="+String(h,2)+" HTTP/1.1");
  wifly.println();

  delay(60000); // leer cada minuto
  wifly.print("$$$");
}

En la función setup() se inicializa el sensor DHT11 y se realiza la conexión del módulo Wifly a la red WiFi. En este caso es una red WiFi abierta y sin protección, por lo que no es necesario establecer la clave de cifrado. Para conectar a una red WiFi cifrada habrá que realizar algún paso más que puede consultarse en el manual de WiFly.

Una vez en marcha, la función loop() lee cada minuto el valor de temperatura y humedad del sensor y se envía al servidor como una petición GET mediante HTTP. El servidor, como veremos enseguida, registra cada petición y almacena los datos. Quiero hacer notar que este código es ilustrativo y que no es válido para un sistema en producción ya que, además de no ser muy óptimo (entre otras cosas por ese delay de un minuto), tampoco se comprueban errores de comunicación o se chequea el estado del módulo Wifly.

Como servidor web se podría haber usado Apache con PHP, Tomcat con Java o cualquier otra alternativa. Para simplificar he usado el pequeño servidor web que trae Python (para un sistema en producción habría que usar algo más serio). El código es el siguiente:

#!/usr/bin/python
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
import urlparse
import datetime

PORT_NUMBER = 8080

datos=[]

class myHandler(BaseHTTPRequestHandler):
	
  # Manejador para peticiones GET
    def do_GET(self):
      if "readsensor" in self.path:
        o = urlparse.urlparse(self.path)
	params = urlparse.parse_qs(o.query)
	t = params["t"][0]
	h = params["h"][0]
	now = datetime.datetime.now()
	datos.append([str(now.hour)+":"+str(now.minute), t, h]);
		
	self.send_response(200)
	self.send_header('Content-type','text/html')
	self.end_headers()
	self.wfile.write('Temperatura: '+t)
	self.wfile.write('<BR>Humedad: '+h)
	self.wfile.write("<BR>OK!")
	return
      else:
	# gerenar datos
	muestra = "['Hora', 'Temperatura', 'Humedad'],"
	for d in datos:
	  muestra=muestra + "['"+d[0]+"',"+d[1]+","+d[2]+"],"

	self.send_response(200)
	self.send_header('Content-type','text/html')
	self.end_headers()
	self.wfile.write("""
	  <html>
	  <head>
	    <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>
	    <script type='text/javascript'>
		google.charts.load('current', {'packages':['corechart']});
		google.charts.setOnLoadCallback(drawChart);

		function drawChart() {
		  var data = google.visualization.arrayToDataTable([""" + muestra +"""]);

		  var options = {
		    title: 'Registro humedad/temperatura',
		    curveType: 'function',
		    legend: { position: 'bottom' }
		  };

		 var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
		   chart.draw(data, options);
		 }
		</script>
	  </head>
	  <body>
		<div id='curve_chart' style='width: 900px; height: 500px'></div>
	  </body>
	</html>
	""");
try:
  server = HTTPServer(('', PORT_NUMBER), myHandler)
  print 'Iniciando servidor HTTP en puerto ' , PORT_NUMBER
  server.serve_forever()

except KeyboardInterrupt:
  print 'CTRL+C: Saliendo...'
  server.socket.close()

 

Se utiliza la librería BaseHTTPServer de Python para crear el servidor web escuchando en el puerto 8080. En el manejador de peticiones se distinguen dos tipos, si se trata de una lectura del sensor (es una llamada GET con readsensor en la URL) se almacena la información. En caso contrario se muestra una gráfica en pantalla con las mediciones. Para generar la gráfica he optado por la librería Javascript Google Charts.

Lecturas de temperatura con DHT11

Más allá del prototipo

Para ir un paso más allá, además de mejorar el software tanto en el Arduino como en el servidor, habría que hacer algunas mejoras. De entrada, eliminar el Arduino y sustituirlo por un Atmega328P junto con su circuiteria en una placa de circuito impreso. En lugar del módulo Wifly usaríamos un RN171 también en la placa, y probablemente con una antena externa. Finalmente, nos queda el asunto de la alimentación. Tanto si vamos a usar una pila como alimentación a través de un transformador o incluso una fuente de alimentación, necesitaremos al menos un regulador de tensión tipo 7805 para obtener los 5V para el sensor. Para obtener los 3.3V del RN171, podemos usar un 7833 o, si queremos ahorrárnoslo, un divisor de tensión para obtener 3.3V a partir del 7805. Pues con esto y una bonita caja, ya estaría listo nuestro dispositivo IoT.

 

Sé el primero en comentar en "Proyecto IoT: Sensor de temperatura wifi con Wifly y DHT11"

Deja un comentario.

Tu dirección de correo no será publicada.


*