Pantalla Nokia 5110 en ESP32 sin instalar librerías


En esta publicación pretendo proporcionar las herramientas necesarias para la utilización de las pantallas empleadas en los antiguos teléfonos Nokia 5110 y otros tantos de esa empresa en nuestros desarrollos electrónicos con ESP32 y sin la utilización de ningún software de terceras partes como Adafruit o Sparkfun por mencionar algunos. Si quieren informarse detalladamente acerca de estas pantallas, su estructura lógica y funcionamiento pueden hacer clic acá para ir directamente a la nota ubicada en la sección de electrónica / información general donde está almacenada. Hace no mucho tiempo hice un altímetro con ESP32 primero (aun no publiqué ese circuito) y luego lo migré a Arduino (ese está publicado en este link) y en ambos casos empleé la librería de Adafruit la cual me pidió adicionalmente una librería SPI. Una chorrera de dependencias que el entorno Arduino IDE debe tener precargados y que si por alguna razón reinstalo perderé y el proyecto ya no compilará. En verdad utilizar dependencias no es una buena práctica porque si bien facilitan mucho el trabajo al punto tal de llegar a desentenderse el programador de lo que está haciendo en verdad ese desconocimiento no es para nada bueno a tal punto de no poder asegurar el correcto funcionamiento del desarrollo. Por mencionar un hecho, me di cuenta que aparecía el logo de Adafruit en la pantalla en mi altímetro cuando arrancaba el ESP32 pero antes de la inicialización y yo no programé el ESP para que suceda eso por ende está ocupando espacio de memoria de programa en mi programa y contra mi voluntad. Y si bien en el Altímetro no me faltó espacio de memoria el que decide que va en el programa y que no va es uno y no el desarrollador de las librerías. Por ello y porque me gusta hacer las cosas bien, como debe ser es que decidí aventurarme en esta librería que no es necesario instalar ni tener en el arduino, basta con copiar en la carpeta del proyecto el archivo nokia5110.h, incluirlo comillado en el sketch y listo!

El conexionado entre el ESP32 y la pantalla es bastante directo sin componentes intermedios ya que tanto el ESP32 como la pantalla trabajan a 3,3 voltios por lo que no es necesario adaptar niveles de tensión entre ambos extremos. El pulsador se utiliza para pasar de letrero en letrero y poder observar cada uno detenidamente todo el tiempo que cada quien necesite.

La primer línea del programa nokia5110.ino es la encargada de incluír en el sketch el archivo de cabecera o .h necesario para tener todas las funciones requeridas para el correcto uso de la pantalla. Las definiciones que siguen se refieren a donde esta conectado el pulsador (en que pin) y el tamaño en filas y columnas de texto en tamaño regular que admite la pantalla. Las declaraciones de filas y columnas se utilizan únicamente en los ciclos for de la rutina encargada de ocupar toda la pantalla con caracteres de tamaño pequeño (7x5). En la sección de configuración se establece como entrada el pin donde está conectado el pusador con PullUp interno activada para minimizar la cantidad de componentes externos en el protoboard. Luego se inicializa el LCD y se deja medio segundo para que se estabilice. Ya hecho esto se ingresa en el bucle infinito de ejecución. Se hace una cuenta regresiva de 3, 2, 1 tanto en positivo como en negativo empleando la fuente mas grande que dispone este archivo, el tamaño llamado LCDGuaso el cual ocupa 28 pixeles de alto por 20 pixeles de ancho y por ende en pantalla no cabe mas de una fila y apenas de dos a tres letras a lo sumo. Seguidamente carga el logo del sitio, luego hace un saludo en tres tamaños de letra poniendo HOLA en tamaño triple, SAMIGO en tamaño doble y Como andai ? En tamaño regular o chico. Nótese que lo único que se puede mandar como cadena de caracteres es en tamaño regular, en los tamaños doble, triple y guaso sólo se puede enviar de a un caracter por vez y si o si indicando su posición en pantalla. El porqué de esta característica también será explicado en detalle cuando publique la nota informativa sobre la pantalla y su controlador genéricamente hablando. A continuación se muestra el uso combinado en una misma línea de distintos tamaños de caracteres a fin de producir abreviaciones como las mostradas. Luego se muestra otra imagen, en esta oportunidad el logo de Microchip, porque nunca se debe olvidar a un gran amor! Y luego se completa toda la pantalla con caracteres consecutivos pero desplazando de a uno conforme avanzan las filas, para esto se emplean las definiciones de filas y columnas de la parte superior del programa y las posiciones de memoria fila y columna también declaradas en esa parte. Si por prolijidad se las quiere bajar a esta parte del programa nadie se opondrá! Luego se carga en un espacio de memoria destinado para tal fin un texto de tipo marquesina con capacidad para 70 caracteres pero que se puede ampliar con solo crecer su valor en la declaración dentro del archivo nokia5110.h este texto queda en un arreglo de memoria que luego se irá transmitiendo hacia el LCD progresivamente en dos fases distintas. La primera desplazando el punto de comienzo de la "impresión" en pantalla de derecha a izquierda (efecto comienzo de marquesina) para luego quedar ocupando toda la pantalla y ya en ese punto empieza la siguiente fase en la cual cambia la columna de comienzo haciendo que el texto pase deslizante.

 

 

Esas son tres de las pantallas que se despliegan durante la ejecución del programa, pueden ver todo el guión completo en este video.

 

