Control · Proyecto 2026-2

Levitador PID

Una bola de ping-pong flotando en un tubo de aire: modelo, diseño del controlador, piezas para imprimir y un laboratorio en vivo con la ESP32 conectada al navegador.

Inicio / Herramientas / Control / Levitador PID
Octubre de 2026 · versión 1

Levitador
neumático PID

Un ventilador empuja aire por un tubo transparente; un láser mide dónde está la bola y la ESP32 decide, cincuenta veces por segundo, cuánto soplar. Tú lo ves y lo controlas desde esta página.

Programa PRI · José Luis Castro Góngora · Universidad Nacional de Colombia, Sede Bogotá

Render del levitador: tubo transparente con la bola flotando sobre la base morada con el ventilador y la caja de electrónica
  • Control · Ingeniería Mecatrónica
  • ESP32 + VL53L1X + ventilador PWM
  • 7 piezas impresas en 3D
  • Pantalla a color, perilla y 30 LED
  • USB y Bluetooth desde Chrome o Edge
Planta\(G(s)=\dfrac{K_v\beta}{s(s+\beta)(\tau s+1)}\)un integrador, la bola y el ventilador
PID por defecto\(t_s\approx 2{,}3\ \text{s}\)sobreimpulso \(\approx 1\,\%\), margen de fase \(46^\circ\)
Lazo digital\(50\ \text{Hz}\)\(T_s = 20\ \text{ms}\), derivada filtrada y antiwindup
Costo total≈ $ 336.408precios de tiendas de Bogotá, octubre de 2026

Lo esencial, en seis frases

  1. La bola sube si el aire que la empuja pesa más que ella, y baja si pesa menos. Hay una sola velocidad de aire \(v_0\) que la deja quieta, y esa velocidad es la misma a cualquier altura.
  2. Por eso la altura se comporta como un integrador: un poquito de aire de más y la bola sube sin parar. Sin control no flota, se va al techo o al piso.
  3. El sensor láser VL53L1X, en la tapa, mide la distancia a la bola; la ESP32 calcula el error \(e = r - y\) y mueve el PWM del ventilador con un PID.
  4. \(K_p\) empuja según qué tan lejos está la bola, \(K_d\) frena según qué tan rápido va, y \(K_i\) corrige lo que se queda pegado cuando algo roba aire.
  5. Una válvula de fuga con servo roba aire de verdad: es la perturbación \(D(s)\) de los talleres, pero la ves y la sientes.
  6. En el laboratorio en vivo conectas la ESP32 por USB o Bluetooth y ves todo en tiempo real, junto a un gemelo digital que corre el modelo al lado de la bola real. Sin computador, la pantalla a color y la perilla del equipo hacen lo mismo.

Pantalla y perilla

Una TFT de \(1{,}3''\) a color muestra la altura, el setpoint, el PWM y la gráfica de los últimos \(24\) s. Con la perilla cambias setpoint, modo, perfil y ganancias; pulsación larga arranca o para.

Tubo que habla en colores

Treinta LED detrás del tubo: el celeste marca el setpoint, el de la bola se pinta verde, amarillo o rojo según el error, y el fondo brilla con el PWM. Desde lejos se ve si el control va bien.

Reto: tú contra el PID

Manejas el ventilador con la perilla y la bola tiene que seguir una secuencia de escalones. La ESP32 mide tu \(\text{IAE}\) y la página lo compara con el del PID. Spoiler: el retardo te gana.

Gemelo digital

El modelo no lineal corre en el navegador con el mismo PID y el mismo setpoint. Si la bola real y la virtual se separan, el modelo te está diciendo qué le falta. Un botón ajusta \(v_0\), \(\tau\) y \(v_{\max}\) con tus datos.

Perturbación que se ve

Un servo SG90 abre una ventana en el embudo y deja escapar aire. Así compruebas en la mesa por qué el P solo deja error y el PI no.

Autoajuste y cascada

Con un botón la ESP32 hace la prueba del relé, mide \(K_u\) y \(P_u\) y propone ganancias. Con el tacómetro del ventilador puedes cerrar un lazo interno de velocidad.

01 Cómo funciona

De abajo hacia arriba: aire, panal, tubo, bola, láser

Gira el modelo con el dedo o el ratón. El botón «Corte» abre las piezas por la mitad para ver por dentro: el embudo, el panal que endereza el aire y el puerto de la válvula.

Render del levitador completo
El modelo 3D sale del mismo código CAD que los archivos STEP y STL. Con «Seguir el laboratorio» la bola, el ventilador y la válvula se mueven con los datos del laboratorio en vivo (simulado o real).
  1. El ventilador sopla hacia arriba

    Un ventilador de PC de \(80\times80\) mm y cuatro hilos toma aire por debajo de la base (por eso las patas) y lo empuja hacia el embudo. El cuarto hilo recibe el PWM de \(25\ \text{kHz}\); el tercero devuelve dos pulsos por vuelta: el tacómetro.

  2. El embudo y el panal ordenan el aire

    El aire sale del ventilador girando. El embudo lo lleva de \(76\) a \(44\) mm y el panal de celdas hexagonales de \(6\) mm le quita el remolino. Sin panal la bola gira y baila de lado; con panal sube derecha. El panal también es el piso donde descansa la bola.

  3. La válvula de fuga roba aire cuando tú quieras

    En un costado del embudo hay un puerto de \(18\) mm tapado por una aleta. Un servo la abre de \(0\) a \(90^\circ\). Abierta, parte del aire se escapa antes de llegar a la bola: eso es una perturbación a la entrada de la planta.

  4. El tubo y la bola

    Tubo de acrílico de \(50\) mm por fuera, \(44\) por dentro y \(500\) de largo. La bola de ping-pong mide \(40\) mm y pesa \(2{,}7\) g: entre la bola y la pared queda una rendija de \(2\) mm por donde se cuela el aire. Esa rendija es la que hace que la bola flote estable de lado.

  5. La caja: cerebro, pantalla y perilla

    La ESP32 vive en una caja impresa al lado de la base, con la pantalla TFT y la perilla en la tapa. Por la tapa ves el estado sin abrir el computador; por USB o Bluetooth, la página recibe los datos \(50\) (USB) o \(25\) (BLE) veces por segundo.

  6. La tira de LED detrás del tubo

    Cuatro abrazaderas impresas sujetan \(50\) cm de tira WS2812B contra la parte de atrás del tubo, con los LED mirando hacia la bola. Cada LED cubre \(16{,}7\) mm de altura.

  7. El láser mide desde arriba

    El VL53L1X va en la tapa, mirando hacia abajo por una ventana de \(10\) mm. Mide la distancia por tiempo de vuelo cincuenta veces por segundo. La altura es \(y = d_0 - d\), donde \(d_0\) es la distancia con la bola en reposo (se calibra con un comando). La tapa tiene seis ventilas en arco: el aire tiene que salir, si no el tubo se presuriza.

