1
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?

ラズピコのMicroPythonからILI9341 TFT液晶を使う

Last updated at Posted at 2025-05-22

概要

Raspberry Pi Picoは、MicroPythonを簡単に動作させてすぐにプログラムを動かすことができます。しかし、MicroPythonでは周辺機器の制御については多くの処理を自力で組み込む必要があります。また、日本語表示をするためには、かなりの工夫が必要になります。

そこで、以前公開したRapberry PI Pico(標準SDK/ArduinoSDK) 用 ILI9341 TFT液晶 日本語ライブラリ を、Micropytonから使用できるようにするため、ユーザーCモジュールとしてビルドしました。

日本語フォントは、MicroPythonファームウェア(firmware.uf2)の一部として組み込まれます。バイナリ形式でフラッシュメモリ上に保持されるため、メインメモリへの圧迫は少なくなります。

Pythonからは数行でILI9341液晶コントローラーが制御できます。

import KNJGfx
    
KNJGfx.setDebugMode(1)
KNJGfx.initHW((0,20,22,18,19,21,0))
KNJGfx.setRotation(3)
KNJGfx.fillScreen(0, 0x00FF)
KNJGfx.loadDefaultKanjiFont(0)
KNJGfx.setCursor(0,10,30)

KNJGfx.print(0,"こんにちは")

ハードウェア

Rapberry PI Pico(標準SDK/ArduinoSDK) 用 ILI9341 TFT液晶 日本語ライブラリ の、使用するまでの準備>ハードウェアを参照し、結線してください。

  • Raspberry PI Picoの右半分に線が集中するようにしてあります
  • 変更は可能ですが、KNJGfx.initHW((0,20,22,18,19,21,0)) の部分に使用するピン番号を指定する必要があります

ビルド済みイメージを使用する

ビルド済みのイメージを使用する場合は、次の手順に従って作業してください。

MicroPythonのダウンロード

Githubのリポジトリページに行き、右側にあるReleses をクリック、最新のリリースを表示させます。

preBuild_MycroPy.zipをダウンロードしてください。

2.png

必要なファームウェアを選定

ZIPファイルの中には、ボードの種類/フォルダ、とディレクトリごとに別れており、それぞれのフォルダの中には firmware.uf2が含まれています。

/
├─── Build-PICO .... Raspberry Pi Pico (無印)用
│   │
│   ├─── build-RPI_PICO_12L1 .... 東雲フォント12ドットゴシック、JIS第一水準
│   ├─── build-RPI_PICO_14L1 .... 東雲フォント14ドットゴシック、JIS第一水準
│   ├─── build-RPI_PICO_16L1 .... 東雲フォント16ドットゴシック、JIS第一水準
│   ├─── build-RPI_PICO_24GL1.... IPAフォント24ドットゴシック、JIS第一水準
│   └─── build-RPI_PICO_24ML1.... IPAフォント24ドット明朝、JIS第一水準
│ 
├─── Build-PICO2 .... Raspberry Pi Pico 2用
│   │
│   ├─── build-RPI_PICO_12L1 .... 東雲フォント12ドットゴシック、JIS第一水準
│    :                  :
│    :                  :
│   └─── build-RPI_PICO_24ML1.... IPAフォント24ドット明朝、JIS第一水準
│
├─── Build-PICOW .... Raspberry Pi Pico W 用
│       :
│       :
└── Build-PICO2W .... Raspberry Pi Pico 2W 用
        :
        :

この中から、必要な firmware.uf2を選択してください。

たとえば、手持ちのボードが Raspberry PI Pico 2で、16ドットフォントを使用したいという場合、build-PICO2\build-RPI-PICO2_16L1フォルダの中にあるfirmware.uf2を使用します。

ボードと、フォント、フォントのセットの組み合わせは膨大になってしまうため、代表的なものだけを含めています。異なる組み合わせ、例えば、16ドットでJIS第二水準を含めたい、などの場合、後述の手順に従ってMicropythonをビルドする必要があります。ビルドが難しいという場合、作者に連絡をお願いします。時間があればビルドしてみます。

ファームウェアのインストール

Raspberry PI Picoのボタンを押しながら、USBを差し込みます。マスストレージデバイスとして認識されるので、firmware.uf2をコピーしてください。

コピーが完了すると、自動的にマスストレージデバイスは切断されます。

Thonny の起動と実行

この説明では、ThonnyでPythonを実行することを前提として説明しています。Thonnyの使い方については、インターネットなどで確認してください。
Visual Studio Code (標準SDK)のmicroPython環境を使用している場合、適宜読み替えてください。Raspberry PI Pico側に、ファームウェアが導入済みであれば基本的に実行することは変わりません。

次のプログラムを入力し、実行ボタンを押してください。

import KNJGfx
    
KNJGfx.setDebugMode(0)
KNJGfx.initHW((0,20,22,18,19,21,0))
KNJGfx.setRotation(3)
KNJGfx.fillScreen(0, 0x00FF)
KNJGfx.loadDefaultKanjiFont(0)
KNJGfx.setCursor(0,10,30)

KNJGfx.print(0,"こんにちは")
2.png

液晶画面には、青地に白文字で「こんにちは」と表示されます。この画像は、24ドット明朝を使用しています。
2.png

