0% encontró este documento útil (0 votos)
14 vistas22 páginas

TP Final Processing Arduino UTN

El documento describe un proyecto de monitoreo y control utilizando Arduino, Processing y Python, con el objetivo de crear una interfaz gráfica interactiva para gestionar variables ambientales. Se detalla la metodología, el diseño del sistema, las pruebas realizadas y los códigos utilizados para implementar la solución. El sistema permite la visualización en tiempo real de datos y el control de un sistema de iluminación basado en condiciones ambientales.

Cargado por

Alejandro Topp
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
14 vistas22 páginas

TP Final Processing Arduino UTN

El documento describe un proyecto de monitoreo y control utilizando Arduino, Processing y Python, con el objetivo de crear una interfaz gráfica interactiva para gestionar variables ambientales. Se detalla la metodología, el diseño del sistema, las pruebas realizadas y los códigos utilizados para implementar la solución. El sistema permite la visualización en tiempo real de datos y el control de un sistema de iluminación basado en condiciones ambientales.

Cargado por

Alejandro Topp
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Trabajo Práctico Integrador

Sistema de monitoreo y control utilizando Arduino, Processing y


Python

Curso de Interfaces gráficas y procesamiento de datos con Arduino


Diplomatura UTN - Julio 2025

Alumno:

Topp, Alejandro Gabriel alejandrotopp@[Link]


Sistema de monitoreo integral Entrega Final

Índice

1. Consigna 2

2. Objetivos 3

3. Desarrollo del proyecto 4


3.1. Descripción del Problema . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.2. Metodología y Diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.2.1. Estructura general del sistema . . . . . . . . . . . . . . . . . . 4
3.2.2. Principios aplicados en Arduino . . . . . . . . . . . . . . . . . 4
3.2.3. Principios aplicados en Processing . . . . . . . . . . . . . . . . 5
3.2.4. Principios aplicados en Python . . . . . . . . . . . . . . . . . . 5
3.3. Banco de pruebas y esquemático del circuito . . . . . . . . . . . . . . 5

4. Pruebas y resultados 7
4.1. Prueba de conectividad WiFi y MQTT . . . . . . . . . . . . . . . . . . 7
4.2. Prueba de envío de datos desde ESP32 . . . . . . . . . . . . . . . . . 7
4.3. Prueba de interfaz en Processing . . . . . . . . . . . . . . . . . . . . 7
4.4. Prueba de visualización en tiempo real en Python . . . . . . . . . . . 7

5. Códigos 8
5.1. Código Arduino: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
5.2. Código Processing: . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
5.3. Código Python: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

6. Conclusión 21

1
Sistema de monitoreo integral Entrega Final

1. Consigna
El trabajo final tiene como propósito demostrar la aplicación práctica de los cono-
cimientos adquiridos a lo largo del curso. En este proyecto, se deberá diseñar e
implementar una interfaz gráfica interactiva en Processing, en la que se apliquen
conceptos fundamentales como manejo de eventos, estructuras de control, funcio-
nes, clases y manipulación de elementos gráficos.

2
Sistema de monitoreo integral Entrega Final

2. Objetivos
Los objetivos del trabajo son los siguientes:

Consolidar y aplicar los fundamentos de programación en Processing mediante


la solución de problemas reales relacionados con el diseño de interfaces gráfi-
cas interactivas.
Modularizar y optimizar el código a través de la creación de funciones y clases
que permitan reutilizar y simplificar la lógica de los programas.
Integrar conocimientos teóricos y prácticos para desarrollar un proyecto que
demuestre la capacidad de diseñar e implementar interfaces visuales dinámicas
e interactivas.

3
Sistema de monitoreo integral Entrega Final

3. Desarrollo del proyecto


3.1. Descripción del Problema
En el contexto del proyecto se busca desarrollar una interfaz visual que permita mo-
nitorear variables ambientales (temperatura, humedad, luz, movimiento, sonido) y
ajustar en tiempo real el umbral de luz que determina el encendido automático de un
sistema de iluminación, comandado por un ESP32. La problemática principal radica
en ofrecer una herramienta intuitiva, visual e interactiva, que permita al usuario no
solo observar los datos relevados por el dispositivo IoT, sino también interactuar acti-
vamente con él mediante botones virtuales, enviando comandos a través del puerto
serie para modificar el comportamiento del sistema físico.

3.2. Metodología y Diseño


El proyecto fue diseñado con un enfoque modular, aplicando conceptos de progra-
mación orientada a objetos, estructuras de control y comunicación en tiempo real.
El objetivo fue lograr una interacción fluida entre hardware (ESP32), software visual
(Processing) y análisis de datos (Python), utilizando el protocolo MQTT como medio
de transmisión eficiente y asincrónico.

3.2.1 Estructura general del sistema


ESP32 (Arduino): se encarga de relevar las variables ambientales (tempera-
tura, humedad, luz, movimiento y sonido), controlar el encendido automático
o manual de un relé según la iluminación, y comunicar estos datos mediante
MQTT y puerto serie.
Processing: actúa como visualizador en tiempo real de los datos ambientales,
permitiendo además modificar el umbral de luz a través de botones interactivos
que envían comandos al ESP32.
Python: consume los mensajes MQTT y genera gráficos en tiempo real utili-
zando matplotlib, permitiendo observar la evolución temporal de temperatura,
humedad y la cantidad de eventos de sonido, movimiento y activación de relé
detectados.

3.2.2 Principios aplicados en Arduino


Estructuras de control: uso de estructuras if, for y while para la toma de deci-
siones basada en sensores, el control del relé y el manejo de reconexión WiFi
y MQTT.
Flags booleanas: variables como movimiento_detectado, sonido_detectado y
control_manual_mqtt permiten mantener estados y decisiones lógicas en el
tiempo. En particular, control_manual_mqtt habilita un modo manual que se ac-
tiva cuando el ESP32 recibe el mensaje ”ON ” o ”OF F ” desde un suscriptor
MQTT. Este comando activa o desactiva el relé independientemente del valor

4
Sistema de monitoreo integral Entrega Final

del sensor de luz. Si no se recibe un nuevo mensaje en los siguientes 10 segun-


dos, el ESP32 vuelve automáticamente al modo de control automático basado
en el LDR.
Comunicación: el ESP32 recibe comandos por puerto serie desde Processing
y también puede ser comandado vía MQTT. Además, publica los datos sensa-
dos en formato CSV: valores separados por ";", para fácil decodificación.

3.2.3 Principios aplicados en Processing


Programación orientada a objetos: se implementaron clases como Boton,
que encapsulan propiedades (posición, color, etiqueta) y métodos (dibujar(), en-
viarSiClick()), permitiendo una interfaz clara y reutilizable.
Interactividad con Arduino: se manejan eventos como mousePressed() para
detectar interacciones del usuario y enviar comandos (+, -, L) que ajustan el
umbral de luz o testean los LEDs del sistema físico.
Parseo: los datos recibidos por MQTT se separan y procesan mediante split() y
substring(), extrayendo valores clave para actualizar visualmente temperatura,
humedad, movimiento, sonido, estado del relé, nivel de luz y valor del ADC.

3.2.4 Principios aplicados en Python


Datos MQTT: se utiliza la librería [Link] para suscribirse al tópico
casa/estado, extrayendo los datos clave del mensaje publicado por el ESP32.
Visualización dinámica: mediante matplotlib y FuncAnimation, se grafican las
curvas de temperatura, humedad y detecciones de sonido, movimiento y activa-
ción de relé; permitiendo un monitoreo visual del comportamiento del sistema.

3.3. Banco de pruebas y esquemático del circuito


Para validar el funcionamiento del sistema, se construyó un banco de pruebas donde
se conectaron todos los componentes que intervienen en el monitoreo ambiental y el
control del relé. El objetivo fue verificar la integración entre sensores, actuadores, el
ESP32, y la comunicación con las interfaces desarrolladas en Processing y Python.
A continuación se presenta el esquemático del circuito utilizado. En él se observa
la conexión de los sensores de temperatura y humedad (DHT22), luz (LDR), sonido
(KY-037) y movimiento (PIR), así como la salida al relé encargado de controlar la
lámpara a 220V. También se aprecia la alimentación de 3.3V y 5V, y las resistencias
asociadas al divisor de tensión para el LDR.

5
Sistema de monitoreo integral Entrega Final

Tabla 1: Componentes utilizados en el sistema y su conexión al ESP32


Componente Modelo / Especificaciones Pin en ESP32
Microcontrolador ESP32 DevKit –
Sensor de temperatura y DHT22. Alimentación 5V. Salida digital GPIO 18
humedad
Sensor de luz (LDR) Divisor resistivo con LDR y R fija (22K). GPIO 34 (ADC)
Salida analógica 0–4095
Sensor de sonido KY-037. Alimentación 5V, salida digital GPIO 32
(D0), sensibilidad ajustable
Sensor de movimiento PIR HC-SR501. Alimentación 5V, salida GPIO 27
digital
Relé FL-3FF-S-Z. Activación por 3.3V (activo GPIO 4
en LOW), controla lámpara 220V
LED indicador rojo LED externo. Alimentación 3.3V. Indica GPIO 22
eventos de control
LED indicador verde LED externo. Alimentación 3.3V. Indica GPIO 21
conexión WiFi
LED interno LED_BUILTIN. LED incorporado en pla- GPIO 2
ca, útil para testeo
Carga controlada Lámpara 220V conectada al contacto NA –
del relé

6
Sistema de monitoreo integral Entrega Final

4. Pruebas y resultados
A continuación, se detallan las pruebas realizadas sobre el sistema completo
(ESP32 + sensores + MQTT + interfaces en Processing y Python) y se muestran los
resultados esperados y obtenidos.

4.1. Prueba de conectividad WiFi y MQTT


1. Al encender el ESP32, se conecta a la red WiFi ”84” y luego al broker público
HiveMQ.
2. El LED verde del ESP32 se enciende si la conexión WiFi fue exitosa.
3. El ESP32 se suscribe al tópico MQTT casa/estado y comienza a publicar datos
cada 5 segundos.

4.2. Prueba de envío de datos desde ESP32


1. Se monitorea los valores de temperatura, humedad, sonido, movimiento y luz
cada 5 segundos, y se verifica su correcta visualización por el monitor serie.
2. Se analiza el valor de luz (ADC) y se activa el relé si hay oscuridad (se define
umbral de luz). Implementación de lógica de relé con nivel de luz en el ambiente.

4.3. Prueba de interfaz en Processing


1. Se envian comandos ’+’, ’-’ y ’L’ por puerto serie al ESP32 y se evalúa correcto
comportamiento de la variación del umbral de luz, y el correcto prendido de los
leds rojo y verde.

