Usando o display OLED I2C
Como 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:
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”