Usando Display OLED I2C com o Raspberry Pi Pico - MakerHero
Usando Display OLED com Raspberry Pi Pico

Usando Display OLED I2C com o Raspberry Pi Pico 5

Aprenda a controlar o Diplay I2C com Raspberry Pi Pico, vamos usar aqui o modelo mais comum, de cor azul e resolução de 128×64 pontos e diagonal de 0,96”.

Os displays OLED com interface I2C, usando o controlador SSD1306, são uma opção muito boa para apresentar informações resumidas e implementar interfaces simples com o operador. De tamanho compacto, monocromáticos e com capacidade gráfica, estes displays estão disponíveis em algumas cores e resoluções.

Material Necessário

Detalhes sobre como preparar o micro e o Raspberry Pi Pico para usar o MicroPython podem ser vistos no artigo da Rosana Guse.

Montagem do Diplay I2C e Raspberry Pi Pico

Uma vez que este display opera a 3,3V podemos ligá-lo diretamente ao Raspberry Pi Pico:

Montagem do Diplay I2C e Raspberry Pi Pico

Classes e Bibliotecas de Apoio

A classe base do MicroPython para tratamento de displays é a FrameBuffer do módulo framebuf. Esta classe mantém uma imagem em memória e fornece vários métodos para desenhar sobre ela, tais como:

  • fill: preenche a tela toda com uma cor
  • pixel: muda a cor de um ponto
  • line: desenha uma linha
  • hline e vline: otimizadas para desenhar uma linha horizontal ou vertical
  • rect: desenha um retângulo (só o contorno)
  • fill_rect: desenha um retângulo preenchido
  • text: desenha um texto (usa sempre um fonte de 8×8 pontos)
  • blit: desenha o conteúdo de um outro framebuf

O módulo framebuf já está dentro do MicroPython. No caso do nosso display temos apenas duas cores: 0 (apagado) e 1 (aceso).

Para escrever e desenhar no display OLED vamos usar o módulo ssd1306.py que deve ser baixado de https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py. Este módulo define a classe SSD1306, que é uma especialização da FrameBuffer. Esta classe acrescenta (entre outros) os seguintes métodos:

  • init_display: inicia o display
  • show: atualiza o display com o conteúdo do framebuffer

A partir da SSD1306 são derivadas duas classes, SSD1306_I2C e SSD1306_SPI, para suportar displays com conexão I2C e SPI.

Graças a estas classes, fica simples usar o display em um programa MicroPython:

  1. Na iniciação criamos um objeto I2C para efetuar a comunicação com a placa
  2. Ainda na iniciação, criamos um objeto SSD1306_I2C, informando o objeto I2C. Este objeto será usado para criar o que queremos apresentar no display e atualizá-lo.
  3. Quando quisermos escrever ou desenhar na tela, usamos os métodos de FrameBuffer para atualizar a imagem em memória. Quando a imagem estiver pronta, usamos o método show para atualizar o display

Apresentando Imagens no Display I2C com Raspberry Pi Pico

A ideia básica para apresentar imagens é simples: criamos um framebuffer com a imagem e depois usamos o método blit para copiar este framebuffer no framebuffer do display.

A criação do framebuffer com a imagem exige alguns cuidados. Fica mais simples se a imagem estiver em um arquivo no formato PBM (Portable BitMap). Nas instruções a seguir vamos usar o programa GIMP, que suporta esse formato

O primeiro passo é editar ou criar a imagem com o tamanho adequado. Feito isso, usamos o comando Image Mode Indexed para transformar a imagem em uma imagem branco-e-preta (se ela já estiver em branco e preto esse passo pode ser dispensado):

Em seguida usamos o comando File Export para salvar a imagem no formato PBM:

Quando perguntar o formato dos dados selecione Raw:

A imagem deve então ser colocada no Raspberry Pico, o que pode ser feito usando o Thonny e selecionando a opção Upload (use View Files para mostrar o painel com os arquivos):

A função abaixo (adaptada de código escrito por Martin Fitzpatrick) lê o arquivo e gera o framebuf:

def loadPBM(arq, tamX, tamY):
    with open(arq, 'rb') as f:
        f.readline() # Magic number
        f.readline() # Creator comment
        f.readline() # Dimensions
        data = bytearray(f.read())
    return framebuf.FrameBuffer(data, tamX, tamY, framebuf.MONO_HLSB)

Aplicação Exemplo

Para rodar este exemplo, salve antes o arquivo ssd1306.py na Raspberry Pi Pico. Você pode fazer isso com o Thonny, usando o Upload (como fizemos com a imagem) ou copiando o código para uma aba e usando File Save as… e escolhendo a opção “Raspberry Pi Pico”:

Você vai precisar também colocar no Pi Pico a image MakerHero.pbm, que você pode baixar daqui. Se você for usar outra imagem, não esqueça de acertar o tamanho na chamada a loadPBM()

'''
Demonstração do uso de display OLED com o Raspberry Pi Pico
'''
from machine import I2C
from time import sleep
from random import randrange
import framebuf
import ssd1306

# Usa a configuração padrão do I2C
i2c = I2C(0)

# Inicia o display
display = ssd1306.SSD1306_I2C(128, 64, i2c)
display.fill(0)
display.text( "Ola, PiPico!", 0, 0)
display.show()

# Carrega imagem
def loadPBM(arq, tamX, tamY):
    with open(arq, 'rb') as f:
        f.readline() # Magic number
        f.readline() # Creator comment
        f.readline() # Dimensions
        data = bytearray(f.read())
    return framebuf.FrameBuffer(data, tamX, tamY, framebuf.MONO_HLSB)

fbuf = loadPBM('MakerHero.pbm', 128, 39)

# Mostra a imagem no display
display.blit(fbuf, 0, 16)
display.show()
sleep(5)

# Limpa a imagem
display.fill_rect(0, 16, 128, 48, 0)

# Vamos fazer um gráfico de barras aleatórias
while True:
    for x in range(0, 128, 16):
        y = randrange (10, 50)
        display.fill_rect(x, 10, 12, 54, 0)
        display.fill_rect(x, y, 12, 64-y, 1)
    display.show()
    sleep(1)

Conclusão

O MicroPython torna bastante simples a apresentação de texto, formas geométricas e imagens em displays OLED. Com isso fica fácil criar interfaces práticas e bonitas.

Agora que você j16á aprendeu como usar um display I2C com Raspberry Pi Pico, que tal usar no seu próximo projeto?

Gostou do artigo?  Para mais artigos e tutorias de projetos acesse nosso blog.


Se você tiver dúvidas, sugestões ou experiências para compartilhar, fique a vontade para deixar um comentário abaixo. E para não perder nenhum conteúdo como este, não deixe de nos seguir no Instagram.

Faça seu comentário

Acesse sua conta e participe

5 Comentários

  1. O link do github para a biblioteca ssd1306 não está disponível

      1. Segui todos os passos do tutorial, mas sempre recebo o erro a seguir:

        Traceback (most recent call last):
        File “”, line 10, in
        File “/lib/ssd1306.py”, line 119, in __init__
        File “/lib/ssd1306.py”, line 38, in __init__
        File “/lib/ssd1306.py”, line 75, in init_display
        File “/lib/ssd1306.py”, line 124, in write_cmd
        OSError: [Errno 5] EIO

        1. Remontei aqui o circuito e testei o programa e verifiquei que tem dois problemas:

          1) A figura do Fritzing está errada! O SCL do display deve ser ligado ao pino 12 (GP9) e o SDA ao pino 11 (GP8)
          2) Pode ser necessário colocar resistores de pullup nos sinais de SDA e SCL. Para isso conecte resistores de 4k7 entre os pinos SDA e SCL e o Vcc (3.3V). Talvez o Micropython tenha deixado de ativar os pullups internos nas versões mais recentes, pois costumo usar estes displays sem pullup externos sem problemas.

          Um último detalhe é que o arquivo de imagem está com o nome ‘FilipeFlop.pbm’ e o código está com ‘MakerHero.pbm’. É preciso mudar o nome do arquivo ou do código.

          Vou ver com o pessoal da MakerHero para atualizar a figura, peço desculpas pela trapalhada.

  2. Ótimo, parabéns!