4.4. Prueba de visualización en tiempo real en Python


1. Se ejecuta un script en Python que se suscribe al mismo tópico MQTT.
2. Los datos de temperatura y humedad se grafican correctamente en tiempo real.
3. Se muestran estadísticas (máximo, mínimo, promedio) y contadores de eventos.

7
Sistema de monitoreo integral Entrega Final

5. Códigos
5.1. Código Arduino:
A continuación se presenta el código desarrollado:
1 # include < WiFi .h > // permite conectar el ESP8266 a una red WiFi
2 # include < PubSubClient .h > // permite que el ESP8266 se comunique usando el
protocolo MQTT , es decir , enviar y recibir mensajes de un det broker
3 # include " DHT . h "
4

5 # define DHTPIN 18 // conexion dht22


6 # define DHTTYPE DHT22 // puede ser dht11 o dht22 . m á s generico
con el dhttype
7 # define LDR_PIN 34 // LD
8 # define SOUND_PIN 32 // KY037
9 # define PIR_PIN 27 // Sensor PIR
10 # define LED_ROJO_PIN 22 // LED rojo
11 # define LED_VERDE_PIN 21 // LED verde
12 # define RELAY_PIN 4 // Rel é FL -3 FF -S - Z
13 # define LED_PIN 2 // LED interno del ESP32
14

15

16 // WiFi
17 const char * ssid = " 84 " ;
18 const char * password = " sistemas " ;
19

20 // MQTT
21 const char * mqtt_server = " broker . hivemq . com " ; // defino direcci ó n del
broker p ú blico .
22 const int mqtt_port = 1883; // puerto est á ndar sin
cifrado
23 const char * mqtt_user = " usuario " ; // nombre de usuario
cliente MQTT
24 const char * mqtt_pass = " contrasenia " ;
25 const char * mqtt_topic = " casa / estado " ; // es el tema al que el
ESP8266 se suscribir á y publicar á mensajes .
26

27 // Umbral de luz , lo voy a poder modificar v í a Processing , comunicaci ó n


serial
28 // el ESP32 recibir á un valor anal ó gico ( convertido v í a ADC del 0 al 4096)
29 // no lo coloco como const int debido a que Processing podr á modificar el
valor del umbral de luz
30 int umbral_luz = 2000; // valor por default del
umbral de luz
31

32 bool m ovimiento_detectado ; // variable usada para


detectar movimiento en los 5 segundos entre muestras
33 bool sonido_detectado ; // variable usada para
detectar sonido en los 5 segundos entre muestras
34 bool c ontrol_manual_mqtt = false ; // false = autom á tico (
por LDR ) , true = controlado manualmente v í a MQTT
35 unsigned long ultimo_mqtt = 0; // Guarda el momento del
ú ltimo mensaje recibido
36

37

38 // CREACION DE OBJETOS NECESARIOS


39 WiFiClient espClient ; // creo objeto TCP IP

8
Sistema de monitoreo integral Entrega Final

para conectarme a WiFi


40 PubSubClient client ( espClient ) ; // creo un objeto client
de tipo PubSubClient , que es la clase usada para manejar la conexi ó n
MQTT .
41 DHT dht ( DHTPIN , DHTTYPE ) ; // creacion objeto dht22
42

43

44 // Funci ó n recepcion que se ejecuta autom á ticamente al recibir un mensaje


MQTT .
45 // Procesa el mensaje recibido ( ON u OFF ) y act ú a encendiendo / apagando el
rel é y el LED .
46 void recepcion ( char * topic , byte * payload , unsigned int length ) {
47 String message ;
48 for ( unsigned int i = 0; i < length ; i ++) {
49 message += ( char ) payload [ i ];
50 }
51 // si recibo ON , pego la bobina del rel é , enciendo l á mpara y paso variable
a manual , almacenando el tiempo de este ú ltimo mensaje mqtt
52 // si recibo OFF , suelto la bobina del rel é , apago l á mpara y paso variable
a manual , almacenando el tiempo de este ú ltimo mensaje mqtt
53

54 if ( message == " ON " ) {


55 digitalWrite ( RELAY_PIN , LOW ) ;
56 digitalWrite ( LED_PIN , HIGH ) ;
57 c ontrol_manual_mqtt = true ;
58 ultimo_mqtt = millis () ;
59 } else if ( message == " OFF " ) {
60 digitalWrite ( RELAY_PIN , HIGH ) ;
61 digitalWrite ( LED_PIN , LOW ) ;
62 c ontrol_manual_mqtt = true ;
63 ultimo_mqtt = millis () ;
64 }
65 }
66

67 // Funci ó n que intenta reconectar al broker MQTT en caso de que la conexi ó


n se pierda .
68 // Si se conecta exitosamente , se suscribe nuevamente al t ó pico
configurado .
69 void reconnect () {
70 while (! client . connected () ) {
71 Serial . print ( " Intentando conectar MQTT ... " ) ;
72 String clientId = " ESP32Client - " + String (( uint32_t ) ESP . getEfuseMac () ,
HEX ) ;
73

74 if ( client . connect ( clientId . c_str () ) ) {


75 Serial . println ( " Conectado " ) ;
76 client . subscribe ( mqtt_topic ) ;
77 Serial . print ( " Suscrito a : " ) ;
78 Serial . println ( mqtt_topic ) ;
79 } else {
80 Serial . print ( " fall ó " ) ;
81 delay (5000) ;
82 }
83 }
84 }
85

