Saltar al contenido
Cursos Ladetec

2020En uso

Control PID para el horno eléctrico de casa

El horno eléctrico que uso a diario en casa, con el termostato bimetálico sustituido por un ESP8266 que regula la temperatura con un PID, enciende las resistencias por triac y sirve su propia página web desde el punto de acceso de la placa. Lleva cocinando desde 2020.

Página web del horno: un indicador de aguja marca 65,42 °C, el estado dice «Listo», el panel de potencia muestra 421 W totales repartidos en 0 W arriba y 421 W abajo, y hay un temporizador en 00:00 y una consigna de 65 °C
La página que sirve la propia placa: 65,42 °C con la consigna en 65, estado «Listo» y 421 W entregándose solo por la resistencia inferior.
Cocina eléctrica blanca arrimada a una esquina y, atornillada a la pared justo encima, la caja gris impresa en 3D del controlador, con un par de cables azules bajando de ella
Como quedó: la caja en la pared, encima del horno que manda. No es un montaje de banco — es el horno de cocinar todos los días.

Un horno doméstico no controla la temperatura: la deja oscilar. El termostato bimetálico enciende las resistencias a tope, espera a pasarse, las apaga y espera a quedarse corto. Lo que el dial marca es el centro de un vaivén, no la temperatura de dentro, y en una masa que depende de los primeros minutos eso se nota. La pregunta del proyecto era si un microcontrolador de tres dólares podía hacerlo mejor que el bimetálico, y la respuesta hay que medirla, no suponerla.

El hardware es una NodeMCU v3 con ESP8266 sobre una placa hecha a la medida para este horno. La temperatura la lee un termopar tipo K con un MAX6675 por SPI. Las dos resistencias — la inferior de 1000 W y la superior de 1300 W — se mandan con triacs disparados por optoacopladores MOC3031 de cruce por cero, y las salidas digitales salen de un registro de desplazamiento 74HC595: el ESP8266 tiene pocos pines y ya se los llevan el SPI del termopar, el I²C del OLED y el zumbador. Una pantalla OLED de 128×32 en el frente dibuja la temperatura, el temporizador y qué resistencia está encendida.

NodeMCU con ESP8266 sobre una protoboard, con cables de puente hacia un módulo MAX6675 verde al que llega un termopar tipo K de sonda roscada con cable trenzado de acero
El banco antes de la placa: la NodeMCU en protoboard y el MAX6675 con el termopar tipo K de sonda.
Placa perforada con una NodeMCU v3 soldada en el centro, una pantalla OLED alargada abajo, un zumbador negro, dos LED, dos bornes verdes y tiras de pines, con cables de colores saliendo por el borde
La placa que quedó: NodeMCU v3, la OLED de 128×32, el zumbador y los bornes por donde salen las resistencias.
Caja impresa en 3D gris, cerrada, con una ventana rectangular para la pantalla OLED, dos agujeros pequeños para los LED y uno grande abajo
El frente de la caja impresa: la ventana de la OLED, los dos LED y el agujero del zumbador.
La misma caja por detrás, hueca, con cuatro aberturas triangulares de ventilación y una pestaña lateral con un agujero de fijación
Por detrás: las aberturas por donde respira y la pestaña con la que se atornilla a la pared.

El mando no es encendido y apagado sino PWM lento: cada segmento dura 100 ms y el periodo son 100 segmentos, o sea diez segundos, el mismo periodo de muestreo del PID. A una resistencia de horno diez segundos le dan igual — su constante térmica son minutos — y el cruce por cero evita trocear el ciclo de la red. La lectura del termopar va filtrada por una media móvil de diez muestras, una por segundo.

Para ajustar el PID hacía falta un modelo, y el modelo salió del horno mismo: se le dieron escalones de potencia, se registró la temperatura y con eso se identificó un ARX en Python — la librería SIPPY sobre python-control — con diez segundos de muestreo. Salió una función de transferencia discreta de quinto orden que sigue la curva medida de cerca, subida y enfriamiento incluidos. Eso es lo que enseña la primera gráfica: medido contra identificado, sobre la misma hoja.

Gráfica de temperatura del horno contra tiempo durante 105 minutos: la curva medida sube hasta 300 °C, baja al cortar el calentador, vuelve a subir y se enfría, con la curva del modelo identificado superpuesta casi encima
El modelo salió del horno: escalones de potencia, temperatura registrada y un ARX identificado encima de la curva medida.

Con el modelo en la mano, Ziegler-Nichols: un proporcional puro llevado hasta la oscilación sostenida da Kcr = 14,28 y Tcr = 340 s, y de ahí salen Kp = 6,93, Ki = 0,42, Kd = 30,34. En simulación se ve bien. En el horno de verdad, no: esas ganancias reaccionan demasiado rápido para un proceso cuya inercia térmica el modelo captura solo a medias, y lo que sobrepasa aquí es una resistencia al rojo. Las ganancias que quedaron en el firmware son Kp = 2,5, Ki = 0,005, Kd = 0, encontradas probando en el horno y registrando cada corrida, no leyendo la tabla.

