#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
// ── Pines ──────────────────────────────────────
#define PIN_LED PA5
#define PIN_BUTTON PB4
#define PIN_SERVO PA6
// ── Objetos ────────────────────────────────────
LiquidCrystal_I2C *lcd = nullptr;
Servo miServo;
// ── Variables de estado ────────────────────────
bool puertaAbierta = false;
bool botonAnterior = HIGH;
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("Iniciando sistema...");
// Configurar pines I2C con pull-ups
pinMode(PB6, INPUT_PULLUP); // SCL
pinMode(PB7, INPUT_PULLUP); // SDA
// LED
pinMode(PIN_LED, OUTPUT);
digitalWrite(PIN_LED, LOW);
// Botón con pull-up interno
pinMode(PIN_BUTTON, INPUT_PULLUP);
// Servo
miServo.attach(PIN_SERVO);
miServo.write(0);
// Inicializar I2C
Wire.begin();
Wire.setClock(50000); // Velocidad reducida para mayor compatibilidad
delay(500); // Dar tiempo al LCD para iniciar
buscarLCD();
Serial.println("Sistema iniciado");
}
void buscarLCD() {
byte direcciones[] = {0x27, 0x3F, 0x26, 0x20, 0x3E, 0x7E};
bool encontrado = false;
Serial.println("Escaneando bus I2C...");
for (byte i = 0; i < 6; i++) {
Wire.beginTransmission(direcciones[i]);
byte error = Wire.endTransmission();
Serial.print("Direccion 0x");
Serial.print(direcciones[i], HEX);
Serial.print(": ");
if (error == 0) {
Serial.println("✓ DISPOSITIVO ENCONTRADO!");
lcd = new LiquidCrystal_I2C(direcciones[i], 16, 2);
lcd->init();
lcd->backlight();
lcd->clear();
lcd->setCursor(0, 0);
lcd->print(" LCD OK! ");
lcd->setCursor(0, 1);
lcd->print("Addr: 0x");
lcd->print(direcciones[i], HEX);
encontrado = true;
delay(2000);
mostrarMensaje("Puerta cerrada");
break;
} else if (error == 2) {
Serial.println("Error en recepcion NACK");
} else {
Serial.println("No responde");
}
}
if (!encontrado) {
Serial.println("ERROR: No se encontro LCD!");
Serial.println("\nVerifica en Wokwi:");
Serial.println("1. El LCD debe tener el modulo I2C (PCF8574)");
Serial.println("2. En Wokwi, usa el componente 'lcd1602-i2c'");
Serial.println("3. Conexiones: VCC=5V, GND=GND, SDA=PB7, SCL=PB6");
}
}
void loop() {
bool botonActual = digitalRead(PIN_BUTTON);
if (botonAnterior == HIGH && botonActual == LOW) {
delay(30);
puertaAbierta = !puertaAbierta;
if (puertaAbierta) {
abrirPuerta();
} else {
cerrarPuerta();
}
}
botonAnterior = botonActual;
delay(10);
}
void abrirPuerta() {
digitalWrite(PIN_LED, HIGH);
miServo.write(90);
mostrarMensaje("Puerta abierta ");
Serial.println(">> Puerta ABIERTA");
}
void cerrarPuerta() {
digitalWrite(PIN_LED, LOW);
miServo.write(0);
mostrarMensaje("Puerta cerrada");
Serial.println(">> Puerta CERRADA");
}
void mostrarMensaje(const char* msg) {
if (lcd != nullptr) {
lcd->clear();
lcd->setCursor(0, 0);
lcd->print(" Estado: ");
lcd->setCursor(0, 1);
lcd->print(msg);
}
}