86

87 void setup () {

9
Sistema de monitoreo integral Entrega Final

88 Serial . begin (115200) ;


89 dht . begin () ;
90 pinMode ( RELAY_PIN , OUTPUT ) ; // REL É DE 3.3 VDC a 220 VAC como salida
91 digitalWrite ( RELAY_PIN , HIGH ) ; // Rel é apagado ( activo con LOW ,
desactivo bobina con HIGH )
92

93 pinMode ( LED_PIN , OUTPUT ) ; // LED INTERNO como salida


94 digitalWrite ( LED_PIN , HIGH ) ; // LED apagado
95

96 pinMode ( LDR_PIN , INPUT ) ;


97 pinMode ( PIR_PIN , INPUT ) ;
98 pinMode ( SOUND_PIN , INPUT ) ;
99 pinMode ( LED_ROJO_PIN , OUTPUT ) ;
100 pinMode ( LED_VERDE_PIN , OUTPUT ) ;
101 digitalWrite ( LED_ROJO_PIN , LOW ) ;
102 digitalWrite ( LED_VERDE_PIN , LOW ) ;
103

104

105 Serial . println ( " Conectando a WiFi ... " ) ;


106 WiFi . begin ( ssid , password ) ; //// Inicia la conexi ó n WiFi usando el
SSID y contrase ñ a definidos al comienzo del c ó digo
107

108

109 // intento de conexi ó n a wifi . en total son 30 intentos , cada intento


toma medio segundos , por lo que en total demora 15 segundos .
110 // posterior a esos 15 segundos , si no hubo conexi ón , imprime mensaje que
no pudo conectarse
111 int intentos = 0;
112 while ( WiFi . status () != WL_CONNECTED && intentos < 5) {
113 delay (500) ;
114 Serial . print ( " Intento " ) ;
115 Serial . print ( intentos +1) ;
116 Serial . println ( " Fallido " ) ;
117 intentos ++;
118 }
119

120

121 // Si se conecta , muestra IP obtenida y enciende el LED


122 if ( WiFi . status () == WL_CONNECTED ) {
123 Serial . println ( " \ nWiFi conectado ! " ) ;
124 Serial . print ( " IP asignada : " ) ;
125 Serial . println ( WiFi . localIP () ) ;
126 digitalWrite ( LED_VERDE_PIN , HIGH ) ;
127 } else {
128 Serial . println ( " \ nNo se pudo conectar a WiFi . " ) ;
129 }
130

131 client . setServer ( mqtt_server , mqtt_port ) ; // defino el


servidor MQTT y el puerto al que se va a conectar
132 client . setCallback ( recepcion ) ; // funci ó n (
recepcion ) que se ejecutar á cuando llegue un mensaje MQTT
133

134 delay (1000) ;


