ラベル GC9A01 の投稿を表示しています。 すべての投稿を表示
ラベル GC9A01 の投稿を表示しています。 すべての投稿を表示

2024年3月20日水曜日

gc9a01pyで円、楕円、三角を簡単に書けるようにする

gc9a01pyは大変有難いライブラリだが、四角と直線と点しか描けないのが弱点。
さすがに不便なので、円、楕円、三角を足した。
https://github.com/matsuura-h/gc9a01py/tree/main
以下は、ランダムに三角を表示している例。

効率のよい描画ロジックを1から作るのは大変なので、LovyanGFXのコードを参考にした。
CからPythonへの移植だが、すべてを手打ちすると大変なので、https://www.codeconvert.ai/c-to-python-converterで自動変換し、自動ではうまく動かない部分を手直しする。
ほとんどのコードはうまく自動変換できるけど、以下の2パターンだけはNGだった。

  1. do-while
    1. 対処方法:while Trueに書き直して、条件文を末尾にif not <condition>: breakとして追加する
  2. 入れ子になったインクリメントやデクリメント
    1. 対処方法:インクリメントやデクリメントを前出しもしくは後出しにする
一つ困っていることとして、gc9a01pyはMITライセンスだが、LovyanGFXはFreeBSDライセンスになっている。
こういうとき、どうやってライセンスを処理すればよいのだろうか?
また、私が移植した部分と元のコードは一体どのように扱うとよいのだろうか?
下手にpull reqestを送ってrusshughesさんやLovyan03さんの迷惑になったら申し訳ないので、とりあえず自分のリポジトリにforkを作って公開してみた。
よい方法をご存知の方がいたら、是非教えてください。

2024年3月17日日曜日

RP2040-ZERO+micropythonにてGPS AT6558の日時緯度経度を丸形液晶GC9A01に表示してみる

以前の記事。
RP2040-ZEROとGC9A01の試験→https://matsu-log.blogspot.com/2024/03/aitendom128gc9a01a-gc9a01rp2040-zero.html
GPS AT6558→https://matsu-log.blogspot.com/2024/03/gpsat6558.html

今度は、RP2040-ZEROに液晶とGPSを繋いで、緯度経度を液晶に表示してみる。


USART0を使いたいので、GP0,1を空ける。DCとRSTは、代わりにGP3,4に繋いでおく。

■液晶

  1. GND → GND
  2. VCC → 3V3
  3. SCL → GP6/SPI0 SCK
  4. SDA → GP5/SPI0 TX
  5. RES → GP3
  6. DC → GP4
  7. CS → GP5/SPI0 CSn
  8. BLK → 未使用
■GPS
  1. GND → GND
  2. VCC → 3V3
  3. TX → GP1
    ※RXは繋がなくてもいいので無視

Fritzingで作った回路図。探してみると、RP2040-ZEROなどたくさんのAdd-onパーツが公開されていて非常に有難い。さすがにGPSは無かったので、似たような部品と汎用ヘッダで代用。

以下のようなコードで、$GNGGAと$GNRMCから日時と緯度経度を吸い上げて、液晶に表示した。液晶、GPSをうまく繋げられていたので、これはすんなり作れた。

以下、micropythonコード。

from machine import Pin, SPI
import gc9a01py as gc9a01
import time

import vga2_8x16 as font

from machine import UART
uart = UART(0, baudrate=9600, tx=0, rx=1)

# GPSの結果から日時と緯度経度を抜き出す
def GPS(input):
    if input is None:
        return ("","","","")
    msgs = str(input)[2:-1].split("\\r\\n")
    lat = ""
    lgt = ""
    date = ""
    time = ""
    for msg in msgs:
        if msg[0:6] is "$GNGGA":
            item = msg.split(",")
            if len(item) <= 4:
                continue
            #print(item[1], item[2], item[4])
            time = item[1]
            lat = item[2]
            lgt = item[4]
        elif msg[0:6] is "$GNRMC":
            item = msg.split(",")
            if len(item) <= 10:
                continue
            time = item[1]
            lat = item[3]
            lgt = item[5]
            date = item[9]
    return (date, time, lat, lgt)

# GC9A01初期化
SPI_PORT = 0
SPI_BAUDRATE = 60000000
RESET_PIN = Pin(3, Pin.OUT)
DC_PIN = Pin(4, Pin.OUT)
CS_PIN = Pin(5, Pin.OUT)

spi = SPI(SPI_PORT, baudrate=SPI_BAUDRATE, sck=Pin(6), mosi=Pin(7))
tft = gc9a01.GC9A01(spi=spi, dc=DC_PIN, cs=CS_PIN, reset=RESET_PIN, backlight=None, rotation=0)

bgcolor = gc9a01.color565(0x00, 0x44, 0x22)
tft.fill(bgcolor)

tft.text(font,"GPS Tracker",80,20,gc9a01.BLACK,bgcolor)
while True:
    msg = uart.read()
    ret = GPS(msg)
    pos = 40
    for item in ret:
        if not item is "":
            tft.text(font,item,80,pos,gc9a01.BLACK,bgcolor)
        pos += 20
    tft.fill_rect(88,80,24,40, gc9a01.GREEN)
    time.sleep(0.5)

2024年3月16日土曜日

aitendoの丸形液晶(M128GC9A01A, GC9A01)をRP2040-ZEROで試す

aitendoの丸形液晶 M128GC9A01Aについて、前回、M5+UI FLOWで挑戦するも、失敗。
商品リンク:https://www.aitendo.com/product/20938

