📺

PicoRubyでLCDに出力したいんじゃ

に公開

PicoRubyドはまり中の人です。
今日は何となく買ったLCDをRaspberry pi picoと組み合わせて遊んでみたという話です。

お買い物

いつもの秋月電子通商さんでお買い物していきます。
多分全部で2,500円くらいだと思います。

Raspberry pi pico H

今回買ったのは無印です。が、2を買ったほうがメモリも多いのでそっちのほうがいいかも。
https://akizukidenshi.com/catalog/g/g118085/

LCD

本日の主役。サイズは親指2本分くらい。
https://akizukidenshi.com/catalog/g/g131019/

ブレッドボード

一応書いておきます。ラズパイもLCDもスペースを取るので、今回はこれを2枚使います。
https://akizukidenshi.com/catalog/g/g100315/

補足

これに加えてジャンパワイヤが必要です。が、ワイヤなんて電気を通せば何でもいいので割愛。

配線

今回は以下の配線で行きます。画像の左から順に下記につないでます。
今回使うLCDはFritzingになかったのでICで代用しています。

GND→3番 
VCC→36番 
SCL→14番 
SDA→15番 
RES→36番
DC→16番 
CS→17番 
BLK→36番

とりあえず動作させてみる

大前提ですが今回はR2P2の0.5.0 を使用しています。

今回動かしたコードは以下にあります。
https://github.com/yusama125718/picoruby-lcd-demo/blob/main/lcd-demo.rb

動くとこんな感じで色が変わっていきます。動くってすごい。
https://x.com/YUSAMA_RTA/status/1996544710664712549?s=20

内容

※ChatGPTとしゃべりながらまとめてます。

接続の定義

以下のコードでSPIとGPIOを定義します。SPIってのは高速なシリアル通信をするためのやつらしいです。

spi = SPI.new(
  unit:     :RP2040_SPI1,
  frequency: 40_000_000, # とりあえず 40MHz
  mode:     0,
  sck_pin:  10,          # GP10 (14番ピン) -> SCL
  copi_pin: 11,          # GP11 (15番ピン) -> SDA (MOSI)
  cipo_pin: 8,           # GP8 を SPI1 RX に割り当て(配線しない)
  cs_pin:   13           # GP13 (17番ピン) -> CS
)

dc = GPIO.new(12, GPIO::OUT)  # GP12 (16番ピン) -> DC

dcのGPIO(16番ピン)はコマンド送信時は 0、データ送信時は 1を入力する用らしいです

通信用ヘルパー

def lcd_cmd(spi, dc, val)
  dc.write 0
  spi.select
  spi.write(val)    # 1バイト
  spi.deselect
end

def lcd_data(spi, dc, *vals)
  dc.write 1
  spi.select
  spi.write(*vals)  # 可変長バイト列
  spi.deselect
end

コマンドとデータを実際に送信する部分らしいです。
コマンドはLCDというよりLCDが積んでいるICの種類で変わってくるらしいです。今回は「ST7789」というICを使用しているらしい。

コマンドはいろいろあるけど基本はコマンド実行→データ送信という流れで描画とか操作をするみたい。

初期化

def lcd_init(spi, dc)
  # ソフトウェアリセット(RESピンは3.3V固定のため)
  lcd_cmd(spi, dc, 0x01)  # SWRESET
  sleep_ms 150

  # スリープ解除
  lcd_cmd(spi, dc, 0x11)  # SLPOUT
  sleep_ms 150

  # 16bitカラー RGB565
  lcd_cmd(spi, dc, 0x3A)  # COLMOD
  lcd_data(spi, dc, 0x55) # 16bit/pixel

  # 画面向き(必要に応じて 0x00,0x60,0xC0,0xA0 を試す)
  lcd_cmd(spi, dc, 0x36)  # MADCTL
  lcd_data(spi, dc, 0x00)

  # 表示ON
  lcd_cmd(spi, dc, 0x29)  # DISPON
  sleep_ms 50
end

さっき話した通りコマンド実行→データ送信という流れでいろんな情報を初期化していって描画に続くみたいです。

文字を描画してみたい

こんな感じのコードを追加します
https://github.com/yusama125718/picoruby-lcd-demo/blob/main/draw_font.rb

あと初期化処理としてこれも追記します

あとついでに21番ピンにタクトスイッチを接続してボタンを追加しています。

動かした

こんな感じで動きました。
https://x.com/YUSAMA_RTA/status/1997062949006184900?s=20

Discussion