Conectando un LCD I2C a una STM32 Blue Pill usando Arduino IDE

Los display LCD de caracteres pueden conectarse de forma directa a un microcontrolador, pero esto demanda una gran cantidad de pines. Afortunadamente existen módulos, como los basados en el chip PCF8574 que resuelven este problema al permitir la conexión usando sólo los dos pines del bus I2C. En este artículo veremos como controlar un LCD con uno de estos módulos desde una placa STM32 Blue Pill programada en el Arduino IDE.

Introducción

Los display LCD fueron utilizados durante muchos años como pantallas para una infinidad de proyectos. Desde los mas simples de una o dos líneas de texto hasta los mas grandes, con capacidad de mostrar gráficos o incluir una capa sensible al tacto (touchscreen) en distintas variedades de formatos, marcas y colores. En la actualidad se está popularizando el uso de pantallas OLED, que son capaces de mostrar gráficos de mayor resolución con gran nitidez, y también podemos usar algunos modelos de pantallas de tinta electrónica (e-ink o e-paper), tecnologías que ofrecen algunas ventajas pero también inconvenientes. El tiempo dirá si desplazan totalmente a los LCD o si se convertirán en una opción para algunas aplicaciones. En este artículo nos centraremos en los LCD de texto y veremos como controlarlos con el auxilio de un módulo con conexión I2C basado en el PCF8574.

LCD de texto

Aunque existe una gran variedad de display LCD, muchos de ellos comparten el mismo chip controlador: el HD44780 de Hitachi o una variante mas moderna del mismo. Este chip se hizo tan popular que estableció una especie de estándar de hecho en la interface eléctrica y de programación de los LCD, haciéndolos bastante compatibles, salvo algunas pequeñas diferencias introducidas por algunos fabricantes. Esto permitió el desarrollo de mucho código y librerías que nos facilitan enormemente la utilización de estos displays, así como los módulos I2C que nos permiten controlarlos con sólo un par de pines.

Fig. 1. El chip HD44780

Conexiones

Gracias a la compatibilidad de hecho antes mencionada, los display de texto presentan una interfaz electrica, unos pines de conexión similares entre distintos modelos, que tienen una distribución como la que se aprecia en la siguiente imagen (aunque siempre conviene asegurarse revisando la hoja de datos antes de conectar nuestro LCD):

Fig. 2. Conexiones de un LCD de texto

Es una gran cantidad de señales, entre las que tenemos:

GND y VCC: Alimentación (Masa y 5V)

Vo: Tensión de contraste

RS, RW, EN: Señales de control para acceder, leer y escribir en el LCD

D0 a D7: Señales de datos para enviar comandos y datos al display.

BL+, BL-: Alimentación del backlight (iluminación posterior). En algunos modelos estos pines no tienen conexión y el backlight se alimenta empleando otro conector.

Aunque existe la posibilidad de usar un modo en el que nos comunicamos con el LCD usando sólo 4 bits de datos, en lugar de 8, sigue siendo una gran cantidad de señales.

El módulo I2C

El módulo que utilizaremos viene a resolver el problema de la cantidad de pines del LCD, sobre todo en aquellos micros que tienen pocos pines disponibles, ya que cuenta con un circuito integrado PCF8574 que, como ya vimos antes, nos permite tener 8 pines bidireccionales que podemos controlar con sólo dos señales del bus I2C. Las salidas de este módulo tienen la misma disposición del LCD, por lo que la conexión es directa, pudiendo montarse frente al LCD o directamente sobre los mismos pines del conector. Además de los pines que van al LCD, la placa tiene otro conector de 4 pines por donde debemos alimentarlo (VCC y GND) y enviar los datos de control (SCL y SDA).

Fig. 3. Módulo I2C con PCF8574

También se incluye un preset para controlar el contraste del display y tres jumpers para soldar marcados A0, A1 y A2 que definen la dirección de la placa en el bus I2C según la siguiente tabla:

Fig. 4. Disposición de los jumper para fijar la dirección I2C