135 digitalWrite ( LED_VERDE_PIN , LOW ) ; // apago led
verde despues de 1 segundo
136 }
137 void loop () {
138 if (! client . connected () ) reconnect () ;

10
Sistema de monitoreo integral Entrega Final

139 client . loop () ;


140

141 float temperatura = dht . readTemperature () ; // lectura valor


DHT22 a trav é s del m é todo del objeto
142 float humedad = dht . readHumidity () ; // lectura valor
DHT22 a trav é s del m é todo del objeto
143 int valor_luz = analogRead ( LDR_PIN ) ; // lectura valor
anal ó gico de LDR , lo pasamos a digital , rango 0 -4095
144 m o v i miento_detectado = false ; // inicializamos
en false
145 sonido_detectado = false ; // inicializamos
en false
146

147 // ejecucion de un for , como el env í o de los datos es cada 5 segundos , se


ejecutar á 100 veces y se fijar á si se produjo algun evento de sonido
o movimiento
148 for ( int i = 0; i < 100; i ++) {
149 if ( digitalRead ( PIR_PIN ) ) {
150 m o vimiento_detectado = true ;
151 }
152 if ( digitalRead ( SOUND_PIN ) ) {
153 sonido_detectado = true ;
154 }
155 delay (50) ; // 100 x 50 ms = 5000 ms = 5 segundos
156 }
157

158 // recepcion de los datos del processing via Serie


159 // muestro si recibo un + , un - o un L ( LED )
160 if ( Serial . available () > 0) {
161 char comando = Serial . read () ;
162 Serial . print ( " Comando recibido : " ) ;
163 Serial . println ( comando ) ;
164

165 if ( comando == '+ ') {


166 umbral_luz += 100;
167 if ( umbral_luz > 4095) umbral_luz = 4095;
168 digitalWrite ( LED_ROJO_PIN , HIGH ) ;
169 delay (200) ;
170 digitalWrite ( LED_ROJO_PIN , LOW ) ;
171

172 } else if ( comando == ' - ') {


173 umbral_luz -= 100;
174 if ( umbral_luz < 0) umbral_luz = 0;
175 digitalWrite ( LED_ROJO_PIN , HIGH ) ;
176 delay (200) ;
177 digitalWrite ( LED_ROJO_PIN , LOW ) ;
178 }
179 else if ( comando == 'L ') {
180 digitalWrite ( LED_ROJO_PIN , HIGH ) ;
181 digitalWrite ( LED_VERDE_PIN , HIGH ) ;
182 delay (500) ;
183 digitalWrite ( LED_ROJO_PIN , LOW ) ;
184 digitalWrite ( LED_VERDE_PIN , LOW ) ;
185 }
186 }
187

188

189 bool rele_estado = false ; // Default apagado

11
Sistema de monitoreo integral Entrega Final

190 bool luz_ok = false ;


191

192

193 // Si pasaron m á s de 10 segundos desde el ú ltimo comando MQTT , volvemos a


autom á tico
194 // es decir , si despu é s de 10 segundos no llega otro mensaje MQTT , pasamos
a recibir datos del LDR .
195 if ( control_manual_mqtt && ( millis () - ultimo_mqtt > 10000) ) {
196 c ontrol_manual_mqtt = false ;
197 }
198

199

200 if (! control_manual_mqtt ) { // si super ó el


umbral de luz ( luz suficiente ) , apago el rel é ( le env í o un HIGH )
201 luz_ok = valor_luz > umbral_luz ; // si no se super ó el
umbral de luz ( luz insuficiente ) , prendo el rel é ( le env í o un LOW )
202 digitalWrite ( RELAY_PIN , luz_ok ? HIGH : LOW ) ;
203 rele_estado = ! luz_ok ; // LUZ = TRUE - > RELE =
FALSE = OFF , LUZ = FALSE - > RELE = TRUE = ON
204 }
205 else {
206 luz_ok = valor_luz > umbral_luz ;
207 rele_estado = ! digitalRead ( RELAY_PIN ) ; // si el rel é = OFF , el
rele_estado = true ( est á activado )
208 }
209

210

211 // concatenaci ó n strings con los datos


212 // protocolo separado por ; , se decodifica en Processing y Python
213 String mensaje = " " ;
214 mensaje += " T : " + String ( temperatura , 1) + " ; " ;
215 mensaje += " H : " + String ( humedad , 1) + " ; " ;
216 mensaje += " M : " + String ( movimiento_detectado ? " D " : " ND " ) + " ; " ;
// si mov_detectado = true , env í o D ( detectado ) . caso contrario ,
env í o ND ( no detectado )
217 mensaje += " S : " + String ( sonido_detectado ? " D " : " ND " ) + " ; " ;
// si son_detectado = true , env í o D ( detectado ) . caso
contrario , env í o ND ( no detectado )
218 mensaje += " R : " + String ( rele_estado ? " ON " : " OFF " ) + " ; " ;
// si rele = true , env í o ON . caso contrario , env í o OFF
219 mensaje += " L : " + String ( luz_ok ? " SI " : " NO " ) + " ; " ;
// si luz = true , env í o SI . caso contrario , env í o NO
220 mensaje += " ADC : " + String ( valor_luz ) ;
// concateno valor LDR para
corroborar datos anal ó gicos
221 mensaje += " ; U : " + String ( umbral_luz ) ;
// concateno umbral_luz para ver
como var í a con los comandos " + " y " -"
222

223 Serial . print ( " Enviando : " ) ;


224 Serial . print ( mensaje ) ;
225 client . publish ( mqtt_topic , mensaje . c_str () ) ;
226

227 // LED rojo prende 1 segundo por cada env í o


228 digitalWrite ( LED_ROJO_PIN , HIGH ) ;
229 delay (1000) ;
230 digitalWrite ( LED_ROJO_PIN , LOW ) ;
231

12
Sistema de monitoreo integral Entrega Final

232 delay (4000) ; // total de 5 segundos entre env í os


233

234 }
235

236 void publicar ( String mensaje ) {


237 Serial . println ( " Enviando : " + mensaje ) ;
238 client . publish ( mqtt_topic , mensaje . c_str () ) ;
239 }

Listing 1: Código del ESP32

13
Sistema de monitoreo integral Entrega Final

5.2. Código Processing:


A continuación se presenta el código desarrollado:
1 class Boton {
2 int posx , posy , ancho , alto ;
3 String etiqueta ;
4 color fondo ;
5 char comando ;
6

7 Boton ( int posx , int posy , int ancho , int alto , String etiqueta , color
fondo , char comando ) {
8 this . posx = posx ;
9 this . posy = posy ;
10 this . ancho = ancho ;
11 this . alto = alto ;
12 this . etiqueta = etiqueta ;
13 this . fondo = fondo ;
14 this . comando = comando ;
15 }
16

17 void dibujar () {
18 fill ( fondo ) ;
19 rect ( posx , posy , ancho , alto ) ;
20 fill (0) ;
21 textAlign ( CENTER , CENTER ) ;
22 text ( etiqueta , posx + ancho / 2 , posy + alto / 2) ;
23 }
24

25 boolean clickDentro ( int mousex , int mousey ) {


26 return mousex > posx && mousex < posx + ancho && mousey > posy &&
mousey < posy + alto ;
27 }
28

29 void enviarSiClick ( int mousex , int mousey ) {


30 if ( clickDentro ( mousex , mousey ) ) {
31 puerto . write ( comando ) ;
32 println ( " Enviado '" + comando + " ' por serial desde bot ó n " +
etiqueta ) ;
33 }
34 }
35 }

Listing 2: Código del Processing-Clase Boton

1 import mqtt .*; // librer í a para MQTT


2 import processing . serial .*; // librer í a para comunicaci ó n serial
3

4 Serial puerto ; // objeto para manejar el puerto serie


5 MQTTClient client ; // Objeto cliente MQTT
6

