Descripción
Lo que sorprende de estos displays OLED, es su tamaño. Son pequeños. Vamos a ver como se conecta y configura la pantalla.
Lo que sorprende de estos displays OLED, es su tamaño. Son pequeños. Vamos a ver como se conecta y configura la pantalla.
¿Para qué se usa un display pequeño y de tecnología OLED?
Porque el consumo que presenta este display es ridículo: unos 16 mA, aún menos que un LED y eso con una resolución de 128×64 pixels.
Porque el consumo que presenta este display es ridículo: unos 16 mA, aún menos que un LED y eso con una resolución de 128×64 pixels.
Tiene un contraste magnifico y no necesita backlit para poder ver el display, ya que la tecnología OLED genera la luz de por sí.
Lo de OLED viene de Organic Light Emitting Diode, o sea que son diodos LED con otra tecnología.
Suelen tener un color azul o blanco y resulta muy agradable de leer, tanto a plena luz, como en la oscuridad completa.
Permite la representación tanto de caracteres como de matrices graficas e imágenes en una cierta resolución, 128×64 pixels, lo que hace que tenga muchas ventajas, entre ellas que supuestamente funciona igual a 5V que a 3.3V, tanto para la alimentación como para las señales de datos.
Materiales
Placa de Arduino
Placa de Arduino
1 Display OLED I2C 128X64
Protoboard, cables para conexiones y un cable USB para conectar Arduino al PC y sirve además como alimentación
La conexión resulta trivial.
OLED ARDUINO
GND GND
VDD 5V
SCK A5
SDA A4
Como es habitual, podemos aprovecharnos de la facilidad de usar una protoboard para conectar los pines del display OLED directamente a los pines de Arduino, para programarlos directamente.
OLED ARDUINO
GND GND
VDD 5V
SCK A5
SDA A4
Como es habitual, podemos aprovecharnos de la facilidad de usar una protoboard para conectar los pines del display OLED directamente a los pines de Arduino, para programarlos directamente.
Montaje
Código
Este primer código es para comprobar que la pantalla funciona
El siguiente código es para ver como imprimir en pantalla texto dinámico, texto animado e información del sistema.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(9600);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("Fallo pantalla");
while (true);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("OK funciona");
display.display();
}
void loop() {}
Librería para comunicación I2C (SDA/SCL)
No tiene parámetros modificables aquí
#include <Wire.h>
Librería gráfica base (textos, líneas, formas)
#include <Adafruit_GFX.h>
Driver específico para pantallas OLED SSD1306
#include <Adafruit_SSD1306.h>
// Ancho de pantalla en píxeles (normal: 128, algunos módulos 128 o 64 de altura)
#define SCREEN_WIDTH 128
Alto de pantalla en píxeles (puede ser 32 o 64 según modelo)
#define SCREEN_HEIGHT 64
Crea el objeto pantalla.
Parámetros:
- SCREEN_WIDTH → ancho en píxeles
- SCREEN_HEIGHT → alto en píxeles
- &Wire → bus I2C (puede ser Wire o Wire1 en otras placas)
- -1 → pin RESET (si la pantalla no tiene pin RESET físico)
Valores posibles:
- Wire / Wire1 / TwoWire custom
- reset pin: número de pin o -1 si no existe
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Índice del menú actual (0,1,2)
int menuIndex = 0;
Guarda el tiempo del último cambio de menú (millis)
unsigned long lastChange = 0;
Posición horizontal de la animación (pixel X)
int animX = 0;
Dirección de movimiento de la animación (+1 derecha, -1 izquierda)
int dir = 1;
Función que establece los valores necesario al encender el arduino
void setup() {
void setup() {
Inicia puerto serie.
Parámetro:
- 115200 → velocidad en baudios
Valores comunes: 9600, 115200
Serial.begin(115200);
Parámetro:
- 115200 → velocidad en baudios
Valores comunes: 9600, 115200
Serial.begin(115200);
Inicializa la pantalla.
Parámetros:
- SSD1306_SWITCHCAPVCC → modo de alimentación interno del driver
- 0x3C → dirección I2C (puede ser 0x3C o 0x3D)
Parámetros:
- SSD1306_SWITCHCAPVCC → modo de alimentación interno del driver
- 0x3C → dirección I2C (puede ser 0x3C o 0x3D)
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Si falla devuelve false e imprime el pantalla "Fallo OLED"
Bloquea el programa si no detecta pantalla
while (true);
Limpia buffer interno de pantalla (no se ve aún)
display.clearDisplay();
Tamaño del texto.
Valores posibles:
1 → tamaño normal (6x8 px por carácter)
2 → doble
3+ → más grande (ocupa mucha pantalla)
display.setTextSize(1);
Color del texto.
Posibles valores:
- SSD1306_WHITE (blanco / encendido)
- SSD1306_BLACK (apagado sobre fondo invertido)
display.setTextColor(SSD1306_WHITE);
Función personalizada llamada drawMenu
void drawMenu() {
Limpia pantalla antes de dibujar menú
display.clearDisplay();
Posición del texto.
Parámetros:
- X → columna (0 a 127)
- Y → fila (0 a 63)
No hay valores fijos, pero:
- Y en pasos de ~8 funciona bien con texto tamaño 1
Escribe texto con salto de línea automático
Posición del texto.
Parámetros:Serial.println("Fallo OLED");
while (true);
Limpia buffer interno de pantalla (no se ve aún)
display.clearDisplay();
Tamaño del texto.
Valores posibles:
1 → tamaño normal (6x8 px por carácter)
2 → doble
3+ → más grande (ocupa mucha pantalla)
display.setTextSize(1);
Color del texto.
Posibles valores:
- SSD1306_WHITE (blanco / encendido)
- SSD1306_BLACK (apagado sobre fondo invertido)
display.setTextColor(SSD1306_WHITE);
Función personalizada llamada drawMenu
void drawMenu() {
Limpia pantalla antes de dibujar menú
display.clearDisplay();
Posición del texto.
Parámetros:
- X → columna (0 a 127)
- Y → fila (0 a 63)
No hay valores fijos, pero:
- Y en pasos de ~8 funciona bien con texto tamaño 1
display.setCursor(0, 0);
display.println("MENU TEST OLED");
- X → columna (0 a 127)
- Y → fila (0 a 63)
No hay valores fijos, pero:
- Y en pasos de ~8 funciona bien con texto tamaño 1 display.setCursor(0, 20);
display.print(menuIndex == 0 ? "> " : " ");
- si menuIndex == 0 → muestra "> "
- si no → espacios
Sirve para marcar opción seleccionada
display.println("Texto dinamico");
display.setCursor(0, 30);
Imprime en pantalla la opción 1
display.print(menuIndex == 1 ? "> " : " ");
Imprime en pantalla "Animacion"
Establece el cursosr en la posición 0, 40
display.println("Animacion");
display.setCursor(0, 40);
display.print(menuIndex == 2 ? "> " : " ");
display.println("Info sistema");
Envía buffer a pantalla física.
display.display();
}
IMPORTANTE:
Sin esto NO se ve nada.
*/
}
Función repetitiva de arduinoa
Cambia automáticamente cada 3 segundos
millis():
- devuelve tiempo desde inicio en ms
Condición:
- cambia menú cada 3000 ms (3 segundos)
*/
Cambia entre 0,1,2%3 → reinicia a 0 cuando llega a 3
actualiza tiempo de referencia
}lastChange = millis();
// ===== MENU 0 =====
muestra tiempo en ms desde encendido
convierte ms a segundos
// ===== MENU 1 =====
mueve posición horizontal
rebote:
- si llega a borde cambia dirección
controla velocidad de animación
(menor = más rápido)
*/
// ===== MENU 2 =====
*/
}
Función repetitiva de arduinoa
void loop() {
millis():
- devuelve tiempo desde inicio en ms
Condición:
- cambia menú cada 3000 ms (3 segundos)
*/
// Cambia menú automáticamente cada 3s
if (millis() - lastChange > 3000) {
menuIndex = (menuIndex + 1) % 3;
}lastChange = millis();
}
muestra tiempo en ms desde encendido
// ===== MENU 0: texto dinámico =====
if (menuIndex == 0) {
display.clearDisplay();
display.setCursor(0, 0);
display.println("Texto dinamico:");
display.setCursor(0, 20);
display.print("Millis: ");
display.println(millis());
display.setCursor(0, 40);
display.print("Seg: ");
display.println(millis() / 1000);
display.display();
}
mueve posición horizontal
// ===== MENU 1: animacion =====
else if (menuIndex == 1) {
display.clearDisplay();
display.setCursor(animX, 20);
display.println("OLED");
animX += dir;
- si llega a borde cambia dirección
if (animX <= 0 || animX >= 100) dir = -dir;
(menor = más rápido)
*/
display.display();
delay(20);
}
// ===== MENU 2: info sistema =====
else if (menuIndex == 2) {
display.clearDisplay();
display.setCursor(0, 0);
display.println("INFO SISTEMA");
display.setCursor(0, 20);
display.println("Arduino UNO");
display.setCursor(0, 35);
display.println("OLED 128x64");
display.setCursor(0, 50);
display.print("I2C: 0x3C");
display.display();
}
Aquí tienes el código completo
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
int menuIndex = 0;
unsigned long lastChange = 0;
int animX = 0;
int dir = 1;
void setup() {
Serial.begin(9600);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("Fallo OLED");
while (true);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
}
void drawMenu() {
display.clearDisplay();
display.setCursor(0, 0);
display.println("MENU TEST OLED");
display.setCursor(0, 20);
display.print(menuIndex == 0 ? "> " : " ");
display.println("Texto dinamico");
display.setCursor(0, 30);
display.print(menuIndex == 1 ? "> " : " ");
display.println("Animacion");
display.setCursor(0, 40);
display.print(menuIndex == 2 ? "> " : " ");
display.println("Info sistema");
display.display();
}
void loop() {
// Cambia menú automáticamente cada 3s
if (millis() - lastChange > 3000) {
menuIndex = (menuIndex + 1) % 3;
lastChange = millis();
}
// ===== MENU 0: texto dinámico =====
if (menuIndex == 0) {
display.clearDisplay();
display.setCursor(0, 0);
display.println("Texto dinamico:");
display.setCursor(0, 20);
display.print("Millis: ");
display.println(millis());
display.setCursor(0, 40);
display.print("Seg: ");
display.println(millis() / 1000);
display.display();
}
// ===== MENU 1: animacion =====
else if (menuIndex == 1) {
display.clearDisplay();
display.setCursor(animX, 20);
display.println("OLED");
animX += dir;
if (animX <= 0 || animX >= 100) dir = -dir;
display.display();
delay(20);
}
// ===== MENU 2: info sistema =====
else if (menuIndex == 2) {
display.clearDisplay();
display.setCursor(0, 0);
display.println("INFO SISTEMA");
display.setCursor(0, 20);
display.println("Arduino UNO");
display.setCursor(0, 35);
display.println("OLED 128x64");
display.setCursor(0, 50);
display.print("I2C: 0x3C");
display.display();
}
}
El siguiente código me permite mostrar una barra que indican el nivcl del sonido
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1 // I2C normalmente no usa reset
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const int ancho = 16;
byte data[6];
void setup() {
Wire.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // dirección típica I2C
while (true); // si falla, se queda aquí
}
display.clearDisplay();
}
void loop() {
for (int i = 0; i < 6; i++) {
data[i] = map(analogRead(i), 0, 1023, 0, 64);
}
barChart();
delay(150);
}
void barChart() {
display.clearDisplay();
for (int j = 0; j < 6; j++) {
int X0 = ancho * j;
int H = data[j];
display.fillRect(X0, 64 - H, ancho - 2, H, SSD1306_WHITE);
}
display.drawLine(0, 63, 127, 63, SSD1306_WHITE);
display.display();
}
El siguiente código es lo mismo pero con una señal de ondas
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Wire.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
while (true); // fallo de pantalla
}
display.clearDisplay();
}
void loop() {
display.clearDisplay();
for (int x = 0; x < 128; x++) {
int y = map(analogRead(A0), 0, 1023, 63, 0); // invertido eje Y
display.drawPixel(x, y, SSD1306_WHITE);
}
display.display();
delay(500);
}
El siguiente código es un osciloscópio tremendamente básico. La entrada de señal está en A0
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int buffer[128];
void setup() {
Wire.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
while (true);
}
display.clearDisplay();
}
void loop() {
// 1. Captura de señal
for (int i = 0; i < 128; i++) {
buffer[i] = analogRead(A0);
delayMicroseconds(200); // ajusta velocidad de muestreo
}
// 2. Dibujar señal
display.clearDisplay();
for (int x = 0; x < 127; x++) {
int y1 = map(buffer[x], 0, 1023, 63, 0);
int y2 = map(buffer[x + 1], 0, 1023, 63, 0);
display.drawLine(x, y1, x + 1, y2, SSD1306_WHITE);
}
display.display();
}
No hay comentarios:
Publicar un comentario