Introducción al Programa Blink
El programa Blink es el equivalente al famoso "¡Hola, Mundo!" en el mundo de los microcontroladores y la mecatrónica. Es tradicionalmente el primer programa que todo ingeniero escribe cuando aprende a programar un microcontrolador, ya que demuestra los conceptos fundamentales de programación embebida.
¿Por qué empezar con Blink?
Este programa simple pero fundamental te enseña:
- Configuración de pines GPIO - Control de entradas y salidas digitales
- Control de tiempo - Uso de delays y temporizadores
- Estructura básica - Setup() y loop() en Arduino
- Debugging visual - Feedback inmediato del sistema
Preparación del Hardware
Para realizar este proyecto necesitarás los siguientes componentes básicos. Vamos a utilizar el LED integrado del ESP32 para simplicidad, pero también aprenderemos a conectar LEDs externos.
Lista de Materiales
- ESP32 DevKit v1 - Placa de desarrollo
- Cable USB - Para programación y alimentación
- LED (opcional) - Para conexión externa
- Resistencia 220Ω (opcional) - Limitación de corriente
- Protoboard (opcional) - Para montaje
Pines GPIO del ESP32
GPIO 2
LED integrado azul - Ideal para comenzarGPIO 4, 16, 17
Pines de salida seguros para LEDs externosGND
Tierra - Conexión negativa3.3V
Alimentación positiva (3.3 voltios)Diagrama de Conexión (LED Externo)
ESP32
GPIO 2
GND
Resistencia 220Ω
LED
Ánodo (+)
Cátodo (-)
Código Básico: Blink Simple
Comencemos con el código más básico para hacer parpadear el LED integrado del ESP32. Este programa demuestra la estructura fundamental de cualquier sketch de Arduino.
/*
Programa Blink Básico para ESP32
Hace parpadear el LED integrado cada segundo
Hardware: ESP32 DevKit v1
Pin usado: GPIO 2 (LED integrado azul)
Autor: Curso Mecatrónica UNAM
*/
// Definir el pin del LED (LED integrado en GPIO 2)
#define LED_PIN 2
// Función setup() - Se ejecuta una sola vez al iniciar
void setup() {
// Inicializar comunicación serie para debug
Serial.begin(115200);
// Configurar el pin del LED como SALIDA
pinMode(LED_PIN, OUTPUT);
// Mensaje de inicio
Serial.println("=== Programa Blink ESP32 Iniciado ===");
Serial.println("LED integrado parpadeando cada 1 segundo");
}
// Función loop() - Se ejecuta continuamente
void loop() {
// ENCENDER el LED (nivel alto = HIGH)
digitalWrite(LED_PIN, HIGH);
Serial.println("LED ENCENDIDO");
// Esperar 1000 milisegundos (1 segundo)
delay(1000);
// APAGAR el LED (nivel bajo = LOW)
digitalWrite(LED_PIN, LOW);
Serial.println("LED APAGADO");
// Esperar 1000 milisegundos (1 segundo)
delay(1000);
}
Código Avanzado: Blink Mejorado
Ahora vamos a crear una versión más avanzada que incluye control de múltiples LEDs, patrones de parpadeo, y conceptos más avanzados que son útiles en aplicaciones mecatrónicas reales.
/*
Programa Blink Avanzado para ESP32 - Aplicación Mecatrónica
Sistema de señalización con múltiples LEDs y patrones
Características:
- Control de múltiples LEDs
- Patrones de parpadeo personalizados
- Indicadores de estado del sistema
- Comunicación serie con comandos
- Control de frecuencia de parpadeo
*/
#include
// Definición de pines para diferentes LEDs
#define LED_BUILT_IN 2 // LED integrado azul
#define LED_STATUS 4 // LED de estado (verde)
#define LED_ERROR 16 // LED de error (rojo)
#define LED_ACTIVITY 17 // LED de actividad (amarillo)
// Variables de control de tiempo (sin usar delay)
unsigned long previousMillis = 0;
unsigned long statusMillis = 0;
unsigned long activityMillis = 0;
// Configuración de intervalos de parpadeo
const long blinkInterval = 500; // Intervalo principal (ms)
const long statusInterval = 2000; // Intervalo de estado (ms)
const long activityInterval = 100; // Intervalo de actividad (ms)
// Estados de los LEDs
bool ledState = false;
bool statusLedState = false;
bool activityLedState = false;
bool systemError = false;
// Contador de parpadeos para estadísticas
int blinkCount = 0;
int systemUptime = 0;
// Patrón de parpadeo personalizado
int blinkPattern[] = {200, 200, 500, 200, 200, 1000}; // ON, OFF, ON, OFF, ON, OFF
int patternSize = sizeof(blinkPattern) / sizeof(blinkPattern[0]);
int patternIndex = 0;
bool useCustomPattern = false;
void setup() {
// Inicializar comunicación serie
Serial.begin(115200);
delay(1000);
// Configurar todos los pines como salida
pinMode(LED_BUILT_IN, OUTPUT);
pinMode(LED_STATUS, OUTPUT);
pinMode(LED_ERROR, OUTPUT);
pinMode(LED_ACTIVITY, OUTPUT);
// Estado inicial de los LEDs
digitalWrite(LED_BUILT_IN, LOW);
digitalWrite(LED_STATUS, LOW);
digitalWrite(LED_ERROR, LOW);
digitalWrite(LED_ACTIVITY, LOW);
// Mensaje de inicio del sistema
Serial.println("\n=== Sistema Blink Avanzado ESP32 ===");
Serial.printf("Chip: %s\n", ESP.getChipModel());
Serial.printf("Núcleos: %d\n", ESP.getChipCores());
Serial.printf("Frecuencia CPU: %d MHz\n", ESP.getCpuFreqMHz());
Serial.println("\nComandos disponibles:");
Serial.println(" 'status' - Ver estado del sistema");
Serial.println(" 'pattern' - Alternar patrón personalizado");
Serial.println(" 'error' - Simular error del sistema");
Serial.println(" 'reset' - Reiniciar contador");
Serial.println(" 'fast' - Parpadeo rápido");
Serial.println(" 'slow' - Parpadeo lento");
Serial.println("\nSistema iniciado correctamente.");
// Secuencia de inicio - Test de LEDs
testLEDSequence();
}
void loop() {
// Obtener tiempo actual
unsigned long currentMillis = millis();
// Control del LED principal sin usar delay()
if (useCustomPattern) {
handleCustomPattern(currentMillis);
} else {
handleBasicBlink(currentMillis);
}
// Control del LED de estado (parpadeo lento)
handleStatusLED(currentMillis);
// Control del LED de actividad (parpadeo rápido)
handleActivityLED(currentMillis);
// Control del LED de error
handleErrorLED();
// Procesar comandos desde Serial
handleSerialCommands();
// Actualizar estadísticas del sistema
updateSystemStats(currentMillis);
// Pequeña pausa para optimización
delay(10);
}
void handleBasicBlink(unsigned long currentMillis) {
if (currentMillis - previousMillis >= blinkInterval) {
previousMillis = currentMillis;
// Cambiar estado del LED
ledState = !ledState;
digitalWrite(LED_BUILT_IN, ledState);
// Incrementar contador
if (ledState) {
blinkCount++;
}
}
}
void handleCustomPattern(unsigned long currentMillis) {
if (currentMillis - previousMillis >= blinkPattern[patternIndex]) {
previousMillis = currentMillis;
// Alternar LED en índices pares (ON) e impares (OFF)
bool shouldBeOn = (patternIndex % 2 == 0);
digitalWrite(LED_BUILT_IN, shouldBeOn);
if (shouldBeOn) {
blinkCount++;
}
// Avanzar al siguiente paso del patrón
patternIndex = (patternIndex + 1) % patternSize;
}
}
void handleStatusLED(unsigned long currentMillis) {
if (currentMillis - statusMillis >= statusInterval) {
statusMillis = currentMillis;
statusLedState = !statusLedState;
digitalWrite(LED_STATUS, statusLedState);
}
}
void handleActivityLED(unsigned long currentMillis) {
if (currentMillis - activityMillis >= activityInterval) {
activityMillis = currentMillis;
activityLedState = !activityLedState;
digitalWrite(LED_ACTIVITY, activityLedState);
}
}
void handleErrorLED() {
// LED de error: ON constante si hay error, OFF si no
digitalWrite(LED_ERROR, systemError ? HIGH : LOW);
}
void handleSerialCommands() {
if (Serial.available() > 0) {
String command = Serial.readString();
command.trim();
command.toLowerCase();
if (command == "status") {
printSystemStatus();
}
else if (command == "pattern") {
useCustomPattern = !useCustomPattern;
patternIndex = 0;
Serial.printf("Patrón personalizado: %s\n",
useCustomPattern ? "ACTIVADO" : "DESACTIVADO");
}
else if (command == "error") {
systemError = !systemError;
Serial.printf("Estado de error: %s\n",
systemError ? "ACTIVADO" : "DESACTIVADO");
}
else if (command == "reset") {
blinkCount = 0;
systemUptime = 0;
Serial.println("Contador reiniciado.");
}
else if (command == "fast") {
// No implementado en esta versión básica
Serial.println("Modo rápido activado");
}
else if (command == "slow") {
// No implementado en esta versión básica
Serial.println("Modo lento activado");
}
else {
Serial.printf("Comando desconocido: %s\n", command.c_str());
}
}
}
void printSystemStatus() {
Serial.println("\n=== ESTADO DEL SISTEMA ===");
Serial.printf("Uptime: %d segundos\n", systemUptime);
Serial.printf("Parpadeos totales: %d\n", blinkCount);
Serial.printf("Memoria libre: %d bytes\n", ESP.getFreeHeap());
Serial.printf("Patrón personalizado: %s\n",
useCustomPattern ? "ACTIVO" : "INACTIVO");
Serial.printf("Estado de error: %s\n",
systemError ? "ERROR" : "OK");
Serial.printf("Temperatura CPU: %.1f°C\n", temperatureRead());
Serial.println("========================\n");
}
void updateSystemStats(unsigned long currentMillis) {
static unsigned long lastSecond = 0;
if (currentMillis - lastSecond >= 1000) {
lastSecond = currentMillis;
systemUptime++;
// Mostrar estadísticas cada 30 segundos
if (systemUptime % 30 == 0) {
Serial.printf("Sistema funcionando: %d seg, %d parpadeos\n",
systemUptime, blinkCount);
}
}
}
void testLEDSequence() {
Serial.println("Iniciando test de LEDs...");
// Encender LEDs secuencialmente
digitalWrite(LED_BUILT_IN, HIGH);
delay(200);
digitalWrite(LED_STATUS, HIGH);
delay(200);
digitalWrite(LED_ERROR, HIGH);
delay(200);
digitalWrite(LED_ACTIVITY, HIGH);
delay(500);
// Apagar todos los LEDs
digitalWrite(LED_BUILT_IN, LOW);
digitalWrite(LED_STATUS, LOW);
digitalWrite(LED_ERROR, LOW);
digitalWrite(LED_ACTIVITY, LOW);
Serial.println("Test de LEDs completado.");
delay(500);
}
Ejercicios Prácticos
Objetivo: Programar el ESP32 para hacer parpadear el LED integrado cada segundo.
Pasos:
- Conectar ESP32 al PC
- Abrir Arduino IDE
- Copiar el código básico
- Subir el programa
- Verificar funcionamiento
Resultado: LED azul parpadeando cada segundo
Objetivo: Conectar un LED externo y controlarlo con diferentes velocidades.
Componentes: LED, resistencia 220Ω, cables, protoboard
Conceptos: Ley de Ohm, limitación de corriente, GPIO
Modificación: Cambiar tiempos de delay para diferentes efectos
Objetivo: Implementar el sistema avanzado con múltiples LEDs y control serial.
Funcionalidades:
- 4 LEDs con diferentes patrones
- Control por comandos serie
- Monitoreo de estadísticas
- Simulación de estados de error
Guía Paso a Paso: Tu Primer Programa
Sigue estos pasos detallados para cargar y ejecutar tu primer programa Blink en el ESP32:
Preparar el Entorno de Desarrollo
- Asegúrate de tener Arduino IDE instalado
- Instala el soporte para ESP32 (Gestor de Tarjetas)
- Selecciona la tarjeta "ESP32 Dev Module"
- Verifica el puerto COM correcto
Conectar el Hardware
- Conecta el ESP32 al PC usando cable USB
- Verifica que el LED azul integrado esté visible
- Opcionalmente conecta LED externo con resistencia
- Confirma la alimentación (LED rojo encendido)
Escribir y Cargar el Código
- Abre un nuevo sketch en Arduino IDE
- Copia el código básico de Blink
- Verifica la sintaxis (Ctrl+R)
- Sube el programa al ESP32 (Ctrl+U)
Verificar y Probar
- Abre el Monitor Serie (115200 baudios)
- Observa los mensajes de debug
- Confirma que el LED parpadea correctamente
- Experimenta modificando los delays
Aplicaciones del Blink en Mecatrónica
Más Allá del Parpadeo Simple
Aunque el programa Blink parece simple, las técnicas que aprendes son fundamentales en aplicaciones mecatrónicas reales:
Indicadores de Estado:
- Señalización de maquinaria
- Indicadores de vida del sistema
- Alertas y advertencias
Control Temporal:
- Secuencias de operación
- Sincronización de procesos
- Temporizadores precisos