I2C significa Circuito Interintegrado (Inter-Integrated Circuit) es un protocolo de comunicación serial desarrollado por Phillips Semiconductors en la década de los 80s.
El IDE de Arduino tiene su propio gestor de librerías para instalar nuevas, para acceder a él se entra a Programa > Incluir Librería > Gestionar Librerías
Librería LiquidCrystal_I2C por Frank de Brabander.
lcd()Crea un objeto de la clase LiquidCrystal_I2C, con todas sus características correspondientes al LCD en uso.
LiquidCrystal_I2C lcd(direccion, columnas, filas)
direccion: dirección I2C del LCD.columnas: número de columnas del LCD.filas: número de filas del LCD.| Referencia | Tipo | Descripción |
|---|---|---|
direccion |
byte |
dirección I2C del LCD. |
columnas |
int |
Número de columnas del LCD. |
filas |
int |
Número de filas del LCD. |
init()Inicializa el modulo adaptador, esta función internamente configura lo necesario para utilizar el LCD mediante I2C.
lcd.init()
backlight()Enciende la luz del fondo de la pantalla.
lcd.backlight()
noBacklight()Apaga la luz del fondo de la pantalla.
lcd.noBacklight()
setCursor()Establecer la ubicación dónde empezará posteriormente la impresión de texto escrito.
A esta ubicación se le denomina cursor.
lcd.setCursor(columna, fila)
columna: columna donde se posicionará el cursor.fila: fila donde se posicionará el cursor.| Referencia | Tipo | Descripción |
|---|---|---|
columna |
int |
Columna donde se posicionará el cursor. |
fila |
int |
Fila donde se posicionará el cursor. |
print()Escribe un texto o mensaje en el LCD, su uso es similar a un Serial.print().
lcd.print(texto)
| Referencia | Tipo | Descripción |
|---|---|---|
texto |
String |
Texto que se escribirá en el LCD. |
clear()Limpia la pantalla y posiciona el cursor en la esquina superior izquierda (posición (0, 0))
lcd.clear()
scrollDisplayLeft()Desplaza el contenido de la pantalla, texto y cursor, un espacio hacia la izquierda.
lcd.scrollDisplayLeft()
scrollDisplayRight()Desplaza el contenido de la pantalla, texto y cursor, un espacio hacia la derecha.
lcd.scrollDisplayRight()
createChar()Crea un carácter personalizado para su uso en la pantalla LCD.
Se admiten hasta ocho caracteres, numerados del 0 al 7, de 5x8 pixeles.
lcd.createChar(numero, datos)
| Referencia | Tipo | Descripción |
|---|---|---|
numero |
int |
Número de carácter. |
datos |
int[][] |
Matriz que contiene los pixeles del carácter. |
Librería Keypad por Mark Stanley, Alexander Brevig.
KeypadKeypad(keyMap, pinsFilas, pinsColumnas, filas, columnas)
| Referencia | Tipo | Descripción |
|---|---|---|
keyMap |
Keymap |
Mapa de las teclas devuelto por makeKeymap(). |
pinsFilas |
int[] |
Arreglo que contiene los pines correspondiente a las filas. |
pinsColumnas |
int[] |
Arreglo que contiene los pines correspondiente a las columnas. |
filas |
int |
Número de filas del teclado. |
columnas |
int |
Número de columnas del teclado. |
Un objeto Keypad que se usará para manipular el teclado.
makeKeymap()makeKeymap(teclas)
| Referencia | Tipo | Descripción |
|---|---|---|
teclas |
char[][] |
Matriz que contiene el valor de cada tecla. |
Un objeto Keymap que contiene un mapa de las teclas.
getKey()objetoKeypad.getKey()
Un char correspondiente a la tecla presionada.
waitForKey()Similar a getKey() con la diferencia de que se espera para siempre hasta que se presione una tecla.
Cuidado: bloquea toda la ejecución del programa hasta que se presione una tecla.
getState()Devuelve el estado actual de cualquiera de las teclas.
Una constante KeyState correspondiente a alguno de los cuatro estados: IDLE, PRESSED, RELEASED and HOLD.
keyStateChanged()New in version 2.0: Let’s you know when the key has changed from one state to another. For example, instead of just testing for a valid key you can test for when a key was pressed.
setHoldTime(unsigned int time)Set the amount of milliseconds the user will have to hold a button until the HOLD state is triggered.
setDebounceTime(unsigned int time)Set the amount of milliseconds the keypad will wait until it accepts a new keypress/keyEvent. This is the “time delay” debounce method.
addEventListener(keypadEvent)Trigger an event if the keypad is used. You can load an example in the Arduino IDE.
[See File -> Examples -> Keypad -> Examples -> EventSerialKeypad] or see the KeypadEvent Example code.

