tdse-tf_3-02

Controlador PID para derretidor de miel con control local via botones y remoto via WiFi
Index Commits Files Refs Submodules README
MEMORIA.md (62161B)
   1 <div align="center">
   2 
   3 <img src="img/logofiuba.png" width="100%">
   4 
   5 **UNIVERSIDAD DE BUENOS AIRES**  
   6 **Facultad de Ingeniería**  
   7 **TA134 - Taller de Sistemas Embebidos**
   8 
   9 # Controlador de derretidor de miel
  10 
  11 **Martin Klöckner** - [mklockner@fi.uba.ar](mailto:mklockner@fi.uba.ar)
  12 
  13 **Fecha:** 31 de mayo de 2026  
  14 **Cuatrimestre de cursada:** Segundo cuatrimestre de 2025
  15 
  16 *Trabajo realizado entre marzo y mayo de 2026.*
  17 
  18 </div>
  19 
  20 <br><br>
  21 
  22 En el presente trabajo se diseña e implementa un sistema para el control de un
  23 derretidor eléctrico de miel, reemplazando el sistema original basado en un
  24 termostato de bulbo capilar por un sistema digital. Las principales
  25 características del sistema diseñado son:
  26 
  27 - Control de temperatura mediante PID con salida PWM sobre MOSFET.
  28 - Sensor digital de temperatura DS18B20.
  29 - Interfaz local con display, botones, luces indicadores y buzzer.
  30 - Control remoto vía Wi-Fi con interfaz web.
  31 - Reloj de tiempo real con batería de respaldo y temporizador programable.
  32 - Persistencia de parámetros incluso si se pierde la alimentación.
  33 
  34 Los resultados demuestran la conveniencia de utilizar un controlador digital por
  35 sobre uno analógico de los equipos comerciales existentes. En las siguientes
  36 secciones se describe el diseño, la implementación y los resultados de las
  37 pruebas realizadas.
  38 
  39 <br>
  40 
  41 # Índice
  42 
  43 - [1. Introducción general](#1-introducción-general)
  44   - [1.1. Alcance](#11-alcance)
  45   - [1.2. Trabajos similares y alternativas](#12-trabajos-similares-y-alternativas)
  46 - [2. Introducción específica](#2-introducción-específica)
  47   - [2.1. Requisitos](#21-requisitos)
  48   - [2.2. Casos de uso](#22-casos-de-uso)
  49   - [2.3. Descripción de módulos principales](#23-descripción-de-módulos-principales)
  50     - [2.3.1. Control principal](#231-control-principal)
  51     - [2.3.2. Módulo remoto](#232-módulo-remoto)
  52     - [2.3.3. Sensor de temperatura](#233-sensor-de-temperatura)
  53     - [2.3.4. Control de temperatura](#234-control-de-temperatura)
  54     - [2.3.5. Display y adaptador paralelo a serie I2C](#235-display-y-adaptador-paralelo-a-serie-i2c)
  55     - [2.3.6. Cable y conector IDC](#234-cable-y-conector-idc)
  56 - [3. Diseño e implementación](#3-diseño-e-implementación)
  57   - [3.1. Hardware del sistema](#31-hardware-del-sistema)
  58     - [3.1.1. Placa NUCLEO](#311-placa-nucleo)
  59     - [3.1.2. Sensor DS18B20](#312-sensor-ds18b20)
  60     - [3.1.3. Módulo ESP-01S](#313-modulo-esp-01s)
  61     - [3.1.4. Display LCD 16x2 I2C](#314-display-lcd-16x2-i2c)
  62     - [3.1.5. Control de temperatura](#315-control-de-temperatura)
  63     - [3.1.6. Luces indicadoras](#316-luces-indicadoras)
  64     - [3.1.7. Buzzer](#317-buzzer)
  65     - [3.1.8. Botones](#318-botones)
  66   - [3.2. Firmware del sistema](#32-firmware-del-sistema)
  67     - [3.2.1. Ejecutor cíclico](#321-ejecutor-cíclico)
  68     - [3.2.2. Tarea central](#322-tarea-central)
  69     - [3.2.3. Tarea para botones](#323-tarea-para-botones)
  70     - [3.2.4. Tarea para el buzzer](#324-tarea-para-el-buzzer)
  71     - [3.2.5. Tarea para luces indicadoras](#325-tarea-para-luces-indicadoras)
  72     - [3.2.6. Tarea para el menu](#326-tarea-para-el-menu)
  73     - [3.2.7. Tarea para control de temperatura](#327-tarea-para-control-de-temperatura)
  74     - [3.2.8. Tarea para sensor de temperatura](#328-tarea-para-sensor-de-temperatura)
  75     - [3.2.9. Tarea para módulo remoto](#329-tarea-para-modulo-remoto)
  76     - [3.2.10. Medición de tiempo de ejecución](#3210-medición-de-tiempo-de-ejecución)
  77 - [4. Ensayos y resultados](#4-ensayos-y-resultados)
  78   - [4.1. Pruebas funcionales del hardware](#41-pruebas-funcionales-del-hardware)
  79   - [4.2. Pruebas funcionales del firmware](#42-pruebas-funcionales-del-firmware)
  80   - [4.3. Pruebas de integración](#43-pruebas-de-integración)
  81   - [4.4. Cumplimiento de requisitos](#44-cumplimiento-de-requisitos)
  82   - [4.5. Comparación con trabajos similares](#45-comparación-con-trabajos-similares)
  83   - [4.6. Documentación del desarrollo realizado](#46-documentación-del-desarrollo-realizado)
  84     - [4.6.1. Consumo de corriente](#461-consumo-de-corriente)
  85     - [4.6.2. Tiempo de ejecución](#462-tiempo-de-ejecución)
  86     - [4.6.3. Factor de uso de CPU](#463-consumo-de-corriente)
  87     - [4.6.4. Uso de memorias](#464-uso-de-memorias)
  88 - [5. Conclusiones](#5-conclusiones)
  89   - [5.1. Resultados obtenidos](#51-resultados-obtenidos)
  90   - [5.2. Próximos pasos](#52-próximos-pasos)
  91 - [6. Referencias](#6-referencias)
  92 
  93 # 1. Introducción general
  94 
  95 ## 1.1. Alcance
  96 
  97 Un derretidor eléctrico de miel es un equipo diseñado para elevar la temperatura
  98 de la miel de forma controlada, con el fin de reducir su viscosidad y facilitar
  99 su manipulación en procesos como envasado, filtrado y bombeo. En la figura 1.1
 100 se muestra un ejemplo de un derretidor eléctrico de miel convencional.
 101 
 102 <div align="center">
 103     <img src="img/derretidor_convencional.png" style="padding: 10px" width="600">
 104     <p align="center"><em>Figura 1.1: Derretidor de miel convencional.</em></p>
 105 </div>
 106 
 107 Los equipos comerciales actuales utilizan un sistema de control basado en un
 108 termostato de bulbo capilar, los cuales ofrecen un control rudimentario, sin
 109 capacidad de programación, monitoreo remoto o registro de datos. Es por esto que
 110 el objetivo del trabajo es diseñar e implementar un controlador digital para un
 111 derretidor eléctrico de miel para tambores, reemplazando el sistema original
 112 basado en un termostato por un sistema digital con mayor control, que permita:
 113 
 114 - Control preciso de temperatura.
 115 - Interfaz de usuario local con display y botones.
 116 - Control y monitoreo remoto vía Wi-Fi.
 117 - Programación de ciclos de derretido con temporizador.
 118 - Persistencia de parámetros ante cortes de energía.
 119 - Indicación luminosa y sonora de estados.
 120 
 121 El alcance de este proyecto está delimitado al desarrollo, implementación y
 122 validación de un Producto Mínimo Viable (MVP) que demuestre la factibilidad
 123 técnica del controlador digital. Quedan fuera del alcance el diseño de una placa
 124 PCB definitiva, el ensayo en un entorno de producción real con miel, y la
 125 validación térmica exhaustiva del conjunto completo. Estos aspectos se
 126 identificaron como un trabajo futuro para una posterior etapa de
 127 industrialización y comercialización del prototipo.
 128 
 129 ## 1.2. Trabajos similares y alternativas
 130 
 131 No se encontraron productos comerciales que integren todas las funcionalidades
 132 propuestas a un costo accesible en el mercado nacional. Los derretidores de miel
 133 comerciales existentes se limitan a sistemas basados en termostatos, con control
 134 on/off y sin display, conectividad y capacidad de programación.
 135 
 136 En el ámbito académico, se identificaron trabajos similares en cuanto al
 137 control de temperatura, como un [horno eléctrico para gastronomía](https://docs.google.com/document/d/1ypnhOz-Gx_ZRbwiI6vEn4dvr7_YqNVnpy5sfgalQAoA/edit)
 138 y un [horno para componentes SMD](https://docs.google.com/document/d/1rQf3P1D7NSb7egpnlkKMTvL_rzy9PuMcMBPcu7NxmQw/edit),
 139 ambos de la misma materia (Sistemas Embebidos, FIUBA). Sin embargo, ninguno
 140 aborda la combinación de control PID, conectividad Wi-Fi con interfaz web, y
 141 temporizador programable en el contexto de derretido de miel.
 142 
 143 # 2. Introducción específica
 144 
 145 Se desarrolló un sistema de control de temperatura basado en el microcontrolador
 146 STM32F103RB de la placa NUCLEO-F103RB y el sensor de temperatura digital
 147 DS18B20. El sistema lee la temperatura de la miel a traves del sensor y controla
 148 automáticamente el dispositivo de calefacción del derretidor. El calefactor del
 149 derretidor se modela como una resistencia de 12 V y 48 W.
 150 
 151 El usuario puede interactuar con el sistema a traves de dos interfaces: una
 152 local, mediante botones, un display, luces indicadoras y un buzzer; y de manera
 153 remota, mediante un navegador web de un dispositivo dentro de la red local del
 154 sistema, accediendo a la pagina proporcionada por el modulo remoto ESP-01S del
 155 sistema.
 156 
 157 ## 2.1. Requisitos
 158 
 159 En la tabla 2.1 se listan los requisitos alcanzados del trabajo, junto con su
 160 descripción correspondiente. En esta tabla no se incluyen requisitos no
 161 alcanzados, los cuales fueron considerados inicialmente durante la definición
 162 del proyecto pero que por restricciones de tiempo no se pudieron alcanzar.
 163 
 164 | ID | Requisito                  | Descripción                                                                   |
 165 | :- | :------------------------- | :---------------------------------------------------------------------------- |
 166 |  1 | Control por botones        | El usuario puede establecer y modificar parámetros mediante 4 botones físicos |
 167 |  2 | Control remoto             | El usuario puede controlar el dispositivo de manera remota vía Wi-Fi          |
 168 |  3 | Programación de ciclos     | El usuario puede programar ciclos con hora de inicio y fin                    |
 169 |  4 | Display                    | El sistema muestra el estado actual en un display LCD 16x2                    |
 170 |  5 | LEDs indicadores           | El sistema tiene LEDs para indicar estado de operación                        |
 171 |  6 | Alarma sonora              | El sistema tiene un buzzer para eventos y alarmas                             |
 172 |  7 | Monitoreo en tiempo real   | El sistema muestra temperatura, set point y duty cycle                        |
 173 |  8 | Conectividad Wi-Fi         | El sistema se conecta a redes Wi-Fi para comunicación remota                  |
 174 |  9 | Persistencia de parámetros | El sistema recuerda la última configuración al encender                       |
 175 | 10 | Reloj de tiempo real       | El sistema mantiene la hora incluso sin alimentación                          |
 176 
 177 <p align="center"><em>Tabla 2.1: Requisitos del trabajo</em></p>
 178 
 179 En la tabla 2.2 se muestran requisitos que quedaron fuera del alcance final del
 180 trabajo debido a restricciones de tiempo y complejidad. Se consideran requisitos
 181 futuros o deseables para una futura iteración del trabajo. 
 182 
 183 | ID | Requisito               | Descripción                                        |
 184 | :- | :---------------------- | :------------------------------------------------- |
 185 | 11 | Curvas de temperatura   | El usuario puede definir perfiles de calentamiento |
 186 | 12 | Registro de temperatura | El sistema almacena registro de temperatura        |
 187 | 13 | Límite de temperatura   | El sistema tiene un límite máximo de temperatura   |
 188 
 189 <p align="center"><em>Tabla 2.2: Requisitos futuros del trabajo</em></p>
 190 
 191 ## 2.2. Casos de uso
 192 
 193 En las tablas 2.3, 2.4 y 2.5 se ejemplifican algunos casos de uso del derretidor
 194 de miel para cada uno de los modos de operación del sistema.
 195 
 196 | Elemento            | Definición                                                                                                                                                                |
 197 | :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
 198 | Disparador          | Se quiere detener un ciclo de derretido de miel de manera remota                                                                                                          |
 199 | Precondiciones      | El sistema está en modo normal operando el calefactor                                                                                                                     |
 200 | Flujo principal     | El usuario interactúa con la interfaz remota seleccionando la opción detener calefactor, se detiene el calefactor y se cambia a modo de operación en reposo               |
 201 | Flujos alternativos | Se pierde la conexión con el sistema, en caso de ocurrir previo a seleccionar la opción el sistema sigue operando en modo normal, se reintenta la conexión con el usuario |
 202 
 203 <p align="center"><em>Tabla 2.3: Caso de uso modo normal</em></p>
 204 
 205 | Elemento            | Definición                                                                                                                                                                                                                                                                                                                                           |
 206 | :------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
 207 | Disparador          | Se desea programar un ciclo de derretido para una hora y fecha especifica                                                                                                                                                                                                                                                                            |
 208 | Precondiciones      | El sistema está en modo reposo                                                                                                                                                                                                                                                                                                                       |
 209 | Flujo principal     | El usuario interactúa con la interfaz remota seleccionando la opción programar ciclo, elije entre las opciones disponibles y guarda la configuración. Llegado el momento definido por el usuario se cambia a modo de operación normal, enciendo el calefactor                                                                                        |
 210 | Flujos alternativos | En caso de que se pierda la energía previo a iniciar el ciclo, luego de que se vuelva a energizar el sistema y vuelva a modo reposo (si no hay fallas) el ciclo configurado permanece guardado porque los parámetros se guardan en memoria no volátil, llegado el momento configurado por el ciclo se cambia a modo normal encendiendo el calefactor |
 211 
 212 <p align="center"><em>Tabla 2.4: Caso de uso modo reposo</em></p>
 213 
 214 | Elemento            | Definición                                                                                                                                                                                                    |
 215 | :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
 216 | Disparador          | El sistema se energiza                                                                                                                                                                                        |
 217 | Precondiciones      | El sistema se encontraba apagado, desenergizado                                                                                                                                                               |
 218 | Flujo principal     | El sistema inicializa todos los bloques, se comprueba que no haya ciclos de derretido predefinidos para el momento actual, en caso de que los haya se pasa a modo normal, si no los hay se pasa a modo reposo |
 219 | Flujos alternativos | Si hubo un error durante la inicialización de alguna tarea el sistema no se inicializa                                                                                                                        |
 220 
 221 <p align="center"><em>Tabla 2.5: Caso de uso modo transición</em></p>
 222 
 223 ## 2.3. Descripción de módulos principales
 224 
 225 ### 2.3.1. Control principal
 226 
 227 El control principal se implementa en la placa NUCLEO-F103RB, la cual se puede
 228 ver en la figura 2.3.1. Esta placa utiliza un microcontrolador ARM Cortex-M3 de
 229 32 bits, el STM32F103RBT6. En la placa se ejecuta el firmware principal del
 230 sistema, compuesto por un ejecutor cíclico con una pauta establecida de que un
 231 tick nunca supere 1 ms. Este ejecutar cíclico tiene asociado 8 tareas, las
 232 cuales controlan diferentes partes del sistema: 'system', 'buttons', 'buzzer',
 233 'leds', 'menu', 'temp_ctrl', 'temp_sensor' y 'remote'. La comunicación entre
 234 tareas se realiza mediante eventos y una estructura de datos compartida.
 235 
 236 <div align="center">
 237     <img src="img/nucleo_f103rb_views.png" style="padding: 10px;" width="600">
 238     <p align="center"><em>Figura 2.1: Placa NUCLEO F103RB</em></p>
 239 </div>
 240 
 241 Esta placa NUCLEO se utilizó exhaustivamente en la materia a lo largo de la
 242 cursada y fue por esto principalmente que se eligió para el desarrollo del
 243 trabajo. 
 244 
 245 ### 2.3.2. Módulo remoto
 246 
 247 Para el control remoto se utilizó el módulo Wi-Fi ESP-01S basado en un
 248 microcontrolador Espressif ESP8266. Este se comunica a través de UART con la
 249 placa NUCLEO para intercambiar comandos con un formato especifico. La elección
 250 se basó en su bajo costo, disponibilidad en el mercado local y capacidad para
 251 actuar como servidor web. En la figura 2.2 se pueden ver imágenes de la placa,
 252 así como también las conexiones que ofrece la misma.
 253 
 254 <div align="center">
 255     <img src="img/esp01s_views.png" style="padding: 10px;" width="600">
 256     <p align="center"><em>Figura 2.2: Modulo ESP-01S</em></p>
 257 </div>
 258 
 259 El firmware utilizado en la placa ESP-01S fue desarrollado utilizando librerías
 260 de Arduino a través de PlatformIO. El firmware implementa funciones como la
 261 conexión a una red Wi-Fi fija, un servidor HTTP en el puerto 80 para servir la
 262 interfaz web estática desde el sistema de archivos, un servidor WebSocket en el
 263 puerto 81 para comunicación bidireccional en tiempo real y la comunicación UART
 264 con la placa NUCLEO.
 265 
 266 ### 2.3.3. Sensor de temperatura
 267 
 268 Para medir la temperatura real del liquido, se utilizó el sensor DS18B20 de
 269 Maxim Integrated el cual es un termómetro digital con interfaz OneWire que
 270 ofrece una precisión de 0.5 °C en el rango de -10 °C a 85 °C. Se seleccionó por
 271 su bajo costo, disponibilidad en el mercado local y por tener la precisión
 272 adecuada para la aplicación.
 273 
 274 <div align="center">
 275     <img src="img/ds18b20_views.png" style="padding: 10px;" width="600">
 276     <p align="center"><em>Figura 2.3: Sensor de temperatura DS18B20</em></p>
 277 </div>
 278 
 279 La placa NUCLEO no es compatible con el protocolo OneWire por defecto es por
 280 esto que se implementó un "emulador" del protocolo utilizando el periférico UART
 281 de la NUCLEO cambiando dinámicamente la tasa de baudios (9600 baudios para
 282 reset, 96500 baudios para transferencia de datos). Y dado que la NUCLEO lo
 283 permite, se utilizo DMA para la comunicación con el sensor, disminuyendo así el
 284 tiempo de bloqueo del ejecutor cíclico.
 285 
 286 ### 2.3.4. Control de temperatura
 287 
 288 Para controlar la temperatura, se modeló el derretidor eléctrico de miel
 289 utilizando un resistor de 12 V y 48 W, y el control de temperatura mediante un
 290 transistor MOSFET, controlado por modulación de ancho de pulsos (Pulse Width
 291 Modulation, PWM). El sistema regula la temperatura mediante un controlador
 292 Proporcional-Integral-Derivativo (PID) implementado en el firmware, siendo la
 293 señal de referencia a la temperatura establecida por el usuario y el valor leído
 294 de temperatura aquel obtenido mediante el sensor de temperatura.
 295 
 296 En la figura 2.4 se muestra, a la izquierda, el encapsulado TO-220 del MOSFET, y
 297 a la derecha, el resistor utilizado para modelar el calefactor del derretidor
 298 eléctrico de miel.
 299 
 300 <div align="center">
 301     <img src="img/temp_ctrl_views.png" style="padding: 10px;" width="600">
 302     <p align="center"><em>Figura 2.4: Dispositivos utilizados para el control de temperatura</em></p>
 303 </div>
 304 
 305 El MOSFET es controlado por la señal PWM generada por un timer de la placa
 306 NUCLEO. La frecuencia de conmutación de la señal se estableció en
 307 aproximadamente 500 Hz y el duty cycle se calcula mediante el algoritmo PID
 308 implementado en la tarea 'temp_ctrl'.
 309 
 310 ### 2.3.5. Display y adaptador paralelo a serie I2C
 311 
 312 Para el control local se utilizó un display LCD con interfaz paralelo de 16x2
 313 caracteres, y para disminuir el número de pines usados de la NUCLEO, se utilizó
 314 una adaptador de interfaz paralelo del display a serie I2C para la NUCLEO,
 315 reduciendo el numero de pines necesarios de la NUCLEO de 6 a 2.
 316 
 317 En la figura 2.5 se muestra a la izquierda el display LCD de 16x2 caracteres
 318 utilizado y a la derecha el adaptador de interfaz paralela a serie I2C.
 319 
 320 <div align="center">
 321     <img src="img/display_views.png" style="padding: 10px;" width="600">
 322     <p align="center"><em>Figura 2.5: Display LCD y adaptador paralelo a serie I2C</em></p>
 323 </div>
 324 
 325 ### 2.3.6. Cable y conector IDC
 326 
 327 Durante el diseño de hardware que se detallará en la sección siguiente, se
 328 separó el sistema en dos placas perforadas separadas. Por un lado la placa una
 329 placa donde se pueda conectar la NUCLEO y por otro una placa con todos los
 330 módulos y demás bloques que componen al sistema. Para interconectar estas dos
 331 placas perforadas se utilizaron conectores IDC de 20 pines (2 hileras de 10
 332 pines cada una). 
 333 
 334 En la figura 2.6 se muestran imágenes de los conectores utilizados, a la
 335 izquierda el conector hembra junto con el cable y a la derecha el conector macho
 336 soldado en ambas placas perforadas.
 337 
 338 <div align="center">
 339     <img src="img/idc.png" style="padding: 10px;" width="600">
 340     <p align="center"><em>Figura 2.6: Display LCD y adaptador paralelo a serie I2C</em></p>
 341 </div>
 342 
 343 # 3. Diseño e implementación
 344 
 345 En la figura 3.1 se muestra el diagrama en bloques con los principales
 346 módulos y conexiones del sistema. Se puede ver que la placa NUCLEO es el
 347 módulo central y luego todos los demás módulos se conectan a este.
 348 
 349 <div align="center">
 350     <img style="padding: 10px" align=center src="img/diagrama_de_bloques.png" width="600">
 351     <p><em>Figura 3.1: Diagrama en bloques del sistema.</em></p>
 352 </div>
 353 
 354 ## 3.1. Hardware del sistema
 355 
 356 El trabajo se divide en dos placas perforadas experimentales. Estas placas
 357 perforadas se utilizan para unir los módulos, evitando utilizar cables. Las
 358 placas perforadas se conectan entre si a través de un cable IDC de 20 hilos, tal
 359 como se ve en la figura 3.2.
 360 
 361 <div align="center">
 362     <img src="img/conexion_placas_perforadas_TA134.png" style="padding: 10px;" width="700">
 363     <p align="center"><em>Figura 3.2: Conexión placas perforadas.</em></p>
 364 </div>
 365 
 366 La primer placa perforada se muestra en la figura 3.3 y hace de adaptador de los
 367 pines de la placa NUCLEO a cable con conector IDC de 2x10.
 368 
 369 <div align="center">
 370     <img src="img/stm32_nucleo_expansion_board_cropped.png" style="padding: 10px;" width="600">
 371     <p align="center"><em>Figura 3.3: Placa perforada adaptador NUCLEO a conector IDC 2x10.</em></p>
 372 </div>
 373 
 374 La segunda placa perforada, considerada la placa principal, se utilizó para unir
 375 todos los módulos restantes del sistema, como el modulo de acceso remoto, la
 376 bornera para el sensor de temperatura, las luces indicadoras, los botones, el
 377 portapilas para almacenar la pila CR2032, entre otros. En la figura 3.3 se
 378 muestra una vista de como se conectan los módulos dentro de la placa y al
 379 conector IDC.
 380 
 381 <div align="center">
 382     <img src="img/main_perf_board.png" style="padding: 10px" align=center width="400px">
 383     <p><em>Figura 3.4: Placa perforada principal.</em></p>
 384 </div>
 385 
 386 En las figuras 3.5, 3.6 y 3.7 se muestran imágenes de las placas armadas en
 387 placa perforada experimental, como se indicó previamente en las figuras 3.3 y
 388 3.4.
 389 
 390 <div align="center">
 391     <img src="img/vista_sup_placa_con_modulos.jpg" style="padding: 10px;" width="600">
 392     <p align="center"><em>Figura 3.5: Vista superior de placas con modulos en los zócalos.</em></p>
 393 </div>
 394 
 395 <div align="center">
 396     <img src="img/vista_sup_placa_sin_modulos.jpg" style="padding: 10px;" width="600">
 397     <p align="center"><em>Figura 3.6: Vista superior de placas sin modulos en los zócalos.</em></p>
 398 </div>
 399 
 400 <div align="center">
 401     <img src="img/vista_inf_placa_sin_modulos.jpg" style="padding: 10px;" width="600">
 402     <p align="center"><em>Figura 3.7: Vista inferior de placas sin modulos en los zócalos.</em></p>
 403 </div>
 404 
 405 ### 3.1.1. Placa NUCLEO
 406 
 407 Como bien se mencionó, el trabajo se desarrolló utilizando la placa NUCLEO, esta
 408 placa utiliza el procesador STM32F103RBT6 configurado para operar a 64 MHz, ya
 409 que esta frecuencia es la que mejor se adapta a los periféricos utilizados. En
 410 particular los periféricos que se utilizaron son los siguientes:
 411 
 412 - I2C1: Conexion con display LCD 16x2.
 413 - USART1: Sensor DS18B20 (modo half-duplex, emulacion de protocolo OneWire).
 414 - USART3: Módulo ESP-01S.
 415 - TIM1_CH1: Salida PWM para control del MOSFET (PA8).
 416 - TIM3_CH1: Salida PWM para buzzer (PA6).
 417 - RTC: Reloj de tiempo real.
 418 - GPIO: Botones (PC13, PA10, PB5, PB4), LEDs (PA5, PB10).
 419 - DMA: Acceso directo a memoria para reducir uso de CPU.
 420 
 421 En la figura 3.8 se muestra una imagen de los pines utilizados del
 422 microcontrolador. Luego en la tabla 3.1 se muestran los nombres asignados y las
 423 funciones para los que fueron utilizados.
 424 
 425 <div align="center">
 426     <img src="img/stm32_pinout_view.png" style="padding: 10px" align=center width="500px">
 427     <p><em>Figura 3.8: Pines utilizados de microcontrolador STM32F103RBT6.</em></p>
 428 </div>
 429 
 430 | Pin  | Etiqueta  | Función                        |
 431 | :--- | :-------- | :----------------------------- |
 432 | PA5  | LD2       | LED verde de la placa NUCLEO   |
 433 | PA6  | TIM3_CH1  | Salida PWM buzzer              |
 434 | PA8  | TIM1_CH1  | Salida PWM control temperatura |
 435 | PA9  | USART1_TX | DS18B20                        |
 436 | PC13 | BTN_A     | Botón A                        |
 437 | PA10 | BTN_B     | Botón B                        |
 438 | PB4  | BTN_D     | Botón D                        |
 439 | PB5  | BTN_C     | Botón C                        |
 440 | PB6  | I2C1_SCL  | Linea SCL bus I2C              |
 441 | PB7  | I2C1_SDA  | Linea SDA bus I2C              |
 442 | PB10 | LD3       | LED azul                       |
 443 | PC10 | USART3_TX | ESP-01S Linea TX               |
 444 | PC11 | USART3_RX | ESP-01S Linea RX               |
 445 
 446 <p align="center"><em>Tabla 3.1: Pinout del sistema</em></p>
 447 
 448 La placa NUCLEO se puede alimentar a través del USB (ST-Link) o por el pin de 5
 449 V externo. Los 5 V externos provienen de un regulador LM7505 ubicado sobre la
 450 placa perforada principal, este regulador recibe alimentación de una fuente de
 451 12 V externa. Para seleccionar que tipo de alimentación se desea utilizar se
 452 debe ajustar la posición del jumper JP5 en la placa NUCLEO, tal como lo indica
 453 la Tabla 8 del manual de usuario de la placa.[1]
 454 
 455 ### 3.1.2. Sensor DS18B20
 456 
 457 El sensor DS18B20 se conectó al USART1 de la placa NUCLEO en modo half-duplex,
 458 es decir, utilizando una sola linea del par TX/RX. De esta forma se puede
 459 aprovechar el periférico emulando el protocolo OneWire. Este protocolo requiere
 460 temporización y niveles específicos, tal como se indica en el manual del sensor
 461 DS18B20.[2]
 462 
 463 Para emular el protocolo OneWire utilizando el periférico USART1, se cambian
 464 dinámicamente la tasa en baudios (o baud rate, en inglés) de transmisión. Para
 465 enviar una señal de reset se requiere de como mínimo 480 μs, por lo que enviando
 466 un byte a 9600 baudios de tasa de transmisión, con los respectivos bits de
 467 inicio y fin (resultando en total 10 bits) se tiene un período de
 468 aproximadamente 1.04 ms:
 469 
 470 $$T_{bit} = \frac{1}{9600\ baudios} \approx 104\ \mu s \Rightarrow \boxed{T_{byte}
 471 \approx 1.04\ ms}$$
 472 
 473 En cambio tomando 96000 baudios de tasa de transmisión, se tiene un
 474 período de bit, y de byte, de aproximadamente $10.4\ \mu s$ y $104\ \mu s$,
 475 respectivamente.
 476 
 477 $$T_{bit} = \frac{1}{96000\ baudios} \approx 10.4\ \mu s \Rightarrow
 478 \boxed{T_{byte} \approx 104\ \mu s}$$
 479 
 480 Teniendo estas dos tasas de transmisión, enviando el byte hexadecimal 0xF0
 481 (equivalente al numero binario 11110000) a 9600 baudios, se logra un pulso lo
 482 suficientemente parecido al reset de OneWire.
 483 
 484 Para transmitir datos, se utiliza la tasa más rápida, de 96000 baudios, y se
 485 envía cada bit de datos en un byte, es decir si se desea enviar un byte de
 486 datos, se deben enviar 8 bytes en la transmisión, un byte por cada dato. Se
 487 transmite el byte 0xFF para representar un bit lógico 1 y el byte 0x00 para
 488 representar un bit lógico 0. Al transmitir el byte 0xFF la línea permanece en
 489 nivel alto durante casi toda la trama, salvo el bit de inicio que es siempre
 490 bajo, esto genera un pulso bajo breve, compatible con la escritura de un bit
 491 lógico 1 del protocolo OneWire. Por otro lado, al transmitir el byte 0x00, la
 492 línea permanece en nivel bajo durante casi toda la trama, a excepción del bit de
 493 fin que es siempre 1, esto produce un pulso bajo de mayor duración, similar al
 494 requerido para transmitir un bit lógico 0.
 495 
 496 Por lo tanto, se utiliza la tasa de 9600 baudios únicamente para aproximar el
 497 pulso de reset, el cual posee una duración considerablemente mayor y es
 498 necesario para comenzar al comunicación con el sensor, y la tasa de 96000
 499 baudios para transmitir datos, ya que se generan intervalos temporales
 500 compatibles con los slots de tiempo definidos por el protocolo OneWire.
 501 
 502 Y aprovechando aún más el periférico USART1, se realizaron las operaciones de
 503 forma no bloqueante mediante acceso directo a memoria (DMA) de esta forma se
 504 reduce aun más el tiempo de bloqueo del ejecutor cíclico y de uso de la CPU.
 505 
 506 ### 3.1.3. Módulo ESP-01S
 507 
 508 El módulo Wi-Fi ESP-01S se conecta con la placa NUCLEO a través del periférico
 509 USART3 a una tasa de transmisión de 115200 baudios.
 510 
 511 Dado que el modulo ESP-01S trabaja con Wi-Fi y requiere, en promedio, entre 150
 512 mA y 250 mA, con picos de corriente durante la transmisión Wi-Fi de hasta 430 mA
 513 a 3,3 V, y dado que la corriente maxima suministrada por el regulador de la
 514 placa NUCLEO es de 500 mA, se decidió utilizar un regulador externo de 3,3 V, el
 515 AIC1117-33PT, montado sobre la misma placa perforada principal, suministrada por
 516 los 12 V de la fuente de tensión externa.
 517 
 518 El desarrollo del firmware del modulo ESP-01S no esta dentro del alcance de la
 519 materia, pero se desarrolló de todas formas utilizando PlatformIO y el framework
 520 Arduino. El firmware se desarrolló para que cumpla las siguientes funciones:
 521 
 522 - Conexión a una red Wi-Fi fija.
 523 - Servidor HTTP en el puerto 80, sirviendo la página web estática desde el
 524   sistema de archivos.
 525 - Servidor WebSocket en el puerto 81 para evitar refrescar la pagina web
 526   constantemente para actualizar la información.
 527 - Sistema de archivos LittleFS.
 528 
 529 ### 3.1.4. Display LCD 16x2 I2C
 530 
 531 El display LCD se conecta al bus I2C1 a través del adaptador paralelo a serie
 532 mencionado previamente. Si bien es posible conectar el display directamente a la
 533 placa NUCLEO sin adaptador, esto requiere del uso de más pines de la placa, es
 534 por esto que se optó por el uso del adaptador I2C. Además al utilizar el
 535 periférico I2C se puede utilizar DMA, reduciendo el tiempo de bloqueo del
 536 ejecutor cíclico y for consiguiente el uso de la CPU.
 537 
 538 ### 3.1.5. Control de temperatura
 539 
 540 La etapa de control de temperatura consiste en un MOSFET IRFZ44N de canal N, el
 541 IRFZ44N, controlado por la señal PWM del TIM1_CH1 (PA8). Dado que el MOSFET es
 542 un dispositivo controlador por tensión, se observó que utilizando directamente
 543 la salida GPIO de la placa NUCLEO para controlar el MOSFET esté elevaba su
 544 temperatura considerablemente. Para solucionar esto se implementó un driver para
 545 controlar el MOSFET con una señal PWM de mayor tensión, en particular 12 V de la
 546 fuente externa. El driver utiliza un transistor TBJ 2N3904 actuando como llave
 547 controlador por la señal PWM de la placa NUCLEO, como se puede ver en el
 548 esquemático de la figura 3.9.
 549 
 550 <div align="center">
 551     <img src="img/npn_inv_mosfet_driver.png" style="padding: 10px" align=center width="700px">
 552     <p><em>Figura 3.9: Driver para el MOSFET que controla el calefactor.</em></p>
 553 </div>
 554 
 555 Este circuito es simple de implementar, pero invierte la señal PWM como se
 556 observa en la figura 3.10. Existe la posibilidad de agregar una etapa adicional
 557 inversora, implementado con otro transistor, pero en este caso no es necesario
 558 ya que se puede invertir la polaridad de la señal PWM desde el firmware de la
 559 placa NUCLEO.
 560 
 561 <div align="center">
 562     <img src="img/npn_inv_mosfet_driver_plot.png" style="padding: 10px" align=center width="700px">
 563     <p><em>Figura 3.10: Simulación del driver para el MOSFET que controla el calefactor.</em></p>
 564 </div>
 565 
 566 El calefactor del derretidor de miel se modeló como una carga resistiva pura,
 567 por lo que se utilizó un resistor de alta potencia de 12 V y 40 W para las
 568 pruebas de laboratorio.
 569 
 570 ### 3.1.6. Luces indicadoras
 571 
 572 Para la luz indicadora, se utilizó un diodo emisor de luz (Light Emitting Diode,
 573 LED) de 5 mm de color verde. Este tipo de LEDs requieren de aproximadamente 20
 574 mA. Se observó que para 20 mA de corriente la luz emitida por el LED es tenue y
 575 que se obtienen mejores resultados con entre 30 mA y 45 mA de corriente.
 576 
 577 Para suministrar esta corriente y evitar sobrecargar el regulador de la placa
 578 NUCLEO, se implementó un circuito driver para alimentar al LED con la fuente de
 579 tensión de 12 V externa, controlando solo el estado del led mediante una pequeña
 580 corriente subintrada por la placa NUCLEO. El circuito resultante se muestra en
 581 la figura 3.11.
 582 
 583 <div align="center">
 584     <img src="img/npn_led_driver.png" style="padding: 10px" align=center width="550px">
 585     <p><em>Figura 3.11: Driver para las luces indicadoras.</em></p>
 586 </div>
 587 
 588 El resistor RC se elige de manera tal que la corriente sobre el LED sea de
 589 aproximadamente 45 mA, como se muestra a continuación.
 590 
 591 $$RC=\frac{12\text{ V} - 2.2\text{ V}}{45\text{ mA}} \approx 220\ \Omega$$
 592 
 593 <!-- El LED 2 LEDs (PA5, PB10) con modos ON, OFF, BLINK (500 ms) y PULSE (250 ms). -->
 594 
 595 ### 3.1.7. Buzzer
 596 
 597 Para el buzzer o parlante se utilizó un zumbador piezoeléctrico pasivo de 12 V.
 598 El termino pasivo implica que se debe suministrar una señal PWM para que este
 599 emita un sonido. Teniendo esto en cuenta, y dado que se requieren de 12 V de
 600 tensión, se replicó el circuito de la figura 3.6 utilizado para controlar el
 601 MOSFET.
 602 
 603 <!-- (TIM3_CH1, 1 kHz) con eventos de beep corto (35 ms) y largo (500 ms). -->
 604 
 605 ### 3.1.8. Botones
 606 
 607 Para los botones, se utilizaron 3 tact switch en la placa perforada principal
 608 con los resistores de pull-up internos de la placa NUCLEO.
 609 
 610 <!--
 611 4 pulsadores tact switch con pull-up externo. Antirebote por máquina
 612 de estados en firmware (50 ms de filtro).
 613 -->
 614 
 615 ## 3.2. Firmware del sistema
 616 
 617 El firmware de la placa NUCLEO se compone de una aplicación que implementa un
 618 ejecutor cíclico con 8 tareas asociadas. Estas tareas se organizan de acuerdo al
 619 rol que cumplen: actuador, sensor o lógica del sistema.
 620 
 621 En la figura 3.12 se muestra un diagrama de bloques de las tareas del sistema y
 622 como interactúan entre ellas. La interacción puede ser a través de eventos o
 623 mediante la estructura global compartida `shared_data`.
 624 
 625 <div align="center">
 626     <img src="img/diagrama_de_bloques_firmware_nucleo_TA134.png" style="padding: 10px" align=center width="650px">
 627     <p><em>Figura 3.12: Diagrama de bloques firmware del sistema.</em></p>
 628 </div>
 629 
 630 <!--
 631 Esta aplicacion tiene como principal caracteristica ser no bloqueante.
 632 -->
 633 
 634 ### 3.2.1. Ejecutor cíclico
 635 
 636 El ejecutor cíclico se implementa en el archivo `app.c`. Este ejecutor ciclico
 637 posee un tick de 1 ms generado por el timer SysTick propio del microcontrolador.
 638 En cada tick, la función `app_update()` recorre secuencialmente las ocho tareas
 639 asociadas, ejecutando tantas iteraciones como ticks estén pendientes. En
 640 operación normal, se cumple que la función `app_update()` no se bloquea por más
 641 de 1 ms, por lo que en cada tick no debería haber más de una operación pendiente
 642 en cada tarea.
 643 
 644 En particular del archivo `app.c` se destaca a continuación la lista de tareas
 645 que se asocian a la aplicación. Las tareas son: `task_system`, `task_buttons`,
 646 `task_buzzer`, `task_leds`, `task_menu`, `task_temp_ctrl`, `task_temp_sensor` y
 647 `task_remote`. Cada tarea tiene asociada una función de inicialización y una
 648 función de actualización, denotadas por el sufijo `_init` y `_update`,
 649 respectivamente.
 650 
 651 ```c
 652 const task_cfg_t task_cfg_list[] = {
 653     {task_system_init,      task_system_update,      &shared_data},
 654     {task_buttons_init,     task_buttons_update,     NULL},
 655     {task_buzzer_init,      task_buzzer_update,      NULL},
 656     {task_leds_init,        task_leds_update,        NULL},
 657     {task_menu_init,        task_menu_update,        &shared_data},
 658     {task_temp_ctrl_init,   task_temp_ctrl_update,   &shared_data},
 659     {task_temp_sensor_init, task_temp_sensor_update, &shared_data},
 660     {task_remote_init,      task_remote_update,      &shared_data},
 661 };
 662 ```
 663 
 664 La función de actualización de cada tarea sigue el mismo patrón: consulta su
 665 contador de ticks (incrementado en cada tick de `SysTick`) y si hay ticks
 666 pendientes, se decrementa el contadora en una unidad y se ejecuta su máquina de
 667 estados o lógica correspondiente, si no hay ticks pendientes no hace nada.
 668 
 669 Las tareas se comunican entre sí mediante dos mecanismos: eventos, a través de
 670 buffers circulares con una interfaz dedicada para cada tarea; o mediante la
 671 estructura global compartida `shared_data`. Que mecanismo utiliza cada tarea se
 672 puede observar en la figura 3.12, en la cual las flechas con lineas punteadas
 673 indican el mecanismo de acceso a la variable compartida y las flechas con lineas
 674 continuas indican el mecanismo de eventos.
 675 
 676 ### 3.2.2. Tarea central
 677 
 678 La tarea central, `task_system`, gestiona la lógica del sistema y la máquina de
 679 estados principal. En la figura 3.13 se muestra un diagrama de estados de la
 680 maquina que implementa la tarea. Este diagrama es una versión simplificada de la
 681 lógica que se implementa en la tarea, ya que no se muestran los eventos que se
 682 envían a otras tareas, pero sirve para mostrar como se cambia la funcionalidad
 683 de los botones de acuerdo al estado.
 684 
 685 <div align="center">
 686     <img src="img/system_statechart.png" style="padding: 10px" align=center width="800px">
 687     <p><em>Figura 3.13: Diagrama de estados de tarea central. Version simplificada.</em></p>
 688 </div>
 689 
 690 Se tienen los siguientes estados:
 691 
 692 - `ST_SYS_IDLE`: Estado de reposo, se muestran varios parámetros en el display,
 693   tal como el estado del calefactor, la temperatura actual, la temperatura
 694   deseada y si hay un timer programado. Este estado también contempla que el
 695   calefactor esté activo, lo que puede resultar confuso. Un mejor nombre quizás
 696   hubiese sido `ST_SYS_MAIN`.
 697 - `ST_SYS_CLOCK_SET`: Configuración de hora del reloj de tiempo real.
 698 - `ST_SYS_TEMP_SET`: Ajuste de temperatura deseada.
 699 - `ST_SYS_TIMER_SET_STATUS`: Habilitación/deshabilitación del timer.
 700 - `ST_SYS_TIMER_SET_START`: Configuración de hora de inicio del timer.
 701 - `ST_SYS_TIMER_SET_END`: Configuración de hora de fin del timer.
 702 
 703 Además en esta tarea se gestiona:
 704 
 705 - Persistencia en flash: Utiliza una página completa (1024 bytes) en la
 706   dirección `0x0801FC00` como emulación EEPROM. Los valores se escriben en
 707   direcciones contiguas para reducir el desgaste, borrando la página solo cuando
 708   está llena (512 escrituras).
 709 - Temporizador programable: Si el timer está activo, en cada segundo se compara
 710   la hora actual del RTC con los límites configurados. Si `end_hour > start_hour`
 711   (mismo día) o `end_hour < start_hour` (cruce de medianoche) se activa o
 712   desactiva el calefactor automáticamente.
 713 
 714 ### 3.2.3. Tarea para botones
 715 
 716 En la tarea `task_buttons` se implementa una máquina de estados de anti-rebote
 717 para cada uno de los botones. En la figura 3.14 se muestra un diagrama de
 718 estados de la maquina.
 719 
 720 <div align="center">
 721     <img src="img/button_statechart.png" style="padding: 10px" align=center width="700px">
 722     <p><em>Figura 3.14: Diagrama de estados para botones.</em></p>
 723 </div>
 724 
 725 Al detectar una pulsación válida (flanco ascendente o descendente confirmado) se
 726 envía un evento a `task_system` y, aunque no se muestra en la figura 3.14, se
 727 envían eventos directamente a `task_buzzer` para que inmediatamente luego de
 728 presionar el botón se active el buzzer, sin interactuar con la tarea central
 729 `task_system`. Esto se observa también en el diagrama de bloques del firmware de
 730 la figura 3.12.
 731 
 732 ### 3.2.4. Tarea para el buzzer
 733 
 734 En la tarea `task_buzzer` se controla el buzzer generando una señal PWM de 1
 735 kHz. Esta tarea recibe eventos para generar beeps cortos (de 35 ms para
 736 pulsación de botón) o largos (de 500 ms para activación/desactivación del
 737 calefactor).
 738 
 739 Para controlar el buzzer se implementa una maquina de estados con los estados
 740 `ST_BUZ_XX_OFF` y `ST_BUZ_XX_ON` con auto-apagado por timeout, tal como se
 741 observa en la figura 3.15.
 742 
 743 <div align="center">
 744     <img src="img/buzzer_statechart.png" style="padding: 10px" align=center width="600px">
 745     <p><em>Figura 3.15: Diagrama de estados de buzzer.</em></p>
 746 </div>
 747 
 748 ### 3.2.5. Tarea para luces indicadoras
 749 
 750 En la tarea `task_leds` se controlan las luces indicadoras o LEDs (LD2, LD3)
 751 permitiendo los modos: encendido, apagado, intermitente y un único pulso. Para
 752 esto se implementa la maquina de estados cuyo diagrama de estados se muestra en
 753 la figura 3.16, con los siguientes estados:
 754 
 755 - `ST_LED_XX_OFF`: LED apagado.
 756 - `ST_LED_XX_ON`: LED encendido fijo.
 757 - `ST_LED_XX_BLINK_ON` / `ST_LED_XX_BLINK_OFF`: Parpadeo cada 500 ms.
 758 - `ST_LED_XX_PULSE`: Encendido por 250 ms y luego apagado.
 759 
 760 <div align="center">
 761     <img src="img/led_statechart.png" style="padding: 10px" align=center width="800px">
 762     <p><em>Figura 3.16: Diagrama de estados de luces indicadoras.</em></p>
 763 </div>
 764 
 765 El modo intermitente se utiliza para cuando el calefactor está activo, indicando
 766 visualmente el estado de operación. Cuando el calefactor esta inactivo las luces
 767 permaneces apagadas.
 768 
 769 ### 3.2.6. Tarea para el menú
 770 
 771 La tarea `task_menu`, gestiona la actualización del display LCD 16x2 según el
 772 estado actual del sistema. Se implementa también una maquina de estados similar
 773 a la implementada para el sistema, con estados similares, de manera tal que cada
 774 estado del sistema tiene su correspondiente estado del menú y cada estado del
 775 menú define su contenido del display. En la figura 3.17 se muestran diferentes
 776 contenidos del display para diferentes estados.
 777 
 778 Por ejemplo en estado reposo (estado del sistema `ST_SYS_IDLE`) con el
 779 calefactor apagado y un timer programado, como se muestra en la figura 3.17(b),
 780 en la primer linea se muestra el estado del calefactor ("Off"), y en la segunda
 781 linea el estado del timer ("[P]" si activo, "   ", si no), la temperatura
 782 actual, la temperatura deseada (entre paréntesis) y la unidad de la temperatura.
 783 
 784 <div align="center">
 785 
 786 <table>
 787 
 788 <tr>
 789 <td align="center">
 790 <img src="img/lcd/lcd_off.png" width="350px"><br>
 791 <em>(a) Calefactor apagado.</em>
 792 </td>
 793 
 794 <td align="center">
 795 <img src="img/lcd/lcd_off_prog.png" width="350px"><br>
 796 <em>(b) Calefactor apagado con timer programado.</em>
 797 </td>
 798 </tr>
 799 
 800 <tr>
 801 <td align="center">
 802 <img src="img/lcd/lcd_on.png" width="350px"><br>
 803 <em>(c) Calefactor encendido con timer programado.</em>
 804 </td>
 805 
 806 <td align="center">
 807 <img src="img/lcd/lcd_clock_set.png" width="350px"><br>
 808 <em>(d) Configuración de reloj.</em>
 809 </td>
 810 </tr>
 811 
 812 <tr>
 813 <td align="center">
 814 <img src="img/lcd/lcd_temp_set.png" width="350px"><br>
 815 <em>(e) Configuracion de temperatura deseada.</em>
 816 </td>
 817 
 818 <td align="center">
 819 <img src="img/lcd/lcd_timer_set.png" width="350px"><br>
 820 <em>(f) Configuracion de encendido/apagado de timer.</em>
 821 </td>
 822 </tr>
 823 
 824 <tr>
 825 <td align="center">
 826 <img src="img/lcd/lcd_timer_set_start.png" width="350px"><br>
 827 <em>(g) Configuracion de inicio de timer.</em>
 828 </td>
 829 
 830 <td align="center">
 831 <img src="img/lcd/lcd_timer_set_end.png" width="350px"><br>
 832 <em>(h) Configuracion de fin de timer.</em>
 833 </td>
 834 </tr>
 835 
 836 </table>
 837 
 838 <em>Figura 3.17: Interfaces mostradas en el display LCD 16x2.</em>
 839 </div>
 840 
 841 La comunicación con el LCD es asíncrona: las operaciones se encolan y se
 842 procesan en cada tick de la tarea mediante `display_i2c_async_tick()`.
 843 
 844 ### 3.2.7. Tarea para control de temperatura
 845 
 846 En la tarea `task_temp_ctrl` se implementa un controlador proporcional, integral
 847 y derivativo (PID) para regular la temperatura. Se toma como señal de referencia
 848 el punto de temperatura deseada, y como señal de error la diferencia entre la
 849 señal de referencia y la temperatura actual leída por el sensor.
 850 
 851 En particular, la sección de código que implementa el controlador PID se muestra
 852 a continuación.
 853 
 854 ```c
 855 p_pid->error = temp_set_point - temp_sensor;
 856 p_pid->pid_p = error * Kp;
 857 p_pid->pid_i = (pid_i + (error * dt)) * Ki;
 858 p_pid->pid_d = ((error - prev_error) / dt) * Kd;
 859 output = clampf(pid_p + pid_i + pid_d, 0.0f, 100.0f);
 860 ```
 861 
 862 Siendo las constantes proporcionales, integrales y derivativas, `Kp`, `Ki` y
 863 `Kd`, respectivamente, las que se muestran a continuación:
 864 
 865 - Kp = 40,0
 866 - Ki = 0,75
 867 - Kd = 0,01
 868 - dt = 250 ms
 869 
 870 La salida del controladora (0 % a 100 %) se asigna directamente al ciclo de
 871 trabajo del PWM que controla el calefactor a través de la variable compartida
 872 por las tareas `shared_data`. Si el calefactor está deshabilitado, se fuerza el
 873 ciclo de trabajo a 0 %.
 874 
 875 ### 3.2.8. Tarea para sensor de temperatura
 876 
 877 La tarea `task_temp_sensor` gestiona la lectura asíncrona del sensor DS18B20.
 878 Cada 1 segundo inicia una secuencia de comandos:
 879 
 880 1. Reset (cambio a 9600 baudios + pulso de presencia).
 881 2. `SKIP_ROM` + `CONVERT_T` (inicia conversión).
 882 3. Espera 100 ms (tiempo de conversión aproximado para resolución de 9 bits).
 883 4. Reset + `SKIP_ROM` + `READ_SCRATCHPAD`.
 884 5. Lectura de bytes LSB y MSB.
 885 6. Conversion de los bytes leídos a temperatura real y almacenamiento en
 886    estructura compartida `shared_data`.
 887 
 888 Todas las operaciones se encolan y ejecutan mediante DMA, con callbacks que
 889 indican la finalización de transmisión/recepción.
 890 
 891 ### 3.2.9. Tarea para módulo remoto
 892 
 893 En la tarea `task_remote` se administra la comunicación con el módulo ESP-01S a
 894 través de USART3. Se implementa un protocolo propio basado en comandos de un
 895 byte (caracteres 'A' a 'F') con parámetros adicionales según el comando.
 896 
 897 Comandos recibidos desde el ESP-01S:
 898 
 899 | Comando | Función                                    | Respuesta                                                                               |
 900 | :------ | :----------------------------------------- | :-------------------------------------------------------------------------------------- |
 901 | 'A'     | Solicitar estado completo                  | 'A' + main_output + system_time + timer_status + timer_params(4B) + temp_now + temp_set |
 902 | 'B'     | Toggle calefactor                          | 'B'                                                                                     |
 903 | 'C'     | Toggle timer                               | 'C'                                                                                     |
 904 | 'D'     | Set timer (start_h, start_m, end_h, end_m) | 'D'                                                                                     |
 905 | 'E'     | Solicitar temperatura                      | 'E' + temp_now + temp_set                                                               |
 906 | 'F'     | Set temperatura deseada                    | 'F' + temp_set_point                                                                    |
 907 
 908 Comandos enviados al ESP-01S periódicamente cada 1 segundo:
 909 
 910 | Comando | Función                | Datos                     |
 911 | :------ | :--------------------- | :------------------------ |
 912 | 'E'     | Actualizar temperatura | 'E' + temp_now + temp_set |
 913 
 914 La recepción se realiza por interrupción (`HAL_UART_RxCpltCallback`) con
 915 encolado en un buffer circular. Cada vez que se recibe un byte se encola
 916 automáticamente, para luego ser procesado.
 917 
 918 La transmisión utiliza DMA para no bloquear el ejecutor cíclico, para esto se
 919 implementa un buffer circular similar al de recepción. En este buffer circular
 920 se encolan los bytes que se desean enviar y mientras la cola no esté vacía, y
 921 siempre que DMA haya terminado, se enviando los bytes.
 922 
 923 <div align="center">
 924 <table>
 925 
 926 <tr>
 927 <td align="center">
 928 <img src="img/pagina_web_dark.png" width="400px"><br>
 929 <em>(a) Esquema de colores oscuro.</em>
 930 </td>
 931 
 932 <td align="center">
 933 <img src="img/pagina_web_light.png" width="400px"><br>
 934 <em>(b) Esquema de colores claro.</em>
 935 </td>
 936 
 937 </tr>
 938 
 939 </table>
 940 
 941 <p><em>Figura 3.18: Pagina web del modulo remoto. Esquema de colores adaptado al
 942 dispositivo.</em></p>
 943 
 944 </div>
 945 
 946 ### 3.2.10. Medición de tiempo de ejecución
 947 
 948 En el ejecutor cíclico se mide el tiempo de ejecución de cada tarea y del ciclo
 949 completo mediante el contador de ciclos del DWT. Por cada tarea se mide:
 950 
 951 - `WCET`: Peor tiempo de ejecución desde que se inicializa el sistema.
 952 - `WCET_interval`: Peor tiempo de ejecución en un intervalo de 10 segundos.
 953 - `runtime_us`: Tiempo total del ciclo actual.
 954 - `runtime_us_mean`: Promedio sobre 1000 muestras (1 segundo).
 955 
 956 Los resultados se pueden consultar mediante la consola de semi-hosting, lo que
 957 permite caracterizar temporalmente el sistema sin afectar los tiempos de
 958 ejecución.
 959 
 960 # 4. Ensayos y resultados
 961 
 962 En esta sección se evaluará el sistema desarrollado, tanto el firmware como el
 963 hardware, en aspectos como consumo de corriente, memoria, factor de uso de CPU,
 964 entres otras cosas. De esta forma, se verificará si las decisiones tomadas para
 965 el diseño fueron correctas y si se cumplen los requisitos. En caso de que se
 966 cumplan los requisitos, se comparará el sistema desarrollado con proyectos
 967 similares.
 968 
 969 ## 4.1. Pruebas funcionales del hardware
 970 
 971 | Ensayo                          | Resultado                            | Estado   |
 972 | :------------------------------ | :----------------------------------- | :------: |
 973 | Alimentación y regulación 3,3 V | Tensión estable en placa NUCLEO      | Correcto |
 974 | Comunicación I2C con LCD        | Inicialización y escritura correctas | Correcto |
 975 | Lectura DS18B20                 | Detección y lectura de temperatura   | Correcto |
 976 | Comunicación UART con ESP-01S   | Intercambio de datos bidireccional   | Correcto |
 977 | Control PWM sobre MOSFET        | Variación de ciclo de trabajo        | Correcto |
 978 | Buzzer PWM                      | Generación de tono a 1 kHz           | Correcto |
 979 | LEDs                            | Estados ON/OFF/BLINK correctos       | Correcto |
 980 | Botones con antirebote          | Eventos limpios sin rebotes          | Correcto |
 981 
 982 <p align="center"><em>Tabla 4.1: Pruebas funcionales de hardware.</em></p>
 983 
 984 ## 4.2. Pruebas funcionales del firmware
 985 
 986 | Ensayo                        | Resultado                                   | Estado   |
 987 | :---------------------------- | :------------------------------------------ | :------: |
 988 | Ejecutor cíclico (1 ms tick)  | Tiempo de ejecucion menor a 1 ms            | Correcto |
 989 | Máquina de estados de sistema | Transiciones correctas en todos los estados | Correcto |
 990 | Algoritmo PID                 | Cálculo con valores esperados               | Correcto |
 991 | Lectura DS18B20 asíncrona     | Actualización cada 1 segundo sin bloqueo    | Correcto |
 992 | Comunicación UART remota      | Envío/recepción de comandos A-F             | Correcto |
 993 | Persistencia en flash         | Lectura/escritura en página dedicada        | Correcto |
 994 | RTC con respaldo              | Mantenimiento de hora sin alimentación      | Correcto |
 995 | Antirebote de botones         | Filtro de 50 ms sin falsos positivos        | Correcto |
 996 
 997 <p align="center"><em>Tabla 4.2: Pruebas funcionales de firmware.</em></p>
 998 
 999 ## 4.3. Pruebas de integración
1000 
1001 Se validó la interacción completa del sistema:
1002 
1003 1. Ciclo completo local: Botón enciende calefactor, PID regula temperatura,
1004    display muestra valores, LEDs parpadean, buzzer suena.
1005 2. Ciclo completo remoto: Web solicita status, ESP-01S envía comando 'A', NUCLEO
1006    responde con estado, WebSocket actualiza interfaz web.
1007 3. Temporizador: Configuración de timer, cambio automático de estado al alcanzar
1008    la hora programada.
1009 4. Persistencia de parámetros: Configuración de la temperatura deseada, corte de
1010    energía, restauración correcta al encender.
1011 
1012 En el siguiente [video](https://www.youtube.com/watch?v=ZpNlU7789YU) se presenta
1013 el sistema y se muestran las pruebas funcionales. En primer lugar, se realiza la
1014 configuración de parámetros de manera local y remota. Luego, se verifica la
1015 persistencia de parámetros al perder la alimentación. Por último, se hace una
1016 prueba del sistema calentando agua desde 19 °C a 30 °C en un vaso.
1017 
1018 Como parte de las pruebas de integración, se utilizó un analizador lógico
1019 (Saleae) para verificar la comunicación mediante el protocolo UART entre la
1020 placa NUCLEO y el módulo ESP-01S, así como también la comunicación mediante el
1021 protocolo OneWire entre la placa NUCLEO y el sensor de temperatura DS18B20.
1022 
1023 ## 4.4. Cumplimiento de requisitos
1024 
1025 | ID   | Requisito                  | Estado          |
1026 | :--- | :------------------------- | :-------------- |
1027 | 1    | Control por botones        | Implementado    |
1028 | 2    | Control remoto             | Implementado    |
1029 | 3    | Programación de ciclos     | Implementado    |
1030 | 4    | Curvas de temperatura      | No implementado |
1031 | 5    | Display                    | Implementado    |
1032 | 6    | LEDs indicadores           | Implementado    |
1033 | 7    | Alarma sonora              | Implementado    |
1034 | 8    | Monitoreo en tiempo real   | Implementado    |
1035 | 9    | Conectividad Wi-Fi         | Implementado    |
1036 | 10   | Registro de temperatura    | No implementado |
1037 | 11   | Límite de temperatura      | Implementado    |
1038 | 12   | Persistencia de parámetros | Implementado    |
1039 | 13   | Reloj de tiempo real       | Implementado    |
1040 
1041 <p align="center"><em>Tabla 4.6: Estado de cumplimiento de requisitos propuestos
1042 inicialmente.</em></p>
1043 
1044 Notas sobre requisitos no implementados:
1045 
1046 - Requisito 4 (curvas de temperatura): No implementado por restricciones de
1047   tiempo. Requeriría una interfaz de usuario más compleja y un algoritmo PID más
1048   sofisticado que el actual.
1049 - Requisito 10 (registro de temperatura): No implementado por restricciones de
1050   tiempo.
1051 
1052 ## 4.5. Comparación con trabajos similares
1053 
1054 En la tabla 4.7 se presentan las principales diferencias entre el sistema
1055 desarrollado y los productos y proyectos académicos mencionados previamente.
1056 
1057 | Característica         | Derretidor comercial  | Horno gastronomía | Horno SMD   | Este trabajo |
1058 | :--------------------- | :-------------------- | :---------------- | :---------- | :----------- |
1059 | Control de temperatura | On/off con termocupla | PID digital       | PID digital | PID digital  |
1060 | Control remoto         | No                    | No                | No          | Si           |
1061 | Display                | No                    | Sí                | Sí          | Si           |
1062 | Programación de ciclos | No                    | No                | No          | Sí           |
1063 | Persistencia           | No                    | No                | No          | Sí           |
1064 | RTC                    | No                    | No                | No          | Sí           |
1065 
1066 <p align="center"><em>Tabla 4.7: Comparación con sistemas similares.</em></p>
1067 
1068 ## 4.6. Documentación del desarrollo realizado
1069 
1070 En esta sección se presentan los resultados de las mediciones de consumo de
1071 corriente, tiempos de ejecución, factor de uso de CPU y uso de memoria.
1072 
1073 ### 4.6.1. Consumo de corriente
1074 
1075 Las mediciones de consumo se realizaron en primer lugar sobre el conjunto NUCLEO
1076 y periféricos, luego sobre el calefactor.
1077 
1078 | Componente                  | Tension [V]  | Corriente [mA]  |
1079 | :-------------------------- | -----------: | --------------: |
1080 | NUCLEO                      | 5            | 31              |
1081 | ESP-01S (conectado, sin TX) | 3,3          | 68              |
1082 | ESP-01S (transmitiendo)     | 3,3          | 210             |
1083 | Buzzer                      | 12           | 34              |
1084 | Luces indicadoras           | 12           | 52              |
1085 | Calefactor                  | 12           | 2600            |
1086 
1087 <p align="center"><em>Tabla 4.3: Consumo de corriente del sistema.</em></p>
1088 
1089 La placa NUCLEO consume menos de 100 mA a 5 V en operación normal, lo cual es
1090 menor al límite de 500 mA de un puerto USB estándar.
1091 
1092 ### 4.6.2. Tiempo de ejecución
1093 
1094 Se midió el tiempo de ejecución de cada tarea utilizando el DWT. Mientras se
1095 realizaban las mediciones se presionaron multiples botones, navegando por
1096 diferentes interfaces, de manera de obtener el peor tiempo de ejecucion posible.
1097 En la tabla 4.4 se muestran los tiempos de ejecucion obtenidos de cada tarea y
1098 el total para el ejecutor ciclico. Denotando $M_{i}$ al peor tiempo de ejecucion
1099 en un intervalo de 10 segundos y $C_{i}$ al peor tiempo de ejecución total,
1100 desde que se inicializa el sistema.
1101 
1102 | Tarea              | $M_{i}\ [\mu s]$ | $C_{i}\ [\mu s]$ |
1103 | :----------------- | ---------------: | -------------: |
1104 | `task_system`      | 5                | 5              |
1105 | `task_buttons`     | 13               | 13             |
1106 | `task_buzzer`      | 4                | 219            |
1107 | `task_leds`        | 6                | 6              |
1108 | `task_menu`        | 6                | 140            |
1109 | `task_temp_ctrl`   | 4                | 5              |
1110 | `task_temp_sensor` | 33               | 33             |
1111 | `task_remote`      | 4                | 94             |
1112 | **Total**          | **75**           | **515**        |
1113 
1114 <p align="center"><em>Tabla 4.4: Tiempo de ejecución aproximado por tarea.</em></p>
1115 
1116 <!--
1117 En la figura 4.1 se muestra la evolución del WCET del sistema a lo largo del tiempo.
1118 
1119 <div align="center">
1120     <img src="img/g_app_WCET_without_DMA.png" width="80%">
1121     <p><em>Figura 4.1: WCET del sistema sin contar transfers DMA</em></p>
1122 </div>
1123 
1124 <div align="center">
1125     <img src="img/g_app_WCET_DMA.png" width="80%">
1126     <p><em>Figura 4.2: WCET del sistema con transfers DMA</em></p>
1127 </div>
1128 
1129 <div align="center">
1130     <img src="img/g_app_runtime_us_mean.png" width="80%">
1131     <p><em>Figura 4.3: Tiempo de ejecución promedio (1000 muestras)</em></p>
1132 </div>
1133 -->
1134 
1135 ### 4.6.3. Factor de uso de CPU
1136 
1137 Utilizando la expresión clásica de sistemas en tiempo real, se define el factor
1138 de uso $U$ como la sumatoria del peor tiempo de ejecucion de cada tarea $C_{i}$
1139 dividido el tiempo de un tick del ejecutor ciclico $T$ (1 ms).
1140 
1141 $$U = \sum_{i=1}^{n} \frac{C_i}{T} = \frac{515\,\mu\text{s}}{1000\,\mu\text{s}} = 51,5\\%$$
1142 
1143 El factor de uso resultante de 51,5\% se mide en el peor caso posible.
1144 Tomando el tiempo de ejecucion en un intervalo de 10 segunddos se tine un factor
1145 de uso de CPU aproximado de 7,5\%.
1146 
1147 <!--
1148 | Tarea            | $C_i$ [us] | $T$ [us] | $C_i/T$ |
1149 | :--------------- | ---------: | -------: | ------: |
1150 | Todas (conjunto) |        515 |     1000 |   0.368 |
1151 
1152 <p align="center"><em>Tabla 4.5: Factor de uso de CPU</em></p>
1153 
1154 En ambos casos se tiene un amplio margen para futuras extensiones, por lo que se
1155 confirma que el microcontrolador STM32F103RBT6 es adecuado para este proyecto.
1156 -->
1157 
1158 ### 4.6.4. Uso de memorias
1159 
1160 El uso de memoria del firmare se reporta al momento de realizar la compilación.
1161 La salida del programa se muestra a continuación.
1162 
1163 ```
1164    text   data    bss     dec     hex   filename
1165   64648    276   5616   70540   1138c   tdse-tf_3-02.elf
1166 ```
1167 
1168 Por lo tanto se tiene:
1169 
1170 - Flash: 64648 bytes + 276 bytes = 64924 bytes (~50,7 % de 128 KB).
1171 - RAM: 5616 bytes + 276 bytes = 5892 bytes (~29,4 % de 20 KB).
1172 
1173 # 5. Conclusiones
1174 
1175 En esta sección se presentan las conclusiones generales del proyecto de acuerdo
1176 con las etapas de desarrollo de firmware y hardware, y los resultados obtenidos.
1177 
1178 Se condensan los hallazgos más significativos del Producto Mínimo Viable (MVP) y
1179 se determina en qué medida el trabajo implementado responde al problema de
1180 ingeniería inicialmente planteado, abriendo camino para las líneas de trabajo
1181 futuro.
1182 
1183 ## 5.1. Resultados obtenidos
1184 
1185 Los principales aportes del trabajo realizado son:
1186 
1187 1. Diseño completo de un sistema embebido funcional para control de temperatura
1188    con conectividad Wi-Fi y múltiples interfaces de usuario.
1189 2. Implementación de un ejecutor cíclico con ocho tareas, máquinas de estado y
1190    medición de WCET, demostrando la factibilidad temporal del diseño (U < 52 %
1191    en el peor caso).
1192 3. Comunicación remota funcional mediante ESP-01S con WebSocket, permitiendo
1193    control y monitoreo desde cualquier dispositivo con navegador web.
1194 4. Control PID de temperatura implementado con éxito, con parámetros ajustables
1195    y salida PWM sobre MOSFET.
1196 5. Persistencia de configuración en flash con manejo de desgaste por escritura
1197    en direcciones contiguas.
1198 
1199 El sistema cumple 11 de los 13 requisitos inicialmente planteados, con los dos
1200 restantes identificados como mejoras para versiones futuras.
1201 
1202 ## 5.2. Próximos pasos
1203 
1204 - Implementar perfiles de temperatura programables (curvas multi-paso).
1205 - Agregar registro histórico de temperatura en memoria externa.
1206 - Migrar a una placa PCB dedicada en lugar de NUCLEO + protoboard.
1207 - Agregar modos de calibración para el sensor DS18B20.
1208 - Unificar las implementaciones de colas en un módulo genérico.
1209 - Implementar exclusión mutua entre interfaz local y remota, es decir, que no se
1210   puedan utilizar al mismo tiempo.
1211 - Permitir un único usuario por vez en la interfaz remota.
1212 - Agregar modo de bajo consumo (Sleep/Stop) para ahorro energético.
1213 ## 6. Referencias
1214 
1215 1. STMicroelectronics, "UM1724 User manual - STM32 Nucleo-64 boards (MB1136)"
1216     Rev. 17, 2025. [En linea]. Disponible en:
1217     [https://www.st.com/resource/en/user_manual/um1724-stm32-nucleo64-boards-mb1136-stmicroelectronics.pdf](https://www.st.com/resource/en/user_manual/um1724-stm32-nucleo64-boards-mb1136-stmicroelectronics.pdf)
1218 
1219 2. Analog Devices, "DS18B20 - Programmable Resolution 1-Wire Digital
1220    Thermometer," Rev. 6, ago. 2019. [En linea]. Disponible en:
1221    [https://www.analog.com/media/en/technical-documentation/data-sheets/ds18b20.pdf](https://www.analog.com/media/en/technical-documentation/data-sheets/ds18b20.pdf)
1222