Arduino Nano misreads the 4x4 hard keypad

Hi people, I am doing a project wich in a part of it involves the use of a matrix keypad 4x4 and an arduino nano, according the the input from the keypad (a password) the arduino nano must send a digital signal through the pin d13 for 3 seconds.

I can see the input i am writing at a lcd screen.

The problem is that the characters received by the nano does not match with the ones I press in the hard keyboard. For example if I press the "2" icon then the arduino marks it as "4". It only recognizes correctly the "1", "5","9" and "D" .

The code worked well with arduino uno.
It also worked using a different keyboard model.


This is the model it worked with


This is the model I want to work with

I am sharing the code too:

#include <Wire.h>
#include <Keypad.h>
#include <LiquidCrystal_PCF8574.h>

// Configura la dirección I2C y el tamaño del LCD
LiquidCrystal_PCF8574 lcd(0x27); // Cambia 0x27 por la dirección de tu pantalla

// Configuración del teclado matricial 4x4
const byte filas = 4; // Número de filas
const byte columnas = 4; // Número de columnas

// Mapeo de teclas (ajusta según tu teclado)
char teclas[filas][columnas] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

// Pines conectados al teclado (ajusta según tu conexión)
byte pinesFilas[filas] = {9, 8, 7, 6};  // Pines digitales del Arduino Nano para las filas
byte pinesColumnas[columnas] = {5, 4, 3, 2}; // Pines digitales del Arduino Nano para las columnas

Keypad teclado = Keypad(makeKeymap(teclas), pinesFilas, pinesColumnas, filas, columnas);

// Configuración de la contraseña
String contrasena = "2016"; // Contraseña correcta
String entrada = "";        // Almacena la entrada del usuario
String entradaesp32 ="";   // Almacena informacion serial desde ESP32

// Configuración de la salida digital
const int salida = 13; // Pin digital del Arduino Nano para la salida (ajusta según tu preferencia)
const unsigned long tiempoActivo = 3000; // Tiempo en milisegundos (3 segundos)

void setup() {
  // Inicia la comunicación serial con el ESP32
  Serial.begin(9600); // Comunicación a través de los pines RX y TX por defecto

  // Configuración de la salida digital
  pinMode(salida, OUTPUT);
  digitalWrite(salida, LOW);

  // Inicializa el LCD
  Wire.begin();     // Inicia la comunicación I2C
  lcd.begin(16, 2);  // Inicializa el LCD con 16 columnas y 2 filas
  lcd.setBacklight(255);  // Activa la luz de fondo (0 para apagarla)
  lcd.setCursor(0, 0);    // Posiciona el cursor en la primera columna y fila
  lcd.print("INGRESAR CLAVE:");  // Muestra un mensaje en la pantalla
}

void loop() {
  // Verifica si hay datos disponibles desde el ESP32
  if (Serial.available() > 0) {
    // Lee la nueva contraseña enviada por el ESP32
    entradaesp32 = Serial.readString();
    entradaesp32.trim();  // Elimina espacios, saltos de línea y retornos de carro
    contrasena = entradaesp32;
    lcd.setCursor(0, 1);
    lcd.print(contrasena); // Muestra la nueva contraseña
    delay(3000);
    lcd.setCursor(0, 1);
    lcd.print("                "); // Limpia la segunda línea
  }

  char tecla = teclado.getKey(); // Lee una tecla del teclado

  if (tecla) {
    if (tecla == '#') {
      if (entrada == contrasena) {
        lcd.setCursor(0, 1);
        lcd.print("Abriendo puerta");
        digitalWrite(salida, HIGH);
        delay(tiempoActivo);
        digitalWrite(salida, LOW);
        lcd.setCursor(0, 1);
        lcd.print("Puerta Cerrada");
        delay(3000);
        lcd.setCursor(0, 1);
        lcd.print("                ");
        entrada = "";
      } else {
        lcd.setCursor(0, 1);
        lcd.print("Clave incorrecta");
        delay(3000);
        lcd.setCursor(0, 1);
        lcd.print("                ");
        entrada = "";
      }
    } else if (tecla == '*') {
      entrada = "";
      lcd.setCursor(0, 1);
      lcd.print("                ");
    } else {
      entrada += tecla;
      lcd.setCursor(0, 1);
      lcd.print(entrada);

      if (entrada.length() > 4) {
        entrada = "";
        lcd.setCursor(0, 1);
        lcd.print("max.4 caracteres");
        delay(3000);
        lcd.setCursor(0, 1);
        lcd.print("                ");
      }
    }
  }
}