En el archivo nokia5110.h hay sólo un set de caracteres de tamaño 7x5, los tamaños Doble, Triple y Guaso se forman ocupando mas de un pixel tanto en horizontal como en vertical tomando como referencia la tabla de caracteres cargada en la matriz ASCII. El siguiente gráfico explica este proceso escalar.

En el tamaño regular o mas pequeño cada punto que conforma el caracter ocupa un sólo pixel o unidad de imagen. En el tamaño siguiente, Doble, cada punto de un caracter ocupa 2x2 pixeles; en el que le sigue, el Triple, ocupa 3x3 pixeles cada punto mientras que en el último y mas grande, el Guaso, ocupa 4x4 pixeles. A través de una serie de verificaciones y copiado de bits encadenados en ciclos for se logra armar el procedimiento por el cual tomando como base la tabla ASCII precargada arma en pantalla letras del doble, triple o cuádruple de su tamaño. Con respecto a la carga de imágenes o gráficos estos deben ser del tipo monocromático, sin escalas de grises osea que cada unidad de imagen puede estar o en blanco o en negro y deben tener un tamaño específico de 84 pixeles de ancho por 48 pixeles de alto. Vemos aquí las imágenes BMP o bitmaps empleadas en ese prototipo:

Ambas imágenes deben ser convertidas a seguidillas de ceros y unos acomodados en bytes u octetos. Se puede hacer esto a mano, no es una tarea imposible pero tampoco se lo deseo a nadie! Por suerte siempre algún buen tipo se toma el trabajo de hacer un programa simple y fácil de usar que haga este trabajo y no podía ser distinto en esta oportunidad. Para bajar una o ambas imágenes basta con hacer clic derecho y seleccionar guardar como... No olviden mantener el tipo de imagen mapa de bits monocromático! Pueden descargarse el programa LCDAssistant haciendo clic acá.

Aquí vemos la pantalla de este programa que por suerte es portable así que no requiere instalación ni ensucia nuestra computadora con tontos archivos de entornos de ejecución únicamente requerido por programas hechos por programadores mediocres. Con el menú File cargamos el archivo BMP, definimos el tamaño de nuestra pantalla, la cantidad de pixeles por byte y el nombre que queremos que le de a la tabla. Luego en el menú file disparamos la exportación o generación de la tabla y listo! Tendremos un archivo de texto que podremos abrir con Notepad o nuestro editor de texto plano sin formato preferido y copiar su contenido para pegarlo dentro de nokia5110.h para ser llamado cuando queramos que se vea esa imagen en pantalla. Aquí vemos el contenido generado por el programa para mostrar el logo Pablin:

//------------------------------------------------------------------------------
// File generated by LCD Assistant
// http://en.radzio.dxp.pl/bitmap_converter/
//------------------------------------------------------------------------------

const unsigned char logo [] = {
0x00, 0x00, 0x03, 0x3C, 0xC0, 0x30, 0x0E, 0x01, 0x0E, 0x30, 0xC0, 0x3C, 0x03, 0x03, 0x3C, 0xC0,
0x30, 0x0E, 0x01, 0x0E, 0x30, 0xC0, 0x3C, 0x03, 0x03, 0x3C, 0xC0, 0x30, 0x0E, 0x01, 0x0E, 0x30,
0xC0, 0x3C, 0x03, 0x00, 0x40, 0xE0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
0x70, 0x70, 0xF0, 0xE0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x70, 0x70, 0x70,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0,
0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0xF1, 0xFF, 0x7F, 0x1F, 0x00, 0x60, 0x70, 0x78, 0x38,
0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x3C, 0xF8, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x70,
0x38, 0x1C, 0x1C, 0x1C, 0x1C, 0x3C, 0x78, 0xF8, 0xE0, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00,
0x00, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x70, 0x38, 0x1C, 0x1C, 0x1C, 0x1C, 0x3C,
0xF8, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF0, 0xFC, 0xFC, 0xCE, 0x86, 0x86, 0x86, 0x83, 0xC3, 0xE3, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xE0, 0xC0, 0x80, 0x80, 0x80, 0x80, 0xC0, 0xE0, 0xFF, 0x7F, 0x1F, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9F, 0x80, 0x00, 0x00,
0x00, 0x00, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x01, 0x03,
0x03, 0x02, 0x00, 0x00, 0x03, 0x03, 0x03, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x00, 0x00, 0x03, 0x03, 0x03, 0x00, 0x00, 0x03, 0x03,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xE0, 0x40, 0x00, 0x7E, 0x81, 0x81, 0x81, 0x81,
0x42, 0x00, 0x00, 0x7E, 0x81, 0x81, 0x81, 0x81, 0x7E, 0x00, 0x00, 0xFF, 0x02, 0x01, 0x01, 0x01,
0xFE, 0x02, 0x01, 0x01, 0x01, 0xFE, 0x00, 0x00, 0x40, 0xE0, 0x40, 0x00, 0x62, 0x91, 0x89, 0x89,
0x49, 0xFE, 0x00, 0x00, 0xFF, 0x02, 0x01, 0x01,
};

El detalle de como se maneja cada señal de interfase con la pantalla podrán encontrarlo en breve cuando suba la nota referida a estas pantallas y su controlador en forma genérica, en esta publicación solo se hace referencia a su conexión y empleo con ESP32.

Como siempre tienen la posibilidad de bajar el sketch y el archivo a incluir haciendo clic acá

 

 

Pablo Canello, 18/04/2020