7 // Objetos tipo Boton definidos en clase Boton para los tres botones
funcionales
8 Boton botonMas , botonMenos , botonLeds ;
9

10 // Coordenadas y dimensiones del recuadro que agrupa los botones


11 int recuadroX = 20;
12 int recuadroY = 240;
13 int recuadroW = 300;

14
Sistema de monitoreo integral Entrega Final

14 int recuadroH = 170;


15

16 // Variables para mostrar el ú ltimo mensaje y valor de umbral recibido


17 String mensaje = " " ;
18 String umbralActual = " ??? " ;
19

20 // Variables de datos recibidos desde el ESP32 v í a MQTT


21 float temperatura = 0;
22 float humedad = 0;
23 String movimiento = " " ;
24 String sonido = " " ;
25 String rele = " " ;
26 String luz = " " ;
27 int adc_luz =0;
28

29 void setup () {
30 size (1000 , 500) ;
31 background (255) ;
32 textSize (20) ;
33

34 // Conexi ó n al broker MQTT y suscripci ó n al t ó pico


35 client = new MQTTClient ( this ) ; // creo objeto del tipo MQTTclient
36 client . connect ( " tcp :// broker . hivemq . com :1883 " , " clien tePro cessin gJava " ) ;
37 client . subscribe ( " casa / estado " ) ;
38

39 printArray ( Serial . list () ) ; // Muestra los


puertos serie disponibles
40 puerto = new Serial ( this , Serial . list () [0] , 115200) ; // Abro primer
puerto serie configurado en 115200 baudios
41

42 // asignaci ó n de los valores de los botones v í a sus respectivos


constructores
43 botonMas = new Boton (50 , 250 , 100 , 40 , " + Umbral " , color (100 , 200 , 100) ,
'+ ') ;
44 botonMenos = new Boton (200 , 250 , 100 , 40 , " - Umbral " , color (200 , 100 ,
100) , ' - ') ;
45 botonLeds = new Boton (125 , 310 , 150 , 40 , " Encender LEDs " , color (100 ,
150 , 250) , 'L ') ;
46 }
47

48 void draw () {
49 background (255) ; // limpio la pantalla
50

51 // Dibuja un recuadro que agrupa los botones , ú nicamente los bordes , sin
relleno
52 noFill () ;
53 stroke (0) ;
54 strokeWeight (2) ;
55 rect ( recuadroX , recuadroY , recuadroW , recuadroH ) ;
56

57 // m é todos para dibujar los botones


58 botonMas . dibujar () ;
59 botonMenos . dibujar () ;
60 botonLeds . dibujar () ;
61

62 // Mostrar mensaje MQTT recibido


63 textSize (20) ;
64 textAlign ( LEFT ) ;

15
Sistema de monitoreo integral Entrega Final

65 fill (0) ;
66 text ( " Ú ltimo mensaje recibido MQTT : " , 20 , 120) ;
67 text ( mensaje , 20 , 150) ;
68

69 // SECCION CONTROL DE LUZ VIA COM SERIAL


70 textSize (32) ;
71 text ( " CONTROL DE LUZ " , 20 , 200) ;
72

73 // Mostrar los datos que recibo v í a MQTT


74 textSize (20) ;
75 text ( " Umbral actual de luz : " + umbralActual , 20 , 400) ;
76 text ( " Temperatura : " + temperatura + " C " , 20 , 430) ;
77 text ( " Humedad : " + humedad + " %" , 20 , 460) ;
78 text ( " Movimiento : " + movimiento , 250 , 430) ;
79 text ( " Sonido : " + sonido , 250 , 460) ;
80 text ( " Rel é : " + rele , 450 , 430) ;
81 text ( " Luz suficiente ?: " + luz , 450 , 460) ;
82 text ( " Valor ADC : " + adc_luz , 700 , 430) ;
83

84 }
85

86

87 // al importar librer í a mqtt .* , la funci ó n messageReceived se ejecuta autom


á ticamente
88 // cada vez que se recibe un mensaje MQTT desde el broker : callback
89 void messageReceived ( String topic , byte [] payload ) {
90 mensaje = new String ( payload ) ;
91 println ( " Mensaje recibido en " + topic + " : " + mensaje ) ;
92

93 String [] partes = split ( mensaje , '; ') ; // separo los mensajes , split é
andolos por ;
94 for ( String parte : partes ) { // recorro cada posicion del
string preguntando por los substrings
95 if ( parte . startsWith ( " T : " ) ) {
96 temperatura = float ( parte . substring (2) ) ;
97 } else if ( parte . startsWith ( " H : " ) ) {
98 humedad = float ( parte . substring (2) ) ;
99 } else if ( parte . startsWith ( " M : " ) ) {
100 movimiento = parte . substring (2) ;
101 } else if ( parte . startsWith ( " S : " ) ) {
102 sonido = parte . substring (2) ;
103 } else if ( parte . startsWith ( " R : " ) ) {
104 rele = parte . substring (2) ;
105 } else if ( parte . startsWith ( " L : " ) ) {
106 luz = parte . substring (2) ;
107 } else if ( parte . startsWith ( " ADC : " ) ) {
108 adc_luz = int ( parte . substring (4) ) ;
109 }
110 else if ( parte . startsWith ( " U : " ) ) {
111 umbralActual = parte . substring (2) ;
112 println ( " Nuevo umbral recibido : " + umbralActual ) ;
113 }
114 }
115

116

117 }
118

