← Índice del curso

Sensores y Actuadores · Tema 37

Displays de 7 segmentos y LCD de caracteres

Un LED dice «sí» o «no»; un número en un display dice cuánto. Los displays de 7 segmentos y los LCD de caracteres son la forma más barata de mostrar valores de sensores sin una computadora. Son, además, dos casos de estudio de cómo ahorrar pines: la multiplexación de dígitos que se hace con un barrido, y los controladores (TM1637, MAX7219, HD44780 con I2C) que hacen ese trabajo por el microcontrolador, con sus propios tiempos y sus propias trampas.

01 · Punto de partida

Mostrar un número

Una estación de temperatura (tema 13), un inclinómetro (tema 21) o un velocímetro con encoder (tema 26) producen números, y una persona los quiere leer sin conectar una computadora. Hay dos familias baratas de salida:

  • Displays de 7 segmentos: cada dígito son siete LEDs (más un punto) con forma de «8». Son brillantes, se leen de lejos y solo muestran números y unas pocas letras.
  • LCD de caracteres: una matriz de puntos de 5 × 8 por carácter, con un controlador que ya trae la tabla de letras. Una pantalla común es de 16 columnas por 2 filas; se lee de cerca, necesita retroiluminación y muestra texto.

Ambos plantean el mismo problema de ingeniería: un display de 4 dígitos tiene 32 LEDs, y un LCD tiene 11 líneas de interfaz. Sin más ayuda, consumirían todos los pines de una placa chica. Las soluciones, en orden de abstracción, son multiplexar con el microcontrolador, delegar en un driver (TM1637, MAX7219) o usar un bus (I2C). Cada una cambia pines por tiempo, corriente o dependencia de una biblioteca.

02 · El dígito

El display de 7 segmentos

Los siete segmentos se nombran de la a a la g (a arriba, luego en el sentido horario b, c, d, e, f, y g en el centro), y un octavo LED es el punto decimal (dp). Cada segmento es un LED, con las mismas reglas del tema 35: una resistencia en serie por segmento (con 5 V y un LED rojo de 2 V a 10 mA, 300 Ω → 330 Ω).

Los ocho LEDs de un dígito comparten un terminal, y de ahí las dos versiones:

Cátodo común y ánodo común.
AspectoCátodo comúnÁnodo común
Terminal comúnA masaA la alimentación
Se enciende un segmento conNivel alto en su pinNivel bajo en su pin
Patrón de un «8»0b011111110b10000000 (el complemento)
La corriente del común esLa suma de los segmentos encendidos, que entra al pin o transistorLa suma de los segmentos encendidos, que sale del pin o transistor

Para mostrar un número, cada dígito se convierte en un byte con un bit por segmento. Con el orden bit 0 = a … bit 6 = g, bit 7 = punto, el 0 es 0x3F, el 1 es 0x06, el 2 es 0x5B, el 3 es 0x4F, el 4 es 0x66, el 5 es 0x6D, el 6 es 0x7D, el 7 es 0x07, el 8 es 0x7F y el 9 es 0x6F. También se pueden formar las letras A, b, C, d, E y F (hexadecimal) y unos pocos símbolos (- es solo g). Para un ánodo común se invierte el byte con ~. Las tablas se guardan en un arreglo y se indexan por el dígito, y el código no se escribe a mano para cada caso.

Y un punto de corriente: un «8» con punto enciende ocho segmentos, 80 mA con 10 mA por segmento, un valor que un pin no entrega. Un «1» enciende dos. Por eso la corriente del terminal común depende del dígito que se muestre, y el transistor o driver que lo maneja debe dimensionarse para el peor caso.

03 · Ahorrar pines

Multiplexar dígitos

Cuatro dígitos con conexión directa necesitarían 32 pines. El multiplexado aprovecha que los segmentos de todos los dígitos son «iguales»: se conectan en paralelo (a con a, b con b…) y cada dígito tiene su común separado. El programa enciende un dígito por vez: pone en los pines de segmentos el patrón de ese dígito, conecta su común, y pasa al siguiente. Si el ciclo es lo bastante rápido, el ojo ve los cuatro dígitos encendidos. Con 4 dígitos se usan 8 + 4 = 12 pines, y con 8 dígitos, 16.

Es el mismo cálculo del tema 35: cada dígito está encendido 1/N del tiempo, así que para el mismo brillo medio la corriente de pico por segmento debe ser N veces mayor.

Multiplexado de dígitos con 5 mA de corriente media por segmento y 100 cuadros por segundo.
DígitosCicloI pico por segmentoBarridoTiempo por dígitoComún con 8 segmentos
11/15 mA100 Hz10 ms40 mA
41/420 mA400 Hz2,5 ms160 mA
81/840 mA800 Hz1,25 ms320 mA

La corriente de pico por segmento (20 mA con 4 dígitos) está al límite de un pin, y la del común (160 mA) lo excede ampliamente, de modo que cada común se maneja con un transistor (NPN para cátodo común, PNP o MOSFET de canal P para ánodo común; tema 27). Y un LED de 7 segmentos típico admite picos de unos 100 mA con ciclos de 1/10 o menores, que figuran en su hoja de datos.

