Objetivos
-
- Comprender el bus I2C.
- Conectar un display I2C.
- Enviando mensajes a la pantalla
Material requerido.
Tienda España | Tienda Mexico | |
---|---|---|
![]() |
Kit inicio UNO | Kit inicio UNO |
![]() |
Kit Inicio Mega | Kit Inicio Mega |
El bus I2C
A medida que la capacidad integración en un único chip aumentaba, el número de componentes comerciales disponibles, aumentaba exponencialmente. Cada vez era, y es, más sencillo fabricar bloques de construcción electrónicos integrados en un único chip, y pronto el grosor de los catálogos de los fabricantes, engordó peligrosamente.
Era relativamente fácil encontrar esos bloques de construcción pero cuando tu diseño requería usar una docena de esos bloques, ponerlos de acuerdo y conseguir que se comunicaran eficazmente, se convirtió en un problema.
Por eso, en los primeros 80, uno de los grandes fabricantes de electrónica (Phillips), propuso una norma de comunicación digital, entre los diferentes componentes de una sistema electrónico.
Una norma que especificaba la velocidad, niveles de tensión, y el protocolo a seguir para conseguir esa comunicación y la hizo abierta.
Esa norma se llamó Inter Integrated Circuits bus, o IIC, y pronto se convirtió en un estándar de facto en la industria. Las especificaciones han ido mejorando con los años, pero la idea básica sigue siendo la misma:
- Protocolo de dos hilos de control, uno para transmitir los datos, SDA y otro, el reloj asíncrono que indica cuando leer los datos SCL. Mas GND y 5V (cuando se requiera).
- Cada dispositivo conectado al bus I2C y cada uno tiene su dirección exclusiva, de 7 bits, (Asi que, en teoría, podemos conectar 27 = 128, dispositivos).
- Uno de estos componentes, debe actuar como master, es decir controla el reloj.
- No se requiere una velocidad de reloj estricta, ya que es el master quien controla el Clock.
- Es multi master, el master puede cambiar, pero solo uno puede estar activo a la vez, y proporciona un protocolo de arbitraje y detección de colisiones. (Si no has entendido esto, no te preocupes, todavía es pronto).
Puedes encontrar que a este bus se le llama I2C, IIC o I2C, y también, como TWI (Two Wire Interface, o interface de 2 hilos), pero siempre es lo mismo.

La idea es que todos los componentes se conecten en paralelo a las dos líneas del Bus, SDA y SCL. En cada momento solo puede haber un master, en este caso, nuestro Duino y los demás se configuran como esclavos.
- Puede haber más de un master. La norma propone un sistema de arbitraje, para transferir el control de uno a otro, pero en un instante dado, solo uno puede ser el master.
- Fijaros también que hay unas resistencias de Pullup conectadas a SDA y SCL. Son imperativas, ya que el bus es activo bajo (Esto es, la señal activa es un 0, no un 1. Pero tranquilo, que esto no te afecta)
- Cuando vayas a conectar algo al busI2C, es imprescindible que leas el manual para saber si los pullups los tienes que poner tú, o vienen puestos en el componente.
- En el caso del display I2C que vamos a usar, normalmente incluyen los pullups.
Y la buena noticia es que nuestro Arduino lo soporta de fábrica con una librería estándar, que utiliza dos de los pines analógicos para las funciones SDA (Datos) y SCL (Clock).
- En el Arduino UNO, los pines I2C están en los pines analógicos A4 (SDA) y A5 (SCL).
- En el Arduino Mega y DUE, son el 20 (SDA) y en el 21(SCL).
La librería I2C, en Arduino se llama Wire (para que no os confiéis), y gestiona el protocolo de comunicaciones completo, lo que es un detalle, pues nos ahorra la parte aburrida de estudiar el protocolo y escribir programas para ello.
- Esto no es vagancia, sino construir sobre el trabajo de terceros. Es una de las muy grandes virtudes de la comunidad Arduino. Muchas librerías para incorporar a nuestros proyectos, sin necesidad de mancharte las manos de grasa.
En esta sesión vamos a conectar un display LCD de 16×2 con interface I2C, y así podréis comprobar porque en la última sesión os recomendé usarlo, en lugar del que se conecta directamente con 16 pines.
Pero antes, tenemos que asegúranos de otro asunto.
Scanner de I2C
Cada componente que conectamos al bus I2C tiene una dirección única, y cada mensaje y orden que transmitimos al bus, lleva anexa esta dirección, indicando cuál de los muchos posibles, es el receptor del mensaje.
Pero, claro, esto implica que sabemos la dirección del componente. Lo normal es comprobar la información técnica del fabricante del componente, y ahí suele decirnos cuál es la dirección por defecto.
Pero como ya sabemos, que en la vida las cosas rara vez son como en los cuentos, algún alma caritativa (y con mucho mundo a sus espaldas), hizo un programita para Arduino, que nos informa, de lo que hay en nuestro bus y con qué dirección. I2C scanner
Naturalmente, este programa, no tiene ni idea de quien responde y lo que hace, pero bastante es que nos informe de que hay alguien en la dirección xx.
Si no sabemos en qué dirección está un componente dado, basta con colocarlo solo en el bus, y ver qué dirección nos reporta el I2C scanner. EL resultado para el LCD que tengo es 0x27 Hexadecimal.

