Display 16x2 Character LCD Expansión I2C - pensactius/Tutoriales GitHub Wiki

Este tutorial está pensado para pantallas LCD de caracteres con el módulo de expansión I2C. Si tu LCD no tiene este módulo (tiene 16 pines) consulta el tutorial

Como se comentó en el tutorial LCD 16x2 Caracteres, incluso con el modo de 4-bits, hay que usar 6 o hasta 7 pines de Arduino. En una placa como Arduino UNO que tiene sólo 14 E/S (Entrada/Salida) digitales, estamos hablando de casi la mitad sólo para el LCD.

Otra opción sería usar un adaptador I2C que se suelda al LCD (algunos LCDs ya vienen con el adaptador soldado). De esta manera sólo se usan dos pines para E/S.

El bus I2C

I2C -también llamado IIC- son las siglas de Inter Integrated Circuit bus (Circuito Inter Integrado). Fue desarrollado por Philips Semiconductors en 1982 para las televisiones. La idea era que los circuitos integrados en las televisiones pudieran "hablarse" los unos a los otros usando un bus estandard.

Este bus ha ido evolucionando y ahora se usa para comunicación entre microcontroladores, circuitos integrados, sensores y micro computadores. Se puede usar para comunicar Arduinos o diferentes micros entre sí, como interfaz entre diversos sensores y dispositivos de salida.

El bus I2C utiliza sólo cuatro conexiones, dos de ellas son para alimentación:

  • Alimentación - Puede ser 5 voltios o 3.3 voltios, dependiendo de la aplicación. Ten en cuenta que hay que tener precaución si se está trabajando con dispositivos I2C que funcionan a 3.3V y 5V en el mismo bus.
  • Ground - Conexión a tierra
  • SDA - Serial Data. Esta línea se ua para transmitir y recibir.
  • SCL - Serial Clock. Por aquí se recibe la señal de reloj para tareas de sincronización. Proviene del dispositivo Bus Master.

En comunicaciones I2C existe el concepto de dispositivos Master (Maestro) y Slave (Esclavo). Puede haber varios de cada uno, pero sólo puede haber un Master en un momento dado. En general el microcontrolador (Arduino, ESPxx, STM32, etc.) hará las tareas de Master durante toda la ejecución del programa y el resto de dispositivos I2C conectados harán de Slave.

El Master transmite la señal de reloj que determina lo rápido que se transmitirán los datos por el bus. Hay varias velocidades según el bus I2C. El diseño original de I2C usaba relojes de 100 KHz y 400 KHz. En algunas configuraciones se consiguen velocidades de hasta 3.4 MHz.

Para la mayoría de diseños con Arduino (o placas similares) se usa una frecuencia de 400 KHz.

Cada dispositivo I2C tiene una dirección única que lo identifica del resto de dispositivos conectados al mismo bus. Cuando un Master quiere comunicarse con un dispositivo Slave utiliza la dirección del Slave para iniciar la comunicación. De esta forma podemos tener múltiples dispositivos I2C conectados en un mismo bus sin interferir entre ellos (siempre y cuando tengas dirección I2C diferentes)

Adaptador I2C

El adaptador I2C para el LCD es una pequeña placa soldada a 16 pines macho. La mayoría de estas placas se basan el el chip PCF8574T. Si realizas una búsqueda en Aliexpress con las palabras pcf8574T lcd encontrarás una gran variedad de estos módulos y LCDs con el módulo ya incorporado. La idea es conectar (soldar) estos pines directamente a los 16 pines del LCD.

El dispositivo tiene además un conector de cuatro pines para el bus I2C. Hay también un potenciómetro pequeño en la placa que permite controlar el brillo de la pantalla del LCD.

La mayoría de estos dispositivos tienen tres jumpers (puentes) o pads para establecer la dirección I2C. De esta forma se puede cambiar la dirección si hay varios dispositivos en conflicto conectados al mismo bus I2C.

Conexión con Arduino

Arduino UNO (o cualquier Arduino basado en ATmega328P como Arduino Nano) utiliza dos de los pines analógivos como conexión I2C. A4 se usa como SDA mientras que A5 se usa como SCL.

Algunas placas Arduino UNO (especialmente las Arduino UNO R3) tiene pines dedicados para I2C. En realidad están conectados internamente a A4 y A5 y suelen estar situadas en la parte superior de los 14 pines E/S digitales.

El siguiente diagrama ilustra como conectar Arduino UNO a una pantalla LCD con el adaptador I2C (extraído de Eldontronics: Electronics Hobbyist). Se ilustra con un Arduino Nano, pero la conexión es idéntica para Arduino UNO.

Determinar la dirección I2C

Como estamos usando un dispositivo I2C, debemos determinar la dirección de este. Carga el programa I2C Scanner que puedes obtener de la web de Arduino.

