Como usar um display OLED (SSD1306): texto, formas e gráficos com Arduino
Como usar um display OLED I2C de 0,96 polegada (SSD1306)? Ligação e endereço I2C (0x3C), as bibliotecas Adafruit SSD1306 e GFX, como desenhar texto, formas, valores de sensores e bitmaps, além de código para ESP32 e para o Pico em MicroPython.
Mesmo sendo pouco maior que a ponta de um dedo, o display OLED de 0,96 polegada mostra uma imagem nítida de 128×64 pixels e é um dos displays mais populares em projetos com Arduino. Ao contrário dos LCDs de caracteres, ele desenha não só letras, mas também linhas, círculos, ícones, gráficos e até joguinhos. É ideal para relógios inteligentes, estações meteorológicas, controles remotos e medidores portáteis. Quase todos esses displays usam um chip controlador chamado SSD1306 e são ligados com apenas dois fios de dados (I2C).

O que é OLED e qual a diferença para um LCD?
Em um display OLED (Organic Light Emitting Diode, diodo orgânico emissor de luz), cada pixel produz a própria luz; não existe luz de fundo. Por isso as áreas pretas são pretas de verdade, o contraste é muito alto, a tela parece nítida de qualquer ângulo e o consumo é muito baixo quando a maior parte da imagem é escura. Os 128×64 pixels permitem gráficos, ícones e desenhos que os LCDs baseados em caracteres não conseguem mostrar.
| Característica | OLED de 0,96" | OLED de 0,91" | LCD 16x2 |
|---|---|---|---|
| Resolução | 128×64 pixels | 128×32 pixels | 16×2 caracteres |
| Gráficos e ícones | Sim | Sim | Não (só caracteres) |
| Luz de fundo | Não precisa | Não precisa | Precisa |
| Conexão | I2C (também existem versões SPI) | I2C | 4 fios com um módulo I2C |
| Sob o sol | Difícil de ler | Difícil de ler | Mais fácil de ler |
Especificações
| Característica | Valor |
|---|---|
| Chip controlador | SSD1306 |
| Tela | 0,96" 128×64 (a versão de 0,91" é 128×32) |
| Cor | Monocromática: branca, azul, ou amarela em cima e azul embaixo |
| Alimentação | 3,3–5 V (há um regulador na placa) |
| Corrente | Cerca de 10–25 mA (depende de quantos pixels estão acesos) |
| Endereço I2C | 0x3C (0x3D em alguns modelos) |
| Pinos | GND, VCC, SCL, SDA |
Ligação do display OLED
| Pino do OLED | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| GND | GND | GND | GND |
| VCC | 5V ou 3.3V | 3V3 | 3V3 |
| SCL | A5 | GPIO 22 | GP5 |
| SDA | A4 | GPIO 21 | GP4 |
Nos modelos de duas cores, as 16 linhas de cima da tela brilham em amarelo e o resto em azul; essas cores não podem ser mudadas por software, então fica bonito desenhar a parte de cima como uma barra de título. Se você não tem certeza do endereço do display, use o sketch scanner I2C de Como usar um display LCD I2C.
Instalando as bibliotecas
- Abra o Gerenciador de Bibliotecas na Arduino IDE e busque Adafruit SSD1306.
- Quando a instalação perguntar sobre as dependências, escolha Instalar tudo para que a Adafruit GFX e a Adafruit BusIO também sejam instaladas.
- Se quiser, abra Arquivo > Exemplos > Adafruit SSD1306 > ssd1306_128x64_i2c e teste com o endereço do display definido como 0x3C.
Primeiro programa: escrevendo texto na tela
1#include <Wire.h>
2#include <Adafruit_GFX.h>
3#include <Adafruit_SSD1306.h>
4
5Adafruit_SSD1306 display(128, 64, &Wire, -1); // genişlik, yükseklik, I2C, reset pini yok / width, height, I2C, no reset pin
6
7void setup() {
8 if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // I2C adresi / I2C address
9 for (;;); // ekran bulunamadı / display not found
10 }
11 display.clearDisplay();
12 display.setTextColor(SSD1306_WHITE);
13 display.setTextSize(2); // 2 kat büyük / double size
14 display.setCursor(0, 0);
15 display.println(F("BlueGrays"));
16 display.setTextSize(1);
17 display.setCursor(0, 24);
18 display.println(F("OLED 128x64 hazir!"));
19 display.display(); // tamponu ekrana gönder / push the buffer to the screen
20}
21
22void loop() {
23}Desenhando formas: funções da Adafruit GFX
| Função | O que desenha |
|---|---|
| drawPixel(x, y, cor) | Um único pixel |
| drawLine(x0, y0, x1, y1, cor) | Uma linha |
| drawRect / fillRect(x, y, largura, altura, cor) | Um retângulo ou um retângulo preenchido |
| drawCircle / fillCircle(x, y, raio, cor) | Um círculo ou um círculo preenchido |
| drawRoundRect(x, y, largura, altura, canto, cor) | Um retângulo com cantos arredondados |
| drawTriangle(x0, y0, x1, y1, x2, y2, cor) | Um triângulo |
| drawBitmap(x, y, matriz, largura, altura, cor) | Uma imagem pronta (bitmap) |
O canto superior esquerdo da tela é (0, 0) e o canto inferior direito é (127, 63). Para a cor, você usa SSD1306_WHITE (aceso), SSD1306_BLACK (apagado) ou SSD1306_INVERSE (inverter).
Mostrando o valor de um sensor: um termômetro ao vivo
O ponto forte do OLED é mostrar leituras com dígitos grandes e gráficos. O código abaixo escreve em fonte grande a temperatura lida de um DHT11 e mostra a umidade embaixo como um gráfico de barras. Para a ligação do sensor, veja Sensor de temperatura e umidade DHT11.
1#include <Wire.h>
2#include <Adafruit_GFX.h>
3#include <Adafruit_SSD1306.h>
4#include <DHT.h>
5
6Adafruit_SSD1306 display(128, 64, &Wire, -1);
7DHT dht(2, DHT11);
8
9void setup() {
10 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
11 display.setTextColor(SSD1306_WHITE);
12 dht.begin();
13}
14
15void loop() {
16 float t = dht.readTemperature();
17 float h = dht.readHumidity();
18 display.clearDisplay();
19 display.setTextSize(1);
20 display.setCursor(0, 0);
21 display.print(F("Sicaklik / Temp"));
22 display.setTextSize(3);
23 display.setCursor(0, 16);
24 display.print(t, 1);
25 display.print(F("C"));
26 display.drawRect(0, 52, 128, 10, SSD1306_WHITE); // nem çubuğu çerçevesi / humidity bar frame
27 display.fillRect(2, 54, (int)(h / 100.0 * 124), 6, SSD1306_WHITE); // nem oranı kadar dolu / filled by humidity
28 display.display();
29 delay(2000);
30}Desenhando seu próprio ícone: bitmaps
Para mostrar um logotipo ou um ícone, você transforma a imagem em um array de bytes: cada bit é um pixel. Ferramentas de conversão como o image2cpp transformam uma imagem em preto e branco direto em um array para o Arduino. Você também pode escrever ícones pequenos à mão; o array 8×8 abaixo desenha um coração:
1const unsigned char PROGMEM heart[] = {
2 0b01100110,
3 0b11111111,
4 0b11111111,
5 0b11111111,
6 0b01111110,
7 0b00111100,
8 0b00011000,
9 0b00000000
10};
11
12// setup() ya da loop() içinde / inside setup() or loop()
13display.drawBitmap(60, 28, heart, 8, 8, SSD1306_WHITE);
14display.display();OLED com o ESP32 e o Raspberry Pi Pico
O mesmo código e as mesmas bibliotecas do Arduino rodam no ESP32; os pinos I2C são o GPIO 21 (SDA) e o 22 (SCL). Como o ESP32 tem bastante memória, animações e gráficos que atualizam rápido ficam muito mais suaves. No Pico com MicroPython, basta copiar para o Pico o arquivo de driver ssd1306.py (da micropython-lib):
1from machine import Pin, I2C
2import ssd1306 # ssd1306.py Pico'da olmalı / must be on the Pico
3
4i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)
5oled = ssd1306.SSD1306_I2C(128, 64, i2c) # adres varsayılan 0x3C / default address 0x3C
6
7oled.fill(0) # ekranı temizle / clear the screen
8oled.text("BlueGrays", 0, 0)
9oled.text("Pico + OLED", 0, 16)
10oled.rect(0, 40, 128, 20, 1) # çerçeve / frame
11oled.fill_rect(2, 42, 80, 16, 1) # dolu çubuk / filled bar
12oled.show() # ekrana gönder / push to the screenVida útil do display e burn-in
Os pixels do OLED perdem brilho com o uso. Se a mesma imagem fica na tela, sem mudar, por meses, pode se formar um leve "fantasma" nos pixels que acendem com frequência. Para evitar isso, desligue o display quando não estiver em uso (display.ssd1306_command(SSD1306_DISPLAYOFF)), diminua o brilho (display.dim(true)), desloque o conteúdo fixo alguns pixels de vez em quando, ou use um sensor PIR para ligar o display só quando houver alguém por perto.
Ideias de projetos com display OLED
- Miniestação meteorológica: mostre temperatura, umidade e pressão com ícones.
- Jogos de bolso: jogue Pong ou o T-Rex runner com botões ou um joystick.
- Display de previsão do tempo: mostre, com ícones, a previsão do tempo que você busca na internet com um ESP32.
- Display de sensor de estacionamento: mostre a distância medida por um HC-SR04 como um número e uma barra.
- Plotador de sinais: desenhe na tela os valores do analogRead como um gráfico que rola.
- Relógio de mesa: reúna em uma só tela a hora da internet, a data e o clima do dia.
Erros comuns e como resolvê-los
- A tela fica em branco: display.display() não é chamado, o endereço está errado (0x3D em vez de 0x3C), ou o SDA e o SCL estão trocados.
- "SSD1306 allocation failed": o Uno ficou sem RAM; o buffer de um display 128×64 ocupa 1 KB. Escreva textos com F(), passe arrays grandes para a PROGMEM ou use a biblioteca U8g2, que economiza RAM.
- A imagem sai embaralhada ou só pela metade: um display 128×32 foi declarado como 128×64 (ou o contrário); use o tamanho correto no código.
- A imagem está de cabeça para baixo: gire 180 graus com display.setRotation(2).
- Ligar o VCC e o GND invertidos: isso queima o display para sempre; leia as marcações dos pinos antes de ligar.
- Travamentos aleatórios: fios I2C longos e frouxos; use fios curtos e, se precisar, diminua a velocidade do I2C.
Um display OLED é o jeito mais barato de dar uma aparência profissional ao seu projeto. Se você só precisa mostrar números, um display de 7 segmentos é uma boa escolha, e para textos que precisam ser legíveis sob o sol, um LCD I2C. No app BlueGrays você encontra jogos de Pong e T-Rex com OLED, um display de previsão do tempo com ESP32, um sensor de estacionamento e um registrador de temperatura, com esquemas do circuito e código.
Perguntas frequentes
O endereço do meu display OLED é 0x3C ou 0x3D?
A maioria dos módulos OLED 128×64 usa o endereço 0x3C; alguns passam a 0x3D com um ajuste de resistor na parte de trás da placa. Se atrás estiver escrito "0x78", essa é a notação de 8 bits e corresponde a 0x3C no código. Para ter certeza, rode o sketch scanner I2C.
O display OLED funciona com 5 V?
A maioria dos módulos SSD1306 tem um regulador na placa, então eles podem ser alimentados com 3,3 V ou 5 V e ligados direto em um Arduino Uno. No ESP32 e no Pico, alimentar o módulo pelo pino 3V3 mantém as linhas I2C também em 3,3 V.
Por que aparece o erro "SSD1306 allocation failed"?
A biblioteca quer reservar um buffer de imagem de 1 KB para um display 128×64; se os 2 KB de RAM do Arduino Uno estiverem cheios de outras variáveis, não sobra espaço para ele. Escreva textos fixos com a macro F(), passe arrays grandes para a PROGMEM ou use a biblioteca U8g2, que desenha página por página.
Um display OLED consegue mostrar caracteres acentuados ou especiais?
A fonte padrão da Adafruit GFX não inclui letras como ã, ç ou é. A biblioteca U8g2 consegue mostrá-las com suporte a UTF-8 e fontes com conjuntos grandes de caracteres; com a Adafruit GFX, você precisa criar uma fonte personalizada ou desenhar as letras como bitmaps.
Existem displays OLED coloridos?
Os displays SSD1306 são monocromáticos; mesmo nos modelos de duas cores, as cores são fixas. Para imagens coloridas, use OLEDs coloridos com controladores SSD1331 ou SSD1351, ou displays TFT coloridos como o ST7789 e o ILI9341.
Posso ligar dois displays OLED em um Arduino?
Sim. Se você mudar o endereço de um dos displays para 0x3D mudando o resistor da parte de trás de lugar, os dois podem dividir o mesmo barramento I2C. Se o endereço não puder ser mudado, você pode usar um segundo barramento I2C no ESP32 e no Pico ou acrescentar um multiplexador I2C como o TCA9548A.
Projetos para montar depois desta leitura
Ver todos os projetos
Jogo de bola e raquetes - SSD1306
Uma bola, duas raquetes e você: jogue tênis de mesa, um dos primeiros videogames, em um pequeno display OLED. Dois botões movem sua raquete à direita para cima e para baixo, enquanto o computador cont