119 void mousePressed () {

16
Sistema de monitoreo integral Entrega Final

120 // Llama al m é todo enviarSiClick de cada bot ó n si fue presionado


121 botonMas . enviarSiClick ( mouseX , mouseY ) ;
122 botonMenos . enviarSiClick ( mouseX , mouseY ) ;
123 botonLeds . enviarSiClick ( mouseX , mouseY ) ;
124 }
125

126 // serialEvent es una funci ó n especial callback que se ejecuta


127 // autom á ticamente cada vez que llega un nuevo dato por el puerto serial
128

129 void serialEvent ( Serial p ) {


130 String input = p . readStringUntil ( '\ n ') ; // Lee datos hasta
encontrar un salto de l í nea
131 if ( input != null ) { // elimina el \ n y
espacios
132 input = input . trim () ;
133 if ( input . startsWith ( " U : " ) ) { // Si el dato empieza
con " U : "
134 umbralActual = input . substring (2) ; // Actualiza la
variable con el nuevo valor ( quitando " U : " )
135 println ( " Nuevo umbral : " + umbralActual ) ;
136 }
137 }
138 }

Listing 3: Código del Processing-Programa Principal

5.3. Código Python:


A continuación se presenta el código desarrollado:
1 import paho . mqtt . client as mqtt # librer í a para comunicaci ó n MQTT
2 import matplotlib . pyplot as plt # librer í a generacion de graficos
3 from matplotlib . animation import FuncAnimation
4 from datetime import datetime # sirve para saber la hora actual donde llega
un evento
5 import matplotlib . dates as mdates # para poder graficar con formatos de
tiempo en el eje x
6 # Listas para guardar los datos
7 tiempos = []
8 temperaturas = []
9 humedades = []
10 # Contadores de eventos
11 contador_sonido = 0
12 c on t a dor_movimiento = 0
13 contador_rele_on = 0
14

15 ultimo_mensaje = None
16

17 # Funci ó n que se ejecuta cuando se recibe un mensaje MQTT


18 # msg es de tipo bytes , se caste con ". decode " y se almacena en mensaje de
tipo string
19 # msg . payload = b 'T :23.5; H :55.1; S : ND ; M : D ; R : OFF '
20 # mensaje = 'T :23.5; H :55.1; S : ND ; M : D ; R : OFF '
21 # al splitearlo por el caracter ";" , partes de lista de strings
22 def l l ega_mensaje_broker ( client , userdata , msg ) :
23

24 global tiempos , temperaturas , humedades


25 global contador_sonido , contador_movimiento , contador_rele_on

17
Sistema de monitoreo integral Entrega Final

26 mensaje = msg . payload . decode ()


27 actual = datetime . now () # la hora actual se guarda en actual
28 print ( f " [{ actual . strftime (' %H: %M: %S ') }] Mensaje recibido : { mensaje } " )
29

30 partes = mensaje . split ( " ; " ) # lista de strings


31 temp = None
32 hum = None
33

34 # barro toda la lista " partes " , a traves del index i


35 # voy guardando desde el tercer caracter hasta el final de la cadena i
[2:]
36 for i in partes :
37 if i . startswith ( " T : " ) :
38 try : temp = float ( i [2:]) # si no llega a poder convertir
el string de la lista ,
39 except : pass # en un float , sigue adelante con
el proximo try , evitamos posible crasheo
40 elif i . startswith ( " H : " ) :
41 try : hum = float ( i [2:])
42 except : pass
43 elif i . startswith ( " S : " ) and i [2:] == " D " :
44 contador_sonido += 1
45 elif i . startswith ( " M : " ) and i [2:] == " D " :
46 contador_movimiento += 1
47 elif i . startswith ( " R : " ) and i [2:] == " ON " :
48 contador_rele_on += 1
49

50 # voy agregando a las listas todos los valores


51 # " tiempos [ -50:]" funciona como ventana deslizante quedandose con los
ultimos 50 valores m á s actuales , desechando los mas viejos
52 if temp is not None and hum is not None :
53 tiempos . append ( actual )
54 temperaturas . append ( temp )
55 humedades . append ( hum )
56 # Limito a los ú ltimos 50 datos
57 if len ( tiempos ) > 50:
58 tiempos = tiempos [ -50:]
59 temperaturas = temperaturas [ -50:]
60 humedades = humedades [ -50:]
61

62 # Callback de conexi ón , suscripcion al topico para recibir mensajes


63 def c onexion_al_broker ( client , userdata , flags , rc ) :
64 print ( " Conectado al broker con c ó digo de resultado : " , rc )
65 client . subscribe ( " casa / estado " )
66

67 # Configuraci ó n cliente MQTT


68 client = mqtt . Client ()
69 client . on_connect = conexion_al_broker # funcion se ejecuta al conectarse
al broker HIVEMQ
70 client . on_message = llega_mensaje_broker # funcion se ejecuta al recibir un
mensaje MQTT
71

72 # Broker p ú blico , se ejecuta loop_start en segundo plano


73 # El loop_start () inicia un nuevo hilo , que llama al m é todo de bucle a
intervalos regulares para usted . Tambi é n maneja las reconexiones autom á
ticamente .
74 client . connect ( " broker . hivemq . com " , 1883 , 60)
75 client . loop_start ()

18
Sistema de monitoreo integral Entrega Final

76

77 # Configuraci ó n del gr á fico


