Good morning, it is a pleasure for me to be part of this community.
I am developing a cabinet with 12 electric locks, with a LCD display with I2C, whose access is done through a 4x4 keypad and a 4 digit user code assigned to a person. Then you are asked to choose the door you want to open from 1 to 12 and the selected relay is activated.
All this is registered in a microSD, thanks to a SD module and a DS3231 clock.
I have a problem that I can't solve. I bought a 16 relay module from aliexpress. When I start the program, let me enter the code, validate it and choose the door, at this point, the multiplexer cd74hc4067 does not activate the relay I select, the relay board does not respond, I do not know if it is a connection fault or what happens. I control all this with an arduino nano. The relay board has the 16 inputs, 2 VCC and 2 GND and two more connectors, DC+ and DC-. I leave the code in case I am making a mistake. Even if I measure the voltage between GND and the SIG pin of the multiplexer, I get 4,7V. However, if I test relay board and multiplexer separately, it works correctly.
Thank you in advance for your attention.
#include <Keypad.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <SPI.h>
#include <SD.h>
// === CONFIGURACIÓN DEL TECLADO ===
const byte ROWS = 4, COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {6, 7, 8, 9};
byte colPins[COLS] = {2, 3, 4, 5};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// === CONFIGURACIÓN DE LA LCD ===
LiquidCrystal_I2C lcd(0x27, 16, 2);
// === RTC ===
RTC_DS3231 rtc;
// === MÓDULO SD ===
const int SD_CS = 10;
// === PINES ===
const int relePin = 8; // Pin de control del relé
// === CONSTANTES ===
const int NUM_CODIGOS = 25;
const int DIGITOS = 4;
const int NUM_PUERTAS = 12;
bool modoCarga = false;
// === FUNCIONES ===
void activarPuerta(byte puerta) {
// Activación del relé
digitalWrite(relePin, HIGH); // El relé se activa (pin en HIGH)
delay(10000); // Mantener el relé activado durante 10 segundos
digitalWrite(relePin, LOW); // El relé se desactiva (pin en LOW)
}
bool validarCodigo(String codigo) {
for (int i = 0; i < NUM_CODIGOS; i++) {
String guardado = "";
for (int j = 0; j < DIGITOS; j++) {
guardado += String(EEPROM.read(i * DIGITOS + j));
}
if (codigo == guardado) return true;
}
return false;
}
void registrarAcceso(String codigo, byte puerta) {
DateTime now = rtc.now();
File log = SD.open("accesos.txt", FILE_WRITE);
if (log) {
log.print(now.timestamp());
log.print(", Codigo: ");
log.print(codigo);
log.print(", Puerta: ");
log.println(puerta);
log.close();
}
}
// === SETUP ===
void setup() {
lcd.init();
lcd.backlight();
lcd.clear();
pinMode(relePin, OUTPUT); // Configura el pin de control como salida
digitalWrite(relePin, LOW); // Inicialmente el relé está apagado
if (!rtc.begin()) {
lcd.print("Error RTC");
while (1);
}
if (!SD.begin(SD_CS)) {
lcd.print("Error SD");
while (1);
}
lcd.setCursor(0, 0);
lcd.print("A: Modo normal");
lcd.setCursor(0, 1);
lcd.print("B: Cargar codigos");
while (true) {
char key = keypad.getKey();
if (key == 'A') break;
if (key == 'B') {
modoCarga = true;
break;
}
}
if (modoCarga) {
lcd.clear();
lcd.print("Cargar codigos");
delay(1000);
for (int i = 0; i < NUM_CODIGOS; i++) {
lcd.clear();
lcd.print("Codigo #");
lcd.print(i + 1);
lcd.setCursor(0, 1);
String codigo = "";
while (codigo.length() < DIGITOS) {
char key = keypad.getKey();
if (key && isDigit(key)) {
codigo += key;
lcd.print("*");
}
}
for (int j = 0; j < DIGITOS; j++) {
EEPROM.write(i * DIGITOS + j, codigo[j] - '0');
}
delay(500);
}
lcd.clear();
lcd.print("Carga completa");
while (1);
}
lcd.clear();
lcd.print("Sistema listo");
delay(1000);
}
// === LOOP PRINCIPAL ===
void loop() {
lcd.clear();
lcd.print("Codigo:");
lcd.setCursor(0, 1);
String codigo = "";
while (codigo.length() < DIGITOS) {
char key = keypad.getKey();
if (key && isDigit(key)) {
codigo += key;
lcd.print("*");
}
}
if (!validarCodigo(codigo)) {
lcd.clear();
lcd.print("Codigo invalido");
delay(1500);
return;
}
lcd.clear();
lcd.print("Puerta (1-12):");
String puertaStr = "";
while (puertaStr.length() < 1) {
char key = keypad.getKey();
if (key && isDigit(key)) {
puertaStr += key;
lcd.print(key);
}
}
byte puerta = puertaStr.toInt();
if (puerta < 1 || puerta > NUM_PUERTAS) {
lcd.clear();
lcd.print("Puerta invalida");
delay(1500);
return;
}
// Mostrar "ACCESO OK" y activar el relé durante 10 segundos
lcd.clear();
lcd.print("Acceso OK");
activarPuerta(puerta - 1); // Activa el relé para abrir la puerta
registrarAcceso(codigo, puerta);
lcd.clear();
lcd.print("Acceso completado");
delay(2000); // Mostrar el mensaje de acceso completado
}