El barrido se hace desde una interrupción de timer o desde un lazo sin bloqueos, no con delay(): si el programa se detiene unos milisegundos en otra tarea, el dígito que estaba encendido queda encendido de más y los demás se apagan (brillo irregular, parpadeo y un dígito con más luz). En un AVR, cada paso del barrido con digitalWrite cuesta unos 40 µs: con 4 dígitos a 100 cuadros por segundo son 400 pasos por segundo, un 1,6 % de la CPU, y con 8 dígitos, 3,2 %. Y hay dos defectos clásicos:

  • Fantasmas: si se cambia el patrón de segmentos con el común anterior todavía activo, el dígito anterior brilla un instante con el patrón nuevo. Se apaga todo, se cambian los segmentos y recién entonces se activa el nuevo dígito.
  • Parpadeo: con menos de unos 60 cuadros completos por segundo se nota, y con una cámara se ven bandas aun a más.

04 · Delegar el barrido

Drivers: TM1637 y MAX7219

Un driver es un circuito que hace el barrido solo y guarda lo que debe mostrar. El microcontrolador escribe los dígitos una vez, por un bus serie de pocos hilos, y se desentiende. Dos son los más comunes en módulos baratos.

TM1637

  • Interfaz de 2 hilos (CLK y DIO), con aspecto de I2C pero sin dirección: no es I2C y no puede compartir bus. Se implementa con bit-banging, bloqueando el programa mientras se envía.
  • Módulos de 4 o 6 dígitos, con los dígitos de 7 segmentos ya cableados, el punto o los dos puntos del reloj en algunos modelos.
  • Brillo de 8 niveles: ciclos de 1/16, 2/16, 4/16, 10/16, 11/16, 12/16, 13/16 y 14/16.
  • También lee un teclado de hasta 16 teclas.
  • Con la biblioteca habitual (100 µs por semiperíodo de reloj), actualizar los dígitos lleva unos 13 ms, tiempo durante el cual el programa está detenido.

MAX7219

  • Interfaz de 3 hilos tipo SPI (DIN, CLK y LOAD/CS), hasta 10 MHz. Maneja 8 dígitos de 7 segmentos o una matriz de 8 × 8 LEDs (64 LEDs con 3 pines).
  • Registros: cada escritura son 16 bits (dirección y dato). Los registros 1 a 8 contienen los dígitos; los otros fijan el modo de decodificación (Code B, que convierte un número en segmentos), la intensidad (0 a 15), el límite de barrido (cuántos dígitos se barren), el apagado y un modo de prueba que enciende todo.
  • Corriente de segmento fija por una resistencia (RSET), de unos 10 kΩ para 40 mA con LEDs rojos a 5 V; la tabla exacta está en la hoja de datos. No hace falta una resistencia por segmento.
  • Brillo de 16 niveles: ciclo (2n + 1)/32, del 3,1 % (nivel 0) al 96,9 % (nivel 15), con barrido interno de unos 800 Hz.
  • En cascada: la salida DOUT de uno va a la entrada del siguiente; con K chips se envían K × 16 bits y se sube LOAD una vez.
  • Pide alimentación de 5 V, con lo que su entrada exige cerca de 3,5 V de nivel alto: una señal de 3,3 V puede no alcanzar, y se usa un adaptador de nivel (como con las tiras del tema 36).

Un detalle del MAX7219: el límite de barrido reduce cuántos dígitos se multiplexan, y los que quedan están encendidos más tiempo. Con 8 dígitos, nivel 15 y 40 mA de pico, la corriente media por segmento es de 4,84 mA; con 4 dígitos, 9,69 mA; con 2, 19,4 mA. Se ajusta la intensidad cuando se cambia el número de dígitos, o los segmentos trabajan sobrecargados.

05 · Texto

El LCD de caracteres HD44780

El LCD de 16 × 2 (o 20 × 4) usa el controlador HD44780 o un compatible. El controlador guarda en su memoria la imagen de cada carácter (5 × 8 puntos) y lo que se debe mostrar, de modo que al programa le basta enviar códigos ASCII.

  • Memoria de pantalla (DDRAM): 80 bytes. En un 16 × 2, la fila 1 empieza en la dirección 0x00 y la fila 2 en 0x40 (en un 20 × 4, las filas empiezan en 0x00, 0x40, 0x14 y 0x54). Para posicionar el cursor se envía 0x80 | dirección.
  • Memoria de caracteres propios (CGRAM): ocho caracteres de 5 × 8 definibles, que sirven para flechas, el símbolo de grado o barras.
  • Tabla de caracteres: la más común (A00) trae ASCII y katakana; el símbolo de grado ° es el 0xDF. Algunas letras del español (la ñ, 0xEE, sí está; la á no) hay que definirlas como caracteres propios.
  • Interfaz paralela: RS (comando o dato), E (enable: la pulsación que captura el dato), RW (casi siempre a masa: solo escritura) y D0 a D7. El modo de 4 bits usa solo D4 a D7 y envía cada byte en dos mitades, con lo que bastan 6 pines (RS, E, D4 a D7).
  • Contraste: el pin V0 va a un potenciómetro de 10 kΩ (a unos 0,5 V suele verse bien). Con el contraste mal ajustado, no se ve nada, o aparecen cuadros negros en la fila superior (señal de que el controlador no se inicializó).
  • Retroiluminación: los pines A y K son un LED que, con 5 V, pide una resistencia (100 a 220 Ω, entre 20 y 100 mA según el módulo) o un transistor.