Corte del embudo mostrando el panal hexagonal y el puerto de la válvula
Corte de la base: embudo, panal y puerto de fuga con la aleta del servo.
Tapa superior con las ventilas en arco y el sensor láser
Tapa: seis ventilas en arco, ventana del láser y ranuras M2 que sirven para casi cualquier tarjeta VL53L1X.
Caja de electrónica con la pantalla a color mostrando la altura y la gráfica, la perilla y la rejilla
La tapa de la caja: pantalla TFT de \(1{,}3''\) con la gráfica en vivo, perilla y rejilla de ventilación. El nombre va grabado en la impresión.
02 Modelar · paso 1

Del aire a una ecuación

Antes de controlar hay que saber qué estamos controlando. Vamos en bloques pequeños: primero las fuerzas, después el equilibrio.

Las dos fuerzas sobre la bola

Hacia abajo, el peso: \(mg\).

Hacia arriba, el empuje del aire. Lo que importa no es la velocidad del aire sola, sino la velocidad del aire respecto a la bola: si la bola subiera tan rápido como el aire, no sentiría viento.

\[F_a = c\,(v_a-\dot y)\,\lvert v_a-\dot y\rvert\]

\(v_a\): velocidad media del aire en el tubo. \(\dot y\): velocidad de la bola. \(c\): agrupa densidad del aire, área y forma (no hace falta conocerlo, se despeja con el equilibrio). El valor absoluto conserva el signo: si la bola baja más rápido que el aire, el empuje sigue siendo hacia arriba.

\(mg\)
\(F_a\)
\(v_a\) aire
\(y,\ \dot y\)
Cuerpo libre. El aire que pasa por la rendija entre la bola y la pared es el que la centra.
  1. Segunda ley de Newton

    Masa por aceleración igual a la suma de fuerzas, positivo hacia arriba:

    \[m\,\ddot y = c\,(v_a-\dot y)\lvert v_a-\dot y\rvert - m g\]

    Es no lineal por el cuadrado. No es grave: en el siguiente paso la vamos a mirar de cerca alrededor del punto de flotación.

  2. El equilibrio: bola quieta

    Quieta significa \(\dot y = 0\) y \(\ddot y = 0\). Entonces \(0 = c\,v_0^2 - mg\), es decir:

    \[v_0 = \sqrt{\frac{m g}{c}}\qquad\Longleftrightarrow\qquad c\,v_0^2 = m g\]

    Lee esto con calma: la velocidad de aire que deja la bola quieta no depende de la altura \(y\). A \(5\) cm o a \(40\) cm, el aire necesario es el mismo. Esa es la razón de todo lo que sigue.

  3. Medir \(v_0\) en vez de calcular \(c\)

    No necesitas conocer \(c\). En la práctica subes el PWM a mano hasta que la bola flota quieta: ese PWM es \(u_0\) (alrededor de \(48\,\%\) en el modelo) y fija \(v_0\). El autoajuste por relé también lo encuentra solo.

03 Modelar · paso 2

Linealizar: la bola es un integrador con un polo

Linealizar es hacer zoom: cerca del equilibrio, la curva del empuje se parece a una recta. Escribimos cada variable como su valor de equilibrio más un cambio pequeño \(\delta\).

  1. Cambio de variable

    \(v_a = v_0 + \delta v_a\), \(\ \dot y = 0 + \delta\dot y\). Llamamos \(w = v_a - \dot y\) a la velocidad relativa; en el equilibrio vale \(w = v_0\).

  2. Pendiente del empuje

    Para \(w>0\), \(F_a = c\,w^2\). Su derivada es \(\dfrac{dF_a}{dw} = 2 c w\), que en el equilibrio vale \(2 c v_0\). Entonces:

    \[\delta F_a \approx 2 c v_0\,(\delta v_a - \delta \dot y)\]
  3. Ecuación lineal

    El peso es constante y se cancela con \(c v_0^2\). Queda \(m\,\delta\ddot y = 2 c v_0(\delta v_a - \delta\dot y)\). Dividimos por \(m\) y usamos \(c = mg/v_0^2\):

    \[\frac{2 c v_0}{m} = \frac{2 g}{v_0} \equiv \beta \qquad\Rightarrow\qquad \delta\ddot y + \beta\,\delta\dot y = \beta\,\delta v_a\]
  4. Laplace con condiciones iniciales en cero

    \[\frac{Y(s)}{V_a(s)} = \frac{\beta}{s\,(s+\beta)}\]

    Dos polos, y cada uno tiene un significado físico:

    • Polo en \(s = 0\): integrador. Si sobra un poco de aire, la bola no se va a otra altura de equilibrio: sube a velocidad constante hasta chocar con la tapa. La altura es la integral de un exceso de aire.
    • Polo en \(s = -\beta\): la bola alcanza al aire. Con \(v_0 \approx 2{,}4\ \text{m/s}\), \(\beta = 2g/v_0 \approx 8{,}2\ \text{s}^{-1}\): la velocidad de la bola se acomoda a un cambio del aire en unos \(1/\beta \approx 0{,}12\ \text{s}\).
Consecuencia que vas a ver en la mesa: con \(u\) fijo, la bola nunca se queda quieta mucho tiempo. Por eso este sistema es tan bueno para aprender control: sin realimentación no funciona.
04 Modelar · paso 3

