Pantalla OLED

Descrición:

OLED vén das siglas “Organic Light Emitting Diode ” (Diodo emisor de luz orgánico). É “orgánico” porque está composto por láminas de carbono que emiten luz cando se lles aplica unha diferenza de potencial.

Para que esa luz saia na pantalla na posición que nós queiramos, fai falta un controlador que converta os datos recibidos desde o arduino en sinais electrónicas que controlan a pantalla. O controlador neste caso é SDD1306.

Son interesantes para proxectos nos que nos interese baixar o consumo ou que teñamos pouco espazo, pois estas pantallas poden darnos moita información nun espazo moi pequeno.

Conexión:

A conexión dunha pantalla OLED con interface I2C resulta moi sinxela, pois só temos catro pins. No caso dunha placa Arduíno UNO as conexións serían:

  • GND e Vcc para a alimentación.
  • SDA ao pin analóxico A4. É o pin de datos.
  • SCL ao pin analóxico A5. É o que envía o sinal de reloxo.

Configuración

Antes de nada imos coñecer cal é o enderezo da nosa pantalla. Para iso carga o programa I2C scanner no teu Arduíno, abre a consola e mira o resultado. No noso caso é 0x3C:

Para poder programar a pantalla OLED necesitaremos unhas librerías. A librería
Adafruit_SSD1306 permítenos manexar o controlador e enviar datos á pantalla, e a librería Adafruit-GFX-Library  permítenos facer gráficos. Necesitaremos, ademais, as librerías wire e SPI.

// Librerías
 
#include 
#include 
#include 
#include 

// Constantes e variables

int ancho=128;
int alto=64;

Adafruit_SSD1306 display(ancho, alto, &Wire, -1);

// Configuración

void setup() {
  
// Primeiro conectamos coa pantalla e comprobamos que todo vai ben
  
  #ifdef __DEBUG__
    Serial.begin(9600);
    delay(100);
    Serial.println("Iniciando a pantalla OLED");
  #endif
  
    // Iniciar pantalla OLED en la dirección 0x3C
    
    if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
      #ifdef __DEBUG__
          Serial.println("No se atopa a pantalla OLED");
      #endif
          while (true);
    }
    
// Agora escribimos un texto de benvida 

  display.clearDisplay();                 // Limpar buffer
  display.setTextSize(1);                 // Tamaño do texto
  display.setTextColor(WHITE);    // Cor do texto
  display.setCursor(0, 2);               // Posición do texto
  display.println("Pantalla acesa");     // Escribir texto
  display.display();                      // Enviar á pantalla

  delay(1000);

  display.clearDisplay();

// Se non coñecemos as dimensións da pantalla, estas funcións nolas devolven:

  ancho=display.width();
  alto=display.height();
  display.setCursor(0, 18);
  display.println("ancho:");
  display.println(ancho);
  display.setCursor(0, 40);
  display.println("alto:");
  display.println(alto);
  display.display();   

  delay(1000);

  display.clearDisplay();
  
}

void loop() {
  // De momento nada
}

No void loop() { //instrucións } introduciremos os tatos que queramos visualizar na pantalla, e que podes ver nestas prácticas:

Prácticas

1.Píxeles

Imos ver como pintar píxeles en determinadas posicións. Para iso utilízase a instrución display.drawPixel(x, y, WHITE) onde x e y marcan as coordenadas. A nosa pantalla ten 128 píxeles de ancho (x va de 0 a 127) e 64 píxeles de alto (y va de 0 a 63).

A instrución  WHITE acende os píxeles e BLACK apágaos.

Por exemplo, se queremos poñer un píxel en cada esquina da pantalla escribiremos o seguinte código:

void loop() {
  
  display.clearDisplay(); 
  display.drawPixel(0, 0, WHITE);
  display.drawPixel(0, 63, WHITE);
  display.drawPixel(127, 0, WHITE);
  display.drawPixel(127, 63, WHITE);
  display.display();
}

Se queremos ir acendendo e apagando píxeles pouco a pouco podemos utilizar un bucle for. Neste caso imos acender todos os píxeles da pantalla de forma que debuxemos unhas liñas, e despois apagarémolas tamén pouco a pouco.

void loop() {
  
  for (int y=0; y<=63; y+=16){
    for (int x=0; x<=127; x++){
      display.drawPixel(x, y, WHITE);
      display.display();
    }
  }

  for (int y=0; y<=63; y+=16){
    for (int x=0; x<=127; x++){
      display.drawPixel(x, y, BLACK);
      display.display();
    }
  }

}

Realmente se queremos debuxar liñas é mellor non facelo así. Verémolo despois na pestana “4.Liñas”

2.Texto

Xa vimos no inicio como escribir texto. Proba escribir texto en diferentes posicións e con distintos tamaños.

void loop() {
  
  display.clearDisplay();         // Limpar buffer
  display.setTextColor(WHITE);    // establecer cor
  
  display.setTextSize(1);       
  display.setCursor(0, 0);         
  display.println("Tamano1");   

  display.setTextSize(2);       
  display.setCursor(0, 11);    
  display.println("Tamano2");
       
  display.setTextSize(3);       
  display.setCursor(0, 28);    
  display.println("Tamano3");
  
  display.display();                      // Enviar á pantalla
  
}

Verías que o ñ non o detecta. Nese caso debemos recorrer ao código ASCII e buscar o número correspondente ao carácter que queremos mostrar. No caso da ñ é o 164.

display.write(164);  

3.Texto en movemento

Para mover todas as filas da pantalla horizontalmente inicio ten que ser igual a 0x00 e fin ten que ser igual a 0x0F (son números en hexadecimal).

display.startscrollright(inicio, fin);

Para mover todas as filas en diagonal tes que pasar como parámetro inicio 0x00 e como fin 0x07

display.startscrolldiagright(inicio, fin);

Imos poñer dentro do loop as seguintes instrucións para mover un texto pola pantalla. Observa o resultado.

void loop() {
  
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 32);
  display.println("Tecnoloxia");
  
  display.display();   // Enviar á pantalla
  delay(2000);
 
  // Mover texto de esquerda á dereita
  
  display.startscrollright(0x00, 0x3F);
  delay(4000);
  display.stopscroll();
  
  // Mover texto de dereita a esquerda
  
  display.startscrollleft(0x00, 0x3F);
  delay(4000);
  display.stopscroll();
 
  // Mover texto en diagonal cara á dereita
  
  display.startscrolldiagright(0x00, 0x07);
  delay(4000);
  display.stopscroll();
 
  // Mover texto en diagonal cara á esquerda
  
  display.startscrolldiagleft(0x00, 0x07);
  delay(4000);
  display.stopscroll();
  
} 

