Estes displays apareceram nos anúncios da AliExpress e me deixaram curioso. Vamos ver o que são eles e como colocar para funcionar com o CircuitPython.
Embora existam placas diferentes com este display, as características básicas são sempre as mesmas:
- 1,28" de diâmetro
- Resolução de 240 x 240 pontos (reparar que parte destes pontos não existem fisicamente)
- Display colorido (16 bits por cor, o chamado "65K" cores)
- LCD (alguns anúncios falam em IPS e outros em TFT)
- Controlador GC9A01 com interface SPI (apesar do conector usar os nomes SDA e SCL)
As diferenças que vi nos anúncios foram:
- Operação a 3,3 e 5V ou apenas a 3,3V
- Controle do backlight
- Placa redonda (como o display) ou quadrada.
O modelo que eu comprei trabalha a 3,3 ou 5V, não tem controle do backlight e a placa é redonda.
Para um primeiro teste resolvi usar o CircuitPython e um XIAO RP2040. Poderia ter sido um Pi Pico, mas com o XIAO ficou mais compacto. As conexões display / XIAO são:
- RST - D0
- CS - D1
- DC - D2
- SDA- D10 (MOSI)
- SCL - DI (SCK)
- GND - GND
- VCC - 3V3
O CircuitPython possui módulos que facilitam bastante o uso de display gráficos e um driver para o GC9A01. Um problema é ter que baixar estes módulos e copiá-los para a placa do microcontrolador. Felizmente existe um utilitário para facilitar isso, o CircUp. Para instalá-lo e usá-lo você precisa ter instalado e acessível na linha de comando:
- Uma versão recente do Python 3
- O utilitário pio correspondente
- O utilitário git
Aí basta um "pip install circup".
A instalação do CircuitPython no XIAO RP2040 (e outras placas baseadas no RP2040) é simples: baixe o arquivo uf2 de https://circuitpython.org/downloads, conecte a placa ap PC com o botão BOOT apertado e copie o arquivo uf2 para o drive RPI-RP2 que foi criado.
Para copiar para o XIAO as bibliotecas necessárias:
circup install gc9a01 circup install adafruit_display_text circup install adafruit_imageload
O código abaixo é uma adaptação do que está em https://github.com/todbot/CircuitPython_GC9A01_demos/tree/main/examples/eyeballs, minha mexida consiste em usar os nomes adequados para os pinos do XIAO.
# qteye.py - a stand-alone GC9A01 round LCD "eye" on a QTPy # 23 Oct 2022 - @todbot / Tod Kurt # Part of https://github.com/todbot/CircuitPython_GC9A01_demos # also see: https://twitter.com/todbot/status/1584309133263532033 # and: https://twitter.com/todbot/status/1584309133263532033 # Copy this file as "code.py" and the two eyeball BMP files to CIRCUITPY drive # To install needed libraries: "circup install adafruit_imageload gc9a01" # 16 Nov 2020 - @dqsoft / Daniel Quadros # Changed pin names in "wiring" for use with XIAO RP2040 # import time, math, random import board, busio import displayio import adafruit_imageload import gc9a01 displayio.release_displays() dw, dh = 240,240 # display dimensions # load our eye and iris bitmaps eyeball_bitmap, eyeball_pal = adafruit_imageload.load("imgs/eye0_ball2.bmp") iris_bitmap, iris_pal = adafruit_imageload.load("imgs/eye0_iris0.bmp") iris_pal.make_transparent(0) # palette color #0 is our transparent background # compute or declare some useful info about the eyes iris_w, iris_h = iris_bitmap.width, iris_bitmap.height # iris is normally 110x110 iris_cx, iris_cy = dw//2 - iris_w//2, dh//2 - iris_h//2 r = 20 # allowable deviation from center for iris # wiring tft0_clk = board.D8 # must be a SPI CLK tft0_mosi= board.D10 # must be a SPI TX tft_L0_rst = board.D0 tft_L0_dc = board.D2 tft_L0_cs = board.D1 spi0 = busio.SPI(clock=tft0_clk, MOSI=tft0_mosi) # class to help us track eye info (not needed for this use exactly, but I find it interesting) class Eye: def __init__(self, spi, dc, cs, rst, rot=0, eye_speed=0.25, twitch=2): display_bus = displayio.FourWire(spi, command=dc, chip_select=cs, reset=rst) display = gc9a01.GC9A01(display_bus, width=dw, height=dh, rotation=rot) main = displayio.Group() display.show(main) self.display = display self.eyeball = displayio.TileGrid(eyeball_bitmap, pixel_shader=eyeball_pal) self.iris = displayio.TileGrid(iris_bitmap, pixel_shader=iris_pal, x=iris_cx,y=iris_cy) main.append(self.eyeball) main.append(self.iris) self.x, self.y = iris_cx, iris_cy self.tx, self.ty = self.x, self.y self.next_time = time.monotonic() self.eye_speed = eye_speed self.twitch = twitch def update(self): self.x = self.x * (1-self.eye_speed) + self.tx * self.eye_speed # "easing" self.y = self.y * (1-self.eye_speed) + self.ty * self.eye_speed self.iris.x = int( self.x ) self.iris.y = int( self.y ) if time.monotonic() > self.next_time: t = random.uniform(0.25,self.twitch) self.next_time = time.monotonic() + t self.tx = iris_cx + random.uniform(-r,r) self.ty = iris_cy + random.uniform(-r,r) self.display.refresh() # a list of all the eyes, in this case, only one the_eyes = [ Eye( spi0, tft_L0_dc, tft_L0_cs, tft_L0_rst, rot=0, eye_speed=0.10), ] while True: for eye in the_eyes: eye.update()
Para rodar o código é preciso copiar na placa a pasta "imgs" do repositório acima.
Nas referências abaixo tem outros exemplos que certamente darão ideias de outros usos para este display.
Referências:
Mais informações sobre o display:
Descrição detalhada do CircUp:
Demos diversos do display com CircuitPython:
Nenhum comentário:
Postar um comentário