El ventilador, el sensor y la función de transferencia completa

Ventilador: primer orden

El rotor tiene inercia: si cambias el PWM \(u\) de golpe, el aire tarda en acomodarse. Se modela como primer orden:

\[\tau\,\dot v_a + v_a = K_v\,u \quad\Rightarrow\quad \frac{V_a(s)}{U(s)} = \frac{K_v}{\tau s + 1}\]

\(K_v \approx 50\ \tfrac{\text{mm/s}}{\%}\) (con \(100\,\%\) el aire va a unos \(5\ \text{m/s}\)) y \(\tau \approx 0{,}35\ \text{s}\). Ambos se miden en la práctica; el gemelo digital los ajusta.

Sensor: casi perfecto, pero con retardo

El VL53L1X entrega una medida cada \(20\ \text{ms}\) y la ESP32 actúa en el siguiente ciclo. Ese retraso se modela como \(e^{-T_d s}\) con \(T_d \approx 30\ \text{ms}\).

El retardo no cambia la amplitud, solo resta fase: \(-\omega T_d\) radianes. A \(4\ \text{rad/s}\) son \(7^\circ\) menos de margen de fase. Pequeño, pero existe, y es la razón de que el límite real de \(K_p\) sea menor que el de Routh.

Multiplicamos los tres bloques en serie (ventilador, bola, sensor):

\[G(s) = \frac{Y(s)}{U(s)} = \frac{K_v\,\beta}{s\,(s+\beta)\,(\tau s+1)}\,e^{-T_d s} = \frac{408{,}8}{s\,(s+8{,}17)\,(0{,}35s+1)}\,e^{-0{,}03 s}\]

Unidades: \(y\) en mm, \(u\) en \(\%\) de PWM. Por eso las ganancias del PID salen en \(\%/\text{mm}\): \(K_p = 0{,}08\) significa «si la bola está \(10\) mm abajo, sube el PWM \(0{,}8\,\%\)».

ParámetroValor del modeloQué esCómo se mide en la mesa
\(m\)\(2{,}7\ \text{g}\)masa de la bolabalanza de cocina (o el dato de la bola reglamentaria)
\(v_0\)\(2{,}4\ \text{m/s}\)aire que equilibra el pesosale de \(u_0\): \(v_0 = K_v u_0\)
\(u_0\)\(48\,\%\)PWM de flotaciónmodo manual: sube \(u\) hasta que la bola flote; o el autoajuste
\(\beta\)\(8{,}17\ \text{s}^{-1}\)polo de la bola\(\beta = 2g/v_0\)
\(K_v\)\(50\ \tfrac{\text{mm/s}}{\%}\)ganancia del ventiladoranemómetro, o el ajuste del gemelo digital
\(\tau\)\(0{,}35\ \text{s}\)constante de tiempo del ventiladorescalón de PWM y curva de rpm del tacómetro: \(63{,}2\,\%\) del cambio
\(T_d\)\(30\ \text{ms}\)retardo de medidaperiodo de muestreo más tiempo de cálculo
05 Controlar · paso 1

El lazo cerrado, con el método de clase

Antes de hablar de estabilidad, la función de transferencia en lazo cerrado. Usamos los movimientos del profe: nombra, ecuación, despeja, apaga, límite.

−++−
\(R(s)\)
\(E\)
\(C(s)\)
PID
\(U\)
\(D(s)\) válvula
\(\dfrac{K_v}{\tau s+1}\)
ventilador
\(V_a\)
\(\dfrac{\beta}{s(s+\beta)}\)
bola
\(Y(s)\)
\(e^{-T_d s}\)
sensor
Llamamos \(G(s)\) al producto ventilador · bola · sensor (el retardo del sensor se pasa al camino directo; para este análisis da lo mismo). La válvula resta aire a la entrada del ventilador.
  1. Nombra y escribe una ecuación por sumador y por bloque

    \[E = R - Y \qquad U = C\,E \qquad Y = G\,(U - D)\]
  2. Despeja \(Y\)

    Sustituye \(U\) y \(E\): \(Y = G\,(C(R-Y) - D)\). Pasa los \(Y\) a la izquierda: \(Y(1 + CG) = CG\,R - G\,D\).

    \[Y(s) = \underbrace{\frac{C G}{1 + C G}}_{T(s)}\,R(s) \;-\; \frac{G}{1 + C G}\,D(s)\]
  3. El error, apagando una entrada a la vez

    \[E(s) = \frac{1}{1 + C G}\,R(s) \;+\; \frac{G}{1 + C G}\,D(s)\]
  4. Límite: error en estado estacionario (después de comprobar estabilidad)

    Cambio de setpoint \(R = r_0/s\) con un P (\(C = K_p\)). Como \(G\) tiene un \(1/s\), \(G(0) \to \infty\):

    \[e_{ss} = \lim_{s\to 0} s\,\frac{1}{1 + K_p G}\,\frac{r_0}{s} = 0\]

    Sistema tipo 1: llega al setpoint aunque solo tengas P. La válvula es otra historia: con \(D = d_0/s\),

    \[e_{ss} = \lim_{s\to 0} \frac{G}{1 + K_p G}\,d_0 = \frac{d_0}{K_p}\]

    Con \(K_p = 0{,}08\ \%/\text{mm}\) y una válvula que roba el equivalente a \(d_0 = 6\,\%\) de PWM, la bola queda \(6/0{,}08 = 75\ \text{mm}\) abajo. El integrador del PI pone un \(1/s\) antes de la perturbación y ese error se vuelve cero. Esto lo vas a medir en el experimento 1.

06 Controlar · paso 2

Qué hace cada ganancia, viéndolo

Mueve los deslizadores. Arriba ves la bola respondiendo a un cambio de setpoint de \(100\) mm y, a los \(8\) s, a la válvula que se abre. Abajo, dónde quedan los polos del lazo cerrado.

\(K_p\): el resorte

Empuja proporcional a la distancia. Más \(K_p\): llega más rápido, pero oscila más. Solo no puede con la válvula: deja \(d_0/K_p\) de error.

\(K_d\): el amortiguador

Reacciona a la velocidad de la bola y la frena antes de pasarse. Agrega amortiguamiento, pero amplifica el ruido del láser: por eso lleva el filtro \(N\).

\(K_i\): la memoria

Suma el error en el tiempo. Mata el error de la válvula. Mucho \(K_i\): sobreimpulso y oscilación lenta, y si el ventilador se satura, «windup».

Altura de la bola

Mando del ventilador

Polos del lazo cerrado

Lectura

setpointaltura \(y\)mando \(u\)válvula

Esta simulación usa el modelo lineal \(G(s)\) con el retardo, en tiempo continuo. El laboratorio usa el modelo no lineal y el PID digital del firmware, así que los números cambian un poco: esa diferencia también enseña.

07 Controlar · paso 3

Estabilidad: Routh con un P, y márgenes del PID

Ya tenemos el lazo cerrado. Ahora sí: ¿hasta dónde puedo subir \(K_p\) sin que la bola empiece a oscilar sola?

  1. Ecuación característica con \(C = K_p\) (sin retardo)

    \(1 + K_p G(s) = 0\). Multiplica por \(s(s+\beta)(\tau s+1)\):

    \[\tau s^3 + (1 + \tau\beta)s^2 + \beta s + K_p K_v \beta = 0 \;\Rightarrow\; 0{,}35 s^3 + 3{,}861 s^2 + 8{,}175 s + 408{,}8 K_p = 0\]

    No falta ningún coeficiente y todos son positivos si \(K_p>0\): pasa el atajo. Toca hacer Routh.

  2. Arreglo de Routh

    \(s^3\)\(0{,}35\)\(8{,}175\)
    \(s^2\)\(3{,}861\)\(408{,}8K_p\)
    \(s^1\)\(\dfrac{3{,}861\cdot 8{,}175 - 0{,}35\cdot 408{,}8K_p}{3{,}861}\)\(0\)
    \(s^0\)\(408{,}8K_p\)

    Primera columna positiva: \(K_p > 0\) y \(31{,}56 - 143{,}1K_p > 0\).

    \[0 < K_p < 0{,}2206\ \tfrac{\%}{\text{mm}}\]
  3. Frecuencia de la oscilación en el límite

    Con \(K_p = 0{,}2206\) la fila \(s^1\) se anula. El polinomio auxiliar de la fila \(s^2\): \(3{,}861 s^2 + 90{,}18 = 0\Rightarrow s = \pm j\,4{,}83\). Periodo \(2\pi/4{,}83 \approx 1{,}30\ \text{s}\).

    Con el retardo de \(30\) ms el límite lineal baja a \(K_u \approx 0{,}167\) y el periodo sube a \(P_u \approx 1{,}50\ \text{s}\). La prueba del relé con \(h = 8\) en el modelo no lineal da \(K_u \approx 0{,}14\) y \(P_u \approx 1{,}7\ \text{s}\): la oscilación de \(\pm 75\) mm ya no es «pequeña» y la ganancia efectiva del arrastre cambia. Que no coincidan exacto también es una lección.

Lugar de las raíces con controlador P
Lugar de las raíces de \(K_pG(s)\): dos ramas salen de \(0\) y \(-\beta\), se encuentran y cruzan el eje imaginario en \(\pm j4{,}83\).
Diagrama de Bode del lazo abierto con el PID por defecto
Bode de \(C(s)G(s)\) con el PID por defecto: margen de fase \(46^\circ\) a \(3{,}9\ \text{rad/s}\), margen de ganancia \(3{,}1\) (\(9{,}8\) dB).
08 Controlar · paso 4

El PID que corre en la ESP32, y lo que lo hace distinto

El controlador de clase es \(C(s) = K_p + \tfrac{K_i}{s} + K_d s\). El que va en el microcontrolador tiene cuatro detalles que lo hacen funcionar en la vida real.

\[u_k = u_0 + \underbrace{K_p\,(b\,r_k - y_k)}_{\text{proporcional}} + \underbrace{I_k}_{\text{integral}} + \underbrace{D_k}_{\text{derivada}}\]

1 · Realimentación anticipada \(u_0\)

El PID no arranca de cero: arranca del PWM que ya deja la bola flotando. Así el integrador solo corrige lo que falta, no todo el peso.

2 · Peso del setpoint \(b\)

Con \(b = 0{,}6\) el proporcional ve solo el \(60\,\%\) del salto de setpoint. Como la planta ya integra, el integrador del PID deja un cero lento que causa sobreimpulso; \(b\) lo compensa sin cambiar cómo se rechaza la perturbación.

3 · Derivada sobre la medida, filtrada

\(D(s) = -\dfrac{K_d s}{s/N + 1}Y(s)\). Derivar \(y\) en vez de \(e\) evita el pico de mando cuando cambias el setpoint. Discretizada con Tustin, \(T_s = 0{,}02\):

\[D_k = \tfrac{2 - N T_s}{2 + N T_s}D_{k-1} - \tfrac{2K_d N}{2 + N T_s}(y_k - y_{k-1})\]

4 · Antiwindup condicional

El PWM solo va de \(0\) a \(100\,\%\). Si el mando está saturado y el error empuja en la misma dirección, el integrador deja de sumar: \(I_{k+1} = I_k + K_i T_s e_k\) solo cuando ayuda.

Lo innovador, con su porqué

Autoajuste por relé (Åström–Hägglund)

La ESP32 reemplaza el PID por un relé: \(u = u_0 \pm h\) según el signo del error. La bola entra en una oscilación límite de amplitud \(a\) y periodo \(P_u\). La primera armónica da:

\[K_u = \frac{4h}{\pi a}\]

Es la versión segura de «subir \(K_p\) hasta que oscile»: la amplitud la limitas tú con \(h\). Además el relé corrige su propio centro: si la mitad con más aire dura más que la otra, sube \(u_0\); al final \(u_0\) queda en el PWM de flotación. De \(K_u\) y \(P_u\) salen las reglas de la tabla.

Lazo en cascada con el tacómetro

El PID de altura ya no manda PWM: pide rpm. Un PI interno, más rápido, mueve el PWM hasta lograr esas rpm. Si el ventilador cambia (se calienta, baja el voltaje, tiene zona muerta), el lazo interno lo corrige antes de que la bola lo note. Es lo que se hace en motores y drones.

Gemelo digital

En el navegador corre la ecuación no lineal del paso 02 con el mismo PID digital. Ves las dos bolas a la vez. El botón «Ajustar gemelo» busca \(v_0\), \(\tau\) y \(v_{\max}\) que mejor predicen tus datos (predicción a \(0{,}6\) s, mínimos cuadrados).

Perturbación física controlada

La válvula se mueve desde la página: un deslizador o un «golpe» de 2 s. Es la \(D(s)\) de los talleres de perturbaciones, pero con aire de verdad.

Perfiles de setpoint

La ESP32 genera la referencia: fija, escalones, seno de \(8\) s o rampa triangular de \(40\) mm/s. Con el seno ves el desfase del lazo; con la rampa, el error de seguimiento. El sistema ya tiene un integrador; con el \(K_i\) del PID el lazo es tipo 2, así que la rampa se sigue sin error en estado estacionario.

Equipo autónomo

Pantalla, perilla y LED hacen que funcione sin computador, para mostrarlo en una feria o en el colegio. Por Bluetooth, la misma página sirve desde un celular Android o un portátil sin cables.

Regla\(K_p\)\(K_i\)\(K_d\)Cuándo usarla
Ziegler–Nichols PID\(0{,}6K_u\)\(1{,}2K_u/P_u\)\(0{,}075K_uP_u\)rápida y agresiva, sobreimpulso alto
Tyreus–Luyben PI\(K_u/3{,}2\)\(K_p/(2{,}2P_u)\)\(0\)suave, buen punto de partida
«Sin sobreimpulso»\(0{,}2K_u\)\(0{,}4K_u/P_u\)\(0{,}066K_uP_u\)cuando la bola no debe tocar la tapa
09 Laboratorio en vivo

Conecta la ESP32 y mira el control mientras pasa

Conecta la ESP32 por cable y pulsa USB, o enciéndela y pulsa Bluetooth (Chrome o Edge). Sin hardware, pulsa Simular: corre el mismo firmware dentro del navegador, con una planta un poco distinta al modelo para que el gemelo tenga algo que aprender.

Sin conexión
realgemelosetpoint
Lo que muestra la pantalla del equipo
Altura
Mando y sus partes
Ventilador y válvula
setpoint \(r\)real \(y\)gemelo \(\hat y\)\(u\)\(u_P\)\(u_I\)\(u_D\)rpm

Modo

Setpoint

Ganancias

Perturbación

Autoajuste por relé

Reto: tú contra el PID

40 s de escalones. Manejas el PWM con el deslizador «PWM manual», con las flechas ↑ ↓ o con la perilla del equipo. Gana el \(\text{IAE}\) más bajo.

Equipo

Medido en vivo

Gemelo digital

Polos con estas ganancias

Consola serie

Seguridad: la ESP32 no deja pasar el setpoint de \(20\) a \(420\) mm y descarga el integrador si la bola se pega a la tapa. Para desenchufar, pon primero el modo Apagado. USB (Web Serial) funciona en Chrome y Edge de computador; Bluetooth (Web Bluetooth) en Chrome y Edge de computador y de Android. En iPhone, Safari no trae ninguno de los dos: usa Simular o la pantalla del equipo.
10 Experimentos guiados

Diez experimentos y lo que deberías ver

Cada uno sirve con la ESP32 o con el simulador. Anota lo que mides: con el botón «Grabar CSV» te llevas los datos para el informe.

Experimento 1

Solo P contra la válvula

\(K_p = 0{,}08\), \(K_i = K_d = 0\), \(b = 1\). Cambia el setpoint: llega sin error (tipo 1). Abre la válvula al \(100\,\%\): la bola baja y se queda abajo. Mide el error y compáralo con \(d_0/K_p\).

Experimento 2

Buscar el límite

Solo P. Sube \(K_p\) de \(0{,}02\) en \(0{,}02\). ¿Con cuánto empieza a oscilar sin parar? Compáralo con Routh (\(0{,}22\)), con el lineal con retardo (\(0{,}167\)) y con el relé (\(\approx 0{,}14\)). ¿Por qué el real es menor?

Experimento 3

El amortiguador

Con \(K_p = 0{,}12\) (oscila), sube \(K_d\) poco a poco. La oscilación muere. Ahora sube \(N\) a \(40\): mira la gráfica de \(u_D\), se llena de ruido del láser.

Experimento 4

La memoria

Vuelve al PID por defecto y repite el experimento 1. La válvula ya no deja error: \(u_I\) sube justo lo que roba la válvula. Duplica \(K_i\): ¿qué pasa con el sobreimpulso?

Experimento 5

Windup

Pon \(r = 400\) y \(u_0 = 30\). El ventilador se satura un rato. Compara la bajada a \(r = 150\) con el antiwindup del firmware y piensa qué pasaría sin él (en el simulador, el gemelo te deja verlo).

Experimento 6

El peso del setpoint

Escalones de \(100\) a \(300\) con \(b = 1\) y con \(b = 0{,}6\). La respuesta a la válvula es igual en los dos casos; la del setpoint, no. ¿Por qué? (Pista: \(b\) no aparece en \(1 + CG\)).

Experimento 7

Relé y reglas de sintonía

Haz el autoajuste con \(h = 8\). Anota \(K_u\) y \(P_u\) y compáralos con el modelo no lineal (\(\approx 0{,}14\) y \(1{,}7\) s) y el lineal (\(0{,}167\) y \(1{,}50\) s). Aplica las tres reglas y mide \(M_p\) y \(t_s\) de cada una.

Experimento 8

Gemelo y cascada

Graba \(30\) s con escalones y ajusta el gemelo. ¿Cuánto cambiaron \(v_0\) y \(\tau\)? Luego pasa a Cascada: compara qué tan parejo queda \(u\) y la respuesta a escalones.

Experimento 9