Comandos principales del HD44780 y su tiempo de ejecución.
ComandoCódigoTiempo
Borrar la pantalla (clear)0x011,52 ms
Cursor al inicio (home)0x021,52 ms
Modo de entrada (cursor hacia la derecha)0x0637 µs
Pantalla encendida, sin cursor0x0C37 µs
Función: 4 bits, 2 líneas, 5 × 80x2837 µs
Posicionar en la DDRAM0x80 | dirección37 µs
Escribir un carácterRS = 1, código ASCII37 µs

Si el programa no lee la bandera de ocupado (RW a masa), debe esperar esos tiempos, y el clear es 40 veces más lento que un carácter. La inicialización en modo de 4 bits sigue una secuencia fija: esperar más de 40 ms tras el encendido, enviar tres veces 0x3 (con esperas de 4,1 ms y de 100 µs) y luego 0x2 para pasar a 4 bits, y finalmente 0x28, 0x08, 0x01, 0x06 y 0x0C. Las bibliotecas lo hacen, pero es la razón por la que un LCD que funcionaba deja de hacerlo si se enciende antes que la alimentación se estabilice: no se inicializó.

06 · Dos hilos

El adaptador I2C

Los módulos baratos de LCD con I2C son un LCD con una plaquita soldada detrás: un expansor de pines PCF8574 (8 salidas controladas por I2C) conectado a los pines del LCD. Alcanza con cuatro cables: VCC, GND, SDA y SCL (el mismo bus I2C de los sensores digitales del tema 12). La conexión habitual es:

Conexión típica del PCF8574 al LCD (puede variar según el módulo).
Bit del PCF8574P0P1P2P3P4 a P7
Señal del LCDRSRWERetroiluminaciónD4 a D7
  • Dirección: 0x20 + (A2 A1 A0) para el PCF8574, es decir 0x20 a 0x27 (los puentes de la plaqueta fijan los tres bits); 0x38 + (A2 A1 A0) para el PCF8574A, 0x38 a 0x3F. Los módulos más comunes salen con 0x27 o 0x3F; si no se sabe, un escáner I2C que pruebe todas las direcciones la encuentra.
  • Un byte del LCD son cuatro bytes I2C: la mitad alta con E = 1, la mitad alta con E = 0 (el flanco que captura el LCD), y lo mismo con la mitad baja.
  • Tiempo: una transacción I2C con dirección y cuatro bytes de datos son unos 47 tiempos de bit: 0,47 ms por carácter a 100 kHz y 0,12 ms a 400 kHz. La biblioteca LiquidCrystal_I2C más difundida hace, según su implementación habitual, una transacción por cada escritura (seis por cada byte de LCD) y espera unos 100 µs: 1,3 ms por carácter a 100 kHz.
  • Resistencias de pull-up: la plaqueta suele traerlas; con otros dispositivos en el bus puede haber más de las necesarias (tema 12).
  • Niveles: la plaqueta funciona a 5 V; con un ESP32 o una placa de 3,3 V, SDA y SCL a 3,3 V suelen ser suficientes para el PCF8574, pero conviene verificarlo y, si no, usar un adaptador de nivel.

La consecuencia práctica es el tiempo: actualizar los 32 caracteres con la biblioteca típica a 100 kHz tarda 44 ms durante los cuales el programa está detenido, y con un clear previo, 47 ms más el parpadeo. Por eso se escribe solo lo que cambió.

07 · Elegir

Comparación y elección

Cuatro formas de manejar displays.
OpciónPines (4 dígitos / 8 dígitos)Quién barreVentajasCosto
Conexión directa con multiplexado12 / 16El microcontrolador (timer)Sin chips; control total del brilloPines, CPU, transistores
Registro de desplazamiento (74HC595)3 + comunesEl microcontroladorAhorra pines de segmentosAún hay que barrer
TM16372El chipMódulos de 4 dígitos baratos; lee teclasBit-banging de ~13 ms; sin bus compartido
MAX72193 (en cadena)El chip8 dígitos o matriz 8 × 8; brillo de 16 niveles; cascadaRSET; nivel de 5 V
LCD 16 × 2 con I2C2 (bus compartido)El controlador del LCDTexto completo; comparte bus con sensoresLento (decenas de ms por pantalla)

