Objetivos
-
- Presentar los gráficos en el display OLED de 0.96”.
- Presentar las primitivas básicas.
- Generar un diagrama de barras leyendo los valores de las puertas analógicas.
- Generar un gráfico de líneas que se van desplazando continuamente hacia la izquierda.
Material requerido.
Tienda España | Tienda Mexico | |
---|---|---|
![]() |
Arduino UNO. | Arduino UNO. |
![]() |
Una Protoboard . | Una Protoboard . |
![]() |
Algunos cables de protoboard. | Algunos cables de protoboard. |
![]() |
Un display OLED de 0.98” SPI. | Un display OLED de 0.98” SPI. |
Los gráficos y el OLED de 128×64
Como os contaba en la sesión anterior, he disfrutado mucho de este pequeño display y como habíamos dejado pendiente el tema de los gráficos, no he podido resistirme a darle otra vuelta al asunto y ver como lo resolvíamos.
No sería difícil de hacer primitivas gráficas sencillas para complementar este display, pero me pareció absurdo que no pudiéramos usar las magníficas librerías graficas GFX de Adafruit que ya probamos en algún capitulo anterior y que para algo se ha currado el tema esta gente (A la que nuevamente renuevo mis agradecimientos).
Así que me dispuse a darle otro repaso al tema y buscar el problema porque en el primer intento me ganó por goleada y desistí. Me puse un cafecito cargado y empecé las pruebas para ver qué pasaba y…. funcionó todo a la primera. Se ve que el día anterior estaba más tonto de lo habitual.
Bastó con definir correctamente los pines a la entrada de los programas de ejemplos y arrancó inmediatamente con todas las funciones gráficas activadas.
Naturalmente, conecté el display OLED directamente a mi Arduino, por pura vagancia y cuando me canse de ver el ejemplo gráfico me puse a ver cómo definir un par de programas más y el resultado, lo tenéis delante. Confio en que os pueda servir de algo.
Conexión de un displays OLED de 128×64
Lo primero es que conectéis vuestro display como en la sesión anterior. Insertando el primer pin GND del display OLED en el pin GND de Arduino que tenemos al lado del digital pin 13, con lo que el resto de los pines encajaran en su sitio sin más.
Ahora la única cuestión es descargar e instalar las librerías correspondientes de Adafruit. La primera es Adafruit_SSD1306 que corresponde al chip de nuestro display, y que no habíamos usado hasta ahora.
La segunda librería es la gráfica de Libreria Adafruit GFX, que ya habíamos utilizado anteriormente en las sesión Display TFT SPI 1.8″ y que incluye muchas primitivas básicas de dibujo. Instaladlas siguiendo el procedimiento habitual.
Una vez listo buscad en el menú \\Archivo\ejemplos\\ Adafruit_SSD1306 el ejemplo SSD1306_128x64_SPI, que es el modelo del que dispongo pero fijaros que también hay ejemplos para display I2C y para 32 pixels de altura en lugar de 64.
Ahora tenemos que redefinir los pines de conexión para que correspondan a la conexión que hemos hecho. Reemplaza el código siguiente:
// If using software SPI (the default case): #define OLED_MOSI 11 // 9 #define OLED_CLK 12 //10 #define OLED_DC 9 //11 #define OLED_CS 12 #define OLED_RESET 10 //13 Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
De este modo mapeareis correctamente los pines. Además tenemos que alimentar el OLED dando tensión al pin 13. Para ello tienes que incluir estas líneas en el setup del ejemplo:
pinMode(13, OUTPUT); digitalWrite(13, HIGH);
Y eso es todo. Volcad el programa y disfrutad el espectáculo.
- El programa de ejemplo es grande y lleva la memoria del Arduino UNO muy cerca de su límite, por lo que veréis mensajes de que puede haber problemas. No le deis más importancia recordad que podéis usar cualquier modelo de Arduino.
Aquí os dejo el ejemplo ya modificado para que lo probéis: Prog_43_1, y mini video con el tema:
Un diagrama de barras o Bar Chart
¿Qué hace un ingeniero cuando resuelve algo demasiado pronto? Pues venirse arriba y complicarse la vida buscando algo más difícil, naturalmente.
La imagen promocional de este display OLED es un diagrama de barras que baila en la pantalla, como si fuera un pequeño ecualizador gráfico, al ritmo de la música mp3, por ejemplo.
Así que se me ha ocurrido montar un programa que nos permitiese mostrar los valores que leemos en las puertas analógicas en forma de barras de altura proporcional a la señal leída.
Veamos cómo empezar el tema, y de paso aprovechamos para hacer un pequeño tutorial de esta librería GFX de Adafruit.
Necesitamos las librerías de SPI y WIRE de Arduino, más las librerías de Adafruit graficas GFX y la que corresponde al chip que controla nuestro display OLED, la SSD_1306:
#include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h>
Después tenemos que definir los pines de control de nuestro display, que son los mismo que comentamos en la sección previa:
#define OLED_MOSI 11 // 9 #define OLED_CLK 12 //10 #define OLED_DC 9 //11 #define OLED_CS 12 #define OLED_RESET 10 //13
La siguiente línea crea una instancia del display SSD_1306:
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
Para simplificar un poco los problemas, vamos a usar barras de 16 pixels de ancho porque 128/16 son 8 barras, y para ordenar el problema definiremos un array de 8 elementos, data [8] que contendrá las alturas de las 8 posibles barras.
const int ancho = 16 ; byte data[8] ;
En el setup, iniciamos el display y lo borramos:
void setup() { display.begin(SSD1306_SWITCHCAPVCC); // Iniciar el display display.clearDisplay(); // Borrar todo }
Como la máxima altura de la barra es de 64 pixels, la del display OLED, calcularemos la altura como 64 * Lectura / 1024. Haremos esto para cada puerta analógica y lo guardaremos en data[]:
void loop() { for (int i=0 ; i<6 ; i++) data[i] = 64 * analogRead( i )/1024 ; barChart( ); delay(150); }
Usamos un bucle de 0 a 5 para leer las puertas analógicas de A0 a A5, porque estoy usando un UNO. SI usáis un MEGA o DUE, podéis subir este límite hasta 8.
- Porque no caben más de 8 con el ancho de 16 pixels, pero podrías tocar la const ancho y bajar la anchura a 12 pixels y podrías usar 10 barras simultaneas.
Usaremos la función display.fillRect () de las librerías GFX, que nos rellena un rectángulo de color. Los parámetros a pasarle son, el punto de inicio X0, Y0, la anchura y la altura del rectángulo y luego un parámetro que es 0 para rellenar con negro y 1 para rellenar con blanco.
- Nótese que el punto (0,0) está en la esquina superior izquierda del display y no en la esquina inferior izquierda como suele ser habitual en las representaciones cartesianas.
Veamos la función:
void barChart() { display.clearDisplay(); for (int j=0 ; j<6 ; j++) { int X0 = ancho * j ; int X1 = ancho - 2 ; byte H = data[j]; display.fillRect( X0,64-H ,X1 , 64, 1 ); } display.drawLine(0, 63, 127, 63, 1); display.display(); }
Hacemos un for de 0 a 5 para calcular las posiciones de las 6 barras. Y calculamos X0 en función del número de barra que toca dibujar, el ancho de la barra es ancho – 2 para tener una zona de separación.
La altura H, no tiene perdida, la leemos del array data [], pero… (Siempre hay un pero) si llamásemos a Fillrect así:
display.fillRect( X0, H , X1 , 0, 1 );
Las barras colgarían del techo, como los murciélagos y las estalactitas, y la costumbre es que la altura de las barras se mida desde el suelo, por lo que tenemos que invertirlas haciendo:
display.fillRect( X0,64-H ,X1 , 64, 1 );
Piénsalo, verás como es así. Tenéis que saber que si dibujas algo, para que estas librerías muestren los cambios de lo que has dibujado en pantalla tienes que invocar a display.display () .Por eso cuando entramos a la función borramos la pantalla y al salir le pedimos que refresque la pantalla.
Aquí os dejo el programa listo para ejecutar
y un pequeño video que muestra el resultado en forma de barras bailando y siguiendo a un par de potenciómetros.
Dibujando líneas que siguen la lectura
Como dibujar las barras han sido demasiado fácil, necesitamos buscarnos problemas mayores. Así que vamos a probar a ver qué pasa con un gráfico tipo las de esas máquinas que muestran el ritmo cardiaco del paciente, en las que un punto va barriendo la pantalla y dejando una estela que nos muestra los valores anteriores.
Vamos a empezar con la parte más sencilla, que es dibujar un punto en cada abscisa (O sea la X) y cuando alcanza el final por la derecha simplemente borra y vuelve a empezar. Aquí teneis
¿En serio os habias creido que era difícil? La parte difícil, no acaba de aparecer, por lo menos hasta ahora. Asi que me dispuse a grabar la imagen aleatoria que generaba el display al leer la puerta A0 y tuve una sorpresa. Echar una ojeada al video y me diréis:
Actualizando el display de modo continúo
No está mal, pero seguro que podemos mejorarlo. Como no estamos dibujando más que puntos sueltos cuando el cambio es rápido los puntos aparecen inconexos, y además como nos sobra tiempo, queremos que el display se vaya desplazando hacia la izquierda de modo continuo para hacer sitio a las nuevas lecturas.
Lo primero que se me ocurre es usar un array de 128, para guardar las lecturas a medida que se produzcan e ir moviendo a la izquierda la pantalla que ya está dibujada.
- Probablemente haya alguna función que me mueve una serie de pixels a la izquierda, pero como lo que quiero es ilustrar la idea de un buffer circular, no voy a buscarla.
En al pantalla solo tengo que dibujar los últimos 128 pixels, pero el número de lecturas puede ser infinito, ¿Cómo puedo resolver esto?
La solución es un buffer circular. La idea es que reservo un array de 128 bytes y un índice que llamaremos index que crece a con cada nueva lectura.

Al empezar index vale 0 pero va creciendo., y lo que queremos es que apunte al 0 cuando sobrepasa el final del array a la lectura 128. ¿Y cómo hacer esto? Así de fácil:
index = index % 128 ;
A medida que el index crece como tomamos su resto con 128, al alcanzar ese valor se pone a 0 él solito. Si grabamos la lectura actual en la posición que indica index++, su valor recorre correrá desde 0 127 y volverá a empezar de modo que nunca rebasaremos su capacidad y conservamos las 128 últimas lecturas para poderlas dibujar. ¿Qué os parece?
A este truco se le llama buffer circular y es muy útil en multitud de ocasiones. Para almacenar las lecturas de A0 tenemos que ajustarlas a escala:
Y por último un mini video con el resultado:
Resumen de la sesión
-
- Hemos visto que es muy sencillo usar gráficos con las librerías de Adafruit GFX.
- Hemos visto el procedimiento para dibujar con ellas y también algunas primitivas básicas, como dibujar puntos y líneas.
- Presentamos un modelo para dibujar gráficos de barras en movimiento.
- Vimos como dibujar graficas de líneas que se van desplazando.
- Presentamos el concepto de buffer circular o Ring Buffer.