// --------------------------------------
// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    https://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// Version 6, November 27, 2015.
//    Added waiting for the Leonardo serial communication.
// 
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//

#include <Wire.h>


void setup()
{
  Wire.begin();

  Serial.begin(9600);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}


void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the 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);           // wait 5 seconds for next scan
}

Despues de cargar el programa abre el monitor serie de Arduino. Si el dispositivo es reconocido como I2C verás la dirección I2C de este. Toma nota de esta dirección para usarla en el ejemplo que veremos a continuación.

Librería NewLiquidCrystal (No la recomiendo)

Si buscas información en Internet sobre cómo programar un LCD con el módulo I2C casi todas las páginas que encuentres utilizan la librería NewLiquidCrystal de fmalpartida.

Yo no la recomiendo por varios motivos:

  • Enlaces obsoletos - En enlace de descarga en bitbucket está roto. He encontrado una descarga en github que sí funciona.

  • Sin actualizaciones recientes - La última actualización data de 5 años o más

  • Problemas de compatibilidad - Con algunas pantallas LCD que he probado no me ha funcionado bien.

Por estos motivos no utilizo esta librería y por tanto no voy a dedicar más líneas.

Librería hd44780

La librería que utilizo yo en mis proyectos para controlar LCDs con el módulo de expansión I2C es la hd44780 de Bill Perry. Es un poco más complicada de usar, pero es más fiable y recibe actualizaciones más frecuentes (a fecha de estas líneas la última actualización es de Agosto de 2020).

Instalación

La libería hd44780 puede instalarse directamente desde el Gestor de Librerías de Arduino.

  • Abre el IDE Arduino. Asegúrate de usar la versión 1.8 o superior.
  • Haz clic en el menú Programa en la barra superior del menú.
  • Haz clic en el submenú Incluir Librería / Administrar Bibliotecas. Se abrirá el cuadro de diálogo Gestor de Librerías.
  • En el cuadro de texto Filtre su búsqueda introduce el texto hd44780 bill perry.
  • Encontrarás la librería hd44780 by Bill Perry. A fecha de estas líneas la última versión es la 1.3.1. Haz clic en Instalar.
  • Cuando termine de instalarse haz clic en el botón Cerrar.

Código Arduino

La librería hd44780 se ha diseñado para ser compatible con la API de LiquidCrystal. Eso significa que la mayoría de funciones se usan exactamente igual. Lo que cambiará es la forma de crear el objeto para controlar el LCD y las cabeceras (ficheros include) a incluir.

Vamos a ver el programa que realizamos en el anterior tutorial usando la librería hd44780. El código a escribe 'Hola Mundo!' por la pantalla del LCD. Sólo explicaré los detalles para usar la librería pues el resto es exactamente igual que el ejemplo anterior.

// incluimos las librerías necesarias para usar el módulo de expansión I2C
#include <Wire.h>
#include <hd44780.h>                        // cabecera principal hd44780
#include <hd44780ioClass/hd44780_I2Cexp.h>  // cabecera para el módulo de expansión I2C

// Creamos un objeto para controlar el LCD
// No necesita ningún parámetro. La librería intenta auto-configurar el módulo I2C y 
// busca su dirección automáticamente.
hd44780_I2Cexp lcd;

void setup() 
{
    // inicializa el LCD con el número de columnas y filas:
    // begin() devuelve un estado que se puede usar para determinar si la inicialización
    // ha fallado.
    //
    // mirar el estado devuelto por begin() es opcional, pero es recomendable al usar
    // el módulo de expansión I2C para comprobar si ha habido algún problema, como que
    // no se haya detectado el módulo, o no se ha encontrado la dirección I2C.
    //
    int status;

    status = lcd.begin(16, 2);
    if (status != 0)    // resultado diferente de cero significa error
    {
        // hd44780 tiene una rutina fatalError que parpadea un led, si es posible.
        // Si llegamos a este punto significa que begin() ha fallado. 
        // Hacemos parpadear el LED interno de la placa con un código de error si
        // es posible
        hd44780::fatalError(status);    // Ya no vuelve, se queda aquí
    }

    // Inicialización exitosa, la iluminación trasera debería estar encendida ahora
    //
    // ---- A partir de aquí el código es idéntico a LiquidCrystal -----
    //
    // Borra la pantalla del LCD 
    lcd.clear();
}

void loop() 
{
    // Establece el cursor a la columna 3, línea 0
    // (nota: línea 0 es la primera fila, ya que comienza a contar por la 0)
    lcd.setCursor(2,0);
    // Muestra un mensaje 
    lcd.print("Hola Mundo!");

    // Establece el cursor a la columna 3, línea 1
    // (nota: línea 1 es la segunda fila, ya que comienza a contar por la 1)
    lcd.setCursor(2, 1);
    // Muestra mensaje 
    lcd.print("===========");   // 11 guiones
}
⚠️ **GitHub.com Fallback** ⚠️