Una guía rápida: para un número de pocas cifras (temperatura, hora) y poco presupuesto de pines, un módulo TM1637; para muchos dígitos o una matriz, un MAX7219; para texto, menús y valores con etiquetas, un LCD con I2C (o, si hace falta dibujar, el OLED del tema 38); y para aprender cómo funciona un barrido, la conexión directa.

08 · Legibilidad

Presentar datos

Tan importante como la electrónica es lo que se hace con el número antes de mostrarlo:

  • Ancho fijo: formatear con un ancho constante (%5.1f) y rellenar con espacios, así el número no «baila» de lugar al cambiar de 9,9 a 10,0, y no quedan caracteres de más. Con un LCD, print("9") tras print("10") deja «90»; hay que escribir "9 ".
  • Frecuencia de actualización: una persona no lee un número que cambia más de 2 a 4 veces por segundo. Un sensor leído a 100 Hz se muestra a 2 o 4 Hz, y el valor puede promediarse (tema 5) en ese intervalo.
  • Histéresis de presentación: si el último dígito de una temperatura fluctúa, mostrar menos decimales o cambiar el valor mostrado solo cuando la diferencia supera la resolución.
  • Desborde y error: si el valor no cabe o el sensor falló (tema 44), mostrar ---- o Err, y no un número cortado o equivocado.
  • Ceros a la izquierda: en un 7 segmentos, apagar los dígitos sin significado (un «7» y no «0007»), salvo en un reloj.
  • Escribir lo que cambió: en un LCD, nada de clear() en cada ciclo; posicionar el cursor y reescribir solo el campo que cambia.
  • Barras: con los 8 caracteres propios se dibuja una barra de progreso con una resolución de 5 columnas por celda: en 16 celdas, 80 pasos.

09 · Programación

Código para manejar displays

Cuatro piezas: la tabla de segmentos con el barrido multiplexado por interrupción, una escritura al MAX7219, el uso del TM1637 y un LCD I2C que reescribe solo lo que cambia.

// --- Tabla de segmentos (cátodo común): bit 0 = a ... bit 6 = g, bit 7 = punto ---
const uint8_t SEGMENTOS[16] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};

// --- Barrido multiplexado de 4 dígitos, llamado desde una interrupción de timer a 400 Hz ---
const uint8_t PIN_SEG[8] = {2, 3, 4, 5, 6, 7, 8, 9};      // a, b, c, d, e, f, g, dp
const uint8_t PIN_DIG[4] = {10, 11, 12, 13};              // comunes (cada uno con su transistor)
volatile uint8_t patron[4];                               // lo que se muestra en cada dígito

void barrer() {
    static uint8_t d = 0;
    for (uint8_t i = 0; i < 4; i++) digitalWrite(PIN_DIG[i], LOW);          // apagar todo antes de cambiar: sin fantasmas
    for (uint8_t s = 0; s < 8; s++) digitalWrite(PIN_SEG[s], (patron[d] >> s) & 1);
    digitalWrite(PIN_DIG[d], HIGH);
    d = (d + 1) & 3;
}

void mostrarEntero(int valor) {                           // ancho fijo de 4 dígitos, sin ceros a la izquierda
    if (valor > 9999 || valor < 0) { for (auto &p : patron) p = 0x40; return; }   // "----"
    for (int i = 3; i >= 0; i--) {
        patron[i] = (valor == 0 && i < 3) ? 0x00 : SEGMENTOS[valor % 10];
        valor /= 10;
    }
}

// --- MAX7219 por SPI: una escritura son 16 bits (dirección y dato) ---
void max7219(uint8_t registro, uint8_t dato) {
    digitalWrite(PIN_CS, LOW);
    SPI.transfer(registro); SPI.transfer(dato);
    digitalWrite(PIN_CS, HIGH);                           // el flanco de subida carga el dato
}
void iniciarMax7219() {
    max7219(0x0F, 0x00);                                  // sin modo de prueba
    max7219(0x0B, 0x07);                                  // barrer los 8 dígitos
    max7219(0x09, 0xFF);                                  // decodificación Code B en todos los dígitos
    max7219(0x0A, 0x08);                                  // intensidad intermedia (0 a 15)
    max7219(0x0C, 0x01);                                  // salir del apagado
}

// --- TM1637 con la biblioteca TM1637Display ---
TM1637Display display(PIN_CLK, PIN_DIO);
void mostrarTemperatura(float t) {
    display.setBrightness(4);                             // 0 a 7
    display.showNumberDecEx((int)round(t * 10), 0b01000000, false);   // un decimal; los dos puntos como separador
}

// --- LCD I2C: reescribir solo el campo que cambió, con ancho fijo ---
LiquidCrystal_I2C lcd(0x27, 16, 2);
void mostrarTemperaturaLcd(float t) {
    char buf[8];
    dtostrf(t, 5, 1, buf);                                // "  9.9", " 23.5": ancho fijo, sin restos
    lcd.setCursor(0, 1);
    lcd.print(buf);
    lcd.print((char)0xDF);                                // símbolo de grado de la tabla A00
    lcd.print("C ");
}