Conexión con la Blue Pill

La Blue Pill tiene dos interfaces I2C, llamadas I2C1 (PB6 y PB7 como pines principales y PB8, PB9 como pines alternativos) e I2C2 (PB10, PB11). Las librerías que veremos mas adelante y que usamos en el programa utilizan por omisión I2C1 en PB6 y PB7, así que conectaremos allí nuestro módulo (hacia el final veremos como modificarlo si es necesario).

Fig. 5. Interfaces I2C de la Blue Pill

Debemos prestar especial atención a los niveles de alimentación, ya que la Blue Pill funciona con 3.3V y el LCD con 5V (hay algunos que si trabajan con 3.3V pero son mas difíciles de conseguir). Esto significa que debemos alimentar el módulo I2C con 5 Voltios, ya que desde allí se deriva la alimentación del LCD. Mientras hacemos pruebas, podemos sacar esta tensión del ST-Link, pero luego si queremos que el circuito funcione de manera autónoma debemos desconectar el ST-Link y proveer de otra fuente de 5V, por ejemplo desde el puerto USB.

Fig. 6. Circuito alimentado desde el ST-Link
Fig. 7. Circuito para alimentar la Blue Pill por USB

El PCF8574 que está en el módulo I2C admite que las señales SCL y SDA no alcancen los 5V, así que los 3.3V de la Blue Pill serán suficientes. Además, los pines que usaremos (PB6 y PB7) son 5V tolerant, así que si en algún momento funcionan como entradas, no se dañarán con señales de este valor.

El circuito se completa con las resistencias de Pull-up de 4,7K y el jumper de Backlight que debe quedar conectado en el módulo para iluminar el LCD.

Programación

Para el programa necesitaremos de dos librerías: una para controlar la interfaz I2C y la otra para el LCD. Para lo primero podemos emplear la libería Wire, que viene instalada en el IDE. Para el LCD podemos usar varias. En mi caso elegí esta que es una adaptación de la conocida librería LiquidCrystal para funcionar a través de I2C. Para utilizarla primero debemos descargarla del repositorio en formato ZIP y luego agregarla al IDE en Programa Incluir libreríaAñadir biblioteca .ZIP

El siguiente programa nos permite comprobar que todo funcione correctamente:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define LCD_ADDRESS 0x27      //Cambiar si es necesario

LiquidCrystal_I2C lcd(LCD_ADDRESS, 16, 2);

void setup() {

    lcd.init ();
    lcd.setCursor (0,0);
    lcd.print ("Hola Mundo!");

 }

 void loop() {

 }

Al compilar el programa seguramente se mostrará un mensaje de alerta (Warning) como el siguiente:

ATENCIÓN: la librería LiquidCrystal_I2C-master pretende ejecutarse sobre arquitectura(s) avr y puede ser incompatible con tu actual tarjeta la cual corre sobre arquitectura(s) stm32.

Que nos alerta de que la librería no es original para STM32, pero podemos ignorarlo ya que no afecta a su funcionamiento.

Funciones de la librería LiquidCrystal_I2C

init () : Inicializa la interfaz I2C y el LCD

clear () : Borra el display, lleva el cursor a 0,0

home () : Lleva el cursor a 0,0

setCursor (uint8_t col, uint8_t fila) : Posiciona el cursor en fila,col. Desde esta posición se mostrarán los elementos que se impriman.

noDisplay () : Apaga el display

display () : Prende el display

noCursor () : Apaga el cursor

cursor () : Prende el cursor

noBlink () : El cursor no parpadea

blink () : El cursor parpadea

print (char c[]) : Imprime un texto

scrollDisplayLeft () : Hace un scroll a la izquierda

scrollDisplayRight () : Hace un scroll a la derecha

leftToRight () : Configura la impresión de de izquierda a derecha

rightToLeft () : Configura la impresión de derecha a izquierda

autoscroll () : Mueve el texto a la izquierda una posición cada vez que se imprime un caracter

noAutoscroll () : Inhabilita el modo anterior.

