Proyecto 1: Comunicación Bi-direccional ESP32 - Computador
Proyecto elaborado por Mauricio Zuñiga, Javier Arredondo y Jeremías Carrasco de la Universidad de Viña del Mar en abril 2026.
Introducción
Este proyecto consiste en establecer una comunicación bi-direccional entre una placa ESP32 y un computador a través del puerto serial (USB). El objetivo es que un evento físico en el ESP32 (presionar un botón) dispare una acción en el computador, y que el computador pueda a su vez responder con una señal que el ESP32 traduce en una acción física (encender un LED).
En nuestra implementación, al presionar el botón el ESP32 avisa al computador por serial; la aplicación puente en el computador baja el brillo de la pantalla y, una vez hecho esto, le indica al ESP32 que encienda el LED como confirmación visual de que la acción se ejecutó correctamente.
Aprendizajes
-
Instalación y configuración del IDE y el SDK de ESP32.
-
Circuitos básicos de entrada (botón con pull-up) y salida (LED con resistencia limitadora).
-
Comunicación serial bi-direccional (UART sobre USB) entre un microcontrolador y un computador.
-
Lectura de botones con debounce para evitar falsos disparos.
-
Automatización de tareas del sistema operativo (control de brillo) desde una aplicación externa.
Descripción del Funcionamiento
-
El usuario presiona el botón conectado al ESP32.
-
El ESP32 detecta el flanco de bajada (con debounce) y envía el mensaje
BTN_PRESSpor el puerto serial. -
La aplicación puente, corriendo en el computador y escuchando ese puerto serial, recibe el mensaje y ejecuta la acción correspondiente: bajar el brillo de la pantalla.
-
La aplicación puente responde al ESP32 con el mensaje
LED_ON. -
El ESP32 recibe el mensaje y enciende el LED, confirmando visualmente que el ciclo se completó.
El protocolo es de mensajes de una línea terminados en \n
(BTN_PRESS, LED_ON, LED_OFF), a 115200 baudios. Esto permite
extender fácilmente el sistema a otras acciones sin cambiar la lógica
base.
|
Lista de Componentes
| Componente | Descripción | Cantidad |
|---|---|---|
ESP32 (DevKit) |
Microcontrolador encargado de leer el botón y controlar el LED, comunicado con el computador por USB. |
1 |
LED |
Indicador visual que se enciende cuando el computador confirma la acción (brillo bajado). |
1 |
Botón pulsador |
Genera el evento que dispara la comunicación hacia el computador. |
1 |
Resistencia limitadora (~220-330 Ω) |
Protege al LED de una corriente excesiva desde el GPIO. |
1 |
Protoboard |
Soporte para armar el circuito del botón y el LED. |
1 |
Cables dupont |
Conexiones entre el ESP32, el botón y el LED. |
Varios |
Cable USB |
Conexión física y alimentación entre el ESP32 y el computador; por este mismo cable viaja la comunicación serial. |
1 |
Esquemático y Tabla de Conexión
| Función | GPIO ESP32 | Descripción |
|---|---|---|
Botón pulsador |
GPIO 4 |
Entrada digital ( |
LED indicador |
GPIO 2 |
Salida digital. Ánodo al GPIO a través de la resistencia limitadora, cátodo a GND. |
Al usar INPUT_PULLUP en el botón no se necesita resistencia
externa para esa entrada; el pull-up interno del ESP32 mantiene el pin
en HIGH hasta que el botón lo conecta a GND.
|
Código
Firmware del ESP32
Sketch completo (proyecto1_esp32.ino) que implementa la lectura del
botón con debounce y el control del LED según los comandos recibidos
por serial.
Aplicación Puente (Computador)
Aplicación puente (proyecto1_puente.py) desarrollada en Python para
Windows. Escucha el puerto serial del ESP32; al recibir BTN_PRESS
alterna el brillo de la pantalla entre normal y bajo usando la
librería screen-brightness-control, y responde al ESP32 con
LED_ON o LED_OFF según corresponda.
Dependencias (instalar antes de ejecutar):
pip install pyserial screen-brightness-control
Antes de ejecutar, ajustar la constante PUERTO al puerto COM
real donde el sistema operativo reconoce al ESP32 (visible en el
Administrador de dispositivos de Windows).
|
Posibles Usos en la Industria
-
Indicadores físicos de estado en estaciones de trabajo (por ejemplo, un LED que señala "modo no molestar" o "grabando" activado desde software).
-
Automatización de oficina: gatillar acciones sobre luces o dispositivos físicos a partir de eventos del computador.
-
Interfaces físicas de accesibilidad: botones grandes que ejecutan funciones del sistema operativo para usuarios con movilidad reducida.
-
Confirmación visual en paneles de control industrial: un LED que confirma que el sistema recibió y procesó una orden.
-
Prototipado rápido de sistemas IoT/domótica que combinan hardware simple con lógica en el computador o en la nube.
Código del proyecto
/*
Proyecto 1: Comunicación bi-direccional ESP32 <-> Computador
---------------------------------------------------------------
Flujo:
1. El usuario presiona el botón conectado al ESP32.
2. El ESP32 envía "BTN_PRESS" por el puerto serial (USB).
3. La aplicación puente en el computador recibe el aviso, baja
el brillo de la pantalla y responde con "LED_ON".
4. El ESP32 enciende el LED al recibir "LED_ON".
5. Un segundo click vuelve todo a su estado normal: el puente
sube el brillo de nuevo y envía "LED_OFF".
Protocolo serial (115200 baudios, mensajes de una línea, '\n' al final):
ESP32 -> PC : "BTN_PRESS"
PC -> ESP32 : "LED_ON" | "LED_OFF"
*/
const int PIN_BOTON = 4; // Botón entre GPIO4 y GND (usa pull-up interno)
const int PIN_LED = 2; // LED + resistencia limitadora (~220-330 ohm) a GND
const unsigned long DEBOUNCE_MS = 50;
int estadoBotonAnterior = HIGH;
unsigned long ultimoCambio = 0;
String bufferSerial = "";
void setup() {
Serial.begin(115200);
pinMode(PIN_BOTON, INPUT_PULLUP);
pinMode(PIN_LED, OUTPUT);
digitalWrite(PIN_LED, LOW);
}
void loop() {
leerBoton();
leerSerial();
}
// Detecta el flanco de bajada del botón (con debounce por tiempo)
// y avisa al computador.
void leerBoton() {
int lectura = digitalRead(PIN_BOTON);
if (lectura != estadoBotonAnterior) {
ultimoCambio = millis();
}
if ((millis() - ultimoCambio) > DEBOUNCE_MS) {
if (lectura == LOW && estadoBotonAnterior == HIGH) {
Serial.println("BTN_PRESS");
}
}
estadoBotonAnterior = lectura;
}
// Arma línea por línea lo que llega desde el computador y ejecuta
// el comando correspondiente sobre el LED.
void leerSerial() {
while (Serial.available() > 0) {
char c = Serial.read();
if (c == '\n') {
bufferSerial.trim();
if (bufferSerial == "LED_ON") {
digitalWrite(PIN_LED, HIGH);
} else if (bufferSerial == "LED_OFF") {
digitalWrite(PIN_LED, LOW);
}
bufferSerial = "";
} else if (c != '\r') {
bufferSerial += c;
}
}
}