La separación es la de siempre: la aplicación llama a mostrarTemperatura(t) y solo el módulo conoce el display, su tabla de segmentos, su dirección y sus tiempos. Cambiar un TM1637 por un LCD no toca el resto del programa.

10 · Verificación

Fallas y verificación

Fallas típicas con displays.
SíntomaCausaDefensa
Dígitos con brillo distintoBarrido con tiempos irregulares (programa bloqueado)Barrer desde un timer, no con delay()
Fantasmas tenuesCambio de segmentos con el común anterior activoApagar todo antes de cambiar de dígito
ParpadeoMenos de 60 cuadros por segundoBarrido de 100 Hz o más por cuadro completo
Un «8» más tenue que un «1»Corriente común compartida a través de una resistencia únicaUna resistencia por segmento, o un driver con corriente constante
Pin o chip recalentadoCorriente del común superior a la del pinTransistor por dígito
LCD con cuadros negros en la fila 1No se inicializó el controladorRevisar secuencia, tiempos tras el encendido y alimentación
LCD en blanco con la retroiluminación encendidaContraste mal ajustadoGirar el potenciómetro de V0
LCD I2C que no respondeDirección equivocada (0x27 en lugar de 0x3F) o SDA y SCL cruzadosEscáner I2C; revisar cableado
Restos de texto anterior en el LCDValor más corto que el anterior, sin rellenoAncho fijo con espacios
Pantalla que parpadea o programa lentoclear() en cada ciclo; escrituras I2C lentasEscribir solo lo que cambió; subir el bus a 400 kHz
MAX7219 sin respuesta con 3,3 VNivel lógico insuficienteAdaptador de nivel; alimentar a 5 V
  1. Mostrá todos los segmentos (un «8.» en cada dígito, o el modo de prueba del MAX7219) y buscá segmentos apagados o puentes.
  2. Recorré los dígitos 0 a 9 en cada posición y verificá la tabla.
  3. Medí la corriente del común con todos los segmentos encendidos (el peor caso) y comprobá que el transistor no se calienta.
  4. Filmá el display con una cámara de teléfono: las bandas muestran la frecuencia de barrido.
  5. Con el LCD, hacé un escáner I2C antes de escribir una línea, y mostrá un texto fijo antes de mostrar datos del sensor.
  6. Mediá el tiempo de una actualización con micros() y comprobá que no frena el lazo.

11 · Analogía con programación

Segmentos, barrido, brillo y tiempos de bus

Calculemos los cinco elementos del tema: la tabla de segmentos, los costos del multiplexado, el brillo de los drivers, el tiempo de actualización del LCD con I2C y la resolución de una barra con caracteres propios.

Python en tu navegador. Los bloques son editables: cambiá los valores y presioná «Ejecutar Python». La primera vez tarda unos segundos en cargar.

import math

# ---- Siete segmentos: bit 0 = a ... bit 6 = g, bit 7 = punto ----
SEG = {"0": 0x3F, "1": 0x06, "2": 0x5B, "3": 0x4F, "4": 0x66, "5": 0x6D, "6": 0x7D, "7": 0x07,
       "8": 0x7F, "9": 0x6F, "A": 0x77, "b": 0x7C, "C": 0x39, "d": 0x5E, "E": 0x79, "F": 0x71}

print("dígito  cátodo común  ánodo común  segmentos")
for d, v in SEG.items():
    print(f"{d:>5s}   0b{v:08b}    0b{v ^ 0xFF:08b}  {bin(v).count('1'):5d}")

i_seg = 0.010
print(f"Corriente de un dígito con '8' a {i_seg * 1000:.0f} mA por segmento: {bin(SEG['8']).count('1') * i_seg * 1000:.0f} mA; con '1': {bin(SEG['1']).count('1') * i_seg * 1000:.0f} mA")

# ---- Multiplexado de dígitos ----
print()
print("dígitos  ciclo  I pico (5 mA medios)  barrido (cuadro de 100 Hz)  tiempo por dígito  común con 8 segmentos  CPU (40 µs por dígito)")
for n in (1, 2, 4, 6, 8):
    pico = 5 * n
    barrido = 100 * n
    print(f"{n:7d}  1/{n:<3d}  {pico:8d} mA            {barrido:6d} Hz            {1000 / barrido:6.2f} ms       {8 * pico:8d} mA         {barrido * 40e-6 * 100:5.1f} %")
for n in (4, 8):
    print(f"{n} dígitos: {8 + n} pines con conexión directa, 2 con TM1637, 3 con MAX7219")

# ---- Brillo de los drivers ----
print()
print("MAX7219: nivel  ciclo (2n+1)/32   percibido")
for nivel in (0, 1, 4, 8, 15):
    ciclo = (2 * nivel + 1) / 32
    print(f"{nivel:21d}  {ciclo * 100:8.1f} %  {ciclo ** (1 / 2.2) * 100:9.0f} %")