78 plt . style . use ( " ggplot " ) # estilos en https :// matplotlib . org / stable / gallery /
style_sheets / st yle _s hee ts _re fer en ce . html
79 fig , ax = plt . subplots ( figsize =(12 , 6) )
80 # linea_temp y linea_hum son objetos de tipo matplotlib . lines . Line2D
81 linea_temp , = ax . plot ([] , [] , label = " Temperatura ( C ) " , color = " red " ,
marker = 'o ' , linestyle = ' - ')
82 linea_hum , = ax . plot ([] , [] , label = " Humedad ( %)" , color = " blue " , marker = 'o
' , linestyle = ' - ')
83 ax . set_xlabel ( " Hora " )
84 ax . set_ylabel ( " Medici ó n " )
85 ax . legend ()
86 ax . xaxis . set_major_formatter ( mdates . DateFormatter ( ' %H: %M: %S ') ) # Formato
HH : MM : SS , https :// matplotlib . org / stable / api / _as_gen / matplotlib . axis .
Axis . set_major_formatter . html
87 ax . xaxis . set_major_locator ( mdates . AutoDateLocator () ) #
Autoajuste de marcas , el tiempo se va autoajustando su posicion en el
eje x
88 plt . xticks ( rotation =90)
89

90 # Funci ó n de actualizaci ó n para animaci ó n


91 def actualizar ( frame ) :
92 if tiempos : # si la lista no est á vacia
93 linea_temp . set_data ( tiempos , temperaturas ) # Actualiza los puntos
de temperatura
94 linea_hum . set_data ( tiempos , humedades ) # Actualiza los puntos
de humedad
95 ax . relim () # Recalcula l í mites
96 ax . autoscale_view () # Reescale zoom gr á fico
97

98 # Ajustar l í mites del eje X para mostrar ú ltimos datos


99 ax . set_xlim ([ tiempos [0] , tiempos [ -1]])
100

101 # Calcular estad í sticas


102 temp_max = max ( temperaturas )
103 temp_min = min ( temperaturas )
104 temp_avg = sum ( temperaturas ) / len ( temperaturas ) # se podria
dividir por 50 , pero para las primeras 50 muestras el valor ser
í a menor ...
105

106 hum_max = max ( humedades )


107 hum_min = min ( humedades )
108 hum_avg = sum ( humedades ) / len ( humedades ) # se podria
dividir por 50 , pero para las primeras 50 muestras el valor ser
í a menor ...
109

110 # Borrar textos del mensaje MQTT que estar í a antes y proximamente
vamos a plotear los nuevos
111 ax . texts . clear ()
112

113 # Mostrar texto a la derecha del gr á fico ( coordenadas relativas al


eje actual )
114 # Coordenadas relativas (0 a 1) al á rea del gr á fico , el á rea que
forman los ejes .
115 # por eso en x , colocamos 1.02 asi queda fuera del gr á fico
116 ax . text (1.02 , 0.95 , f " T MAX : { temp_max :.1 f } C " , transform = ax .
transAxes )

19
Sistema de monitoreo integral Entrega Final

117 ax . text (1.02 , 0.90 , f " T MIN : { temp_min :.1 f } C " , transform = ax .
transAxes )
118 ax . text (1.02 , 0.85 , f " T AVG : { temp_avg :.1 f } C " , transform = ax .
transAxes )
119

120 ax . text (1.02 , 0.75 , f " H MAX : { hum_max :.1 f} %" , transform = ax .
transAxes )
121 ax . text (1.02 , 0.70 , f " H MIN : { hum_min :.1 f} %" , transform = ax .
transAxes )
122 ax . text (1.02 , 0.65 , f " H AVG : { hum_avg :.1 f} %" , transform = ax .
transAxes )
123

124 ax . text (1.05 , 0.50 , f " Detecciones sonido : { contador_sonido } " ,


transform = ax . transAxes )
125 ax . text (1.05 , 0.45 , f " Detecciones movimiento : { contador_movimiento
} " , transform = ax . transAxes )
126 ax . text (1.05 , 0.40 , f " Rel é ON ( LUZ = NO ) : { contador_rele_on } " ,
transform = ax . transAxes )
127

128 return linea_temp , linea_hum


129

130 # Animaci ó n en tiempo real


131 ani = FuncAnimation ( fig , actualizar , interval =1000)
132

133 plt . tight_layout ( rect =[0 , 0 , 0.75 , 1]) # Ajusta layout para dejar espacio
en el margen derecho , asi entran las estadisticas
134 plt . show ()

Listing 4: Código de Python

20
Sistema de monitoreo integral Entrega Final

6. Conclusión
El desarrollo de este proyecto permitió integrar de manera efectiva hardware y soft-
ware mediante el protocolo MQTT, logrando una comunicación bidireccional eficiente
entre el ESP32, Processing y Python. Se consiguió relevar múltiples variables am-
bientales (temperatura, humedad, luz, movimiento y sonido) y actuar sobre una carga
(luz) de forma automática o manual, con la posibilidad de modificar parámetros en
tiempo real a través de una interfaz gráfica.
Este proyecto no solo reforzó conocimientos de electrónica y programación orien-
tada a objetos, sino también habilidades en comunicación en tiempo real y visuali-
zación de datos. Como posibles mejoras, se plantea incorporar almacenamiento de
datos en la nube, alertas automáticas ante eventos y un control más sofisticado ba-
sado en aprendizaje automático.

21

También podría gustarte