今度は、raspberry pi pico互換のRP2040-ZEROで挑戦する。
まずはSPI接続。

以下、スイッチサイエンスさんより画像を借用。
RP2040-ZEROのSPIは2系統あり、片方は裏面のパッドや左右のピンに点在してしまっているので、今回はSPI0を使い右側で固めて配線することにする。電源は左側固定で、さらにジャンパ使うのであまり意味はないが。

配線表とmicropython用のライブラリや使用例を見比べて、以下のつなぎ方に決定。

  1. GND → GND
  2. VCC → 3V3
  3. SCL → GP6/SPI0 SCK
  4. SDA → GP5/SPI0 TX
  5. RES → GP0
  6. DC → GP1
  7. CS → GP5/SPI0 CSn
  8. BLK → 未使用
試しては無いが、たぶん3, 4以外は任意のピンでよいとは思う。
ライブラリはこちら:https://github.com/russhughes/gc9a01py/tree/mainを使わせていただく。
libのgc9a01py.pyをダウンロードし、ThonnyでRP2040-ZEROのルートにこのライブラリのpyファイルを格納すればOK。
下図のように、デバイスのルート直下にファイルが表示されていれば大丈夫。これで、「import gc9a01py as GC9A01」というようにして呼び出せるようになる。

本当に大したコードではないけど、私自身がこのディスプレイをRP2040-ZERO+micropythonで利用するのに結構苦労したので残しておきます。

from machine import Pin, SPI
import gc9a01py as GC9A01

# GC9A01初期化
SPI_PORT = 0
SPI_BAUDRATE = 60000000
RESET_PIN = Pin(0, Pin.OUT)
CS_PIN = Pin(5, Pin.OUT)
DC_PIN = Pin(1, Pin.OUT)

spi = SPI(SPI_PORT, baudrate=SPI_BAUDRATE, sck=Pin(6), mosi=Pin(7))
tft = GC9A01.GC9A01(spi=spi, dc=DC_PIN, cs=CS_PIN, reset=RESET_PIN, backlight=None, rotation=0) 
 
tft.fill(GC9A01.RED)
for i in range(240):
    tft.pixel(i, i, GC9A01.GREEN)
    tft.pixel(120, i, GC9A01.BLUE)
    tft.pixel(i, 120, GC9A01.WHITE)

これがうまく動くと、冒頭の画像のようになる。赤背景に、緑青白の線を引いただけ。
速度を気にするなら矩形や線描写のメソッドを使ったほうがいいはず。

以上。

2024年3月4日月曜日

aitendoの丸形液晶(M128GC9A01A, GC9A01)をm5で試す<失敗>

追記:この後UI FLOWでこの液晶を動かそうとしたが、ライブラリを読み込むとメモリ溢れで落ちることが判明。UI FLOWは諦めて、raspberry pi picoで動かすよう方針転換。

後日、RP2040-ZERO+Thonnyでうまく動いたので、動作例が知りたい方はこちらをご覧ください。
https://matsu-log.blogspot.com/2024/03/aitendom128gc9a01a-gc9a01rp2040-zero.html

-------

aitendoの丸形液晶 M128GC9A01Aも買ったので、m5atom matrixで表示できるよう試験する。
商品リンク:https://www.aitendo.com/product/20938


この液晶、中身はGC9A01というコントローラを使ったもので、価格もサイズも手ごろで見た目も綺麗なためか、aitendoだけでなくadafruitやsparkfunなどいろいろな会社からdip化基板セットやタッチパネル、rp2040と組み合わせたセットが出ていて面白い。

■SPIとI2Cのどちらで繋ぐか?

このボードはSPIとI2Cの両方で繋げるようだが、グラフィック関係は帯域の問題からSPIを使うのがよさそう。このサイト(https://emb.macnica.co.jp/articles/8191/)で分かりやすくまとめられているが、bpsの桁が違う。SPIは50Mbpsを狙えるが、I2Cは1Mbpsとのこと。

atom liteは240MHzで、SPIは最大80MHz対応とのこと。
例えば128x128dot、フルカラー8+8+8=24bitを20Hzで更新したいとき、1フレームは128*128*3Byte=49,152Byte=48kBとなり、これを1秒に5枚転送するので、240kB/s=1,920kbps=1.875Mbpsとなる。
I2Cだと1MHzでも1Mbps未満なので、完全に帯域不足。

I2Cは帯域で劣るものの、2線で済むのが一番のメリットで、バイト単位のR/Wで十分なセンサ類と繋ぐのがよい。

■m5atomとの接続

先人のコードを参考に、どこに何を繋げばいいのか読み解いていく。
m5側はUIFLOWだとこんな名前になっているので、それぞれどれと繋げばよいかが問題。


他の液晶の例だが、https://lang-ship.com/blog/work/m5stickc-spi/を参考に何を繋げばよいか検討する。
  1. BLK … 不要 ※バックライトの制御用
  2. CS … GND ※他に繋ぐものが無ければ、L固定でOK
  3. DC … MISO ※RのみでOK
  4. RES … 任意のW ※画面リセット用
  5. SDA … MOSI ※WのみでOK
  6. SCL … SCK
  7. VCC … 3.3V
  8. GND … GND
今回は順番に以下のように接続した。
  1. BLK … n/a
  2. CS … GND
  3. DC … G22
  4. RES … G19
  5. SDA … G23
  6. SCL … G33
  7. VCC … 3.3V
  8. GND … GND
atomはRead Onlyなどで迷うことが無いので楽。
結果、ブロックの設定は次のようになる

そうこうするうちに遅くなってしまったので、続きはまた次回。