TM = [1 / 16, 2 / 16, 4 / 16, 10 / 16, 11 / 16, 12 / 16, 13 / 16, 14 / 16]
print("TM1637 ciclos:", ", ".join(f"{t * 100:.1f} %" for t in TM))
for n in (8, 4, 2):
    prom = (31 / 32) / n * 40
    print(f"MAX7219 con límite de barrido de {n} dígitos, nivel 15 y 40 mA de pico: corriente media por segmento {prom:.2f} mA")

# ---- LCD con PCF8574: tiempo de actualización ----
print()
def t_opt(f, n_bytes):                  # los 4 bytes de cada dato de LCD en una sola transacción
    return n_bytes * (9 + 4 * 9 + 2) / f

def t_lib(f, n_bytes):                  # 6 transacciones por byte de LCD y 2 esperas de ~51 µs
    return n_bytes * (6 * (9 + 9 + 2) / f + 102e-6)

print("actualización de 32 caracteres + 2 posicionamientos (34 bytes de LCD):")
for f in (100e3, 400e3):
    print(f"  I2C {f / 1000:.0f} kHz: una transacción por byte {t_opt(f, 34) * 1000:5.1f} ms; biblioteca típica {t_lib(f, 34) * 1000:5.1f} ms")
print(f"  con borrado previo (clear: +1,52 ms de espera y 1 byte de LCD más), biblioteca a 100 kHz: {(t_lib(100e3, 35) + 1.52e-3) * 1000:5.1f} ms")
print(f"  solo un número de 4 caracteres + 1 posicionamiento (5 bytes), biblioteca a 100 kHz: {t_lib(100e3, 5) * 1000:5.1f} ms")

# ---- Direcciones I2C ----
print()
for chip, base in (("PCF8574", 0x20), ("PCF8574A", 0x38)):
    print(f"{chip}: 0x{base:02X} a 0x{base + 7:02X}")

# ---- Barra con caracteres personalizados ----
print()
columnas = 16 * 5
for valor in (0, 33, 50, 100):
    cols = round(columnas * valor / 100)
    print(f"{valor:3d} %: {cols} de {columnas} columnas = {cols // 5} celdas llenas y {cols % 5} columnas más")

Resultado: el 8 enciende 7 segmentos (70 mA a 10 mA por segmento) y el 1, 2 (20 mA); en ánodo común, el patrón de un «8» es 0b10000000. Con 5 mA medios, 4 dígitos piden 20 mA de pico, un barrido de 400 Hz (2,5 ms por dígito), 160 mA en el común con 8 segmentos y el 1,6 % de la CPU; 8 dígitos, 40 mA de pico, 800 Hz, 320 mA y 3,2 %. La conexión directa usa 12 o 16 pines; el TM1637, 2 y el MAX7219, 3. El MAX7219 va del 3,1 % (nivel 0) al 96,9 % (nivel 15) de ciclo, y el nivel 0 todavía se percibe a un 21 %; con límite de barrido de 8, 4 y 2 dígitos la corriente media por segmento es de 4,84 · 9,69 · 19,38 mA. Actualizar los 32 caracteres de un LCD I2C tarda 16,0 ms a 100 kHz con una transacción por byte, 44,3 ms con la biblioteca típica y 13,7 ms a 400 kHz; con clear previo, 47,1 ms, y un número de 4 caracteres, 6,5 ms. Las direcciones del PCF8574 son 0x20 a 0x27 y las del PCF8574A, 0x38 a 0x3F. Una barra de 16 celdas tiene 80 pasos: el 33 % son 26 columnas (5 celdas llenas y 1 columna más).

12 · Exploración interactiva

Segmentos, barrido, brillo y LCD

El primer instrumento codifica un dígito en segmentos y calcula las corrientes. El segundo dimensiona el barrido de un display multiplexado. El tercero compara el brillo de un MAX7219 y un TM1637. El cuarto calcula el tiempo de actualización de un LCD con I2C. El límite de un pin se toma como 20 mA.

Instrumento 1: un dígito de 7 segmentos

Byte (a = bit 0 … g = bit 6, punto = bit 7)—
Segmentos encendidos—
Corriente del terminal común—
Resistencia por segmento (VF 2,0 V)—
Estado
—

Instrumento 2: el barrido multiplexado

Ciclo de trabajo—
Corriente de pico por segmento—
Barrido · tiempo por dígito—
Común con 8 segmentos—
CPU del barrido (40 µs por paso) · pines—
Estado
—

Instrumento 3: brillo de los drivers

Ciclo de trabajo del nivel—
Corriente media por segmento—
Brillo percibido (γ = 2,2)—
Pines · tiempo de actualización—
Estado
—

Instrumento 4: LCD con adaptador I2C

Dirección I2C—
Bytes de LCD enviados—
Tiempo de la actualización—
Actualizaciones por segundo (máximo)—
Estado
—

