Objetivos del trabajo
Este trabajo consiste en realizar la lectura de temperatura y humedad que proporciona el sensor DHT11. Dichos parámetros se subirán cada 10 segundosa la plataforma IoT de Mathworks, Thingspeak. Por defecto, Thingspeak solo deja subir medidas cada 15 segundos, debido a la licencia de estudiante que se tiene en la universidad. Este problema se puede solventar realizando una lectura automática de los parámetros atmosféricos tomados por el sensor utilizando dos canales. Además, estos canales se van a generar de manera automática empleando el método adecuado que nos proporcionan la API de Thinspeak para crear canales. Para ello será necesario tener claro cual debe ser la estructura de una petición HTTP. Estas varían en función del método empleado, pero por lo general son: método, uri, cabecera y contenido. A modo de aclaración se proporciona el siguiente código de Phyton realizado en clase, en el que lee el porcentaje de CPU y RAM utilizada por nuestro ordenador.
Para realizar este proyecto se trabajará con la Raspberry 3B+, el sensor de temperatura y humedad DHT11 y la plataforma IoT de Thingspeak. Para realizar la programación se utiliza el lenguaje de programación Python. Para la visualización y el tratamiento de los resultados obtenidos se empleará Matlab por medio de un programa que permita leer los datos que se encuentran en la nube y reordenarlos para obtener una única gráfica.
Configuración de la raspberry:
1 Instalar SO en Raspberry
Necesitamos una tarjeta microSD que conectamos al portátil mediante un adaptador de microSD. Con un creador de imágenes de SO como el balena Etcher, esa imagen la introducimos a la microSD.
2 Comprobar si el SO se ha instalado correctamente
Para ello conectamos a la Raspberry PI una fuente de alimentación, una pantalla, un teclado y un ratón. Nos pide iniciar sesión, con un usuario y contraseña por defecto. Usuario por defecto: pi Contraseña: raspberry. Si se inicia la sesión, significa que se ha instalado correctamente.
Para cambiar configuración: escribimos sudo raspi-config.
Para una conexión remota adecuada, es necesario activar el SSH y el I2C.
3 Asignamos dirección IP estática
Es necesario que la dirección IP de la raspberry se encuentre en el mismo segmento que el router (primeros 3 octetos iguales), para conectarse a su red, por ejemplo 192.168.0.X. Cambiar el del router es más complejo.
El modo más ortodoxo de realizar esta asignación es introducir el comando sudo nano /etc/dhcpcd.conf e introducimos la configuración deseada. Para las conexiones wifi por ejemplo:
Interface wlan0
Static ip:address=192.168.43.204/24
Static routers=192.168.43.1
Static domain_name_servers=192.168.43.1
Para comprobar si se ha configurado correctamente se modifica la IP Ethernet del portátil, que también debe estar en el mismo segmento. Conectamos la Raspberry al Portatil y escribimos en la ventana de comandos del portatil: ping dirección_IP_raspberry, si responde estará configurado adecuadamente. Si además google responde a ese mismo comando, significa que está conectada a la red wifi.
4 Conectar por SSH:
Necesitamos esta conexión para conectarnos remotamente a la Raspberry yusar su ventana de comandos. Para ello se ha empleado el Programa PUTTY:
Usando esta ventana descargamos Python y las librerías necesarias, incluyendo el Adafruit_DHT.
Con esto tendríamos nuestra Raspberry configurada.
Programa para enviar lectura del sensor a ThingSpeak:
Para conectarnos con la plataforma IoT ThingSpeak y poder enviar la temperatura y humedad medidas, hemos utilizado el intérprete de Python. Para ello, se ha desarrollado un programa que crea 2 canales en ThingSpeak y va enviando peticiones de escritura a los canales con los datos leídos por el sensor.
1 Declaramos el servidor de Thingspeak, la variable sensor, el pin en el cual recibe los datos la raspberry.
2 El siguiente paso es crear los canales, para ello la petición debe tener los siguientes campos:
cabeceras={"Host":server,
"Content-Type":"application/x-www-form-urlencoded"}
contenido={"api_key":"User_api_key",
"field1":"Temperatura",
"field2":"Humedad",
"name":"Canalauto1",
"public_flag":"true"}
contenido_codificado=urllib.urlencode(contenido)
cabeceras["Content-Length"]=str(len(contenido_codificado))
#envio la peticion
respuesta=requests.post(uri,headers=cabeceras,data=contenido_codificado)
De los datos recibidos en la respuesta guardamos la identidad y la Write api-key que emplearemos para poder subir los datos del sensor.
Repetimos el proceso para crear dos canales.
3 Después procedemos a enviar peticiones de escritura con los datos del sensor. Creando para ello un bucle while que se ejecutará hasta que el programa interrumpa el programa. En este bucle inicialmente leemos la temperatura y la humedad, preparamos la petición de escritura y la enviamos a uno de los canales creados anteriormente, mediante la identidad y la api-key de escritura:
while True:
humedad,temperatura = (dht.read_retry(sensor, pin))
cabeceras={"Host":server,
"Content-Type":"application/x-www-form-urlencoded"}
contenido={"api_key": WRITE_API_KEY1,
"field1": str(temperatura),
"field2": str(humedad)}# pasar a un string
contenido_codificado=urllib.urlencode(contenido)
cabeceras["Content-Length"]=str(len(contenido_codificado))
#envio la peticion
respuesta=requests.post(uri,headers=cabeceras,data=contenido_codificado)
Time.sleep(9)
Tratamiento de los datos en Matlab
Para el tratamiento de los datos tenemos que tener en cuenta que los datos se suben a Thingspeak cada 10 segundos. Por lo que se tienen en cuenta los siguientes aspectos:
- ¿Este sistema varía rápido? No, la temperatura y la humedad en un hogar no varía drásticamente. Por lo que podemos leer datos en minutos. En nuestro caso hemos decidido leerlos cada 2 minutos.
- ¿Cómo ordeno los datos? La lógica empleada para resolver este problema es coger los datos de un canal primero y luego los del otro teniendo en cuenta el tiempo, estableciendo para ello una serie de reglas. Para las lectura tenemos ThingSpeakRead.
- Por último, visualizamos los datos de temperatura y humedad ordenados para ver si coinciden con los de Thingspeak.
El código empleado se muestra a continuación:
d_canal1 = 916312;
id_canal2 = 916313;
minutos_2 = 6;
%Bucle principal
while true
% Ayuda de thinSpeakRead queremos leer
% data = thingSpeakRead(channelID)
% data = thingSpeakRead(channelID,Name,Value)
% data = thingSpeakRead(___,'ReadKey','channel Read API key')
% [data,timestamps] = thingSpeakRead(___)
% timestamps te da el tiempo en el que se ha obtenido el dato
% Queremos leer 12 datos del canal uno y 12 del canal 2, y saber en que momento se ha hecho.
%Ademas queremos que se lea tanto el field 1c como el field 2 (temperatura y humedad)
[canal1, timestamps1] =
thingSpeakRead(id_canal1, 'Fields',[1,2],'NumPoints', minutos_2);
[canal2, timestamps2] =
thingSpeakRead(id_canal2, 'Fields',[1,2],'NumPoints', minutos_2);
%Guardamos en dos matrices los valores de temp y humedad de cada canal
[muestras1 graficas1] = size(canal1);
[muestras2 graficas2] = size(canal2);
for i = 1:muestras1
% Se ordenan los datos teniendo en cuenta el momento en el que han sido
% recibidos en ThingSpeak (en las variables timestamps).
par = i*2;
imp = (i*2)-1;
if i <= muestras1
if i <= muestras2
if timestamps1(i) < timestamps2(i)
orden_datos(imp, :) = canal1(i, :);
orden_datos(par, :) = canal2(i, :);
timestamps(imp, :) = timestamps1(i, :);
timestamps(par, :) = timestamps2(i, :);
else
orden_datos(imp, :) = canal2(i, :);
orden_datos(par, :) = canal1(i, :);
timestamps(imp, :) = timestamps2(i, :);
timestamps(par, :) = timestamps1(i, :);
end
end
end
end
%Visualización
end
Control
Para implementar el controlador, se ha decidido implementar un simple controlador proporcional en lazo abierto. La acción de control saldrá cada 2 minutos. Hay que tener en cuenta, que necesitamos tener un error para poder obtener la acción de control, este error se calcula restando la temperatura medida, a un valor de consigna de temperatura.
Para que ocurra cada 2 minutos, se genera un contador “variable_para_control” que cuando llega a 12 permite calcular la acción de control y mostrarla en pantalla.
Esto se traduce en añadir al algoritmo de tratamiento de datos de Matlab, los siguientes segmentos:
%En la inicialización:
ref=21;
kp=12;
variable_para_control=1;
%En el bucle principal:
%Ultimos datos de temperatura y humedad medidas
Temperatura_ultima_medida = orden_datos(end, 1);
Humedad_ultima_medida = orden_datos(end, 2);
%Control
if variable_para_control == 12
error=ref-Temperatura_ultima_medida;
accion_control=kp*error;
disp(accion_control)
variable_para_control = 0;
variable_para_control = 0;
end
variable_para_control=variable_para_control+1;
No hay comentarios:
Publicar un comentario