,

Display OLED 0.96″ com Arduino

Posted by

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.

Mostrando texto no display OLED 0.96 polegadas
Mostrando texto no display OLED 0.96 polegadas
Gif do display OLED 0.96 mostrando mensagem
Gif do display OLED 0.96 mostrando mensagem

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.

Termômetro com sensor NTC e display OLED 0.96″

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.

Escudo do time Botafogo cortado pela metade

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.

Estrelas da Adafruit
Estrelas da Adafruit

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);

}
Escudo do time botafogo

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

O seu endereço de email não será publicado. Campos obrigatórios marcados com *