Recorrido guiado

  1. Con el 5 en cátodo común: byte 0x6D (01101101), cinco segmentos y 50 mA en el común a 10 mA por segmento. El estado avisa que el común supera un pin. Bajá a 4 mA: 20 mA, justo en el límite. Pasá a ánodo común: el byte se invierte (0x92).
  2. Probá el dígito 1 (dos segmentos) y el 8 con punto (ocho): la corriente del común va de 20 a 80 mA con el mismo valor por segmento. Con 3,3 V, la resistencia por segmento baja a 150 Ω.
  3. En el barrido con 4 dígitos, 5 mA medios y 100 cuadros por segundo: 20 mA de pico por segmento, 400 Hz de barrido, 160 mA en el común y el 1,6 % de la CPU. Pasá a 8 dígitos: 40 mA, 800 Hz, 320 mA y 3,2 %. Subí la corriente media a 20 mA con 8 dígitos: el pico supera los 100 mA que admite el LED.
  4. Bajá a 30 cuadros por segundo: el estado avisa de parpadeo.
  5. En el MAX7219 con 8 dígitos y nivel 15: ciclo de 96,9 % y 4,84 mA medios por segmento. Bajá los dígitos barridos a 4: 9,69 mA, el doble de brillo con el mismo nivel. Con 1 dígito, 38,8 mA: se supera lo que admite un LED de forma continua.
  6. Cambiá al TM1637: los niveles pasan a 0 a 7 y a los ciclos del chip (6,2 % a 87,5 %); con más de 6 dígitos, el estado avisa que el chip no llega. El nivel 2 da 25 % y el 3 salta a 62,5 %: la escala no es lineal.
  7. En el LCD con biblioteca típica a 100 kHz y 6 caracteres: 7 bytes de LCD y unos 9 ms. Llevá los caracteres a 32: 44 ms. Cambiá a 400 kHz: 13,7 ms; con cuatro bytes por transacción, 4,0 ms.
  8. Marcá clear(): la pantalla se redibuja entera y hay 47 ms a 100 kHz con parpadeo. Cambiá el expansor a PCF8574A con A2 A1 A0 = 7: la dirección es 0x3F.
Desafío: un termómetro con LCD y alarma visual

Un LCD 16 × 2 muestra en la fila 1 la temperatura «T = 23,5 °C» y en la fila 2 una barra de 0 a 50 °C con caracteres propios. La temperatura se lee a 4 Hz y la pantalla se actualiza cuando cambia. ¿Cuánto tiempo bloquea cada actualización y cuántas columnas tiene la barra a 23,5 °C? Si solo cambian 4 caracteres de la fila 1 más un posicionamiento (5 bytes) y la barra tiene hasta 16 celdas más otro posicionamiento (17 bytes), el total es de 22 bytes: con la biblioteca típica a 100 kHz, 22 × 1,3 ms ≈ 29 ms, es decir un 11,5 % del tiempo a 4 Hz; a 400 kHz, 8,8 ms (3,5 %). La barra a 23,5 °C: 23,5 / 50 × 80 = 37,6 → 38 columnas = 7 celdas llenas y 3 columnas más. Mejora: reescribir la barra solo cuando cambia la cantidad de columnas (a menudo no cambia), con lo que se baja a 5 bytes: 6,5 ms. La alarma visual (un LED, tema 35) no necesita el LCD.

13 · Método de trabajo

Cómo integrar un display, para cualquier proyecto

  1. Elegí por la información (número, texto, gráfico) y los pines disponibles: directo, TM1637, MAX7219 o LCD con I2C.
  2. Calculá las corrientes del peor caso (todos los segmentos) y de pico si hay multiplexado, y usá transistores o un driver donde un pin no alcanza.
  3. Barré desde un timer a 100 cuadros por segundo o más, apagando todo antes de cambiar de dígito.
  4. Conocé los tiempos del bus (13 ms de un TM1637, decenas de ms de un LCD con I2C) y no actualices más rápido de lo que se lee.
  5. Escribí solo lo que cambia y con ancho fijo; nada de clear() en cada ciclo.
  6. Adaptá los niveles si el driver es de 5 V y el microcontrolador de 3,3 V.
  7. Encapsulá el display en un módulo con una función de «mostrar»; la tabla, la dirección y los tiempos quedan adentro.
  8. Probá el peor caso: todo encendido, todos los dígitos, el valor más largo y el error.

Si hay brillo desigual, el barrido se bloquea; si hay restos de texto, falta ancho fijo; si el LCD no responde, revisá contraste, dirección y secuencia de inicio; si el programa va lento, medí el tiempo de la actualización.

14 · Comprensión

Confusiones frecuentes

«El TM1637 es un dispositivo I2C»

Usa dos hilos parecidos, pero sin dirección y con otro protocolo: no puede compartir el bus con sensores I2C, y se implementa por software con retardos.

«Un display de cuatro dígitos necesita 32 pines»

Solo con conexión directa. Con multiplexado bastan 12 y con un driver, 2 o 3.

«El multiplexado ahorra corriente»

