Mando a Distancia TV Personalizado con Arduino UNO: Alimentado por Batería, Carcasa Impresa en 3D
Componentes y Suministros
| Arduino UNO | ×1 |
| Batería 9V (genérica) | ×1 |
| Conector 9V a Jack Barril | ×1 |
| Emisor IR (genérico) | ×1 |
| Tornillo Máquina M3 | ×4 |
| Tornillo Máquina M2.5 | ×3 |
| Tuerca M3 | ×4 |
| Tuerca M2.5 | ×3 |
| Resistencia Pasante 47 Ω | ×2 |
| Placa Prototipo 2.54mm | ×1 |
| Pulsador PCB | ×6 |
| Header Macho 36 Posiciones 1 Fila (0.1") | ×1 |
Herramientas y Máquinas Necesarias
- Impresora 3D (genérica)
- Soldador (genérico)
- Hilo Soldar Sin Plomo
- Filamento PLA 1.75mm
Sobre el Proyecto
Introducción
El mando de la TV de mi novia dejó de funcionar. Podía comprar uno barato, pero pensamos: somos ingenieros, ¡hagamos el nuestro!
Nuestras habilidades son complementarias, así que fue una forma diferente y divertida de pasar tiempo durante el confinamiento, aprendiendo cómo funciona esta tecnología cotidiana. Tener una impresora 3D pequeña en casa también ayudó.
Funcionamiento
Lectura de Botones
Evaluamos comandos mínimos para nuestra TV: 6 bastan: ON/OFF, Fuente, Canal+/-, Volumen+/-. Para evitar resistencias extra, usamos pull-ups internos del Arduino. Si no está en modo sleep, cada botón se sondea cada ciclo. Para evitar rebotes, rutina debouncing con millis().
Envío Señales Infrarrojas
Comunicación IR gestionada por librería IRremote.h (¡gracias a sus autores!). Configurar protocolo TV (cada fabricante tiene el suyo) y buscar códigos HEX de comandos en Google, asociarlos a botones. El LED IR debe ir en pin 3 (PWM) del Arduino UNO.
Código soporta 3 tipos TV, seleccionables comentando/descomentando #define al inicio.
Ahorro Batería
Estrategias de bajo consumo con avr/sleep.h y avr/power.h:
- Desactivar periféricos no usados en
setup(): ADC, SPI, TWI, Timer1, USART - Apagar LED integrado en pin 13 PWM
- Desoldar LED de alimentación Arduino UNO (siempre encendido; no recomendado pero efectivo)
- Si ningún botón pulsado en 5 segundos → modo sleep; despierta al pulsar ON/OFF
Construcción
Ensamblaje Electrónico
Circuito en placa prototipo diseñada para encajar en headers Arduino UNO. Soldar botones considerando posición final en mando. En cara inferior, dos resistencias 47Ω en paralelo para corriente deseada en LED IR. Con hilo soldar, hacer pistas en placa conectando botones y LED IR a headers macho. Así la placa funciona como shield que encaja en Arduino UNO, asegurando conexiones correctas.
Carcasa: CAD y CAM
Carcasa diseñada para contener batería, Arduino UNO + placa prototipo, exponiendo solo botones arriba y LED IR frontal.
Dos piezas diseñadas en SolidWorks, preprocesadas con Ultimaker Cura, impresas en PLA con Anycubic Mega Zero.
Arduino UNO atornillado a base con 3 tornillos M2.5 en orificios de alineación extruidos. LED IR sobresale de placa prototipo para alinearse con orificio; tres mini-postes evitan movimiento lateral de patillas LED. Batería a presión en hueco dedicado.
Tapa expone solo botones, con símbolo grabado junto a cada uno indicando función. Base y tapa unidas con 4 tornillos M3.
Galería de Fotos
Código
TV_remote.ino
Arduino
#include <IRremote.h>
#include <avr/sleep.h>
#include <avr/power.h>
// Pin definition
// An IR LED must be connected to Arduino PWM pin 3
#define OnOff 1
#define Source 0
#define CH_plus 4
#define CH_minus 5
#define Vol_plus 6
#define Vol_minus 7
#define Interrupt_Pin 2 // Only pin 2 or 3 on Arduino Uno
// TV model definition
//#define LG_TV
//#define SAMSUNG_TV
#define SONY_TV
// Codes definition
#ifdef LG_TV
unsigned long on_off_code = 551489775; // HEX 20DF10EF
unsigned long vol_plus_code = 551502015; // HEX 20DF40BF
unsigned long vol_minus_code = 551534655; // HEX 20DFC03F
unsigned long ch_plus_code = 551485695; // HEX 20DF00FF
unsigned long ch_minus_code = 551518335; // HEX 20DF807F
unsigned long source_code = 551538735; // HEX 20DFD02F
#endif
#ifdef SAMSUNG_TV
unsigned long on_off_code = 3772793023; // HEX E0E040BF
unsigned long vol_plus_code = 3772833823; // HEX E0E0E01F
unsigned long vol_minus_code = 3772829743; // HEX E0E0D02F
unsigned long ch_plus_code = 3772795063; // HEX E0E048B7
unsigned long ch_minus_code = 3772778743; // HEX E0E008F7
unsigned long source_code = 3772809343; // HEX E0E0807F
#endif
#ifdef SONY_TV
unsigned long on_off_code = 2704; // HEX A90
unsigned long vol_plus_code = 1168; // HEX 490
unsigned long vol_minus_code = 3216; // HEX C90
unsigned long ch_plus_code = 144; // HEX 090
unsigned long ch_minus_code = 2192; // HEX 890
unsigned long source_code = 2640; // HEX A50
#endif
// Enable Debug
//#define DEBUG
IRsend irsend;
unsigned long debounce_time;
unsigned long last_time;
void setup() {
analogWrite(13, 0); // turn off builtin led
// noInterrupts(); CLKPR = _BV(CLKPCE); CLKPR = _BV(CLKPS0); interrupts(); // clock prescaler (optional)
pinMode(OnOff, INPUT_PULLUP);
pinMode(Source, INPUT_PULLUP);
pinMode(CH_plus, INPUT_PULLUP);
pinMode(CH_minus, INPUT_PULLUP);
pinMode(Vol_plus, INPUT_PULLUP);
pinMode(Vol_minus, INPUT_PULLUP);
pinMode(Interrupt_Pin, INPUT_PULLUP);
// Power saving
power_adc_disable();
power_spi_disable();
power_timer1_disable();
power_usart0_disable();
power_twi_disable();
#ifdef DEBUG
Serial.begin(9600);
#endif
}
void loop() {
// Check OnOff
if (!digitalRead(OnOff)) {
debounce_time = millis();
while (millis() - debounce_time < 40) { ; }
if (!digitalRead(OnOff)) {
#ifdef LG_TV irsend.sendNEC(on_off_code, 32);
#endif
#ifdef SAMSUNG_TV irsend.sendSAMSUNG(on_off_code, 32);
#endif
#ifdef SONY_TV irsend.sendSony(on_off_code, 12);
#endif
last_time = millis();
#ifdef DEBUG Serial.println("OnOff");
#endif
}
}
// Check Source
if (!digitalRead(Source)) {
debounce_time = millis();
while (millis() - debounce_time < 40) { ; }
if (!digitalRead(Source)) {
#ifdef LG_TV irsend.sendNEC(source_code, 32);
#endif
#ifdef SAMSUNG_TV irsend.sendSAMSUNG(source_code, 32);
#endif
#ifdef SONY_TV irsend.sendSony(source_code, 12);
#endif
last_time = millis();
#ifdef DEBUG Serial.println("Source");
#endif
}
}
// Check CH_plus
if (!digitalRead(CH_plus)) {
debounce_time = millis();
while (millis() - debounce_time < 40) { ; }
if (!digitalRead(CH_plus)) {
#ifdef LG_TV irsend.sendNEC(ch_plus_code, 32);
#endif
#ifdef SAMSUNG_TV irsend.sendSAMSUNG(ch_plus_code, 32);
#endif
#ifdef SONY_TV irsend.sendSony(ch_plus_code, 12);
#endif
last_time = millis();
#ifdef DEBUG Serial.println("CH+");
#endif
}
}
// Check CH_minus
if (!digitalRead(CH_minus)) {
debounce_time = millis();
while (millis() - debounce_time < 40) { ; }
if (!digitalRead(CH_minus)) {
#ifdef LG_TV irsend.sendNEC(ch_minus_code, 32);
#endif
#ifdef SAMSUNG_TV irsend.sendSAMSUNG(ch_minus_code, 32);
#endif
#ifdef SONY_TV irsend.sendSony(ch_minus_code, 12);
#endif
last_time = millis();
#ifdef DEBUG Serial.println("CH-");
#endif
}
}
// Check Vol_plus
if (!digitalRead(Vol_plus)) {
debounce_time = millis();
while (millis() - debounce_time < 40) { ; }
if (!digitalRead(Vol_plus)) {
#ifdef LG_TV irsend.sendNEC(vol_plus_code, 32);
#endif
#ifdef SAMSUNG_TV irsend.sendSAMSUNG(vol_plus_code, 32);
#endif
#ifdef SONY_TV irsend.sendSony(vol_plus_code, 12);
#endif
last_time = millis();
#ifdef DEBUG Serial.println("Vol+");
#endif
}
}
// Check Vol_minus
if (!digitalRead(Vol_minus)) {
debounce_time = millis();
while (millis() - debounce_time < 40) { ; }
if (!digitalRead(Vol_minus)) {
#ifdef LG_TV irsend.sendNEC(vol_minus_code, 32);
#endif
#ifdef SAMSUNG_TV irsend.sendSAMSUNG(vol_minus_code, 32);
#endif
#ifdef SONY_TV irsend.sendSony(vol_minus_code, 12);
#endif
last_time = millis();
#ifdef DEBUG Serial.println("Vol-");
#endif
}
}
// Sleep after 5 seconds inactivity
if (millis() - last_time > 5000) {
#ifdef DEBUG Serial.println("Going to sleep...");
#endif
going_to_sleep();
#ifdef DEBUG Serial.println("Waking up...");
#endif
}
}
void going_to_sleep() {
sleep_enable();
attachInterrupt(digitalPinToInterrupt(Interrupt_Pin), wake_up, LOW);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_cpu();
}
void wake_up() {
sleep_disable();
detachInterrupt(digitalPinToInterrupt(Interrupt_Pin));
}
Piezas Personalizadas y Carcasas
(Archivos de diseño 3D no incluidos en la fuente original)
Esquemáticos
remote_sketch_r4f8a47oWX.fz (Fritzing)
Proceso de manufactura
- Sistema de control de acceso integrado con QR, RFID y verificación de temperatura
- Capturar comandos de mando IR en Raspberry Pi sin LIRC: enfoque Python UART
- PiCy: Construya su propio mini robot alimentado por Raspberry Pi
- Construye un Juego Giroscópico en Tiempo Real con Arduino Nano y Sensor MPU-6050
- Cámara de Seguridad con Detección de Movimiento ESP32 para Discord
- Alcancía Inteligente: Controla un Aceptador de Monedas con Arduino Nano
- Unopad: Controlador MIDI Arduino para Ableton Live sin complicaciones
- Controla un LED por Bluetooth con Arduino – Guía DIY paso a paso
- Sensor de obstáculos IR casero con Arduino – Tutorial fácil con LED IR y fotodiodo
- 5 Beneficios clave del control remoto de producción para la industria moderna
- Millport SmartLathez 1740 CNC – Precisión y potencia