Seno y rampa

Perfil seno: mide cuánto se atrasa \(y\) respecto a \(r\) y compáralo con la fase de \(T(j\omega)\) en \(\omega = 2\pi/8\). Perfil rampa con \(K_i = 0\) y luego con \(K_i > 0\): ¿cuándo desaparece el error de seguimiento? Piensa en el tipo del sistema.

Experimento 10

Tú contra el PID

Haz el reto dos veces. Mira la gráfica: ¿dónde te pasas? Casi siempre es porque reaccionas tarde: la bola ya va rápido cuando corriges. Eso que tú no ves a tiempo es lo que \(K_d\) mide.

11 Construir · mecánica

Siete piezas impresas en 3D

Todas las piezas salen del modelo paramétrico. Los STL ya vienen acostados sobre la cara plana: los abres en el laminador (Cura, PrusaSlicer, Bambu Studio) y los mandas sin girarlos.

P2 difusor con panal
P2 · Difusor con panal. Embudo, enderezador de flujo, encaje del tubo, puerto de fuga y soporte del servo en una sola pieza.
P1 base con patas
P1 · Base con patas. Rejilla contra dedos y \(30\) mm de aire libre por debajo para que respire el ventilador.
P4 tapa del sensor
P4 · Tapa del sensor. Ventilas en arco, ventana del láser y ranuras M2.
P3 aleta de la válvula
P3 · Aleta de la válvula. Se atornilla al brazo del servo y tapa el puerto de \(18\) mm.
P5 caja de electrónica
P5 · Caja de electrónica. Para placa perforada de \(7\times9\) cm, USB, jack de \(12\) V, interruptor y salida de cables.
P6 tapa de la caja con ventana para la pantalla
P6 · Tapa de la caja. Ventana y cuna para la pantalla de \(1{,}3''\), agujero M7 de la perilla, rejilla y nombre grabado.
P7 abrazadera del tubo con bolsillo para la tira LED
P7 · Abrazadera LED (×4). Entra a presión en el tubo y aprieta la tira WS2812B contra la parte de atrás.
PiezaArchivoMedidas (mm)MaterialAjustesSoportes
P1 Base con patasP1_base_patas.stl\(109\times109\times34\)PLA o PETGcapa 0,2 · 3 perímetros · relleno 25 %No
P2 Difusor con panalP2_difusor_panal.stl\(100\times110\times105\)PETG (mejor) o PLAcapa 0,2 · 3 perímetros · relleno 20 % · boquilla 0,4No (el puerto Ø18 puentea)
P3 Aleta de la válvulaP3_aleta_valvula.stl\(42\times26\times2{,}5\)PLAcapa 0,15 · 100 %No
P4 Tapa del sensorP4_tapa_sensor.stl\(56\times59\times24\)PLA o PETGcapa 0,2 · 3 perímetros · relleno 25 %No
P5 Caja de electrónicaP5_caja_electronica.stl\(105\times85\times40\)PLAcapa 0,2 · 2 perímetros · relleno 15 %Sí, solo en los huecos laterales (o sin, con puentes)
P6 Tapa de la cajaP6_tapa_caja.stl\(105\times85\times5\)PLA (cambia de color en la capa del grabado si quieres el nombre resaltado)capa 0,2 · relleno 20 %No
P7 Abrazadera LEDP7_clip_led_x4.stl (imprime 4)\(55\times52\times12\)PETG (flexa mejor) o PLAcapa 0,2 · 4 perímetros · relleno 30 %No

Antes de imprimir todo, imprime solo los últimos \(10\) mm del encaje de P2 (corta la pieza en el laminador) y prueba que el tubo entre ajustado. Si queda flojo o duro, cambia HOLGURA en levitador_cad.py y vuelve a generar: todos los encajes se mueven juntos.

La lista de compras con precios está en la cotización.

  1. Base

    Pon el ventilador sobre P1 con la etiqueta hacia abajo (sopla hacia arriba: la flecha de flujo del marco apunta al embudo). Encima va P2. Los cuatro M4 × 40 atraviesan las tres piezas.

  2. Válvula

    Mete el SG90 por la ventana de la pared de P2 con el eje mirando hacia la boca del puerto, atorníllalo, llévalo a \(0^\circ\) (comando V 0) y monta la aleta tapando el puerto.

  3. Tubo y tapa

    El tubo entra en el encaje de P2 hasta apoyarse en el borde del panal. Mete la bola. Atornilla el VL53L1X en P4 mirando hacia abajo por la ventana y pon la tapa.

  4. Tira de LED

    Corta \(50\) cm (30 LED) de la cinta por la línea de corte. Ponla detrás del tubo con los LED mirando hacia el tubo y la flecha de datos apuntando hacia arriba (la entrada DIN queda abajo). Mete las cuatro abrazaderas P7 a presión: el bolsillo aprieta la cinta.

  5. Caja, pantalla y perilla

    Pega la pantalla en la cuna de P6 con dos puntos de silicona caliente, vidrio hacia la ventana. La perilla se atornilla con su tuerca M7 por arriba. Arma la placa perforada según la sección 12, atorníllala en los postes de P5 y saca los cables por el agujero lateral.

12 Construir · electrónica

Conexiones