La corriente media es la misma; la de pico es N veces mayor para mantener el brillo, y la del común suma todos los segmentos.

«El LCD I2C es rápido porque solo tiene dos cables»

Es más lento que el paralelo: cada byte de LCD son cuatro bytes de I2C, y las bibliotecas habituales hacen una transacción por cada uno. Actualizar toda la pantalla puede llevar decenas de milisegundos.

«Para actualizar el LCD hay que borrarlo primero»

El borrado cuesta 1,52 ms más el redibujado y produce parpadeo. Basta escribir encima del texto anterior con ancho fijo.

«Con la retroiluminación encendida, el LCD funciona»

La luz es independiente del controlador: puede estar encendida con el contraste mal ajustado o el controlador sin inicializar.

15 · Práctica guiada

Predecí antes de comprobar

1. Codificación

¿Qué byte representa el dígito 7 en cátodo común y en ánodo común, con el orden a = bit 0 … g = bit 6, punto = bit 7?

Ver solución

El 7 enciende a, b y c: bits 0, 1 y 2 → 0b00000111 = 0x07 en cátodo común. En ánodo común se invierte: 0b11111000 = 0xF8.

2. Corriente del común

Un dígito con 8 mostrándose, a 6 mA por segmento y sin punto: ¿qué corriente entra al terminal común?

Ver solución

7 segmentos × 6 mA = 42 mA: más del doble de lo que conviene a un pin; hace falta un transistor.

3. Multiplexado

Un display de 6 dígitos con 4 mA medios por segmento y 100 cuadros por segundo: ¿pico por segmento y frecuencia de barrido?

Ver solución

Pico = 4 × 6 = 24 mA; barrido = 6 × 100 = 600 Hz, 1,67 ms por dígito. Con 8 segmentos en el común, 24 × 8 = 192 mA.

4. Brillo del MAX7219

Con límite de barrido de 4 dígitos, nivel 15 y 40 mA de pico, ¿qué corriente media pasa por segmento? ¿Qué nivel de intensidad iguala la corriente que había con 8 dígitos (4,84 mA)?

Ver solución

(31/32) / 4 × 40 = 9,69 mA. Para volver a ~4,84 mA hace falta un ciclo de la mitad: (2n + 1)/32 ≈ 0,484 → n ≈ 7.

5. Tiempo del LCD

Con la biblioteca típica a 400 kHz, ¿cuánto tarda en escribir una cadena de 10 caracteres más un posicionamiento (11 bytes de LCD)?

Ver solución

Por byte: 6 × 20 / 400 000 + 102 µs = 300 + 102 = 402 µs; 11 × 402 µs ≈ 4,4 ms.

6. Diagnóstico

Un LCD I2C que mostraba «Temp: 100» ahora muestra «Temp: 900» cuando baja a 9. ¿Qué pasa y qué cambiás?

Ver solución

Se escribe «9» sobre el primer dígito y los dos ceros del valor anterior quedan en pantalla. Se formatea con ancho fijo ("%3d" o "9 ") para escribir también los espacios, en lugar de usar clear().

16 · Síntesis

Ideas para recordar

  • Un dígito de 7 segmentos son 7 LEDs más un punto con un terminal común (cátodo o ánodo): cada número es un byte de segmentos, y la corriente del común depende del dígito mostrado.
  • El multiplexado enciende un dígito por vez a 100 cuadros por segundo o más; ahorra pines, pero la corriente de pico es N veces la media y el común necesita un transistor.
  • El barrido se hace desde un timer, apagando todo antes de cambiar de dígito para evitar fantasmas.
  • El TM1637 (2 hilos, sin dirección, ~13 ms bloqueantes) y el MAX7219 (3 hilos, 8 dígitos o matriz, 16 niveles, cascada) hacen el barrido solos.
  • El MAX7219 con menos dígitos barridos ilumina más: hay que ajustar la intensidad para no sobrecargar los segmentos.
  • El LCD HD44780 guarda el texto en la DDRAM (filas en 0x00 y 0x40), admite 8 caracteres propios, y el clear tarda 1,52 ms.
  • Con I2C (PCF8574, 0x20 a 0x27 o 0x38 a 0x3F), cada byte del LCD son 4 bytes de bus; actualizar la pantalla entera puede tardar 44 ms con la biblioteca típica a 100 kHz.
  • Se muestra con ancho fijo, solo lo que cambia, a no más de 2 a 4 Hz, y con una señal clara de error; el display queda encapsulado en un módulo.

¿Listo para el tema 38?

Antes de avanzar, codificá el dígito 3 en cátodo común, calculá la corriente de pico por segmento de un display de 4 dígitos con 6 mA medios y decí por qué escribir «9» sobre «10» en un LCD deja «90». Si podés justificar las tres respuestas, ya sabés manejar displays de números y texto.

En el próximo tema pasamos de caracteres a píxeles: las pantallas gráficas OLED y TFT, con el controlador SSD1306, la memoria de video, las fuentes y el refresco.