Así que ya podemos pasar a hablar de como programar el uso del display.
Diagrama de conexión
La conexión es, nuevamente, trivial:

Simplemente Arduino A4 a SDA (Datos) y A5 a SCL (Clock), más GND y alimentación. Vamos con el programa.
Programa de control
Lo primero, es que descarguéis una nueva librería para maneja el display con I2C, Se llama LiquidCrystal_I2C y es un añadido para la librería estándar que viene con tu Duino (tranquilo no duele y debería ser automático).
No he encontrado información del autor o autores, y solo he visto que hacen referencia a que el nombre de la librería es Malpartida (A mí no me miréis).
Descarga la librería LiquidCrystal_I2C , y vamos a instalarla lo primero
\\Programa\ImportarLibreria\Añadir \Librería
Busca en tu directorio de descargas, la librería LiquidCrystal_I2C .zip y haz doble click, para que se instale en nuestro IDE.
Ahora vamos a incluir la librería I2c que en Arduino se llama Wire, y como es estándar la incluyes con:
\\Programa\ImportarLibreria\Wire
Ahora hay que incluir la librería LiquidCrystal normal y después la de LiquidCrystal_I2C.Deberiamos tener 3lineas como estas:
#include <Wire.h> #include <LCD.h> #include <LiquidCrystal_I2C.h>
Vamos ahora a definir una variable con la dirección de nuestro display. En mi caso la 0x27
byte dir = 0x27 // Ese 0x significa que es hexadecimal, no decimal
Y por último creamos una instancia del objeto LiquidCrystal_I2C:
LiquidCrystal_I2C lcd( dir, 2, 1, 0, 4, 5, 6, 7);
Al que le pasamos la dirección dir del display y varios números que indican que pines debe usar la librería para el display, no de Arduino. Ignóralo y lo copias así para los displays. El resto queda así:
#include <Wire.h> #include <LCD.h> #include <LiquidCrystal_I2C.h> #define I2C_ADDR 0x27 LiquidCrystal_I2C lcd(I2C_ADDR,2, 1, 0, 4, 5, 6, 7); void setup() { lcd.begin (16,2); // Inicializar el display con 16 caraceres 2 lineas lcd.setBacklightPin(3,POSITIVE); lcd.setBacklight(HIGH); lcd.home (); // go home lcd.print("Prometec.net"); lcd.setCursor ( 0, 1 ); // go to the 2nd line lcd.print("Malpartida lib"); } void loop() {}
Aquí tenéis el resultado:

Resumen de la sesión
En esta curso de arduino hemos aprendido lo siguiente:
-
- Hemos presentado los displays LCD de 16×2 I2C
- Funciona igual que los normales, pere requieren muchos menos cables para instalarlos y se evitan montones de problemas.
- Muy practicos y cuestan poco mas que uno normal.
Hola Jesús, nunca he visto ese error pero por lo que veo estas usando el lcd con el nodemcu y puede ser que el problema venga por ahí. Nunca los he usado juntos, así que no sé muy bien qué decirte. Un saludo.
Hola:
Ya he visto que has soluciondo varios problemas parecidos al mio, y lo he intentado arreglar con las soluciones que has dado aquí, pero no me funciona ninguna de ellas. Tengo un montón de librerías de liquidCristal_I2C instaladas, y no me funciona incluyendo ninguna, ni modificando el archivo que me indica el error, ¿Puedes ayudarme?
/Users/jesus/Documents/Arduino/libraries/jm_Wire/src/utility/jm_twi.c:25:20: fatal error: avr/io.h: No such file or directory
#include
^
compilation terminated.
exit status 1
Error compilando para la tarjeta NodeMCU 1.0 (ESP-12E Module).
Muchas gracias! voy a ver el link recomendado! nuevamente, gracias
Mientras tengan direcciones diferentes no tienes problema. Tendrás que soldar alguno de los puentes de los lcd para cambiarle la dirección si te coinciden las dos pantallas. Echa un ojo a esta sesión a ver si te ayuda: https://www.prometec.net/combinar-dispositivos-i2c/
Hola!, muy buen aporte, gracias. Una pregunta, quiero conectar 2 lcds y un reloj.
Se que debería utilizar el i2c scanner para deterctar las 2 direcciones de los lcd’s, ¿¿¿pero el reloj lo utilizo normalmente?? ¿¿no interfiere en nada??
Muchas gracias
Hola Jose, tienes razón, vamos a ver si la actualizamos.
la libreria LiquidCrystal_I2C que esta en tu pagina es pesada para arduino uno su tamaño es de 1.95 MB cambialo
Sin problemas Antonio, pero tienes que unir las tierras de Arduino y la fuente. Un saludo.
Buenas!
Tengo el Arduino UNO conectado a display 2lc, pulsadores pulldown, sensores y reles. Cuando un rele corta, la luz del display parpadea (apenas perceptible pero lo hace).
¿Se puede conectar el vcc y gnd del display a una fuente de +5V externa? (tengo una fuente de pruebas ATX.)
Felicitaciones por la pagina! De antemano muchas gracias!
Hola MArio, con que los tienes ocupados? No puedes cambiarlo?
Hola Luis, Accede a este archivo libraries/LiquidCrystal_I2C/I2CIO.cpp y busca una línea que pone #include . Ahí sustituye el …/Wire/Wire.h por Wire.h
Hola. muy bueno el tutorial. Te consulto tengo ocupada los pines 20 y 21. que puedo hacer para realizar la conexion?
Arduino:1.8.1 (Windows 7), Tarjeta:»Arduino/Genuino Uno»
C:\Users\Usuario final\Documents\Arduino\libraries\LiquidCrystal_I2C\I2CIO.cpp:35:26: fatal error: ../Wire/Wire.h: No such file or directory
#include
^
compilation terminated.
exit status 1
Error compilación en tarjeta Arduino/Genuino Uno.
Este reporte podría tener más información con
«Mostrar salida detallada durante la compilación»
opción habilitada en Archivo -> Preferencias.
pudiste resolverlo
Gracias por el aporte.
Hola Dan, puede ser que se haya estropeado algún cable. Yo los cambiaría por si acaso. Si no has tocado nada, o es eso o se he estropeado el LCD. Un saludo.
hola lo que pasa es que al cargar algun programa el lcd solo me muestra basura, estaba trabajando bien y derrepente se puso en ese estado que puede ser ??
Hola ivan. Al parecer hay mucha gente con problemas con esta libreria. Esto se debe a que hay distintan versiones circulando y algunos cambios no estan actualizados entre ellas. Yo solucion mi problema asi: Verifica que por lo menos la pantalla se retro ilumine. Actualiza el ide de arduino. Actualiza la libreria desde el ide yo uso la 1.1.2 de brabander. Utiliza el codigo de ejemplo que viene con la libreria. Cualquier cosa nos avisas si solucionaste elproblema
Hola Iván, has probado a girar el potenciómetro de detrás de la pantalla? Sirve para ajustar el contraste, puede ser que la tengas con muy poco contraste y no se llegue a ver nada. Un saludo.
Buenas noches.
Sigo intentando hacer funcionar el display I2C de 20×4 y de momento nada…
La dirección en el bus I2C es 0x3F y es la que le indico en el programa. No me da error al compilar, es solo que lo único que hace es iluminarse. Trabajo desde Raspbian con el Ide Arduino. ¿Alguna idea de por donde mirar? Gracias.