Corrida do T-Rex no OLED: jogo do dinossauro com Arduino
O jogo do dinossauro que aparece quando a internet cai, agora na sua mesa: o dinossauro corre pelo pequeno display OLED, os cactos vêm na sua direção e você pula com um único botão. Sua pontuação aume

ESP32 HTTPClient + API de clima (com display OLED SSD1306)
Neste projeto, usamos o ESP32 para fazer uma chamada REST à API de clima wttr.in pela internet com HTTPClient.h. Diferentemente da versão anterior com LCD I2C, aqui usamos um display OLED SSD1306 (128×64), que permite usar fontes grandes, ícones vetoriais e uma apresentação visual rica em uma única tela. Sete ícones vetoriais de condições do tempo (ensolarado, parcialmente nublado, nublado, chuvoso, com neve, com tempestade e com neblina) são desenhados durante a execução, sem arquivos bitmap.

ESP32 em sono profundo — Economia de bateria (OLED + contador na RAM RTC)
O modo de sono profundo do ESP32 reduz o consumo de corrente para ~10 µA ao desligar a CPU e a maioria dos periféricos, sendo essencial para dispositivos IoT alimentados por bateria. Neste projeto, usamos três fontes de despertar: um temporizador (15 segundos), um pino externo (EXT0 — botão no GPIO 33) e toque (T0/GPIO 4). As variáveis marcadas com RTC_DATA_ATTR são preservadas durante o sono profundo, mantendo os contadores de inicializações e de despertares por temporizador e botão.

