Página
principal
Termómetro
OLED 128x64
SSD1306Z
GM009605
Arduino
Hace tiempo que me había llegado una
pantalla del tipo OLED, con una resolución de 128x64, y aún no lo
había empleado.
Nunca he trabajado con pantallas de tipo OLED, por lo que no sabía
como trabajaba.
En primer lugar diremos que la pantalla viene para ser controlada
mediante el bus I2C, por lo cual se necesitan pocos cables,
alimentación y CLK , SDA.
Lo primero que suelo hacer es bajarme todos las manuales del
fabricante que puedo.
Lo siguiente es intentar buscar alguna librería para arduino
que maneje la pantalla.
La librería mas famosa es la de Adafruit-GFX-Library , junto
con Adafruit_SSD1306. Estas librerías funciona muy bien,
tienen todo lo necesario para manejar gráficamente la pantalla.
Otra librería es Universal 8bit Graphics Library,
https://github.com/olikraus/u8glib/ , que puede manejar
diferentes tipos de pantalla. Antes de utilizar esta librería de
debe de descomentar la linea que corresponde a nuestra pantalla. En
las pruebas que realicé para mi pantalla la línea era : U8GLIB_SSD1306_128X64
u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C
/ TWI
Estas librería están hechas para un montón de pantallas, por lo cual
no están optimizadas para una en concreto. El resultado es que
suelen ocupar bastante memoria de programa (10Kb), y la mitad de la
memoria RAM 1024. En muchos casos no se puede añadir otra librería
por falta de memoria.
Este aviso suele aparecer en la compilación:
Las variables Globales usan 1.956 bytes (95%)
de la memoria dinámica, dejando 92 bytes para las variables
locales. El máximo es 2.048 bytes.
Poca memoria disponible, se pueden producir
problemas de estabilidad.
Como me gusta programar mis propias rutinas de manejo de pantalla,
me puse manos a la obra.
Tomando como referencia la librería Adafruit , me puse crear
mis rutinas sin utilizar librería alguna, todas las rutinas están en
el propio programa.
Empecemos por conocer la estructura de pantalla del OLED.
La estructura es bastante común, líneas de 128 bytes, y el total de
líneas es de 8, por lo cual el total de bytes es de 1024 bytes.
En anteriores montajes arnok.html y
matrixd.html también había trabajado con
esquemas de pantalla parecidos, por lo cual ya tengo alguna
experiencia.
En líneas generales el funcionamiento es el siguiente:
- -Se crea un buffer (buffer[OLE_BUFFER];)
de 1024 bytes donde se pintan todas las líneas o caracteres.
- -Una vez pintado todo, se vuelca todo en la pantalla OLED
mediante la orden display();
Esto es simple, y es el método que se utiliza en la mayoría de los
programas de ordenador.
Pero mover 1024 bytes mediante en el Bus I2C no es lo rápido que
debiera ser para no ser notado el repintado.
Para solucionar este problema, cree una rutina que solo repintaba 1
línea de la 8 que existen.
Mediante este método conseguía una velocidad 8 veces mayor en
escritura de caracteres, no sirve para puntos y líneas.
La activación de este método es mediante ModeDisplay=1;
.
Otro problema que tuve fue lo pequeños que se ven los caracteres,
diminutos, había que solucionarlo, crear diferentes tamaños de
caracteres.
El resultado no fue del todo malo, por lo menos se veían los
caracteres, que es lo que se pretendía.
En modo gráfico solo he implementado plot, line
(en solo modo vertical y horizontal),y drawBox.
Para probar todo he pensado un termómetro digital utilizando el
18B20, sencillo y rápido.
Esquema del circuito(existe un error, la resistencia debe ser
de 4K7).
Circuito montado.
He realizado dos programas, uno inserta todas la rutinas
en el propio programa y otro coloca un fichero de cabecera olex.h
donde se colocan las rutinas. Los dos funcionan igual, pero en uno
queda el programa mas sencillo de ver, solo queda el programa no las
rutinas.
El tener que utilizar 1024 bytes a modo de buffer, implica usar la
mitad de la memoria impidiendo hacer programas más grandes.
En el próximo programa intentaré hacer rutinas para texto que solo
utilicen 128 bytes.
En las mediciones de consumo se puede observar que varía bastante
dependiendo los puntos que se encuentren encendidos, entre 3 mA y 17
mA, en modo normal. En las pruebas el circuito funcionaba
perfectamente a 3.3V
PROGRAMA
Después de un par de días pensando
en la poca memoria RAM que dejaba al utilizar un buffer de 1024byes,
decidí solucionar el problema.
La solución era reducir el buffer a 256bytes. Esto implica no poder
utilizar gráficos (plot , líne). Además se imprime caracteres en
líneas completas.
Para el caso que nos ocupa sirve de sobra, y la liberación de
memoria es bastante 768 bytes.
La salida del compilador nos da lo siguiente:
El Sketch usa 7.320 bytes (22%) del espacio
de almacenamiento de programa. El máximo es 32.256 bytes.
Las variables Globales usan 1.004 bytes (49%) de
la memoria dinámica, dejando 1.044 bytes para las variables
locales. El máximo es 2.048 bytes.
PROGRAMA2
Como seguía pensando en el montaje, y en
la posibilidad de eliminar el buffer de la memoria RAM para
representar caracteres, me puse manos a la obra. El resultado es la
eliminación del buffer y la liberación de la memoria RAM, resultando
1300 bytes libres para ser utilizados por otras librerías.
También se corrigió el que salían los decimales negativos.
Salida del compilador nos da lo siguiente:
El Sketch usa 7.422 bytes (23%)
del espacio de almacenamiento de programa. El máximo es 32.256
bytes.
Las variables Globales usan 748 bytes (36%) de la
memoria dinámica, dejando 1.300 bytes para las variables
locales. El máximo es 2.048 bytes.
PROGRAMA3
Hasta pronto.
Juan Galaz
Bibliografía:
https://github.com/adafruit/Adafruit_SSD1306
https://github.com/adafruit/Adafruit-GFX-Library
https://github.com/olikraus/u8glib/
arnok.html
matrixd.html
http://www.instructables.com/id/Monochrome-096-i2c-OLED-display-with-arduino-SSD13/