Manual Técnico Proyecto: Casa Inteligente 1. Arquitectura del sistema El sistema está dividido en módulos:
Control de iluminación por ambiente.
Motor DC para ventilador.
Servo para puerta con botón físico.
Comunicaciones :
Serial USB
Bluetooth HC-06 (Serial1)
Persistencia :
EEPROM para modo actual
EEPROM para modos custom
Interfaz de usuario :
2. Entorno de desarrollo
Arduino IDE 2.x (recomendado)
Placa: Arduino Mega 2560
Baud rate: 9600
Librerías:
EEPROM.h
Wire.h
LiquidCrystal_I2C.h
Servo.h
3. Versiones recomendadas
Python: 3.10+ (probado en 3.10/3.11)
pyserial: 3.5+
Arduino AVR Boards actualizado en Board Manager
Biblioteca LiquidCrystal_I2C compatible con lcd.init() y lcd.backlight()
4. Mapa de pines 4.1 LEDs ambientes
Sala: 2, 3, 4
Comedor: 5, 6, 7
Cocina: 8, 9
Habitación: 10, 22
4.2 Estado
Azul: 28
Verde: 29
Rojo: 30
4.3 Actuadores
Motor DC: 31
Servo: 32
Botón puerta: 33 (INPUT_PULLUP)
4.4 LCD I2C
SDA: 20
SCL: 21
VCC: 5V
GND: GND
4.5 Bluetooth HC-06
HC-06 TX -> RX1 (pin 19)
HC-06 RX -> TX1 (pin 18) (ideal con divisor de voltaje)
5. EEPROM (diseño de almacenamiento)
EEPROM_MODO_ACTUAL = 50
Custom 1: base 100
Custom 2: base 130
Estructura por custom
+0 firma 'C'
+1 ventilador (0/1)
+2 sala (0/1)
+3 comedor (0/1)
+4 cocina (0/1)
+5 habitación (0/1)
+6..+15 nombre (10 chars)
6. Instalación de Python para carga .org 6.1 Instalar Python Windows:
Descargar desde https://www.python.org/downloads/
Activar “Add Python to PATH”.
6.2 Instalar pyserial
6.3 Verificar instalación 1 2 python --version pip show pyserial
7. Script Python de carga .org Ejemplo mínimo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import serialimport timePORT = "COM5" BAUD = 9600 FILE = "config.org" with serial.Serial(PORT, BAUD, timeout=1 ) as ser: time.sleep(2 ) with open (FILE, "r" , encoding="utf-8" ) as f: for line in f: line = line.strip() if not line: continue ser.write((line + "\n" ).encode("utf-8" )) print ("Enviado:" , line) time.sleep(0.15 ) print ("Carga finalizada" )
8. Funciones importantes (snippets) 8.1 Aplicar modo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 void aplicarModo (int modo) { switch (modo) { case MODO_FIESTA: apagarTodosLEDs (); encenderMotor (); break ; case MODO_RELAJADO: apagarTodosLEDs (); apagarMotor (); digitalWrite (SALA_L1, HIGH); digitalWrite (COMEDOR_L1, HIGH); break ; } }
8.2 Estado 1 2 3 4 5 6 if (cmd == "estado" ) { String s = "Modo actual: " + estadoModoTexto (); Serial.println (s); Serial1. println (s); lcdMostrar ("Estado actual" , estadoModoTexto ()); }
8.3 Parpadeo LED verde durante carga 1 2 3 4 5 6 7 8 void actualizarLedCarga () { if (!parpadeoCargaActivo) return ; if (millis () - tiempoAnteriorCarga >= INTERVALO_CARGA) { tiempoAnteriorCarga = millis (); estadoLedCarga = !estadoLedCarga; digitalWrite (LED_VERDE, estadoLedCarga ? HIGH : LOW); } }
8.4 Debounce botón puerta 1 2 3 4 5 6 7 8 if ((millis () - ultimoTiempoRebote) > debounceDelay) { if (lecturaActual != estadoBotonEstable) { estadoBotonEstable = lecturaActual; if (estadoBotonEstable == LOW) { } } }
8.5 Guardar custom en EEPROM 1 2 3 4 5 6 void guardarCustomEnEEPROM (int base, ModoCustom m) { EEPROM.write (base + 0 , 'C' ); EEPROM.write (base + 1 , m.fanOn ? 1 : 0 ); EEPROM.write (base + 2 , m.salaOn ? 1 : 0 ); }
Ejemplo:
1 2 3 4 5 6 7 8 conf_ini modo_custom_1: Cena ventilador:on leds:sala:on,comedor:on,cocina:off,habitacion:off modo_custom_2: NochePro ventilador:off leds:sala:off,comedor:off,cocina:on,habitacion:on conf:fin
10. Criterios de validación técnica
conf_ini obligatorio para iniciar carga.
conf:fin obligatorio para cerrar.
Nombre custom: 1..10 chars alfanuméricos/underscore.
Cada custom debe incluir:
ventilador:on/off
leds:... con los 4 ambientes válidos.
Si no se define custom en archivo, se conservan los anteriores en EEPROM.