Hoje vamos conhecer o display OLED 0.96″ com Arduino, um display bem completo porém (pela minha experiência) bem difícil de lidar. O modelo que eu comprei foi de cores amarelo/azul com i2c, daqui (link de afiliado).
A resolução deste pequeno display (é pequeno mesmo) é 128×32 pixels, acessíveis individualmente. Eu começei com esse código e com um Digispark Attiny85 como controlador. Mas para isso tive que baixar a biblioteca daqui e editar o arquivo “DigisparkOLED.cpp” para modificar as linhas:
if(Wire.writeAvailable()){
ssd1306_send_data_stop();
ssd1306_send_data_start();
}
Que tem que ficar assim:
//if(Wire.writeAvailable()){
ssd1306_send_data_stop();
ssd1306_send_data_start();
//}
OBS: fazer este tipo de modificação está longe da facilidade que o Arduino deveria oferecer, portanto eu não recomendo utilizar este display OLED com Digispark Attiny85 e esta biblioteca.
Escrevi o código abaixo apenas para mostrar texto no display, conforme imagem. Observe que tive que apontar o referido arquivo como caminho absoluto na primeira linha do arquivo.
#include <C:\Users\Clovisf\Documents\GitHub\Display-OLED-0.96\teste-display-oled-0.96\DigisparkOLED.h>
#include <Wire.h>
// ============================================================================
void setup()
{
// put your setup code here, to run once:
oled.begin();
oled.clear(); //all black
}
void loop()
{
oled.setCursor(0, 0); //top left
oled.setFont(FONT6X8);
oled.print(F("This is a text test")); //lines auto wrap
oled.setCursor(0, 1);
oled.print(F("from FritzenLab")); //lines auto wrap
oled.setFont(FONT8X16);
oled.setCursor(0, 2); //two rows down because the 8x16 font takes two rows of 8
oled.print(F("FritzenLab.net")); //wrap strings in F() to save RAM!
oled.setCursor(0, 4); //two rows down because the 8x16 font takes two rows of 8
oled.print(F("FritzenLab.com.br")); //wrap strings in F() to save RAM!
//delay(3000);
}
O resultado ficou bem legal, note que o display tem uma “faixa” amarela no topo e o restante dele é azul. Esqueci de mencionar, ele funciona com 5V.
Arduino UNO e Adafruit
Porém esta biblioteca para o Attiny85 Digispark é bem limitada, então mudei para utilizar Arduino UNO. A biblioteca da Adafruit que tem exemplos aqui foi a que eu usei como base no restante do artigo.
Realizei um exemplo de um termômetro com sensor NTC (já visto aqui) e o display OLED. O código está abaixo. Observe que como não temos pino extra de reset, fazemos:
#define OLED_RESET -1
Você precisa instalar na IDE do Arduino as bibliotecas “Adafruit_GFX.h” e “Adafruit_SSD1306.h”, vá em “Rascunho > Incluir biblioteca > Adicionar biblioteca .ZIP” e procure pelas mesmas.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET -1
Adafruit_SSD1306 display(OLED_RESET);
// Conexão do termistor
const int pinTermistor = A0;
// Parâmetros do termistor
const double beta = 3950.0;
const double r0 = 10000.0;
const double t0 = 273.0 + 25.0;
const double rx = r0 * exp(-beta/t0);
// Parâmetros do circuito
const double vcc = 4.92;
const double R = 9810.0;
// Numero de amostras na leitura
const int nAmostras = 5;
void setup(){
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}
void loop(){
int soma = 0;
for (int i = 0; i < nAmostras; i++) {
soma += analogRead(pinTermistor);
delay (100);
}
// Determina a resistência do termistor
double v = (vcc*soma)/(nAmostras*1024.0);
double rt = (vcc*R)/v - R;
// Calcula a temperatura
double t = beta / log(rt/rx);
t= t-273;
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0,0);
display.println("FritzenLab");
display.setTextColor(WHITE);
display.setTextSize(3);
//display.setTextColor(WHITE);
display.setCursor(0,9);
display.print(t);
display.println(" C");
display.display();
delay(1000);
}
E aqui o resultado final, um termômetro com display OLED lendo um sensor termistor NTC. O sensor NTC tem um resistor de 10k Ohm em série e está conectado ao pino A0 do Arduino. Conforme já visto no artigo linkado acima.
Uma dificuldade que tive foi mostrar imagens (bitmaps) nesta pequena telinha. A forma oficial (usando a biblioteca da Adafruit) inicialmente não funcionou, a imagem ficava cortada conforme abaixo.
Porém o código de exemplo da Adafruit na IDE do Arduino (ssd1306_128x64_i2c.ino) em “Arquivo > Exemplos > Adafruit SSD1306 >” funcionou tranquilamente, mostrou as estrelas da Adafruit “caindo” como deveria ser.
Descobri então que eu comprei um display 128×32 ao invés do que eu gostaria, que era 128×64. Aí as imagens começaram a sair conforme planejado, como o escudo do Botafogo de futebol e regatas. O código e a imagem estão abaixo:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET -1
Adafruit_SSD1306 display(OLED_RESET);
/*#define LOGO16_GLCD_HEIGHT 128
#define LOGO16_GLCD_WIDTH 50 */
static const unsigned char PROGMEM drawing[] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x80, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0x80, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0x80, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xc0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x03, 0xc0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x7f, 0xfe, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1f, 0xfc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0f, 0xf0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x07, 0xe0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07, 0xf0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0f, 0xf0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x70, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0x08, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
void setup() {
// put your setup code here, to run once:
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
// init done
// Show image buffer on the display hardware.
// Since the buffer is intialized with an Adafruit splashscreen
// internally, this will display the splashscreen.
display.display();
delay(2000);
// Clear the buffer.
display.clearDisplay();
}
void loop() {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0,0);
display.println("Botafogo");
// put your main code here, to run repeatedly:
display.clearDisplay();
// miniature bitmap display
display.drawBitmap(0, 0, drawing, 128, 40, 1);
display.display();
delay(2000);
}
OBS: para gerar o binário da imagem do código acima, utilizei este serviço: https://javl.github.io/image2cpp/ .
Na realidade eu postei a questão no fórum Arduino Stackexchange e uma pessoa me ajudou, orientando a colocar as dimensões do display no código, conforme abaixo:
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);
No fim das contas não era o meu display que veio errado, e sim o exemplo de código que estava incompleto.
Pra finalizar
Neste artigo mostrei como descobri que meu display não era 128×64 e sim 128×32. Mostrei como gerar texto, inclusive fazendo um exemplo de um termômetro com termistor NTC. Por fim fizemos o exemplo de converter uma imagem para binário e mostrar no display OLED.
Lembrando que se quiser comprar o display deste artigo, use meu link de afiliado do Banggood aqui.
Deixe um comentário