Gráfica de una oscilación sostenida de amplitud constante entre 0 y 2 grados a lo largo de 6000 segundos, con el título «Controlador proporcional con Kcr=14.28 -> Tcr=340s»
Ziegler-Nichols sobre el modelo: el proporcional puro que deja la oscilación sostenida da Kcr = 14,28 y Tcr = 340 s.
Gráfica de simulación con el título «Pid ajustado Kp=6.93, Ki=0.42, Kd=30.34»: la temperatura sobrepasa hasta 1,57 veces la consigna antes de asentarse hacia 1,0
Las ganancias que sale de la tabla, en simulación. En el horno real ese sobrepico es una resistencia al rojo.
Gráfica de una corrida real de catorce minutos con consigna de 115 °C: la temperatura se mantiene entre 105 y 118 °C mientras el mando baja de 50 % a casi cero y vuelve a subir
Una de las corridas de la barrida de ganancias, registrada en el horno: consigna 115 °C y el mando buscando el punto de equilibrio.

Lo que de verdad resuelve el arranque no es el PID sino lo que va antes. Mientras falten más de 30 °C para la consigna, las dos resistencias van al 100 % y el término integral se mantiene en cero: integrar un error enorme durante quince minutos solo sirve para llegar arriba con el mando saturado y pasarse. Al entrar en esa banda el control se queda un minuto apagado — el calor que ya está en las paredes sigue subiendo la temperatura por su cuenta — y recién entonces arranca el PID. Ese minuto de espera es lo que quita el sobrepico, y no está en ninguna fórmula de sintonía.

El firmware es MicroPython, y ahí apareció el problema que no era de control: el servidor web no cabía. Un ESP8266 deja alrededor de 30 KB de montículo, y picoweb más el controlador más el PID más los drivers no entran si se cargan como ficheros .py normales. La solución fue recompilar el firmware con los módulos congelados en la imagen, que así se ejecutan desde flash en lugar de copiarse a RAM. El servidor corre sobre uasyncio con tres tareas: el controlador cada 100 ms, la pantalla y el temporizador cada segundo, y las peticiones HTTP cuando llegan.

La placa levanta su propio punto de acceso — SSID «Horno», sin contraseña — y sirve la página en 192.168.4.1. No hay nube, ni cuenta, ni aplicación que instalar: el teléfono se conecta a la red del horno y abre una dirección. La página enseña la temperatura en un indicador de aguja, la potencia que está entregando cada resistencia en vatios, el temporizador y el estado — «Calentando», «Listo», «Apagado» — y permite fijar la consigna en automático o mandar cada resistencia a mano. Cuando alcanza la temperatura suena el zumbador dos veces; cuando se acaba el temporizador suena tres y el horno se apaga solo.

Captura del navegador en la dirección 192.168.4.1 con la página del horno: indicador de aguja en 55,15 °C, estado «Calentando», potencia total de 1024 W y los controles de automático y manual
Servida desde el punto de acceso de la placa, en 192.168.4.1. No hay nube ni aplicación: el teléfono se conecta a la red del horno.

La misma ruta que alimenta la página, /get_values, es la que convirtió el horno en un banco de pruebas: un script en la computadora la consulta cada diez segundos y escribe un CSV con temperatura, mando, error y potencia de cada resistencia. Todas las gráficas de este caso salen de esos ficheros. La instrumentación no se añadió para medir: ya estaba ahí porque la interfaz la necesitaba.

El resultado, medido en corridas reales de cocina y no en el banco: unas pizzas a 150 °C se mantienen dentro de unos pocos grados de la consigna durante los veinte minutos de horneado, con un sobrepico de unos 4 °C en la entrada; un pescado a 180 °C aguanta una hora de meseta, con las dos bajadas que se ven en la gráfica, que son la puerta abriéndose. Eso es lo que no hacía el bimetálico, y es la razón por la que el horno sigue así desde 2020.

Gráfica de una corrida de cocina de 55 minutos con consigna de 150 °C marcada con una línea discontinua: la temperatura sube, sobrepasa unos 4 grados y se mantiene pegada a la consigna unos veinte minutos antes de apagarse
Pizzas a 150 °C: unos 4 °C de sobrepico en la entrada y veinte minutos de meseta pegada a la consigna.
Gráfica de una corrida de cocina de 88 minutos con consigna de 180 °C: una hora de meseta con dos bajadas marcadas de unos 25 grados que el control recupera subiendo el mando
Pescado a 180 °C: una hora de meseta. Las dos bajadas son la puerta abriéndose, y se ve al mando subir para recuperarlas.

Lo que no hace

  • No tiene seguridad de red: el punto de acceso es abierto y la página no pide contraseña. Quien esté al alcance del WiFi puede encender el horno.
  • No hay protección independiente contra sobretemperatura: si el firmware se cuelga con los triacs conducidos, nada lo corta por hardware.
  • No se conecta al WiFi de la casa ni sale a Internet: se controla desde la red que levanta la propia placa.
  • Las ganancias del PID están sintonizadas para este horno. En otro hay que repetir la identificación.

Es una instalación de casa y se comporta como tal: manipula 120 V directamente sobre resistencias de 2300 W en total y no tiene corte térmico redundante, así que no es un diseño para copiar tal cual. Las cifras de energía que aparecen en los registros son estimadas multiplicando el porcentaje de mando por la potencia nominal de cada resistencia, no medidas con un vatímetro.