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:
| Aspecto | Cátodo común | Ánodo común |
|---|---|---|
| Terminal común | A masa | A la alimentación |
| Se enciende un segmento con | Nivel alto en su pin | Nivel bajo en su pin |
| Patrón de un «8» | 0b01111111 | 0b10000000 (el complemento) |
| La corriente del común es | La suma de los segmentos encendidos, que entra al pin o transistor | La 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.
| Dígitos | Ciclo | I pico por segmento | Barrido | Tiempo por dígito | Común con 8 segmentos |
|---|---|---|---|---|---|
| 1 | 1/1 | 5 mA | 100 Hz | 10 ms | 40 mA |
| 4 | 1/4 | 20 mA | 400 Hz | 2,5 ms | 160 mA |
| 8 | 1/8 | 40 mA | 800 Hz | 1,25 ms | 320 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
0x00y la fila 2 en0x40(en un 20 × 4, las filas empiezan en 0x00, 0x40, 0x14 y 0x54). Para posicionar el cursor se envía0x80 | 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.
| Comando | Código | Tiempo |
|---|---|---|
| Borrar la pantalla (clear) | 0x01 | 1,52 ms |
| Cursor al inicio (home) | 0x02 | 1,52 ms |
| Modo de entrada (cursor hacia la derecha) | 0x06 | 37 µs |
| Pantalla encendida, sin cursor | 0x0C | 37 µs |
| Función: 4 bits, 2 líneas, 5 × 8 | 0x28 | 37 µs |
| Posicionar en la DDRAM | 0x80 | dirección | 37 µs |
| Escribir un carácter | RS = 1, código ASCII | 37 µ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:
| Bit del PCF8574 | P0 | P1 | P2 | P3 | P4 a P7 |
|---|---|---|---|---|---|
| Señal del LCD | RS | RW | E | Retroiluminación | D4 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_I2Cmá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
| Opción | Pines (4 dígitos / 8 dígitos) | Quién barre | Ventajas | Costo |
|---|---|---|---|---|
| Conexión directa con multiplexado | 12 / 16 | El microcontrolador (timer) | Sin chips; control total del brillo | Pines, CPU, transistores |
| Registro de desplazamiento (74HC595) | 3 + comunes | El microcontrolador | Ahorra pines de segmentos | Aún hay que barrer |
| TM1637 | 2 | El chip | Módulos de 4 dígitos baratos; lee teclas | Bit-banging de ~13 ms; sin bus compartido |
| MAX7219 | 3 (en cadena) | El chip | 8 dígitos o matriz 8 × 8; brillo de 16 niveles; cascada | RSET; nivel de 5 V |
| LCD 16 × 2 con I2C | 2 (bus compartido) | El controlador del LCD | Texto completo; comparte bus con sensores | Lento (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")trasprint("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
----oErr, 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
| Síntoma | Causa | Defensa |
|---|---|---|
| Dígitos con brillo distinto | Barrido con tiempos irregulares (programa bloqueado) | Barrer desde un timer, no con delay() |
| Fantasmas tenues | Cambio de segmentos con el común anterior activo | Apagar todo antes de cambiar de dígito |
| Parpadeo | Menos de 60 cuadros por segundo | Barrido 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 única | Una resistencia por segmento, o un driver con corriente constante |
| Pin o chip recalentado | Corriente del común superior a la del pin | Transistor por dígito |
| LCD con cuadros negros en la fila 1 | No se inicializó el controlador | Revisar secuencia, tiempos tras el encendido y alimentación |
| LCD en blanco con la retroiluminación encendida | Contraste mal ajustado | Girar el potenciómetro de V0 |
| LCD I2C que no responde | Dirección equivocada (0x27 en lugar de 0x3F) o SDA y SCL cruzados | Escáner I2C; revisar cableado |
| Restos de texto anterior en el LCD | Valor más corto que el anterior, sin relleno | Ancho fijo con espacios |
| Pantalla que parpadea o programa lento | clear() en cada ciclo; escrituras I2C lentas | Escribir solo lo que cambió; subir el bus a 400 kHz |
| MAX7219 sin respuesta con 3,3 V | Nivel lógico insuficiente | Adaptador de nivel; alimentar a 5 V |
- Mostrá todos los segmentos (un «8.» en cada dígito, o el modo de prueba del MAX7219) y buscá segmentos apagados o puentes.
- Recorré los dígitos 0 a 9 en cada posición y verificá la tabla.
- Medí la corriente del común con todos los segmentos encendidos (el peor caso) y comprobá que el transistor no se calienta.
- Filmá el display con una cámara de teléfono: las bandas muestran la frecuencia de barrido.
- 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.
- 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
Instrumento 2: el barrido multiplexado
Instrumento 3: brillo de los drivers
Instrumento 4: LCD con adaptador I2C
Recorrido guiado
- 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).
- 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 Ω.
- 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.
- Bajá a 30 cuadros por segundo: el estado avisa de parpadeo.
- 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.
- 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.
- 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.
- 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
- Elegí por la información (número, texto, gráfico) y los pines disponibles: directo, TM1637, MAX7219 o LCD con I2C.
- 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.
- Barré desde un timer a 100 cuadros por segundo o más, apagando todo antes de cambiar de dígito.
- 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.
- Escribí solo lo que cambia y con ancho fijo; nada de
clear()en cada ciclo. - Adaptá los niveles si el driver es de 5 V y el microcontrolador de 3,3 V.
- Encapsulá el display en un módulo con una función de «mostrar»; la tabla, la dirección y los tiempos quedan adentro.
- 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.