RP2040にST7789Vを接続した開発ボードです。
MicroPythonで使う
セットアップ
ST7789V組み込みのファームが以下で公開されています。
firmware/T-DISPLAY-RP2040/
にあるファイルをRP2040に書き込みます。
起動させ,examples/configs/tdisplay_rp2040/
にあるtft_config.py
をフラッシュ領域のトップに保存します。(main.py
と同じ位置)
from machine import Pin, SPI
import st7789
import tft_config
tft = tft_config.config(0)
tft.init()
などと始めると,画面にいろいろなものもを描けるようになります。
文字・図形描画
上記のあと tft.text()
関数で描画できますが,描くだけなので,表示文字を更新するにはひと工夫必要です。
線分はtft.line()
で,この2つが最低限あればいろいろ使えます。
ボタン2つを適当に押すと,それに応じた値を出して,波形のように流して表示するのを書いてみました。
from machine import Pin, SPI
import st7789
import tft_config
tft = tft_config.config(0)
tft.init()
#import vga1_8x8 as font
#import vga1_8x16 as font
#import vga1_16x16 as font
#import vga1_bold_16x16 as font
#import vga1_bold_16x32 as font
#import vga1_16x32 as font
import vga2_16x32 as font
tft.rotation(1)
'''
rotation(1):
(0,0)+-----------+ GPIO7 x<240
| |
| | USB
| |
+-----------+ GPIO6
y<128
'''
# boot message
tft.text(font, "TTGO RP2040", 16, 48, st7789.WHITE, st7789.BLACK)
import time
time.sleep(1)
tft.fill(st7789.BLACK)
# end of boot message
trend_X_top=20
trend_Y_top=0
trend_width=200 # dots
trend_height=62 # dots
trend_Y_max=150 # display y 0 to 150
trend_Y_min=0 # display y 0 to 150
trend_scale_base=[0,50,100,150] # display scale at y=0,50,100,150
trend_scale=[]
for i in range(len(trend_scale_base)):
#print(i, trend_scale_base[i])
trend_scale.append(
int(trend_Y_top+trend_height-
(trend_scale_base[i]-trend_Y_min)/(trend_Y_max-trend_Y_min)*trend_height))
# clear data
trend_data=[]
for i in range(trend_width):
#trend_data.append(trend_Y_top+trend_height-(i % (trend_height+1))) # test data
trend_data.append(
int(trend_Y_top+trend_height-(
0-trend_Y_min)/(trend_Y_max-trend_Y_min)*trend_height)
)
def update_trend():
for i in range(trend_width):
# clear
tft.line(
trend_X_top+i, trend_Y_top,
trend_X_top+i, trend_Y_top+trend_height,
st7789.BLACK)
#wait(0.05)
# scale
for j in range(len(trend_scale)):
tft.line(
trend_X_top+i,
trend_scale[j],
trend_X_top+i,
trend_scale[j],
st7789.color565(127,127,127))
#wait(0.05)
if i==(trend_width-1):
tft.line(
trend_X_top+i,trend_data[i],
trend_X_top+i,trend_data[i],st7789.YELLOW)
else:
tft.line(
trend_X_top+i, trend_data[i],
trend_X_top+i, trend_data[i+1],
st7789.YELLOW)
def put_data_to_trend(d):
del trend_data[0]
trend_data.append(
int(trend_Y_top+trend_height-(d-trend_Y_min)/(trend_Y_max-trend_Y_min)*trend_height)
)
update_trend()
class TextBox:
def __init__(self,x,y,font,fc,bc):
self.x=x
self.y=y
self.s=''
self.font=font
self.fc=fc # text color
self.bc=bc # background color
tft.text(self.font, self.s,
self.x,self.y,
self.fc,self.bc
)
def draw(self,s):
tft.text(self.font, self.s,
self.x,self.y,
self.bc,self.bc
)
tft.text(self.font, s,
self.x,self.y,
self.fc,self.bc
)
self.s=s
p7=Pin(7, Pin.IN, Pin.PULL_UP)
p6=Pin(6, Pin.IN, Pin.PULL_UP)
label0=TextBox(0,2*32,font,st7789.CYAN, st7789.BLACK)
label1=TextBox(0,3*32,font,st7789.WHITE, st7789.BLACK)
while True:
put_data_to_trend(150-25-66*p7.value()-33*p6.value())
label0.draw('p7 = '+str(p7.value())+' p6 = '+str(p6.value()))
label1.draw('value '+str(150-25-66*p7.value()-33*p6.value()))
フォントは数種類ファームウエアに含まれていてありがたいのですが,縦16ドット以下のものは,私には小さくて読みにくく,32ドットは大きすぎて表示文字数を多くできないのが悩みですね... 外部フォントファイルも使えますが,遅いので計測的な目的では使いにくい。コンパイルして埋め込むほどの腕はない...
ただ,MicroPythonとして普通に使えるのでいいですね。
CircuitPythonで使う
表示されている文字は,こちらのほうが見やすくていいですね。文字や線を出すまでに結構時間を取りました。
セットアップ
- Raspberry Pi Pico としてCircuitPythonのファームを書き込みます。
- ST7789Vと文字・ピクセル表示のため,以下をRP2040の
/lib
フォルダーに置きます。
--adafruit_display_text/
--adafruit_st7789.mpy
このボードをCircuitPythonで使う例がずばりここに置いてありました。参照してST7789Vを使えるようにします。
文字表示
こちらに複数文字を表示し,表示内容を更新する例がありました。
splash = displayio.Group()
display.show(splash)
text1 = label.Label(terminalio.FONT, text='Demo', color=0xFFFFFF)
text_group = displayio.Group(scale=2, x=5, y=110)
text_group.append(text1) # Subgroup for text
splash.append(text_group)
text2 = label.Label(terminalio.FONT, text='', color=0xFFFF00)
text_group = displayio.Group(scale=2, x=120, y=110)
text_group.append(text2) # Subgroup for text
splash.append(text_group)
概念を理解するのに時間がかかりました...
本家に優しい解説があるのですが,
これを使うと,複数文字列を同時に表示できません。上のように,Group
の変数splash
を用意し,そこにlabel
をappend
することで文字列を追加していきます。
点を表示する
ここに解説がありました。
TileGrid
のオブジェクトを作り,上の文字表示で用意されたsplash
にappend
することで文字列と共存して表示します。
bitmap = displayio.Bitmap(display.width, display.height, 4) # 4 color
としてしまうと,全画面領域がビットマップ用となってしまい,文字が表示できませんので,適宜領域を減らします。
import os
import board
import time
import terminalio
import displayio
import busio
from adafruit_display_text import label
import adafruit_st7789
displayio.release_displays()
tft_cs = board.GP5
tft_dc = board.GP1
tft_res = board.GP0
spi_mosi = board.GP3
spi_clk = board.GP2
import digitalio
displayio.release_displays()
tft_pwr = board.GP22
tft_clk = board.GP2
tft_mosi = board.GP3
tft_cs = board.GP5
tft_dc = board.GP1
tft_rst = board.GP0
tft_bl = board.GP4
pwr_pin = digitalio.DigitalInOut(tft_pwr)
pwr_pin.switch_to_output(value=True)
tft_spi = busio.SPI(clock=tft_clk, MOSI=tft_mosi)
display_bus = displayio.FourWire(tft_spi, command=tft_dc, chip_select=tft_cs, reset=tft_rst)
display = adafruit_st7789.ST7789(display_bus,
width=135, height=240,
rowstart=40, colstart=53,
backlight_pin=tft_bl)
display.rotation=270
'''
rotation=270
+------------------+
| |
| | USB
| |
+------------------+
'''
splash = displayio.Group()
display.show(splash)
text1 = label.Label(terminalio.FONT, text='Demo', color=0xFFFFFF)
text_group = displayio.Group(scale=2, x=5, y=110)
text_group.append(text1) # Subgroup for text
splash.append(text_group)
text2 = label.Label(terminalio.FONT, text='', color=0xFFFF00)
text_group = displayio.Group(scale=2, x=120, y=110)
text_group.append(text2) # Subgroup for text
splash.append(text_group)
#bitmap = displayio.Bitmap(display.width, display.height, 4) # 4 color
bitmap = displayio.Bitmap(display.width, 100, 4) # 4 color
palette = displayio.Palette(4)
palette[0] = 0x000000
palette[1] = 0xffff00 # yellow
palette[2] = 0x00ffff # cyan
palette[3] = 0x7f7f7f
tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette)
splash.append(tile_grid)
for x in range(240):
text2.text='x='+str(x)
for c in [0,1,2,3]:
bitmap[x, (c+1)*20] = c
補足
adafruit_display_shapes
を使うと,線分や円も描けるようになるのですが,線分の端点を移動させる手段が見つかりませんでした... とりあえずは上の「点描画」をループで回してしのごうかと。
ボードの補足
LiPoバッテリー対応なのは良いのですが,コネクターが底面にあるため,ブレッドボードにボードが素直におさまりません。最近樹脂のシェルも売られていますので,購入しました。ブレッドボードじゃなくてシェルにいれたまま,M5Stack/M5StickCPlusのように,「ちょっとした時」にささっと接続して MicroPython / CircuitPython で使うといいかなと。
ESP32はADCが少し難ありで,M5ではたいていADCユニットと一緒に使っていますが,RP2040ならADCは普通に使えますし。