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