Contador de rakats para oração com ESP32 (HC-SR04 + OLED SSD1306 + 2 botões)
Você às vezes esquece quantos rakats já fez durante a oração? Este projeto cria um contador de rakats que fica ao lado do tapete de oração e conta as prostrações quando você aproxima a mão. O sensor ultrassônico de distância HC-SR04 detecta a aproximação da mão, o display OLED SSD1306 mostra a contagem de rakats e dois botões permitem selecionar 2, 3 ou 4 rakats e zerar a contagem.

Luminária com mistura de cores e ESP32 (3 potenciômetros + LED RGB + OLED)
Uma luminária inteligente que permite misturar a cor que você quiser girando três potenciômetros com o ESP32! Ao girar os potenciômetros de vermelho, verde e azul, o LED RGB de cátodo comum muda de cor em tempo real. O display OLED SSD1306 mostra os valores de cada cor na faixa de 0–255, barras de preenchimento e o código HEX da cor para a web, como #FF8040.

Iluminação inteligente com ESP32 (PIR + LDR + relé + OLED)
Transforme a iluminação do corredor, banheiro ou despensa em iluminação inteligente com ESP32! Com um sensor de movimento PIR, um sensor de luz LDR e um módulo relé, montamos o cenário clássico de "acender a luz ao detectar movimento no escuro" — se o ambiente já estiver claro, o movimento NÃO aciona a luz, economizando energia durante o dia. A luz fica acesa por 30 segundos; se o movimento continuar, o temporizador reinicia e a luz permanece acesa por mais tempo.

Registrador de temperatura com ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
Monte um registrador de temperatura com data e hora usando ESP32! Leia a temperatura e a umidade do DHT22 a cada minuto, obtenha a hora real do DS1307 RTC e grave os dados em CSV no cartão microSD. O OLED exibe a temperatura atual em letras grandes, a porcentagem de umidade, a data e a hora e o contador de registros. O arquivo /temp_log.csv no cartão SD pode ser aberto no Excel, Google Sheets ou pandas do Python para análise — ideal para monitorar estufas, acompanhar a temperatura de casa ou…
Mais artigos
App BlueGrays
Monte este circuito passo a passo pelo celular
Esquema do circuito, código e lista de componentes em uma só tela. Mais de 200 projetos com Arduino, ESP32 e Pico prontos para montar.
Escaneie com seu celular
Aponte a câmera para o código para abrir a loja de aplicativos do seu celular.
ou abrir a loja