ESP32 DevKit 3V3GNDG21 SDAG22 SCLG13 XSHUT G18 SCKG23 MOSIG16 DCG17 RESG5 BLK G32 ENC AG33 ENC BG4 ENC SW VIN 5VGNDG25 PWM G34 TACHG26 SERVOG27 LED USB VL53L1Xen la tapa, mirando abajo VINGNDSDASCLXSHUT TFT 1,3" SCLSDADCRESBLKVCCGND ST7789240 × 240 3V3 Perilla KY-040 CLKDTSW + a 3V3, GND a tierra 5V Ventilador 80 mm4 hilos, 12 V, PWM GND+12VPWMTACH 12V 1 kΩ 2N2222 3V3 10 kΩ Servo SG90válvula de fuga señal+5VGND 5V Tira WS2812B30 LED (50 cm) detrás del tubo DIN+5VGND 330 Ω 5V 1000 µF entre +5V y GND Jack 12 Vfuente 12 V 2 A KCD1 LM2596 → 5,0 Vajústalo antes de conectar 12V 5V → VIN, servo, tira GND común
Todas las tierras van unidas. El transistor invierte el PWM del ventilador (el firmware lo compensa con FAN_PWM_INVERTIDO). El tacómetro es de colector abierto: la resistencia de \(10\ \text{k}\Omega\) va a \(3{,}3\) V, nunca a \(12\) V. La tira de LED se alimenta del LM2596, no del pin de \(5\) V de la ESP32.
SeñalPin ESP32Va aNota
I2C SDA / SCL21 / 22VL53L1Xcable trenzado si pasa de \(50\) cm; el firmware usa \(400\) kHz
XSHUT13VL53L1Xreinicia el sensor al arrancar
SPI SCK / MOSI18 / 23TFT: SCL / SDAla pantalla no tiene CS: modo SPI 3, \(40\) MHz
DC / RES / BLK16 / 17 / 5TFTBLK en alto enciende la luz de fondo
Perilla A / B / pulsador32 / 33 / 4KY-040: CLK / DT / SWpull-up internos; si salta de a dos pasos cambia ENC_DIV
PWM ventilador25base del 2N2222 por 1 kΩ\(25\) kHz, 10 bits, lógica invertida
Tacómetro34cable verde + 10 kΩ a 3V3dos pulsos por vuelta
Servo26señal del SG90\(50\) Hz, \(1\)–\(2\) ms
Datos LED27DIN de la tira por 330 Ω30 LED, brillo 60/255 por defecto (comando LED)
¿Ventilador de 2 o 3 hilos? También sirve: cambia el 2N2222 por un MOSFET lógico (IRLZ44N) en el negativo del ventilador, con diodo 1N4007 en paralelo al ventilador, y pon FAN_PWM_INVERTIDO = false y FAN_FREQ = 20000. Pierdes el tacómetro, así que el modo Cascada no estará disponible.
13 Construir · firmware

Firmware y protocolo

  1. Instala

    Arduino IDE 2 → Gestor de tarjetas: esp32 de Espressif. Gestor de bibliotecas: VL53L1X (Pololu), Adafruit ST7735 and ST7789, Adafruit GFX y Adafruit NeoPixel. Abre levitador_pid.ino, elige «ESP32 Dev Module» y en Partition Scheme pon «Huge APP (3MB No OTA)»: con Bluetooth el programa no cabe en la partición normal. Con PlatformIO usa el platformio.ini incluido (ya trae todo eso).

  2. Prueba sin la página

    Al encender, la pantalla dice «Levitador PID» y la tira se apaga. Monitor serie a \(115200\): escribe ? y debe responder una línea I {…}. M 1 y luego UM 40 enciende el ventilador al \(40\,\%\). En el celular, una app como nRF Connect debe ver «Levitador-PRI».

  3. Cierra el monitor serie

    Solo un programa puede tener el puerto abierto. Ciérralo antes de pulsar «Conectar ESP32» en esta página.

ComandoQué haceEjemplo
M nModo: 0 apagado, 1 manual, 2 PID, 3 cascada, 4 relé, 5 retoM 2
R mmSetpoint de altura (\(20\) a \(420\))R 250
P nPerfil: 0 fijo, 1 escalones, 2 seno, 3 rampaP 2
G kp ki kdGanancias del PIDG 0.08 0.04 0.03
B b · N nPeso del setpoint · filtro de la derivadaB 0.6
U0 % · UM %PWM de flotación · PWM manualU0 48
V %Apertura de la válvula de fugaV 100
TUNE hAutoajuste por relé con amplitud \(h\)TUNE 12
CI kp ki · RPM nLazo interno de velocidad · rpm con \(100\,\%\)CI 0.01 0.05
LED nBrillo de la tira (\(0\) a \(255\))LED 120
CAL · SAVE · ?Calibrar \(d_0\) · guardar en memoria · pedir parámetrosCAL

La ESP32 responde con una línea por mensaje. La telemetría sale \(50\) veces por segundo:

D,ms,y,r,u,rpm,uP,uI,uD,valvula,modo,perfil
D,48210,201.4,200.0,47.83,1490,0.42,-0.31,0.12,0,2,0

Por Bluetooth es el mismo texto, en el servicio UART de Nordic (6E400001-…), a \(25\) datos por segundo. Las líneas I {…} traen los parámetros, A {…} el resultado del relé y RETO {…} tu puntaje. Esta página lee exactamente eso; el simulador del navegador habla el mismo protocolo, así que lo que pruebas sin hardware funciona igual con hardware.

14 Cotización

Cuánto cuesta, pieza por pieza

Precios con IVA consultados el 27 de octubre de 2026 en tiendas de Bogotá. «Verificado» quiere decir que el precio salió de la página del producto ese día; «estimado» es un rango típico que conviene confirmar antes de comprar.