A única maneira de controlar o desprazamento no exemplo anterior é modificando o tempo do delay.

4.Liñas

Para debuxar liñas utilizamos a funcióndisplay.drawLine(x0, y0, x1, y1, cor); (x0, y0) serán as coordenadas do punto inicial, (x1, y1) as coordenadas do punto final, e cor a cor da liña( WHITE).

Por exemplo:

void loop() {
  
  display.drawLine(0, 5, ancho, 5, WHITE);    // liña horizontal na fila 5
  display.display(); 
  delay(2000);

  display.clearDisplay();

  display.drawLine(63, 0, 63, alto, WHITE);   // liña vertical na columna 63
  display.display(); 
  delay(2000); 

  display.clearDisplay();

  display.drawLine(0, 0, ancho, alto, WHITE);   // diagonal 1
  display.display(); 
  delay(2000); 

  display.clearDisplay();

  display.drawLine(0, alto, ancho, 0, WHITE);   // diagonal 2
  display.display(); 
  delay(2000); 

  display.clearDisplay();
  
}

No seguinte exemplo imos debuxar liñas cun bucle:

void loop() {

  for (int i=0; i<alto; i+=4) {
    display.drawLine(ancho-1, 0, 0, i, WHITE);
    display.display();
    delay(1);
  }
  for (int i=0; i<ancho; i+=4) {
    display.drawLine(ancho-1, 0, i, alto-1, WHITE); 
    display.display();
    delay(1);
  }
  delay(250);
  
  display.clearDisplay();
  
}

4.Figuras

Tamén podemos debuxar cadrados , rectángulos, círculos e triángulos:

Rectángulo: Poñemos as coordenadas do punto de inicio, a¡o ancho,o alto e a cor. As coordenadas do inicio son as do vértice superior esquerdo.

  • Sen recheo: display.drawRect(x0, y0, w, h, WHITE);
  • Recheo: display.fillRect(x0, y0, w, h, WHITE);

Rectángulo con esquinas redondeadas: indicamos, ademais do anterior, o radio das esquinas

  • Sen recheo: display.drawRoundRect(x0, y0, w, h, radio, color);
  • Recheo: display.fillRoundRect(x0, y0, w, h, radio, color);

Círculo: indicamos o centro e o radio

  • Sen recheo:  display.drawCircle(x0, y0, radio, color);
  • Recheo: display.fillCircle(x0, y0, radio, color);

Triángulo: Indicamos as coordenadas dos tres vértices.

  • Sen recheo:  display.drawTriangle(x0, y0, x1, y1, x2, y2, color);
  • Recheo: display.fillTriangle(x0, y0, x1, y1, x2, y2, color);

Exemplo:

void loop() {

  // rectángulos
  
  display.drawRect(0, 0, ancho, alto, WHITE);
  display.display(); 
  delay(2000);

  display.clearDisplay();

  display.fillRect(0, alto/2, ancho/2, alto/2, WHITE);
  display.display(); 
  delay(2000);

  display.clearDisplay();

  
  // rectángulos coas esquinas redondeadas

  display.drawRoundRect(0, 0, ancho, alto, 5, WHITE);
  display.display(); 
  delay(2000);

  display.clearDisplay();

  display.fillRoundRect(ancho/2, alto/2, ancho/2, alto/2, 5, WHITE);
  display.display(); 
  delay(2000);

  display.clearDisplay();

  // círculos

  display.drawCircle(ancho/2, alto*2/3, 20,WHITE);
  display.display(); 
  delay(2000);

  display.clearDisplay();

  display.fillCircle(ancho/2, alto*2/3, 20, WHITE);
  display.display(); 
  delay(2000);

  display.clearDisplay();

  // Triángulos

  display.drawTriangle(0,0, ancho,0, ancho/2, alto/2, WHITE);
  display.display(); 
  delay(2000);

  display.clearDisplay();

  display.fillTriangle(0,20, 30,20, 30,64, WHITE);
  display.display(); 
  delay(2000);

  display.clearDisplay();

}

 

Propostas:

  • Conecta un potenciómetro e fai que se debuxe unha liña horizontal cun tamaño marcado polo valor que tome o potenciómetro.
  • Fai o mesmo pero mostrando un círculo de máis ou menos radio segundo a posición do cursor.
  • Conecta un pulsador. Unha variable almacenará o número de veces que premes nel. Aparecerá na pantalla unha barra vertical que se irá facendo máis alta a medida que aumenta o número de pulsos. Fai que tamén apareza o número de pulsos na pantalla, enriba ou debaixo da barra.