Antes que nada, necesitamos averiguar la dirección I2C de nuestro LCD para llamar al constructor lcd(). Por esto, lo que haremos será escanear todos los dispositivos I2C que estén conectados a nuestra placa Arduino con el siguiente código.
void setup() {
Wire.begin();
Serial.begin(9600);
while (!Serial);
Serial.println("\nI2C Scanner");
}
void loop() {
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ ) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
} else if (error==4) {
Serial.print("Unknown error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000);
}
En el monitor serial:
Scanning...
I2C device found at address 0x3F !
done
Dónde 0x3F será nuestra dirección I2C correspondiente al LCD y la llamada al constructor se vería algo así:
LiquidCrystal_I2C lcd(0x3F, 16, 2);
La dirección
0x3Fpuede ser distinta dependiendo de cada caso, por lo que siempre es bueno hacer un escaneo para asegurarse.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(3, 0);
lcd.print("Club INNDEV");
lcd.setCursor(6, 1);
lcd.print("UTEM");
}
void loop() {
}
Hay herramientas que nos facilitan mucho este trabajo, como esta aplicación que con sólo empezar a dibujar en el panel de 8x5 que tiene disponible, nos genera un código automáticamente.
Sólo necesitamos copiar el arreglo
customCharque nos genera la aplicación.
Sin desconectar el LCD, conectaremos el teclado matricial de la siguiente manera:

#include <Keypad.h>
const byte FILAS = 4;
const byte COLUMNAS = 4;
char significadoTeclas[FILAS][COLUMNAS] = {
{'0','1','2','3'},
{'4','5','6','7'},
{'8','9','A','B'},
{'C','D','E','F'}
};
byte pinsFilas[FILAS] = {5, 4, 3, 2};
byte pinsColumnas[COLUMNAS] = {9, 8, 7, 6};
Keypad teclado = Keypad(makeKeymap(significadoTeclas), pinsFilas, pinsColumnas, FILAS, COLUMNAS);
void setup(){
Serial.begin(9600);
}
void loop(){
char presionada = teclado.getKey();
if (presionada) {
Serial.println(presionada);
}
}
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const byte FILAS = 4;
const byte COLUMNAS = 4;
char significadoTeclas[FILAS][COLUMNAS] = {
{'1','4','7','*'},
{'2','5','8','0'},
{'3','6','9','#'},
{'A','B','C','D'}
};
byte pinsFilas[FILAS] = {5, 4, 3, 2};
byte pinsColumnas[COLUMNAS] = {9, 8, 7, 6};
int contador = 0;
int posicionFila = 0;
Keypad teclado = Keypad(makeKeymap(significadoTeclas), pinsFilas, pinsColumnas, FILAS, COLUMNAS);
LiquidCrystal_I2C lcd(0x3F, 16, 2);
void setup(){
lcd.init();
lcd.backlight();
}
void loop(){
char presionada = teclado.getKey();
if (presionada) {
contador++;
if (contador >= 16) {
contador = 0;
if (posicionFila == 0)
posicionFila = 1;
else
posicionFila = 0;
lcd.setCursor(0, posicionFila);
}
lcd.print(presionada);
}
}
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const byte FILAS = 4;
const byte COLUMNAS = 4;
const String contrasenia = "9#B0";
String textoIngresado = "";
char significadoTeclas[FILAS][COLUMNAS] = {
{'1','4','7','*'},
{'2','5','8','0'},
{'3','6','9','#'},
{'A','B','C','D'}
};
byte pinsFilas[FILAS] = {5, 4, 3, 2};
byte pinsColumnas[COLUMNAS] = {9, 8, 7, 6};
int contador = 0;
int posicionFila = 0;
Keypad teclado = Keypad(makeKeymap(significadoTeclas), pinsFilas, pinsColumnas, FILAS, COLUMNAS);
LiquidCrystal_I2C lcd(0x3F, 16, 2);
void setup(){
lcd.init();
lcd.backlight();
lcd.setCursor(2, 0); // Se mueve el cursor para que el texto quede centrado
lcd.print("Contrasenia:");
lcd.setCursor(6, 1); // Se mueve el cursor para que la contraseña quede centrada
}
void loop() {
char presionada = teclado.getKey(); // Guardamos la tecla presionada
if (presionada) { // Si se presiona una tecla
textoIngresado = textoIngresado + presionada;
if (contador >= 3) {
lcd.clear();
if (contrasenia == textoIngresado) {
lcd.setCursor(4, 1); // Se mueve el cursor para que el texto quede centrado
lcd.print("Correcto");
lcd.setCursor(2, 1); // Se mueve el cursor para que el texto quede centrado
lcd.print("Bienvenido");
delay(2000);
} else {
lcd.print("Incorrecto");
lcd.setCursor(2, 1); // Se mueve el cursor para que el texto quede centrado
lcd.setCursor(0, 1);
lcd.print("Prueba otra vez");
delay(2000);
}
lcd.clear();
textoIngresado = "";
contador = 0;
lcd.setCursor(2, 0);
lcd.print("Contrasenia:");
lcd.setCursor(6, 1);
} else {
lcd.print("*");
contador++;
}
}
}