各行は、次のような意味を持っています。

  • KNJGfx.setDebugMode(0)
    デバッグモードを無効にします。1を指定すると、実行した命令がそのまま標準出力に表示されます。
     
  • KNJGfx.initHW((0,20,22,18,19,21,0))
    ハードウェアを初期化します。引数がタプルになっていること(かっこが2つ)に注意してください。
    引数は次のようになっています。Rapberry PI Pico(標準SDK/ArduinoSDK) 用 ILI9341 TFT液晶 日本語ライブラリを参照し、結線にあわせて指定してください。
     
     0・・SPIチャンネル(0または1)
    20・・DC…TFTのデータ/コマンドポート番号
    22・・CS…デバイスセレクト、
    18・・CSK…クロック
    19・・MOSI…マスタ⇒スレーブ信号線
    21・・Reset…リセット信号
     0・・Debug…デバッグポート番号(未使用。ゼロを指定)
     
  • KNJGfx.setRotation(3)
    画面の回転方向を指定します。0(端子側短辺を下)、1(端子側短辺を右)、2、3が指定できます。
    -KNJGfx.fillScreen(0, 0x00FF)
    画面をカラーコード0x00FFで塗りつぶします。引数は次のようになっています。
     
    0・・対象の画面番号。0が、物理的に接続されているTFT液晶です。1~32は、オンメモリに確保するキャンバスに対して描画します。キャンバス機能については実際のサンプルプログラムで確認してください。
    0x00FF・・塗りつぶす色です。フォーマットはRGBGの565です。(赤が0xF800,緑が0x07E0,青が0x001F)
     
  • KNJGfx.loadDefaultKanjiFont(0)
    漢字コードを読み込みます。対象の画面番号を指定します。0が、物理的に接続されているTFT液晶です。
     
  • KNJGfx.setCursor(0,10,30)
    表示位置を指定します。最初の0は画面番号、次の2つがXY位置です。座標は、(0,(10,30))のようにタプルとして渡すことができます。原則として、このプログラムでは座標などはタプルとして扱いますが、setCursorだけは特別に、独立した引数として渡すことができます。(作っている最中に毎回間違えたのでここだけ対応した)
     
  • KNJGfx.print(0,"こんにちは")
    画面にテキストを表示します。

高度なサンプルプログラムを使用する

文字表示以外の描画を行うサンプルプログラムは次のURLからダウンロードできます。

GithubのExamplesサブフォルダ

ここから、test9341.py と、BitmapDataサブフォルダをダウンロードします。

BitmapDataサブフォルダには、ビットマップ画像のデータなどが含まれています。

BitmapDataサブフォルダの内容を、事前に RaspberryPI Picoに転送しておいた上で、test9341.pyを実行します。

データの転送

一般的な方法として、ThonnyでBitmapサブフォルダに含まれる .py ファイルを開き、保存先をRaspberry Pi PicoにすることでファイルをPicoに転送できます。この方法が使用できる場合、この方法でBitmapDataサブフォルダにあるファイルをすべて、Picoに転送してください。

2.png

私の環境ではなぜか、ファイルサイズが大きくなると転送に失敗してしまいます。そのため、rshellを使用してファイルを転送します。説明は、より「めんどくさい」Windowsをベースにしています。linuxを使用している場合適宜読み替えてください。(一般的に、windowsよりlinuxの方が簡単です)

  • pythonとpipがインストールされていることを確認します。
e:\work>python --version
Python 3.13.3

e:\work>pip --version
pip 25.1.1 from <site-packagesの場所>\pip (python 3.13)
  • pipを使用してrshellを導入します。
e:\work>pip install rshell
Defaulting to user installation because normal site-packages is not writeable
Collecting rshell
    :
    :
Cache\local-packages\Python313\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pyreadline-2.1 pyudev-0.24.3 rshell-0.0.36
  • rshellが動作するかを確認します。
rshell --help

Windowsの場合、rshellは、通常、自動的に exe 形式になりインストールされています。
例:C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\Scripts\rshell.exe
rshellが起動できない場合、PC内を検索し、pathを通してください。

rshellがインストール出来たらThonnyを終了し、cpコマンドを使用してコピーしてください。