Electrónica$ 240.675ESP32, sensor, pantalla, LED, ventilador, fuente
Mecánica$ 67.000tubo, bolas, tornillos, tabla
Impresión 3D$ 28.733306 g de PLA con impresora propia
Total$ 336.408$ 445.375 si mandas a imprimir
ComponenteCant.UnitarioSubtotalDónde
Electrónica
ESP32 DevKit 30 pines CP2102 (micro USB)1$ 38.500$ 38.500Electronilab
verificado
Sensor láser VL53L1X (4 m, I2C, XSHUT)1$ 31.900$ 31.900Electronilab
verificado
Pantalla TFT IPS 1,3" 240×240 ST7789 (7 pines)1$ 27.965$ 27.965JA-Bots (23.500 + IVA)
verificado
Encoder rotativo KY-040 con pulsador1$ 6.950$ 6.950Electronilab
verificado
Servo SG901$ 11.000$ 11.000Ferretrónica
verificado
Reductor LM2596 (3 A)1$ 6.900$ 6.900Electronilab
verificado
Cinta WS2812B 60 LED/m IP65, 1 m (se usan 50 cm)1$ 42.900$ 42.900Electronilab
verificado agotado hoy
Ventilador 80×80×25 mm 12 V, 4 pines PWM con tacómetro1$ 35.000$ 35.000MercadoLibre / tiendas de PC
estimado
Fuente 12 V 2 A, plug 2,1 mm1$ 17.900$ 17.900Electronilab
verificado agotado hoy
Jack hembra 2,1 mm1$ 440$ 440Electronilab
verificado agotado hoy
Interruptor basculante KCD11$ 4.500$ 4.500Electronilab
verificado
Transistor 2N22222$ 110$ 220Electronilab
verificado
Placa universal FR-4 7 × 9 cm1$ 4.500$ 4.500Electronilab
verificado
Resistencias, condensador 1000 µF, borneras, headers y cable1$ 12.000$ 12.000cualquier tienda
estimado
Mecánica
Tubo de acrílico Ø50 × Ø44 mm, 50 cm1$ 45.000$ 45.000acrílicos / MercadoLibre
estimado
Bolas de ping-pong 40 mm (paquete)1$ 8.000$ 8.000papelería / deportes
estimado
Tornillería M4×40, M3×10, M2×8 y tuercas1$ 6.000$ 6.000ferretería
estimado
Tabla MDF 200 × 300 mm (opcional)1$ 8.000$ 8.000ferretería
estimado
Impresión 3D
Filamento PLA, 306 g (impresora propia; rollo ELEGOO de 1 kg a $ 93.900)1$ 28.733$ 28.733Electronilab
verificado
Alternativa: mandar a imprimir (306 g × $ 450/g)1$ 137.700$ 137.700servicios en Bogotá
referencia
Electrónica$ 240.675
Mecánica$ 67.000
Total con impresora propia$ 336.408
Total mandando a imprimir$ 445.375
Pieza impresaPLA aprox.
P1 Base con patas29 g
P2 Difusor con panal125 g
P3 Aleta2 g
P4 Tapa del sensor19 g
P5 Caja66 g
P6 Tapa de la caja22 g
P7 Abrazaderas LED ×420 g
Total con purga y bordes (+8 %)306 g

Para que salga más barato

  • Electronilab manda gratis los pedidos web de más de $ 300.000: con esta lista casi llegas; pide todo junto.
  • Si alguien del grupo tiene impresora, la impresión baja de unos $ 138 mil a unos $ 29 mil.
  • Un ventilador de 4 pines usado de un PC viejo funciona igual. Revisa que diga PWM y que tenga 4 cables.
  • Los servicios de impresión cotizan distinto: unos por gramo (referencia $ 450/g) y otros por tiempo de máquina. Manda los STL y pide precio con PLA al 20 %.

La hoja con todos los precios y enlaces está en cotizacion/cotizacion_levitador.csv (se abre en Excel). Fuentes: páginas de producto de Electronilab, Ferretrónica y JA-Bots; tarifas de impresión de Kojak Graphic (desde $ 90/g más tiempo de máquina) y un anuncio de MercadoLibre a $ 450/g en Bogotá.

15 Puesta en marcha

Del primer encendido a la bola flotando, en orden

  • LM2596 a 5,0 V con el multímetro, sin nada conectado a la salida.
  • Ventilador solo: modo Manual, sube el PWM. A \(0\,\%\) debe estar quieto (o al mínimo), a \(100\,\%\) a tope. Si va al revés, cambia FAN_PWM_INVERTIDO.
  • Calibrar: modo Apagado, bola en reposo sobre el panal, botón «Calibrar \(d_0\)». La altura debe leer \(\approx 0\).
  • Encontrar \(u_0\): modo Manual, sube despacio hasta que la bola flote y suba muy lento. Ese número es \(u_0\): pásalo al deslizador \(u_0\).
  • Primer lazo: modo PID con las ganancias por defecto, \(r = 200\). Si oscila, baja \(K_p\) a la mitad.
  • Autoajuste: «Iniciar prueba» con \(h = 8\) y el setpoint a media altura (\(r \approx 220\)). Aplica la regla «Sin sobreimpulso» y luego afina.
  • Pantalla y perilla: gira la perilla y mira el campo de abajo en la pantalla; clic pasa al siguiente campo (setpoint, modo, perfil, ganancias, válvula); pulsación larga arranca o para el PID.
  • Guardar: «Guardar en la ESP32». La próxima vez arranca con esas ganancias.
  • Si la bola gira o golpea la pared: revisa que el tubo esté vertical y que el panal no tenga hilos de plástico. Una bola con una línea de marcador te deja ver si gira.
16 Archivos del proyecto

Descargas

ArchivoQué esEstado
stl/P1…P7_*.stlLas siete piezas para imprimir, ya orientadas en la cama (P7 se imprime cuatro veces).Mallas cerradas, un cuerpo
step/levitador_ensamble.stepEnsamble con 24 componentes con nombre y color. En Fusion 360: Archivo → Abrir, o el script.Generado del modelo
step/*.stepUn STEP por pieza (impresas P y compradas C).Generado del modelo
fusion360/Levitador_PID/Script de Fusion: importa el ensamble, crea parámetros de usuario y juntas para animar bola, hélice y válvula.Sin ejecutar en Fusion
cad/levitador_cad.pyCódigo paramétrico (CadQuery) del que sale todo lo anterior.Funciona
firmware/levitador_pid/Firmware de la ESP32 (Arduino y PlatformIO): lazo, pantalla, perilla, LED y Bluetooth.Revisado, sin compilar en placa
modelo/modelo_levitador.pyModelo, Routh, PID, márgenes, simulación no lineal y relé con python-control.Probado
render/Renders del ensamble y el video de funcionamiento.Generado
diagramas/Diagrama de bloques y de conexiones (SVG y PNG).Generado
cotizacion/cotizacion_levitador.csvLista de compras con precios, tiendas y enlaces.27 oct 2026
Render de funcionamiento: la bola sigue una secuencia de setpoints con el PID por defecto y a los \(11\) s se abre la válvula.

Levitador PID · Programa PRI · Control 2026-2 · El modelo, el CAD, el firmware y esta página salen del mismo juego de parámetros.