terça-feira, junho 30, 2026

O Controlador do Display OLED de 1.3 polegadas

Quando eu vi a nova versão do Badge do Garoa, o display parecia ser um velho conhecido: o display OLED de 0,96". Quando reparei que era um modelo maior, de 1,3", mas com os mesmos 128x64 pontos, achei que não mudava nada na programação. Grande engano!



A versão de 1,3" utiliza o controlador SH1106, que tem diferenças significativas em relação ao SSD1306 usado no modelo de 0.96".  E os drivers que examinei parecem não levar isto totalmente em conta.

Comunicação

Os dois controladores suportam comunicação paralela, SPI e I2C. O mais comum é o uso de I2C com um conector de 4 pinos (VCC, GND, SCL e SDA, não necessariamente nesta ordem). Obs.: na foto acima eu usei um modelo incomum do display de 0,96", com pinos de Reset e DC.

No modo I2C, ambos os controladores suportam os endereços 0x3C e 0x3D, selecionados por meio de um pino.

O formato do pacote na escrita I2C é igual nos dois controladores, utilizando um ou mais bytes de controle. O primeiro byte após o endereço é um byte de controle, e outros podem vir no pacote. O byte de controle possui dois bits de interesse:
  • O bit 7 é 1 se é o último byte de controle, indicando que todos os bytes seguintes são dados ou comandos. Este bit é 0 se for seguido de um único byte de dados ou de comando e de um novo byte de controle.
  • O bit 6 indica se o que segue é dado (1) ou comando (0)
O SH1106 permite a leitura da RAM do controlador. Neste caso, os dados são enviados pelo controlador assim que recebe o endereço. O SSD1306 permite apenas a escrita na RAM.

A Memória RAM

Os dois controladores mapeiam os pontos do display "na vertical": cada byte na memória corresponde a 8 pontos na mesma coluna, em linhas consecutivas. O SH1106 suporta até 132 colunas, o SSD1306 até 128 colunas; ambos suportam até 64 linhas.

A memória do SH1106 é organizada em 8 páginas de 132 bytes, e a do SSD1306, em 8 páginas de 128 bytes. Para fins de endereçamento, cada byte possui um endereço (coluna) e uma página.

Os displays mais usuais (como os da foto acima) possuem resolução de 128 x 64 pontos. O SH1106 centraliza as colunas usadas na memória. Esta é uma das "pegadinhas" ao usar o driver do SSD1306 com o SH1106: as duas primeiras colunas são "perdidas". Ao atualizar a memória de um display SH1106 de 128 pontos horizontais, a primeira coluna começa com um deslocamento de 2 bytes.

Uma outra diferença importante é no modo de endereçamento. O SSD1306 permite selecionar entre três modos de endereçamento:
  • horizontal: a coluna é incrementada a cada acesso. Ao atingir o fim da página, a coluna volta a zero e a página é incrementada. O resultado é que é possível acessar, sequencialmente, todos os bytes da memória, da esquerda para a direita e de cima para baixo.
  • vertical: a página é incrementada a cada acesso. Ao atingir o fim da memória, a página volta a zero e a coluna é incrementada. O resultado é que é possível acessar sequencialmente todos os bytes da memória, de cima para baixo e da esquerda para a direita.
  • página:  a coluna é incrementada a cada acesso. Ao chegar ao fim da página, a coluna volta a zero, mas a página permanece a mesma. Este é o modo adotado após um reset.
O SH1106 possui apenas endereçamento por página e não possui o comando de seleção.

Comandos

As tabelas a seguir resumem os comandos disponíveis nos dois controladores (clique para ampliar). Reparem que temos várias diferenças.

SSD1306:








SH1106:


Iniciação do SH1106

Após o reset do display, é necessário enviar uma sequência de comandos para configurar o controlador e selecionar os modos desejados. A rigor, estes valores dependem das características do display e do uso pretendido, mas a sequência a seguir (baseada no que vi em drivers) parece ser a mais apropriada:

SH1106_DISPLAYOFF                  // 0xAE
SH1106_SETDISPLAYCLOCKDIV ,0x80    // 0xD5 0x80
SH1106_SETMULTIPLEX       ,0x3F    // 0xA8 0x3F
SH1106_SETDISPLAYOFFSET   ,0x00    // 0xD3 0x00
SH1106_SETSTARTLINE | 0x0          // 0x40
SH1106_SETDCDC            ,0x8B    // 0xAD 0x8B
SH1106_SET_SEGMENT_REMAP           // 0xA1
SH1106_COMSCANDEC                  // 0xC8
SH1106_SETCOMPINS         ,0x12    // 0xDA 0x12
SH1106_SETCONTRAST        ,0xCF    // 0x81 0xCF
SH1106_SETPRECHARGE       ,0x1F    // 0xD9 0x1F
SH1106_SETVCOMDETECT      ,0x40    // 0xD8 0x40
SH1106_NORMALDISPLAY               // 0xA6
SH1106_DISPLAYALLON_RESUME         // 0xA4
SH1106_DISPLAYON                   // 0xAF

Atualizando a Imagem

Quando o microcontrolador possui memória suficiente, uma estratégia comum é manter uma cópia da imagem no microcontrolador, fazer as escritas sobre ela e depois transferir para o controlador do display. Isso simplifica e agiliza operações que exigem mesclar o conteúdo anterior ao novo (lembrando que o SSD1306 não permite ler a memória do display).

Com o SSD1306, podemos selecionar o modo de endereçamento horizontal e enviar toda a tela em uma única transação I2C. Obs.: no caso da biblioteca Wire do Arduino, as escritas passam por um buffer interno da biblioteca, o que exige quebrar as transferências.

Com o SH1106 o envio da tela precisa ser feito por página. Para cada página, é preciso selecionar a página e a coluna inicial (lembre-se de que, no display de 128x64, a imagem começa no segundo byte da página).

Alguns Drivers para o SH1106

A lista a seguir são alguns drivers que eu encontrei e os meus comentários.

Driver para MicroPython - https://github.com/robert-hh/SH1106

Curiosamente, não envia nenhum comando de iniciação, deixando os valores default.

Driver para Arduino - https://github.com/adafruit/Adafruit_SH110x

Esta foi a minha principal fonte para os comandos de iniciação, porém inclui um comando de seleção do modo de endereçamento que não existe no SH1106.

Driver para Arduino - https://github.com/winneymj/SH1106

Código bastante confuso, usa comandos do SSD1306 não existentes no SH1106

Driver para Arduino - https://github.com/wonho-maker/Adafruit_SH1106

Outra adaptação do driver do SSD1306  da Adafruit, também usa comandos não existentes no SH1106.


Estou colocando na minha lista de projetos fazer um driver melhor para o MicroPython.

Referências


Artigo sobre as diferenças: https://pcbsync.com/sh1106-vs-ssd1306/







Nenhum comentário: