Sistemas Embebidos - Arduino y Automatización Industrial
🎯 ¿Qué son los Sistemas Embebidos?
Un sistema embebido es una computadora especializada diseñada para realizar una tarea específica dentro de un sistema más grande. A diferencia de una PC que puede hacer mil cosas, un sistema embebido hace una cosa muy bien.
Ejemplos cotidianos:
- Microondas: Controla tiempo, potencia y temperatura
- Lavarropas: Gestiona ciclos de lavado, temperatura del agua, centrifugado
- Auto: Control de motor, ABS, airbags, climatización
- Celular: Aunque parece una PC, tiene decenas de sistemas embebidos internos
En la industria:
- PLCs (Controladores Lógicos Programables)
- Controladores de motores
- Sistemas de monitoreo
- Instrumentación y medición
- Robots industriales
🔧 Arduino: Tu primer sistema embebido
Arduino es una plataforma de hardware y software libre perfecta para aprender sistemas embebidos. Es como el “Hola Mundo” del hardware.
¿Por qué Arduino?
✅ Fácil de programar: Usa un lenguaje basado en C/C++ ✅ Económico: Mucho más barato que equipos industriales ✅ Gran comunidad: Miles de proyectos y tutoriales ✅ Escalable: De prototipos a aplicaciones reales ✅ Compatible: Con sensores, actuadores y módulos industriales
Modelos principales:
| Modelo | Características | Uso ideal |
|---|---|---|
| Arduino UNO | 14 I/O digitales, 6 analógicos | Aprendizaje, proyectos básicos |
| Arduino Mega | 54 I/O digitales, 16 analógicos | Proyectos complejos |
| Arduino Nano | Compacto, 14 I/O digitales | Proyectos embebidos finales |
| ESP32 | WiFi + Bluetooth integrado | IoT, control remoto |
💻 Programación de Arduino
Estructura básica
Todo programa de Arduino tiene dos funciones principales:
void setup() {
// Se ejecuta UNA VEZ al inicio
// Configuración de pines, inicialización
}
void loop() {
// Se ejecuta INFINITAMENTE
// Lógica principal del programa
}
Ejemplo 1: Blink (el “Hola Mundo” del hardware)
// Definir el pin del LED
const int LED_PIN = 13;
void setup() {
// Configurar el pin como salida
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, HIGH); // Encender LED
delay(1000); // Esperar 1 segundo
digitalWrite(LED_PIN, LOW); // Apagar LED
delay(1000); // Esperar 1 segundo
}
¿Qué hace? Hace parpadear un LED cada segundo.
Ejemplo 2: Lectura de sensor analógico
const int SENSOR_PIN = A0; // Pin analógico
const int LED_PIN = 13;
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600); // Iniciar comunicación serial
}
void loop() {
// Leer valor del sensor (0-1023)
int valorSensor = analogRead(SENSOR_PIN);
// Convertir a voltaje (0-5V)
float voltaje = valorSensor * (5.0 / 1023.0);
// Mostrar en monitor serial
Serial.print("Valor: ");
Serial.print(valorSensor);
Serial.print(" | Voltaje: ");
Serial.print(voltaje);
Serial.println(" V");
// Encender LED si el valor supera un umbral
if (valorSensor > 512) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
delay(500); // Leer cada medio segundo
}
🌡️ Sensores: Los ojos del sistema
Los sensores convierten magnitudes físicas en señales eléctricas que el microcontrolador puede leer.
Sensores digitales
Salida: HIGH (1) o LOW (0)
1. Sensor de proximidad (HC-SR04 - Ultrasónico)
const int TRIG_PIN = 9;
const int ECHO_PIN = 10;
void setup() {
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
Serial.begin(9600);
}
void loop() {
// Enviar pulso
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Leer tiempo de respuesta
long duracion = pulseIn(ECHO_PIN, HIGH);
// Calcular distancia en cm
float distancia = duracion * 0.034 / 2;
Serial.print("Distancia: ");
Serial.print(distancia);
Serial.println(" cm");
delay(500);
}
Aplicación industrial: Medición de nivel en tanques, detección de objetos en cintas transportadoras.
2. Sensor de temperatura y humedad (DHT22)
#include <DHT.h>
#define DHT_PIN 2
#define DHT_TYPE DHT22
DHT dht(DHT_PIN, DHT_TYPE);
void setup() {
Serial.begin(9600);
dht.begin();
}
void loop() {
// Leer humedad y temperatura
float humedad = dht.readHumidity();
float temperatura = dht.readTemperature();
// Verificar si la lectura es válida
if (isnan(humedad) || isnan(temperatura)) {
Serial.println("Error al leer el sensor!");
return;
}
Serial.print("Temperatura: ");
Serial.print(temperatura);
Serial.print(" °C | Humedad: ");
Serial.print(humedad);
Serial.println(" %");
delay(2000); // DHT22 requiere mínimo 2 segundos entre lecturas
}
Aplicación industrial: Control de clima en invernaderos, cámaras frigoríficas, procesos químicos.
Sensores analógicos
Salida: Valor variable (0-1023 en Arduino)
3. Sensor de temperatura (LM35)
const int LM35_PIN = A0;
void setup() {
Serial.begin(9600);
}
void loop() {
// Leer valor analógico
int lectura = analogRead(LM35_PIN);
// Convertir a voltaje (5V = 1023)
float voltaje = lectura * (5.0 / 1023.0);
// Convertir a temperatura (LM35: 10mV/°C)
float temperatura = voltaje * 100.0;
Serial.print("Temperatura: ");
Serial.print(temperatura);
Serial.println(" °C");
delay(1000);
}
4. Sensor de luz (LDR - Fotoresistor)
const int LDR_PIN = A0;
const int LED_PIN = 13;
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
}
void loop() {
int valorLuz = analogRead(LDR_PIN);
Serial.print("Nivel de luz: ");
Serial.println(valorLuz);
// Encender LED automáticamente cuando oscurece
if (valorLuz < 300) { // Umbral de oscuridad
digitalWrite(LED_PIN, HIGH);
Serial.println("LED encendido (oscuro)");
} else {
digitalWrite(LED_PIN, LOW);
Serial.println("LED apagado (claro)");
}
delay(500);
}
Aplicación industrial: Iluminación automática, control de persianas, optimización de paneles solares.
⚙️ Actuadores: Los músculos del sistema
Los actuadores convierten señales eléctricas en acciones físicas.
1. Motor DC con control de velocidad (PWM)
const int MOTOR_PIN = 9; // Pin PWM
const int POT_PIN = A0; // Potenciómetro para control
void setup() {
pinMode(MOTOR_PIN, OUTPUT);
Serial.begin(9600);
}
void loop() {
// Leer potenciómetro (0-1023)
int valorPot = analogRead(POT_PIN);
// Mapear a velocidad PWM (0-255)
int velocidad = map(valorPot, 0, 1023, 0, 255);
// Controlar motor
analogWrite(MOTOR_PIN, velocidad);
Serial.print("Velocidad: ");
Serial.print((velocidad * 100) / 255);
Serial.println(" %");
delay(100);
}
PWM (Pulse Width Modulation): Técnica para controlar la potencia promedio variando el ancho del pulso.
2. Servo motor (control de posición)
#include <Servo.h>
Servo miServo;
const int SERVO_PIN = 9;
const int POT_PIN = A0;
void setup() {
miServo.attach(SERVO_PIN);
Serial.begin(9600);
}
void loop() {
int valorPot = analogRead(POT_PIN);
// Mapear a ángulo (0-180 grados)
int angulo = map(valorPot, 0, 1023, 0, 180);
miServo.write(angulo);
Serial.print("Ángulo: ");
Serial.print(angulo);
Serial.println(" °");
delay(15); // Pequeño delay para estabilidad
}
Aplicación industrial: Válvulas, brazos robóticos, posicionamiento de cámaras.
3. Relé (control de cargas AC)
const int RELE_PIN = 7;
const int BOTON_PIN = 2;
bool estadoRele = false;
bool estadoBotonAnterior = LOW;
void setup() {
pinMode(RELE_PIN, OUTPUT);
pinMode(BOTON_PIN, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
bool estadoBoton = digitalRead(BOTON_PIN);
// Detectar flanco descendente (botón presionado)
if (estadoBoton == LOW && estadoBotonAnterior == HIGH) {
estadoRele = !estadoRele; // Cambiar estado
digitalWrite(RELE_PIN, estadoRele);
Serial.print("Relé: ");
Serial.println(estadoRele ? "ENCENDIDO" : "APAGADO");
delay(50); // Debounce
}
estadoBotonAnterior = estadoBoton;
}
Aplicación industrial: Control de bombas, motores AC, calefacción, iluminación.
🏭 Proyecto Integrador: Sistema de Control de Temperatura
Vamos a crear un sistema completo que controla la temperatura de un proceso industrial.
Componentes:
- Arduino UNO
- Sensor de temperatura LM35
- Relé para controlar calefactor
- LED indicador
- Display LCD para visualización
Código completo:
#include <LiquidCrystal.h>
// Pines
const int TEMP_PIN = A0;
const int RELE_PIN = 7;
const int LED_PIN = 13;
// LCD (RS, E, D4, D5, D6, D7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Parámetros de control
const float TEMP_OBJETIVO = 25.0; // °C
const float HISTERESIS = 2.0; // °C
bool calefactorEncendido = false;
void setup() {
pinMode(RELE_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
lcd.begin(16, 2); // LCD de 16x2
lcd.print("Sistema Control");
lcd.setCursor(0, 1);
lcd.print("Temperatura");
delay(2000);
lcd.clear();
Serial.begin(9600);
}
void loop() {
// Leer temperatura
float temperatura = leerTemperatura();
// Control ON/OFF con histéresis
if (temperatura < (TEMP_OBJETIVO - HISTERESIS)) {
// Temperatura muy baja: encender calefactor
if (!calefactorEncendido) {
encenderCalefactor();
}
} else if (temperatura > (TEMP_OBJETIVO + HISTERESIS)) {
// Temperatura muy alta: apagar calefactor
if (calefactorEncendido) {
apagarCalefactor();
}
}
// Actualizar display
actualizarDisplay(temperatura);
// Enviar datos por serial
enviarDatosSerial(temperatura);
delay(1000);
}
float leerTemperatura() {
int lectura = analogRead(TEMP_PIN);
float voltaje = lectura * (5.0 / 1023.0);
float temperatura = voltaje * 100.0;
return temperatura;
}
void encenderCalefactor() {
digitalWrite(RELE_PIN, HIGH);
digitalWrite(LED_PIN, HIGH);
calefactorEncendido = true;
Serial.println("🔥 Calefactor ENCENDIDO");
}
void apagarCalefactor() {
digitalWrite(RELE_PIN, LOW);
digitalWrite(LED_PIN, LOW);
calefactorEncendido = false;
Serial.println("❄️ Calefactor APAGADO");
}
void actualizarDisplay(float temp) {
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(temp, 1);
lcd.print(" C ");
lcd.setCursor(0, 1);
lcd.print("SP: ");
lcd.print(TEMP_OBJETIVO, 1);
lcd.print(" ");
lcd.print(calefactorEncendido ? "ON " : "OFF");
}
void enviarDatosSerial(float temp) {
Serial.print("Temperatura: ");
Serial.print(temp);
Serial.print(" °C | Setpoint: ");
Serial.print(TEMP_OBJETIVO);
Serial.print(" °C | Calefactor: ");
Serial.println(calefactorEncendido ? "ON" : "OFF");
}
Diagrama de conexión:
Arduino UNO
├── A0 ──→ LM35 (Vout)
├── 7 ──→ Relé (IN)
├── 13 ──→ LED
└── LCD:
├── 12 → RS
├── 11 → E
├── 5 → D4
├── 4 → D5
├── 3 → D6
└── 2 → D7
LM35:
├── VCC → 5V
├── GND → GND
└── Vout → A0
Relé:
├── VCC → 5V
├── GND → GND
├── IN → Pin 7
└── COM/NO → Calefactor
📡 Comunicación Serial
La comunicación serial permite que Arduino hable con la PC o con otros dispositivos.
Comandos básicos:
Serial.begin(9600); // Iniciar a 9600 baudios
Serial.print("Hola"); // Enviar texto sin salto de línea
Serial.println("Mundo"); // Enviar texto con salto de línea
Serial.write(65); // Enviar byte (ASCII 'A')
int dato = Serial.read(); // Leer un byte
String linea = Serial.readStringUntil('\n'); // Leer hasta nueva línea
Ejemplo: Control remoto por serial
const int LED_PIN = 13;
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
Serial.println("Sistema listo. Comandos: ON, OFF, STATUS");
}
void loop() {
if (Serial.available() > 0) {
String comando = Serial.readStringUntil('\n');
comando.trim(); // Eliminar espacios
comando.toUpperCase(); // Convertir a mayúsculas
if (comando == "ON") {
digitalWrite(LED_PIN, HIGH);
Serial.println("✅ LED encendido");
}
else if (comando == "OFF") {
digitalWrite(LED_PIN, LOW);
Serial.println("✅ LED apagado");
}
else if (comando == "STATUS") {
bool estado = digitalRead(LED_PIN);
Serial.print("Estado del LED: ");
Serial.println(estado ? "ENCENDIDO" : "APAGADO");
}
else {
Serial.println("❌ Comando no reconocido");
}
}
}
🎯 Ejercicios Prácticos
🟢 Nivel Básico
Ejercicio 1: Creá un semáforo con 3 LEDs (rojo, amarillo, verde) que cambie automáticamente cada 5 segundos.
Ejercicio 2: Usá un potenciómetro para controlar el brillo de un LED (PWM).
Ejercicio 3: Implementá un sistema que encienda un LED cuando un botón es presionado y lo apague cuando se suelta.
🟡 Nivel Medio
Ejercicio 4: Creá un sistema de alarma que active un buzzer cuando un sensor ultrasónico detecte un objeto a menos de 20 cm.
Ejercicio 5: Implementá un termómetro digital que muestre la temperatura en un LCD.
Ejercicio 6: Diseñá un sistema de riego automático que active una bomba cuando la humedad del suelo sea baja.
🔴 Nivel Avanzado
Ejercicio 7: Creá un sistema de monitoreo de 3 sensores (temperatura, humedad, luz) que envíe datos por serial en formato JSON.
Ejercicio 8: Implementá un control PID para mantener una temperatura constante.
Ejercicio 9: Diseñá un sistema de acceso con teclado matricial y servo que simule una cerradura electrónica.
Ejercicio 10: Creá un datalogger que guarde lecturas de sensores en una tarjeta SD con timestamp.
💡 Buenas Prácticas
✅ Hacé esto:
- Comentá tu código: Explicá qué hace cada sección
- Usá constantes:
const int LED_PIN = 13;en vez de números mágicos - Nombres descriptivos:
temperaturaActualen vez detemp - Modularizá: Creá funciones para tareas específicas
- Validá lecturas: Verificá que los valores sean razonables
- Debounce en botones: Evitá lecturas múltiples
- Delays inteligentes: Usá
millis()para tareas no bloqueantes
❌ Evitá esto:
- Delays largos: Bloquean todo el programa
- Leer sensores muy rápido: Respetá los tiempos mínimos
- Ignorar límites: Verificá rangos de valores
- Conexiones incorrectas: Revisá el datasheet
- Sobrecargar pines: Respetá corrientes máximas
🔧 Herramientas Útiles
Software:
- Arduino IDE: Editor oficial
- PlatformIO: IDE profesional
- Fritzing: Diseño de circuitos
- Tinkercad Circuits: Simulador online
Hardware:
- Multímetro: Medición de voltaje/corriente
- Protoboard: Armado de prototipos
- Soldador: Proyectos permanentes
- Fuente de alimentación: Testing
🎓 Resumen
✅ Sistemas embebidos: Computadoras especializadas para tareas específicas
✅ Arduino: Plataforma ideal para aprender y prototipar
✅ Sensores: Convierten magnitudes físicas en señales eléctricas
✅ Actuadores: Convierten señales eléctricas en acciones físicas
✅ Comunicación serial: Interfaz con PC y otros dispositivos
✅ Aplicaciones industriales: Control, monitoreo, automatización
🚀 Próximos Pasos
- Practicá con los ejercicios propuestos
- Experimentá con diferentes sensores
- Investigá sobre protocolos industriales (Modbus, I2C, SPI)
- Aprendé sobre ESP32 para IoT
- Estudiá PLCs para automatización profesional
¿Tenés dudas? ¡Preguntá en clase! 🙋♂️
¡A programar hardware! 💪🔧