0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

LilyGO T-Display RP2040 MicroPython / CircuitPython で使う

Posted at

RP2040にST7789Vを接続した開発ボードです。

pinout

MicroPythonで使う

セットアップ

ST7789V組み込みのファームが以下で公開されています。

firmware/T-DISPLAY-RP2040/にあるファイルをRP2040に書き込みます。
起動させ,examples/configs/tdisplay_rp2040/にあるtft_config.pyをフラッシュ領域のトップに保存します。(main.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つを適当に押すと,それに応じた値を出して,波形のように流して表示するのを書いてみました。

trend.py
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を使えるようにします。

文字表示

こちらに複数文字を表示し,表示内容を更新する例がありました。

main(抜粋).py
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を用意し,そこにlabelappendすることで文字列を追加していきます。

点を表示する

ここに解説がありました。

TileGridのオブジェクトを作り,上の文字表示で用意されたsplashappendすることで文字列と共存して表示します。

main(抜粋).py
bitmap = displayio.Bitmap(display.width, display.height, 4) # 4 color

としてしまうと,全画面領域がビットマップ用となってしまい,文字が表示できませんので,適宜領域を減らします。

demo.py
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は普通に使えますし。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?