Usando o display OLED I2C – Homúnculo

Usando o display OLED I2C

I2C vs SPIComo salientei no post Itens Opcionais, o ideal é usar um display OLED I2C (lê-se “I squared C”) que utiliza apenas 2 pinos para comunicação, ao invés dos 4 pinos utilizados do modelo SPI.

 

 

 

Mesmo que conseguíssemos usar o modelo SPI (não achei uma biblioteca que funcionasse), esbarraríamos no problema de que, para usar o armazenamento interno ou o cartão de memória, é necessário desativar a comunicação SPI, já que a Linkit ONE tem uma pequena chave na qual você escolhe este modo ou o SDCard:

Essa incompatibilidade vem do fato de ambos usarem a mesma “via de comunicação”. Aí vem o caso… se formos usar o I2C, que é através dos pinos SDA e SCL (A4 e A5 no Arduino original), lembrando que a controladora de servos (PCA9685) também é I2C e já está conectada nestes pinos, como ligaremos o display? A resposta: nestes mesmos pinos! Esta é a vantagem do protocolo I2C, você pode conectar centenas de dispositivos I2C nestes 2 pinos. A PCA9685 tem, inclusive, uma “extensão” dos pinos do lado direito, onde você conectar várias delas em sequência:

A única observação é que os dispositivos conectados PRECISAM ter endereços diferentes. Estes “endereços” são valores hexadecimais. A PCA9685 tem jumpers nos quais você pode soldar para especificar o endereço, no caso de ligar várias em sequência:

Entretanto, não precisamos nos preocupar porque normalmente cada tipo de dispositivo usa um determinado endereço e não teremos problemas de conflito entre a PCA9685 (0x40)  e o display OLED (0x3c). Portanto, em nosso caso, podemos tranquilamente ligar ambos nos mesmos pinos ou em sequência.

O display OLED I2C que adquiri foi este aqui:

http://www.dx.com/p/0-96-128-x-64-i2c-interface-yellow-and-blue-oled-display-module-board-for-arduino-419092?Utm_rid=75888205&Utm_source=affiliate

Custei muito a conseguir foi uma biblioteca que me permitisse fazer qualquer coisa no display com a Linkit ONE. Com o Arduino é extremamente simples e qualquer biblioteca funciona (inclusive a da Adafruit). Por fim, achei este exemplo…

http://fritzing.org/projects/esp8266-arduino-oled-spi

Apesar do “spi” no link, é um exemplo para o ESP8266 (farei um artigo sobre ele, quando puder) de um display OLED I2C. Retirei toda a parte do Wifi e do SPI deste exemplo e foi a primeira vez que o display mostrou algo com a Linkit ONE!!!

Em seguida, achei esta biblioteca aqui (OzOLED):

http://blog.oscarliang.net/arduino-oled-display-library/

A princípio ela funcionou, porém ao reiniciar a placa, nada acontecia… o display ficava apagado. Gravei novamente o sketch anterior (oriundo do ESP8266) e em seguida gravei novamente o exemplo da biblioteca  OzOLED e funcionou. Descobri então que havia algo que o código de exemplo da ESP8266 “inicializava” no display e que a OzOLED não fazia. Vasculhei o código-fonte e achei a rotina que inicializava o display, eram várias instruções… Comparei com a do OzOLED e vi que não haviam todas lá. Copiei as que não estavam e fui testando até achar quais eram as necessárias para fazer o display ligar. Então, apresento a versão modificada que funciona na Linkit ONE com o display OLED I2C que comprei:

OzOLED_mod_LinkitONE_SSD1306.rar

(Atualizado em 15/05/2016) Preferencialmente, utilize esta versão: OzOLED_mod_LinkitONE_SSD1306_2.rar

As modificações são no espaçamento entre as fontes e o ajuste do sinal de pontuação (.).

Não sei se funciona para qualquer um (este usado é baseado no SSD1306), só sei que recompilei dezenas de vezes até chegar no resultado esperado. Além da biblioteca, vejamos um exemplo de utilização:

#include <Wire.h>
#include <OzOLED.h>

static unsigned char OscarLogo[] ={
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, 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, 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, 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, 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, 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, 0x80, 0x80, 0x80, 0xC0, 0xC0, 0xC0, 0xE0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF8,
0xF8, 0x78, 0x78, 0x78, 0x7C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
0x1E, 0x0E, 0x0E, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0E, 0x1E, 0x1E,
0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x3E, 0x3E, 0x3C, 0x3C, 0x3C, 0x7C, 0x7C, 0x7C, 0xF8, 0xF8, 0xF8,
0xF8, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0xC0, 0xC0, 0x80, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE,
0xFF, 0x7F, 0x3F, 0x3F, 0x1F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x07, 0x07, 0x0F, 0x0F, 0x1F, 0x3F, 0x3F, 0x7F, 0xFF, 0xFF,
0xFE, 0xFE, 0xFE, 0xFC, 0xFC, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xE0, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x0F, 0x03, 0x01,
0x00, 0x00, 0x00, 0x00, 0x40, 0xC0, 0xC0, 0x80, 0x80, 0x80, 0x80, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 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, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x03, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xF0, 0x00,
0x00, 0x07, 0x1F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF0, 0xE0, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x7E,
0x7E, 0x7E, 0x7E, 0x7C, 0x7C, 0x7C, 0x7C, 0x78, 0x78, 0x78, 0x78, 0x70, 0x30, 0x30, 0x30, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x60, 0x60,
0x60, 0x70, 0x70, 0x70, 0x70, 0x78, 0x78, 0xF8, 0xF8, 0xFC, 0xFC, 0x7C, 0x7C, 0x7E, 0x7E, 0x7E,
0x7E, 0x3F, 0x1F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0,
0xE0, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x07, 0x0F, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x7F,
0x7F, 0xFF, 0xFE, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0xC0, 0xC0, 0x80, 0x80, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x80, 0x80, 0xC0, 0xC0, 0xE0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF,
0x7F, 0x7F, 0x3F, 0x3F, 0x1F, 0x1F, 0x0F, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0F, 0x0F,
0x0F, 0x1F, 0x1F, 0x1E, 0x1E, 0x1E, 0x3E, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x7C, 0x78, 0x78, 0x78,
0x78, 0x78, 0x78, 0x78, 0x78, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
0x78, 0x78, 0x7C, 0x7C, 0x3C, 0x3C, 0x3C, 0x3E, 0x3E, 0x3E, 0x3E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

void setup(){
  Serial.begin(9600);
  
  OzOled.init();  //initialze Oscar OLED display
  delay(50);
  
  OzOled.clearDisplay();               // clear the screen and set start position to top left corner
  OzOled.drawBitmap(OscarLogo, 0, 0, 16, 8);
  OzOled.setCursorXY(2, 0);
  OzOled.printString("CHIMICHANGAS");
  OzOled.setCursorXY(4, 1);
  OzOled.printString("DEADPOOL");
}

int linha = 0;

void loop(){
  char data[32];
  int numero;
  
  if (Serial.available() > 0)
  {
    numero = Serial.readBytesUntil (13, data, 32);
    data[numero] = 0;

    if (data[0]=='#')
    {
      OzOled.clearDisplay();               // clear the screen and set start position to top left corner
      OzOled.drawBitmap(OscarLogo, 0, 0, 16, 8);
    }
    else
    {
      OzOled.setCursorXY(0, linha);
      OzOled.printString(data);
  
      linha++;
  
      if (linha==8)
      {
        linha=0;
      }
    }      
  }
}

O exemplo acima desenha uma imagem (o logotipo do Deadpool), com os textos “CHIMICHANGAS” e “DEADPOOL”. Além disso, você pode escrever no Monitor Serial e o texto será reproduzido na tela. E ao enviar “#” o logotipo é redesenhado.

Agora o próximo passo é fazer ler uma “imagem” do armazenamento interno para exibição no display. Veremos se isso é possível nos próximos capítulos…

 

One thought on “Usando o display OLED I2C

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Translate »