createChar (uint8t location, uint8t charmap[]) : Escribe la definición de un carácter redefinible en location (0 a 7). charmap contiene la definición del caracter con los 8 patrones de bits. Luego explicaré con mas detalle como usar los caracteres definibles por el usuario (custom chars)

noBacklight () : Apaga el backlight

backlight () : Prende el backlight

write (char) : Imprime el caracter char

Caracteres definibles por el usuario

Los controladores HD44780 y compatibles tienen los patrones de los caracteres a imprimir almacenados en una memoria ROM y por tanto no se pueden modificar. Sin embargo, existe un espacio de memoria denominado CGRAM (Character Generator RAM) donde podemos almacenar los patrones de hasta 8 caracteres definidos según nuestras necesidades.

Cada caracter se define con 8 bytes, de los cuales se emplean sólo los 5 bits mas bajos, puesto que cada uno se representa como una matriz de 5×8 puntos. En cada byte, un valor “1” ilumina un punto y un valor “0”. Lo apaga.

Por ejemplo, estos son los 8 bytes necesarios para definir el patrón de un corazón:

Fig. 8. Patrones para definir un corazón

Siempre conviene dejar la última línea en blanco porque es la posición que toma el cursor cuando está visible.

Ejemplo:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define LCD_ADDRESS 0x27    //Cambiar si es necesario

LiquidCrystal_I2C lcd(LCD_ADDRESS, 16, 2);

byte corazon [8] = {
 B00000,
 B00000,
 B01010,
 B11111,
 B11111,
 B01110,
 B00100,
 B00000,
 };

void setup() {

   lcd.init ();
   lcd.clear ();

   lcd.createChar (0, corazon);  //Define el caracter del usuario 0

   lcd.setCursor (0,0);
   lcd.print ("Hola");
   lcd.write (0);                //Imprime el caracter 0
}

void loop() {
   // put your main code here, to run repeatedly:
}

Fig. 9. Caracteres definidos por el usuario

Remapeo de pines I2C

Si por alguna razón necesitamos conectar el LCD en otros pines que no sean PB6 y PB7, tenemos la posibilidad de remapear los pines I2C, como se puede ver en el siguiente ejemplo:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define LCD_ADDRESS 0x27   //Cambiar si es necesario

LiquidCrystal_I2C lcd(LCD_ADDRESS, 16, 2);

void setup() {

    //Remapear a PB8, PB9
    //Wire.setSDA(PB9);
    //Wire.setSCL(PB8);
    //Wire.begin();

    //Remapear a PB10, PB11
    Wire.setSDA(PB11);
    Wire.setSCL(PB10);
    Wire.begin();

    lcd.init ();
    lcd.setCursor (0,0);
    lcd.print ("Hello Mundo!");

}

void loop() {
// put your main code here, to run repeatedly:

}

Esta página les puede ser de gran ayuda para definir sus propios caracteres.

Conclusión

En este artículo vimos como conectar un LCD de texto a una placa Blue Pill usando el puerto I2C. También vimos como emplear la librería LiquidCrystal_I2C para controlar el display, sus distintas funciones y el procedimiento para definir caracteres especiales y mostrarlos en pantalla.

Espero que la información les sea de utilidad para sus proyectos! Cualquier duda o sugerencia pueden dejarla mas abajo en la sección de comentarios.

1 comentario en «Conectando un LCD I2C a una STM32 Blue Pill usando Arduino IDE»

  1. Hola, necesito remapear los pines sda y scl de las conexiones I2C pero al intentar compilarlas las instrucciones
    Wire.setSDA(PB11);
    Wire.setSCL(PB10);
    me dan un error
    class TwoWire’ has no member named ‘setSDA
    y al intentar la instruccion
    Wire.begin(PB11,PB10);
    me da un error
    no matching function for call to ‘TwoWire::begin(, )’

    Alguna sugerencia?

    Responder

Responder a Jose Alarcon Cancelar la respuesta

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Habilitar notificaciones OK No, gracias