rshell [-p ポート番号 --buffer-size=8192] cp <サンプルのpythonがあるフォルダ>/*.py /pyboard/

ポート番号と--buffer-sizeに大きめの値を指定すると速度が速く安定します。また、フォルダには、ドライブを除く絶対パスを、/ を区切り記号として指定します。このツール自体がlinuxを前提としているためWindowsでは使いにくさが残ります。

たとえば、Raspberry PIがCOM17 に接続されており、転送するファイルがE:\hoge\BitmapData\の中にある場合、次のようなコマンドになります。

rshell -p COM17 --buffer-size=8192 cp /hoge/BitmapData/*.py /pyboard/

Using buffer-size of 8192
Connecting to COM17 (buffer-size 8192)...
Trying to connect to REPL  connected
Retrieving sysname ... rp2
Testing if ubinascii.unhexlify exists ... Y
Retrieving root directories ...
Setting time ... May 22, 2025 10:01:34
Evaluating board_name ... pyboard
Retrieving time epoch ... Jan 01, 1970
Copying '/hoge/BitmapData/Apr1.py' to '/pyboard/Apr1.py' ...
    :
Copying '/hoge/BitmapData/Sep1.py' to '/pyboard/Sep1.py' ...

サンプルプログラムの実行

転送が完了したら、Thonnyを起動し、test9341.py を読み込みます。
画面には、Pico側にデータファイルが転送されていることが確認できます。
確認が終わったらプログラムを実行してください。

2.png

基本的な図形の描画、ビットマップの表示、キャンバスの利用などのサンプルが実行されます。

ビットマップ キャンバス 基本図形 透過表示
2.png 2.png 2.png 2.png

Micropython C拡張モジュール 関数リファレンス

引数の凡例

液晶表示関連

仮引数名 説明
a_Target 対象の画面番号。0が物理的に接続されているTFT液晶。1~32はメモリ上に確保されているキャンバス(オフスクリーンメモリ)
a_tf True、もしくはFalseを指定
a_Rotation 画面の回転角度。0(端子側短辺を下)、1(端子側短辺を右)、2(端子側短辺を上)、3(端子側短辺を左)
a_top,a_bottom スクロール時に除外する上下エリアの大きさ
a_x X座標
a_y Y座標
a_color,a_bgColor 色指定。フォーマットはRGBGの565。(赤が0xF800,緑が0x07E0,青が0x001F)
a_xy X座標、Y座標を含むTupple。(x,y)として指定する
a_xyl X座標、Y座標、長さ(幅や高さなど)を含むTupple。(x,y,l)として指定する
a_xywh X座標、Y座標、幅、高さを含むTupple。(x,y,w,h)として指定する
a_xyxy 二つのX座標、Y座標を含むTupple。(x1,y1,x2,y2)として指定する
a_xyxy 三つのX座標、Y座標を含むTupple。(x1,y1,x2,y2,x3,y3)として指定する
a_xyr X座標、Y座標、半径を含むtupple。(x,y,r)として指定する
a_xyxyr 二つのX座標、Y座標と半径を含むTupple。(x1,y1,x2,y2,r)として指定する
a_xywhr X座標、Y座標、幅、高さ、半径を含むTupple。(x,y,w,h,r)として指定する
a_str 文字列を指定する
a_size 文字の拡大率を指定する。2を指定すると文字は2倍の大きさで表示される
a_canvasID キャンバス(オフスクリーンメモリ)の番号を指定します。1~32が指定できます。使用前にはキャンバスを作成してから使用します
a_keyColor キーカラーを指定します。キーカラーに指定された色は、ビットマップ表示などでは透明色として扱われます

画面のタッチ関連

仮引数名 説明
a_cs タッチスクリーンのCSを指定します。
a_IRQ タッチスクリーンの割り込みポートを指定します。255の場合未使用です
a_minmax X座標、Y座標の最大、最小値を指定します
a_Rotation TFT液晶の説明を参照してください

初期化・設定関数

関数名 説明
initHW((spi,dc,cs,csk,mosi,Reset,Debug)) ハードウェアの初期化を行います。
SPIチャンネル
DC…TFTのデータ/コマンドポート番号
CS…デバイスセレクト
CSK…クロック
MOSI…マスタ⇒スレーブ信号線
Reset…リセット信号
Debug…デバッグポート番号(未使用。ゼロを指定)
setDebugMode(a_mode) デバッグモードを設定します。0...デバッグ表示なし、1...デバッグ表示あり
loadDefaultKanjiFont(a_Target) デフォルトの漢字フォントをロードします
loadDefaultAsciiFont(a_Target) デフォルトのASCIIフォントをロードします
setRotation(a_Rotation) ディスプレイの回転を設定します
displaySleep(a_tf) ディスプレイのスリープを制御します

特殊描画関数

関数名 説明
invertDisplay(a_tf) 画面の色を反転します
setScrollMargins(a_top, a_bottom) スクロール範囲の上下マージンを設定します
scrollTo(a_y) 指定したY座標へスクロールします

基本描画関数

関数名 説明
fillScreen(a_Target, a_color) 画面を指定色で塗りつぶします
drawPixel(a_Target, a_xy, a_color) 指定座標にピクセルを描画します
drawFastHLine(a_Target, a_xyl, a_c) 水平線を描画します
drawFastVLine(a_Target, a_xyl, a_c) 垂直線を描画します
fillRect(a_Target, a_xywh, a_color) 指定範囲を塗りつぶします
drawRect(a_Target, a_xywh, a_color) 長方形を描画します
drawLine(a_Target, a_xyxy, a_color) 線を描画します
drawCircle(a_Target, a_xyr, a_color) 円を描画します
fillCircle(a_Target, a_xyr, a_color) 円を塗りつぶします
drawRoundRect(a_Target, a_xywhr, a_color) 角丸の長方形を描画します
fillRoundRect(a_Target, a_xywhr, a_color) 角丸の長方形を塗りつぶします
drawTriangle(a_Target, a_xyxyxy, a_color) 三角形を描画します
fillTriangle(a_Target, a_xyxyxy, a_color) 三角形を塗りつぶします

テキスト描画関数

関数名 説明
setCursor(a_target,a_xy) テキストカーソルの位置を設定します
setCursor(n_args,a_x,a_y) テキストカーソルの位置を設定します
print(a_Target, a_str) テキストを描画します
setTextWrap(a_Target, a_tf) テキストの折り返しを設定します
setTextForegroundColor(a_Target, a_color) テキストの前景色を設定します
setTextBackgroundColor(a_Target, a_color) テキストの背景色を設定します。背景色と前景色が同じ場合、その文字は背景透過となります
setTextColor(a_Target, a_color, a_bgcolor) テキストの前景色と背景色を設定します。背景色と前景色が同じ場合、その文字は背景透過となります
setTextSize(a_Target, a_size) テキストのサイズを設定します。2を指定すると文字の大きさは2倍になります
setKanjiMode(a_Target, a_tf) 漢字モードを設定します。漢字モードが有効な場合、ASCII文字を含むすべての文字は日本語フォントとして描画されます。Falseを指定すると、ASCII文字はデフォルトのアスキーフォントとして描画されます。この場合日本語は表示されません。
setKanjiFont(a_Target, a_code, a_bitmap) 未実装です。フォントデータをPython側に持って指定するようにしましたが、メモリが圧倒的に足りないため実装は困難です。

ビットマップ関数

関数名 説明
drawBitmap(a_Target, a_xywh, a_bitmap) 指定座標にビットマップを描画します
drawBitmapWithKeyColor(a_Target,a_xywh,a_bitmap,a_keyColor) キーカラー付きでビットマップを描画します。キーカラーに指定された色は、透明色として描画されるので背景がそのまま残ります
drawBitmapFromCanvas(a_Target, a_xy, a_canvasID) キャンバスからビットマップを描画します

キャンバス関数

関数名 説明
createCanvas(a_wh) キャンバスを作成します。戻り値には作成されたキャンバスのIDが1~32で戻されます。このキャンバスに対して、画面と同じように描画することができます。作成したキャンバスはビットマップ転送で画面に表示できます。
deleteCanvas(a_canvasID) キャンバスを削除します。
setCanvasKeyColor(a_canvasID, a_keycolor) キャンバスのキーカラーを設定します。ここで指定した色は、ビットマップで画面に表示するときに透明色として扱われます
resetCanvasKeyColor(a_canvasID) キーカラーをリセットします

タッチ関数

関数名 説明
initTouchHW(a_CS, a_IRQ) タッチハードウェアを初期化します。IRQを使用しない場合255を指定します。
setTouchCalibrationValue(a_minmax) タッチのキャリブレーション値を設定します。
setTouchRotation(a_Rotation) タッチ回転を設定します。通常、TFTと同じ値を指定します。
beginTouch() タッチ操作を開始します
isTouch() タッチされているかを確認します。タッチされている場合、Trueが返されます。getTouchXYでタッチされている座標を取得します。
getTouchRawXYZ() タッチの生データを取得します。キャリブレーションを行うときに使用します。
getTouchXY() タッチ座標を取得します。XYのタプルが返されます

タッチパネルのキャリブレーションについて

小ロット生産者とともに歩む秋月電子のILI9341搭載2.8インチSPI制御タッチパネル付TFT液晶MSP2807では、XPT2046がコントローラとして付属しています。このコントローラーはキャリブレーションが必要で、キャリブレーションを行わない場合タッチ位置が微妙にずれてしまいます。

多少のずれを問題にしないため、多くのサンプルではデフォルトの値のまま使用しています。このライブラリでも、私が購入した製品で行ったキャリブレーション値をデフォルトとして使用しています。

あまり精密な操作は要求されないため、多くの場合デフォルトでも問題ありませんが、タッチ位置のズレが気になる人は、次のようなコードで購入したデバイスにあわせた値を求め、setTouchCalibrationValue(a_minmax)で調整してから使用してください。

import KNJGfx
import time
import random

def Touch10():
    count = 0
    minx = 99999
    miny = 99999
    maxx = 0
    maxy = 0
    
    while True:
        if KNJGfx.isTouch():
            rawpos = KNJGfx.getTouchRawXYZ()
            pos = KNJGfx.getTouchXY()
            KNJGfx.fillCircle(0,(pos[0],pos[1],5),random.randint(0,0xFFFF))
            minx = rawpos[0] if (minx > rawpos[0]) else minx
            miny = rawpos[1] if (miny > rawpos[1]) else miny
            maxx = rawpos[0] if (maxx < rawpos[0]) else maxx
            maxy = rawpos[1] if (maxy < rawpos[1]) else maxy
            count = count + 1
        if count > 10 :
            return [minx,miny,maxx,maxy]
        time.sleep(0.1)


def main():
    # 初期化処理    
    KNJGfx.setDebugMode(0)
    KNJGfx.initHW((0,20,22,18,19,21,0))
    KNJGfx.setRotation(3)
    KNJGfx.loadDefaultKanjiFont(0)

    KNJGfx.initTouchHW(17,255)
    KNJGfx.setTouchRotation(3)
    KNJGfx.beginTouch()

    # 左上の最小値を求める
    KNJGfx.fillScreen(0, 0x00FF)
    KNJGfx.setCursor(0,10,10)
    KNJGfx.setTextColor(0,0xFFFF,0xFFFF)
    KNJGfx.print(0, "画面左上をタップ")
    rawPos = Touch10()
    minX = rawPos[0]
    minY = rawPos[1]
    
    #右下の最小値を求める
    KNJGfx.fillScreen(0, 0xFF0)
    KNJGfx.setCursor(0,100,210)
    KNJGfx.setTextColor(0,0x0000,0x0000)
    KNJGfx.print(0, "画面左下をタップ")
    rawPos = Touch10()
    maxX = rawPos[2]
    maxY = rawPos[3]

    KNJGfx.fillScreen(0, 0x00FF)
    KNJGfx.setTextColor(0,0xFFFF,0xFFFF)
    KNJGfx.setCursor(0,10,10)
    
    #結果を画面に表示する
    KNJGfx.print(0,f"min: {minX},{minY}\r\n")
    KNJGfx.print(0,f"max: {maxX},{maxY}\r\n")

    print(f"KNJGfx.setTouchCalibratonValue(({minX},{minY},{maxX},{maxY}))")
    KNJGfx.setTouchCalibrationValue((minX,minY,maxX,maxY))



if __name__ == "__main__":
    main()    

実行すると、画面の左上をタップするような指示があります。画面のなるべく左上をタップしてください。タップした箇所には小さい丸が出ます。画面の外をタップすると無効ですが、気にせずなるべく外側を連打してください。
10回、タッチが認識されると画面の色が変わり、今度は左下をタップするように指示があります。同様にタップしてください。

終了すると、画面には最小値、最大値が表示されます。この値を、KNJGfx.setTouchCalibratonValue(({minX},{minY},{maxX},{maxY}))のように呼びだしてください。
標準出力には、KNJGfx.setTouchCalibratonValue((418,353,3863,3747)) のように実際の呼び出しの方法が示されます。

このキャリブレーションは保存されません。使用するときにはプログラムの先頭で毎回指定してください。

自分用にビルドする

使いたいフォントを変更したい、フォントセットを変更したい、機能を強化したい、バグを何とかしたい、などの要望がある場合、Micropythonをビルドすることもできます。

環境の準備

この説明では、Windows PC (Windows 10以上)があるものとして準備を進める。しかし、実際の手順はほとんどがWSLを使用した linux上で行われるので、元々linuxでビルドするという場合は、Windows部分を無視すれば問題ない。

WSLのインストールと環境の構築

※ Linux上にビルド環境を構築する場合は不要

いろいろ試したが、MicroPythonのビルドスクリプトを、Windows上のRaspberry Pi PicoSDKで動かすことができなかった。(クロスコンパイラの環境構成が複雑なこと、CMakeが生成するビルドのレシピ内で、パスの表現形式がWindows (C:\hoge\moge)になってしまうがコンパイラなどのツールがこの形式を受け入れないこと等が原因と思われる。)

そのため、エディタやファイルの管理などではWindowsを使用して、ビルドはWSLのubuntu を使用する方法で環境を作成する。Visusal Studio CodeはシームレスにWSLを使用することができるので、使用感はほとんどWindowsでビルドするのと変わらない。

WSLのインストール

WSLをインストールし、WSL1.0にバージョンダウンする。すでにWSLを使用している場合でも1.0に戻す必要がある。(1.0に戻しても既存の2.0環境は破壊されない。2.0に戻すことも可能)
WSL 2.0は、Windowsからのファイルシステム操作が1.0よりも極端に遅く、Windowsから編集・ビルドを行うのは事実上使い物にならない。そのため、WSL 1.0を使用する必要がある。

WSLのインストール

[WSL を使用して Windows に Linux をインストールする方法](https://learn.microsoft.com/ja-
jp/windows/wsl/install)や、【WSL2セットアップ】Windowsの機能の有効化または無効化 などを参照し、WSLをインストールする。

インストールが終了したら、Microsoft Storeから、Ubuntu をインストールする。

ubuntu1.png

インストールが終了したら、スタートメニューから ubuntuを選び、起動する。最初に起動すると、ユーザー名とパスワードを聞かれるので、適当に入力する。次のようなプロンプトが出れば正常。(user / mmachinenameは環境により異なる)
user@machinename : ~$
確認が終了したら、ubuntuは終了(ログアウト)しておく。

WSLのバージョン確認とバージョンダウン

もし、現状WSL2がインストールされている場合、WSLに戻す。WSL2は、Windowsのファイルシステム操作が非常に遅くMicroPythonのビルドが2~3時間かかってしまう。WSLの場合、フルビルドの場合でも30分程度で終了する。

管理者権限のコマンドプロンプトを開き、現在のWSLバージョンを確認する。

C:\Windows\System32>wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-24.04    Running         2

バージョンが1の場合、バージョンダウンは不要。バージョンが2の場合、ディストリビューションを指定してバージョンを1に変換する。変換操作で変換対象のlinux環境がリセットされることはない。変換後にバージョンが1になっていることを確認しておく。(3分以内)

C:\Windows\System32>wsl --set-version Ubuntu-24.04 1
変換中です。これには数分かかる場合があります。
この操作を正しく終了しました。

C:\Windows\System32>wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-24.04    Running         1

Visual Studio CODEのインストール

Windows側で、Visual Studio Codeをインストールしておく。
WSL側には、Visual Studio Codeのインストールは必要ないことに注意。

Visual Studio Codeには次のアドインの導入をしておく。

  • WSL。必須。Visual Studio CodeとWSLを連携させ、WSL内のLinux環境で開発を行う
    ubuntu1.png
  • C/C++、Cmake Tools、Python
  • Raspberry PI PICO なくても良いが、あると何かと便利

必要なツールのインストール

スタートメニューからubuntuを起動し、ビルドに必要なツールをインストールしていく。
最初に、update/upgradeをしてから、ビルドツールを導入する。(10分)

必要なものは次の通り。すでに導入済みの場合、この作業は不要。

WSL側には、Visual Studio Codeのインストールは必要ない(インストールすべきではない)ことに注意。

名称 正式名称 概要
gcc-arm-none-eabi GNU Arm Embedded Toolchain ARM Cortex-MやCortex-Rなどの組み込みプロセッサ向けに設計されたクロスコンパイラツールチェーン
libnewlib-arm-none-eabi Newlib C Library for ARM Embedded Systems 組み込みシステム向け軽量Cライブラリ。Cortex-MやCortex-Rプロセッサ用、stdio、mathなど標準ライブラリを提供。
build-essential Build Essential Package ソフトウェアをビルドするために必要な基本的なツール群。gcc、g++、makeなどが含まれる。
cmake Cross-Platform Make オープンソースのビルドシステムで、プラットフォームやコンパイラに依存しない構成ツール。
~$ sudo apt update
~$ sudo apt upgrade
~$ sudo apt install gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential
~$ sudo apt-get install cmake

すべてのツールが非常に一般的なものなので、apt やpacmanなど一般的なパッケージツールでインストールできる。(cmakeは最新版がaptなどでインストールできないが、最新版は不要)

実行例(開発ツール)

~$ sudo apt update
 :
~$ sudo apt upgrade
 :
~$ sudo apt install gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential
$ sudo apt install gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following package was automatically installed and is no longer required:
   :
   :
Setting up libheif-plugin-libde265:amd64 (1.17.6-1ubuntu4.1) ...
Setting up libheif-plugin-aomenc:amd64 (1.17.6-1ubuntu4.1) ...
Processing triggers for libc-bin (2.39-0ubuntu8.4) ...
Processing triggers for man-db (2.12.0-4build2) ...   
~$

実行例(cmake)

~$ sudo apt-get install cmake
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
  :
Processing triggers for man-db (2.12.0-4build2) ...
Processing triggers for libc-bin (2.39-0ubuntu8.4) ...
~$ 

ビルドディレクトリの作成とマウント

今回は、Windowsファイルシステム上にビルド用のファイルを作成し、Windowsから編集などのファイル操作をおこない、linux側ではビルドだけ、という形で構成する。
そのため、Windows側でビルドのフォルダを用意し、それをlinux側でマウントし、Windows/Linux双方でファイルにアクセスできるようにしておく。

今回は、E:\Work\PythonMod でビルドを行い、linux側はE:ドライブ全体を、/e にマウントして操作できるように設定する。例えば、Windowsで e:\work\PythonModは、Linux側からは /e/work/PythonModとしてアクセスできる。

Windows

E:\>mkdir work\PythonMod
E:\>cd \work\PythonMod

Linux

~$ sudo ln -s  /mnt/e/ /e
~$ cd /work/PythonMod

MicroPythonをソースコードからビルドする

ソースコード取得

/e/work/PythonMod/micropythonディレクトリにおいて、gitから、MicroPythonのソースコードを取得する。この操作で、/e/work/PythonMod/micropythonディレクトリにMicroPythonのソースコードが格納される。

 git clone https://github.com/micropython/micropython.git --branch master

実行例

~$ cd /e/work/PythonMod
/e/work/PythonMod$ git clone https://github.com/micropython/micropython.git --branch master
Cloning into 'micropython'...
remote: Enumerating objects: 127569, done.
   :
/e/work/PythonMod$   

ビルド

ソースコードを取得出来たら、まずはC拡張モジュール無しで、そのままMicroPythonをビルドできるようにしておく。

Submoduleのビルド

make -C ports/rp2 submodules

コマンドを使い、サブモジュールをビルドする。

このとき、ターゲットのボードをビルドの引数で指定する。省略時は、Raspberry Pi Pico無印(BOARD=RPI_PICO と同じ)。
指定可能なビルドターゲットは、…\micropython\ports\rp2\boards 内にフォルダとして含まれている。良く使うだろうと思われるものは次の通り。

指定する引数 対象デバイス
BOARD=RPI_PICO Raspberry Pi Pico(デフォルト)
BOARD=RPI_PICO_W Raspberry Pi Pico W
BOARD=RPI_PICO2 Raspberry Pi Pico 2
BOARD=RPI_PICO2_W Raspberry Pi Pico2 W

たとえば

make -C ports/rp2 submodules BOARD=RPI_PICO_W

などとすれば、Raspberry Pi Pico Wとしてビルドできる。Submoduleに関して言えば、Raspberry Pi PicoとPico 2は互換性があるが、 Raspberry Pi Pico Wなどは、Raspberry Pi Pico WのWi-Fiドライバ(cyw43-driver)を組み込む必要があるので正しいサブモジュールをビルドしておかないと後のビルドでエラーが発生する。

/e/work/PythonMod/micropython$ make -C ports/rp2 submodules
make: Entering directory '/mnt/e/work/PythonMod/micropython/ports/rp2'
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
make -f ../../py/mkrules.mk GIT_SUBMODULES="lib/pico-sdk" submodules
make[1]: Entering directory '/mnt/e/work/PythonMod/micropython/ports/rp2'
  :
  :
Resolving deltas: 100% (918/918), done.
Submodule path 'lib/tinyusb': checked out '5217cee5de4cd555018da90f9f1bcc87fb1c1d3a'
make[1]: Leaving directory '/mnt/e/work/PythonMod/micropython/ports/rp2'
make: Leaving directory '/mnt/e/work/PythonMod/micropython/ports/rp2'

ツールのビルド

/e/work/PythonMod/micropython$ make -C mpy-cross
make: Entering directory '/mnt/e/work/PythonMod/micropython/mpy-cross'
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
mkdir -p build/genhdr
GEN build/genhdr/mpversion.h
GEN build/genhdr/qstr.i.last
    :
CC ../shared/runtime/gchelper_generic.c
LINK build/mpy-cross
   text    data     bss     dec     hex filename
 400585   17792     864  419241   665a9 build/mpy-cross
make: Leaving directory '/mnt/e/work/PythonMod/micropython/mpy-cross'
/e/work/PythonMod/micropython$ 

MicroPythonのビルド

ports/rp2でmakeを実行し、本体をビルドする。

 $ make

BORDシンボルでビルドのターゲットを変更できる。省略時は、Raspberry Pi Pico無印(BOARD=RPI_PICO と同じ)。たとえば make BOARD=RPI_PICO2 などとすれば、Raspberry Pi Pico 2としてビルドできる。

指定可能なビルドターゲットは、…\micropython\ports\rp2\boards 内にフォルダとして含まれている。
良く使うだろうと思われるものは次の通り。

指定する引数 対象デバイス
BOARD=RPI_PICO Raspberry Pi Pico(デフォルト)
BOARD=RPI_PICO_W Raspberry Pi Pico W
BOARD=RPI_PICO2 Raspberry Pi Pico 2
BOARD=RPI_PICO2_W Raspberry Pi Pico2 W

今回の実行例では、PICOとして実行しているが、適宜引数を追加して環境にあわせる。

初回は、いくつか警告が出る。また、PicoToolがインストールされていないという警告が出て、自動的にダウンロードされるので時間がかかる。(20分程度)

実行例

 $ cd ports/rp2
 $ make
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
[ -e build-RPI_PICO/Makefile ] || cmake -S . -B build-RPI_PICO -DPICO_BUILD_DOCS=0 -DMICROPY_BOARD=RPI_PICO -DMICROPY_BOA
   :
  (略)
   :
CMake Warning at /e/work/PythonMod/micropython/lib/pico-sdk/tools/Findpicotool.cmake:30 (message):
  No installed picotool with version 2.1.1 found - building from source
   :
  (略)
   :
[ 97%] Building C object CMakeFiles/firmware.dir/e/work/PythonMod/micropython/lib/tinyusb/src/class/vendor/vendor_device.c.o
[ 97%] Building C object CMakeFiles/firmware.dir/e/work/PythonMod/micropython/lib/tinyusb/src/class/video/video_device.c.o
[ 97%] Building C object CMakeFiles/firmware.dir/e/work/PythonMod/micropython/lib/pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c.o
[ 97%] Building C object CMakeFiles/firmware.dir/e/work/PythonMod/micropython/lib/pico-sdk/src/rp2_common/cmsis/stub/CMSIS/Device/RP2040/Source/system_RP2040.c.o
[ 98%] Linking CXX executable firmware.elf
   text    data     bss     dec     hex filename
 332792       0    5484  338276   52964 /e/work/PythonMod/micropython/ports/rp2/build-RPI_PICO/firmware.elf
make[3]: Leaving directory '/mnt/e/work/PythonMod/micropython/ports/rp2/build-RPI_PICO'
[100%] Built target firmware
make[2]: Leaving directory '/mnt/e/work/PythonMod/micropython/ports/rp2/build-RPI_PICO'
make[1]: Leaving directory '/mnt/e/work/PythonMod/micropython/ports/rp2/build-RPI_PICO'
/e/work/PythonMod/micropython/ports/rp2$   

ビルドされたものを確認する

ビルドは、ターゲット(今回は指定していないので、Raspberry Pi Pico )の種類ごと、サブフォルダにfirmware.uf2の名前で生成される。

内容を確認し、正しくビルドされたかを調査する。

/e/work/PythonMod/micropython/ports/rp2$ ls -al  build-RPI_PICO/firmware.uf2
-rwxrwxrwx 1 user user 665600 Mar 12 13:27 build-RPI_PICO/firmware.uf2

micropython/ports/rp2/build-RPI_PICO/_deps/picotool/には、picotoolというツールが同時に生成される。このツールを使って生成されたuf2の詳細を確認できる。

/e/work/PythonMod/micropython/ports/rp2$ build-RPI_PICO/_deps/picotool/picotool info -a build-RPI_PICO/firmware.uf2
File build-RPI_PICO/firmware.uf2 family ID 'rp2040':

Program Information
 name:              MicroPython
 version:           v1.25.0-preview.365.g3823aeb0f
 features:          thread support
                    USB REPL
 frozen modules:    neopixel, dht, ds18x20, onewire, uasyncio, asyncio/stream, asyncio/lock, asyncio/funcs,
                    asyncio/event, asyncio/core, asyncio, _boot_fat, _boot, rp2
 binary start:      0x10000000
 binary end:        0x100513f8
 embedded drive:    0x100a0000-0x10200000 (1408K): MicroPython

Fixed Pin Information
 none

Build Information
 sdk version:       2.1.1
 pico_board:        pico
 boot2_name:        boot2_w25q080
 build date:        Mar 12 2025
 build attributes:  MinSizeRel

Metadata Blocks
 none

ILI9341のライブラリをMicroPythonに組み込む

ライブラリのソースコードの入手

MicroPythonのビルドができるようになったので、次にILI9341のライブラリをユーザー定義Cモジュールとして組み込む。
ILI9341のライブラリについて詳細はここを参照すること

今回は、拡張ライブラリのソースコードは micropython/ports/rp2/myModule に配置してビルドすることにする。事前に、このフォルダを作成しておく。

/e/work/PythonMod/micropython/ports/rp2$ mkdir myModule

GitHubのリリースページから、Download codeをクリックし、zipファイルをダウンロードする。

Zipファイルからlib-9341 サブフォルダの内容を、micropython\ports\rp2\myModuleにコピーしておく。
その後、次のフォルダについて、削除や移動する。

  • ForMPY … ファイルの内容をmyModule直下に移動する
  • ForMPY/tasks.json.txt 名前をtasks.jsonに変更し、ルートディレクトリ/.vscodeに移動する
  • Examples - 削除 (Ardiuno IDE用なので不要)
  • library.properties - 削除 (Ardiuno IDE用なので不要)
  • KNJGfx9341.h - 削除 (Ardiuno IDE用なので不要)

最終的に、次のようなファイル構成になる。

/
├─── .vscore
│   │
│   └─── .tasks.json ビルド用の設定ファイル
│
└──── micropython
    │
    ├─── .git
    ├─── .github
    ├─── docs
    ├─── drivers
      :   :
    ├─── ports
    │     ├─── rp2      
    │     :   ├── boards
    │     :   :
    │     :   └── myModle
    │     :       ├── Adafruit_GFX_Library
    │     :       │    ├──
    │     :       │    :
    │     :       ├── Adafruit_ILI9341
    │     :       │    ├──
    │     :       │    :
    │     :       ├── core
    │     :       │    ├──
    │     :       │    :
    │     :       ├── Kanji
    │     :       │    ├── Fonts
    │     :       │    ├── KanjiHelper.cpp
    │     :       │    └── KanjiHelper.h
    │     :       ├── misc
    │     :       │    ├──
    │     :       │    :
    │     :       ├── spi
    │     :       │    ├──
    │     :       │    :
    │     :       ├── XPT2046_Touchscreen
    │     :       │    ├──
    │     :       │    :
    │     :       ├── gfx.cpp
    │     :       ├── GFXModule.c
    │     :       ├── GFXModule.h
    │     :       └── micropython.cmake
    │     ├─── samd          
    │     ├─── stm32          
    │     └─── zephyr 
    ├─── py
      :
    └─── tools
 

ビルドの実行

今回は、tasks.jsonにかかれた設定に基づいてビルドを行う。 Visual Studioのワークスペースフォルダ/.vscode/tasks.json を前のステップでコピーしたが、それを利用する。
WSLから、code と入力するとVisual Studio Codeが起動する。

起動したら、Micropyton のソースコードが含まれているフォルダを開き、CTRL+SHIFT+dを押す。(もしくはコマンドパレットから「ビルドタスクの実行」を選択する)

次の順番でビルドを実行する。

  1. SubmoduleのMake / ボード名
  2. ToolのMake / ボード名
  3. MicropthonのMake / ボード名
ubuntu1.png

ビルドが完了すると、
<プロジェクトルート>\micropython\ports\rp2\build-RPI_PICO
内に、firmware.uf2が生成される。

フォントの変更

Micropythonで使用するフォントを変更する場合、<プロジェクトルート>\micropython\ports\rp2\myModle\GFX.cpp を変更する必要がある。

ソースコード中、フォントをインクルードしている部分を変更する。

#include "../Kanji/Fonts/JF-Dot-Shinonome16_16x16_LEVEL1.inc"

の部分で、使用したいフォントをincludeする。

次に、ソースコードの220行目付近、loadDefaultKanjiFont メソッドの#defineを変更する。前の手順でincludeしたファイル内で定義されている構造体名を指定する。

	mp_obj_t loadDefaultKanjiFont(mp_obj_t a_Target)
	{
		if (!mp_obj_is_int(a_Target)) raise_mustInt();
		int iTarget = mp_obj_get_int(a_Target);

		msg_OnDebug("loadDefaultKanjiFont(%d)\r\n", iTarget);
#define KANJI_CODESET JFDotShinonome16_16x16_LEVEL1     ← この部分
#define KANJI_BITMAP JFDotShinonome16_16x16_LEVEL1_bitmap  ← この部分
		if (iTarget == 0) { // ターゲットが0なら、TFT
			pTFT->setFont(KANJI_CODESET, KANJI_BITMAP);
		} else { // ターゲットが0以外なら、キャンバス
			canvasTable[iTarget - 1].setFont(KANJI_CODESET, KANJI_BITMAP);
		}

この二カ所を変更すしてビルドすると、Micropythonで使用しているフォントが変更できる。


よくあるトラブル

WSLで apt upgradeを実行するとエラーが発生する

sudo apt upgrade 中に、Failed to take /etc/passwd lock: Invalid argumentというエラーが発生した場合、次のコマンドを実行し、問題が修正してから再実行する。 こちらも参照

~$ cd /bin
/bin$ sudo mv -f systemd-sysusers{,.org}
/bin$ sudo ln -s echo systemd-sysusers

何もしていないのにビルドに失敗するようになってしまった

ビルドに失敗したり、何かの操作を途中で中断すると次回からmakeが動かなくなってしまうことがある。その場合は、次のフォルダの中にあるファイルを削除し、中途半端に生成されたファイルを削除すること。(イタリック部分-RPI_PICOなどは、ビルド時の引数指定により異なる。通常、複数あった場合にはすべて削除してよい。

  • レベル1
    E:\work\PythonMod\micropython\ports\rp2\build-RPI_PICO\CMakeCache.txt
    E:\work\PythonMod\micropython\ports\rp2\build-RPI_PICO\generated フォルダ

  • レベル2
    レベル1に加え、次のフォルダを削除する
    E:\work\PythonMod\micropython\mpy-cross\build

  • レベル3
    E:\work\PythonMod\micropython\ports\rp2\build-*RPI_PICO フォルダすべて

ユーザーモジュールが組み込まれない

Raspberry Pi Pico上でサンプルプログラムを実行しても、KNJGfxモジュールのインポートができない場合には次のようなエラーが発生する。

ImportError: no module named 'KNJGfx'

この場合、makeコマンドで指定している引数
USER_C_MODULES=/e/work/PythonMod/micropython/ports/rp2/myModule/micropython.cmake
のファイルが存在するか、内容が正しいかを確認する。

問題がない場合、ビルドのログでユーザーモジュールが認識されているかを確認する。ビルドログの前半(30秒頃)に、組み込まれたユーザーモジュールが表示されている。

    :
Including User C Module(s) from /e/work/PythonMod/micropython/ports/rp2/myModule/micropython.cmake
Found User C Module(s): KNJGfx
-- Configuring done (32.3s)
   :
  • Found User C Module(s): KNJGfx としてKNJGfxが表示されている場合、モジュールは正常に組み込まれているので、ファームウェアのコピーが正しく行われているか、Python側のサンプルプログラムに誤りが無いかを確認する
  • Found User C Module(s):  とだけ表示されている場合、モジュールは組み込まれていないので、makeの引数や、cmakeファイルを再度確認する
  • この行自体が存在しない場合、ビルドフォルダ(build-*RPI_PICO)を削除して、再度完全にビルドする。

MP_QSTR_XXXXでビルドエラーが発生する

GFXModule.cのMP_DEFINE_CONST_FUN_OBJ_nではエラーが発生せず、MP_QSTR_XXXXマクロでだけエラーが発生することがある。

GFXModule.c:67:22: error: 'MP_QSTR_InitHW' undeclared here (not in a function); did you mean 'MP_QSTR_init'?

この場合、コンパイル後のオブジェクト間でUSE_MICROPYTHON_MODULEのシンボルの整合性が取れていない可能性がある。この場合、E:\work\PythonMod\micropython\ports\rp2\\build-*RPI_PICO フォルダすべてを削除し、完全なビルドを行う。 (make cleanはあてにならない・・・)

ビルド時にcyw43-driver not initializedのエラーが発生する

ビルドの際に、次のようなエラーが発生することがある。

CMake Error at CMakeLists.txt:391 (message): cyw43-driver not initialized. Run 'make BOARD=RPI_PICO_W submodules'

この場合、submoduleのmakeと、本体のmakeでターゲットボードが異なっている。

一度、submoduleのビルドに戻り、git submodule update --initを実行してサブモジュールをリセットしてから、正しいBOARD引数(MicroPythonのビルドで使用したものと同じ引数)を使用して再ビルドを行う)

権利に関する表記

このライブラリは、Adafruitのグラフィックライブラリを改変して作成されました。
Adafruitのライブラリは、2条項BSDライセンスに基づきソースコードの再配布が許可されています。
Micropythonは、MITライセンスに基づきソースコードの再配布が許可されています。
(MITライセンスと二条項BSDライセンスは同じ)

これに基づいて、本ライブラリの権利も同じ2条項BSDライセンスに基づくものとします。

1
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
1
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?