Wrap your formatted code in code tags using the <CODE> button in the reply/message box. The result should look like this:

void setup() {
}
void loop() {
}

You probably have switched column and row pins.

1 Like

Translated the Spanish:

#include <Wire.h>
#include <Keypad.h>
#include <LiquidCrystal_PCF8574.h>

// Set the I2C address and LCD size
LiquidCrystal_PCF8574 LCD(0x27); Change 0x27 to your screen direction

// 4x4 Matrix Keyboard Setup
const byte rows = 4; Number of rows
const byte columns = 4; Number of columns

// Keymapping (adjusts according to your keyboard)
char keys[rows][columns] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};

// Pins connected to the keyboard (adjusts according to your connection)
byte pinsRows[rows] = {9, 8, 7, 6}; Arduino Nano digital pins for rows
byte pinsColumns[columns] = {5, 4, 3, 2}; Arduino Nano digital pins for columns

Keypad keyboard = Keypad(makeKeymap(keys), pinsRows, pinsColumns, rows, columns);

// Password settings
String password="2016"; Correct password
String input = ""; Store user input
String inputes32 =""; Stores serial information from ESP32

// Setting up the digital output
const int output = 13; Arduino Nano digital pin for output (adjust according to your preference)
const unsigned long timeActive = 3000; Time in milliseconds (3 seconds)

void setup() {
// Initiate serial communication with the ESP32
Serial.begin(9600); Communication via RX and TX pins by default

// Setting up the digital output
pinMode(output, OUTPUT);
digitalWrite(output, LOW);

// Initialize the LCD
Wire.begin(); Start I2C communication
lcd.begin(16, 2); Initializes the LCD with 16 columns and 2 rows
lcd.setBacklight(255); Turn on the backlight (0 to turn it off)
lcd.setCursor(0, 0); Position the cursor in the first column and row
lcd.print("ENTER KEY:"); Display a message on the screen
}

void loop() {
// Check if data is available from ESP32
if (Serial.available() > 0) {
// Read the new password sent by the ESP32
inputsesp32 = Serial.readString();
inputsesp32.trim(); Eliminates gaps, line breaks, and carriage returns
password = entries esp32;
lcd.setCursor(0, 1);
lcd.print(password); Show the new password
delay(3000);
lcd.setCursor(0, 1);
lcd.print(" "); Clean up the second line
}

char key = keyboard.getKey(); Read a key on the keyboard

if (key) {
if (key == '#') {
if(input == password) {
lcd.setCursor(0, 1);
lcd.print("Opening door");
digitalWrite(output, HIGH);
delay;
digitalWrite(output, LOW);
lcd.setCursor(0, 1);
lcd.print("Closed Door");
delay(3000);
lcd.setCursor(0, 1);
lcd.print(" ");
input = "";
} else {
lcd.setCursor(0, 1);
lcd.print("Incorrect key");
delay(3000);
lcd.setCursor(0, 1);
lcd.print(" ");
input = "";
}
} else if (key == '*') {
input = "";
lcd.setCursor(0, 1);
lcd.print(" ");
} else {
input += key;
lcd.setCursor(0, 1);
lcd.print(input);

if(input.length() > 4) {
    input = "";
    lcd.setCursor(0, 1);
    lcd.print("max.4 characters");
    delay(3000);
    lcd.setCursor(0, 1);
    lcd.print(" ");
  }
}

}
}

Your pins are backwards.

The 1, 5, 9, D is a clue.

You nailed it. Since 1,5,9,D work.

Did you verify that the matrix is ​​the same as the one on the bubble keypad (the one in the first photo)?
With a tester in continuity mode (or the lowest resistance scale) test which pins have continuity when you press each key, so you can identify each row and each column.

Yes, however it seems to be more a thing of code or arduino nano, because the same order of connection for rows and columns was used at arduino uno and worked with no problems.

Could be a difference there. But try it out, switch the pins!

There are no differences between UNO and Nano except that the latter has 2 more analog pins. If it works on UNO, it works on Nano.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.