電子ブロック工房 https://www.rad51.net/blog/mycom/ IC・トランジスタで出来たコンピューターを設計・製作するためのブログ ja Jeans CMS © Weblog http://backend.userland.com/rss https://www.rad51.net/jeans/skins/jeans/images/jeans2.gif 電子ブロック工房 https://www.rad51.net/blog/mycom/ Raspberry Pi Pico用のC/C++ビルド環境を構築する https://www.rad51.net/blog/mycom/?itemid=988 MachiKania のソースコードからビルドする方法について述べるが、他の Raspberry Pi Pico 用のプログラムでも同じであり、また、Pico 2, Pico W, Pico 2 W にも対応できる。

Raspberry Pi Pico 用のソースコードからビルドするには、VS code の extension を用いる方法があるが、私自身がその extension の中身をよく理解しておらず、どういう操作を行っているか分からないので、使っていない。この記事でも、VS code は使わず、必要なソフトウェアーを個々に揃えて利用する方法をとる。

success.png
(画像は、ビルドに成功した時のスクリーンショット)


必要なツール

Raspberry Pi Pico 用の C/C++ プログラムをビルドするのに必要なツールは以下の通り。

1.Git
2.pico-sdk
3.CMake
4.MinGW
5.ARM CC (ARM C コンパイラー)
6.Python

Git は、バージョン管理システムと呼ばれるもので、多くのソフトウェアーが Git で管理されている。次に述べる pico-sdk が Git で管理されているため、これが必要になる。また、目的の C プログラムをビルドするときにも、Gitが必要になる場合がある。

pico-sdk は、Raspberry Pi Pico 向けの C/C++ 開発用ソフトウェア開発キットだ。必要なライブラリーを含んでおり、ビルドの方法も提供する。

CMake は、ソフトウェアプロジェクトの構築を管理するためのクロスプラットフォームツールだ。プロジェクトの構造や依存関係を記述するスクリプトを基にプラットフォームに応じたビルドシステム生成するためのものだ。

MinGW(Minimalist GNU for Windows)は、Windows 向けの軽量な開発環境で、GNU コンパイラコレクション(GCC)を使用して C、C++ などのプログラムをコンパイルするためのツールである。

ARM CC (ARM C Compiler)は、Raspberry Pi Pico で採用されている CPU、ARM cortex M0+ もしくは ARM cortex M33 用に、C/C++ ソースコードをコンパイルするためのコンパイラーだ。

Python は汎用性の高いプログラミング言語で、シンプルな構文と豊富なライブラリが特徴である。pico-sd によるビルドの際にもこれが使われる。

では、順番に見ていく。ここでは、これらのツールのうち Windows のインストーラーを用いてインストールするのは Git のみで、他のものは ZIP アーカイブをダウンロードして、解凍してできたファイル群を特定のフォルダーに配置する形をとる。

環境によっては、Git や Python などがすでにインストール済みであったりするケースもあるだろうが、その場合はそれぞれの項をスキップしていただきたい。また、それぞれのツールのインストール先、配置先が異なる場合は、後に説明するパス指定を、適宜修正する必要がある。

Git

Windows 用の Git は、次の場所から入手できる。
https://git-scm.com/downloads/win
64-bit Windows 用には「Click here to download」もしくは「64-bit Git for Windows Setup」をクリックすれば、インストーラーがダウンロードされる。2025/03/15 現在、「Git-2.48.1-64-bit.exe」である。

インストーラーをダウンロードしたら、ダウンロードファイルをダブルクリックしてGitをインストールする。基本的にデフォルトの設定のまま「Next」ボタンを押し続けてインストールすればよい。
Git.png

pico-sdk

Git をインストールすると、スタートメニューの検索欄に「git bash」と打つことで、次のようなアプリケーションが出るようになっているはずだ。これをクリックして、起動する。
gitClone.png
このコンソール上で、順に「cd Desktop/」 「git clone --recurse-submodules https://github.com/raspberrypi/pico-sdk.git」とタイプする。デスクトップ上に「pico-sdk」が現れる。すべてのファイルを取得するのに、数分かかる。エラー無く作業が済めば、「pico-sdk/libs」内にある5つのフォルダー(btstack, syw43-driver, lwip, mbedtls, tinyusb)のすべてが、空ではなくファイル・フォルダーが含まれている状態になっているはずなので、確認する。もし空のフォルダーがあれば、「git clone」に失敗しているので、一度「pico-sdk」フォルダー全体を削除してやり直す。

ここでは、「pico-sdk」フォルダーを「c:\pico」に移動して使用することとする。「c:\」に「pico」という名で新規にフォルダーを作成し、デスクトップ上の「pico-sdk」をそこに移す。

「c:\pico\pico-sdk」フォルダーの中身は、次のようになる。
picoSdkFolder.png

CMake

Windows 用の CMake は、次の場所で手に入る。
https://cmake.org/download/
「Latest Release」のZIPアーカイブのものを選べばよい。ここでは、Windows x64 ZIP(cmake-3.31.6-windows-x86_64.zip)を選んだ。

ZIPアーカイブに含まれているフォルダーを展開し、フォルダー名を「cmake」に変更して、「c:\pico」に移す。「c:\pico\cmake」フォルダーの中身は、次のようになっている。
cmakeFolder.png

MinGW

MinGW (MinGW-w64)は、次の場所で手に入る。
https://winlibs.com/
Web ページの上から4分の1ぐらいのところに、「Help! I don't know which download to choose!(助けて!どのダウンロードファイルを選択したらよいかわからない!)」 「Don't worry. For most purposes the latest Windows 64-bit release version with MSVCRT runtime and POSIX threads is a good choice.(心配しないで。ほとんどの目的には、MSVCRTとPOSIX対応の64ビットバージョンを選ぶのがよい選択だよ!)」という記述の後に「Download it here.(ここで、それをダウンロード)」というリンクがあるので、それを選ぶ。ここでは、「winlibs-x86_64-posix-seh-gcc-14.2.0-mingw-w64msvcrt-12.0.0-r3.zip」をダウンロードした。

ダウンロードした ZIP アーカイブには「mingw64」というフォルダーがあるので、それを解凍して「c:\pico」に展開する。「c:\pico\mingw64」フォルダーの中身は、次のようになる。
migw64Folder.png

ARM CC

ARM C コンパイラーは、次の場所で手に入る。
https://developer.arm.com/downloads/-/gnu-rm/product-release
Windows 用の ZIP アーカイブを選択する。2025/03/15現在、最新版は「Version 10-2020-q4-major」なので、ここでは「gcc-arm-none-eabi-10-2020-q4-major-win32.zip」を選んだ。

ZIP アーカイブのフォルダーを解凍し、フォルダー名を「gcc-arm」に変更して、「c:\pico」フォルダーに移す。「c:\pico\gcc-arm」フォルダーの中身は、次のようになる。
gccFolder.png

Python

Python は、次の場所で手に入る。
https://www.python.org/downloads/windows/
「Windows installer」ではなく、「Windows embeddable package」を選ぶ。ここでは、「python-3.13.2-embed-amd64.zip」を選択した。

「c:\pico」フォルダーに「python」という名のフォルダーを作成し、そこにZIPアーカイブのすべてのファイルを展開する。「c:\pico\python」フォルダーの中身は、次のようになる。
pythonFolder.png

ソースコードを入手して配置

必要なツールのインストールが終了したので、いよいよビルドの準備を行う。まず、ソースコードを入手して、配置する。次の場所から、開発中の MachiKania を入手する。
https://github.com/machikania/phyllosoma/tree/production
「Code:」ボタンを押して、「Download ZIP」を選択すると、「phyllosoma-production.zip」がダウンロードできる。

ダウンロードしたZIPアーカイブの「phyllowoma-production」フォルダーを解凍し、フォルダー名を「phyllosoma」に変更して「c:\pico」フォルダーに移す。「c:\pico\phyllosoma」フォルダーの中身は、次のようになる。
phyllosomaFolder.png

ビルド用のフォルダーを作成

「c:\pico」フォルダーに、「build」という名で新規にフォルダーを作成する。このフォルダー内に、「cmake.bat」 「make.bat」の2つのバッチファイルを作成する。バッチファイルの中身は、次の通り。

cmake.bat
@cd "%0\.."
@SET PATH=%PATH%c:\pico\cmake\bin;c:\pico\gcc-arm\bin;c:\pico\mingw64\bin;
@SET PICO_SDK_PATH=c:\pico\pico-sdk
@SET PARAMS=
@SET PARAMS=%PARAMS% -DPython3_EXECUTABLE="c:\pico\python\python.exe"
@SET PARAMS=%PARAMS% -DPICO_BOARD=pico -DPICO_PLATFORM=rp2040
cmake.exe -G "MinGW Makefiles" %PARAMS% ..\phyllosoma
pause

make.bat
@cd "%0\.."
@SET PATH=%PATH%c:\pico\cmake\bin;c:\pico\gcc-arm\bin;c:\pico\mingw64\bin;
mingw32-make
pause

ただし、これらのバッチファイルの中で、「cmake」 「gcc-arm」 「mingw64」 「pico-sdk」 「python」のインストール先を指定している。もしこれらが実際の場所と異なる場合は、適宜書き換える必要がある。また、「..\phyllosoma」はソースコードを含むフォルダーの指定なので、これが異なる場合も、書き換えなければならない。


「c:\pico\build」フォルダーの中身は、次のようになる。
buildFolder.png

これで、すべての準備ができた。「c:\pico」フォルダーの中身は、次のようになった。
picoFolder.png

いよいよビルド

まず、「c:\pico\build」フォルダーに作った「cmake.bat」のアイコンをダブルクリック。エラーなしに終了すると、次のような結果になる。
cmake.png

次に、「make.bat」のアイコンをダブルクリックすると、ビルドが開始される。1分から数分でビルドが終了し、エラーがなかった場合、次のような結果になる。
make.png

上記のような結果でビルドがうまく行くと、「c:\pico\build」フォルダーに、「phyllosoma.uf2」と「phyllosoma_kb.uf2」の2つのバイナリーが作成されているが、これらがビルドできたファームウェアーだ。「BOOTSEL」ボタンを押しながら Raspberry Pi Pico を USB スロットに差し込むと、「RPI-RP2」もしくは「RP2350」ドライブが出現する。ここに「*.uf2」ファイルをドラッグ&ドロップすると、これらのファームウェアーが Raspberry Pi Pico に書き込まれる。

Pico 2, Pico W, Pico 2 W 用のビルド

上記で説明した方法は、Raspberry Pi Pico 用のビルドであるが、Pico 2, Pico W, Pico 2 W用のビルドもできる。「cmake.bat」の内容で「-DPICO_BOARD=pico -DPICO_PLATFORM=rp2040」の部分をそれぞれ、次のようにすればよい。
Pico:     -DPICO_BOARD=pico -DPICO_PLATFORM=rp2040
Pico2:    -DPICO_BOARD=pico2 -DPICO_PLATFORM=rp2350-arm-s
Pico W:   -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040
Pico 2 W: -DPICO_BOARD=pico2_w -DPICO_PLATFORM=rp2350-arm-s

また、「build」というフォルダー名ではなく「build_pico2」などの名でフォルダーを作って「cmake.bat」 「make.bat」を配置すれば、4つの異なる Raspberry Pi Pico 用のファームウェアーをそれぞれ別々に作成することも可能である。

ソースコードに変更があった場合のビルド

ソースコードに変更があった場合は、「make.bat」を実行しなおすだけでよい。「cmake.bat」の実行は不要である。

SDKに変更があった場合のビルド

pico-sdk に変更があった場合は、「c:\pico\build」ディレクトリーにあるファイルのうち、「cmake.bat」 「make.bat」以外のファイルを全部削除し、「cmake.bat」の実行からやり直す。これをやらないと、おかしなファームウェアーがビルドされる可能性がある。]]>
Raspberry Pi Pico https://www.rad51.net/blog/mycom/?itemid=988 Sat, 15 Mar 2025 21:26:43 PDT ITEM988_20250315
MachiKaniaの「auxcode」機能について https://www.rad51.net/blog/mycom/?itemid=987
MachiKania では、BASIC で様々なことを行う機能を提供してきた:

1.液晶ディスプレイや NTSC ビデオに、(日本語を含む)文字やグラフィックスを容易に表示
2.キーボードを接続して、BASIC コードを編集しながら実行する、スタンドアローンPCとしての機能
3.SPI・I2C・UART などの I/O 機能を、BASIC コードから容易に使用する方法を提供
4.複雑な動作を行うコードを、容易に利用するためのクラスライブラリーを提供

ここで書いた3の部分は、MachiKania 本体で提供、4の部分はクラスで提供している。ほとんどのクラスが BASIC で書かれているが、いくつかは C で書かれたコードを BASIC から呼び出す形をとっている(方法1方法2)。

C で書かれたコードの中には、容易に MachiKania から呼び出すように修正できるものもあれば、そういったことが非常に難しいものがある。例えば、RP2040 の PIO 機能を使ったものは、BASIC で利用できるように実装するのは非常に難しい。

「auxcode 機能」は、そういった C のコードを MachiKania で実行できるようにするものだ。「auxcode 機能」を使うには MachiKania 本体のビルドが必要になるが、どうしても必要な機能を MachiKania に取り込むのには汎用性が高いと言える。

auxcode 機能を使うには

auxcode 機能は、MachiKania 本体に次のような機能追加を行うものだ

1.BASIC ステートメントの追加
2.整数型関数の追加
3.文字列型関数の追加
4.浮動小数点型関数の追加
5.上記ステートメント・関数を実行する機能の追加

auxcode 機能はすべて、ソースコード中の「auxcode」ディレクトリーに収める形で提供する。MachiKania のソースコードにはデフォルトで auxcode ディレクトリーがあり、そこには次の2つのファイルが収められている。

  auxcode.c
  auxcode.cmake

これらのファイルは、デフォルトでは次の通り。

auxcode.c
#include "pico/stdlib.h"
#include "../compiler.h"

int aux_statements(void){
	return ERROR_STATEMENT_NOT_DETECTED;
}
int aux_int_functions(void){
	return ERROR_STATEMENT_NOT_DETECTED;
}
int aux_str_functions(void){
	return ERROR_STATEMENT_NOT_DETECTED;
}
int aux_float_functions(void){
	return ERROR_STATEMENT_NOT_DETECTED;
}
int lib_aux(int r0, int r1, int r2){
	return r0;
}

auxcode.cmake
add_library(aux_files
	auxcode/auxcode.c
)
target_link_libraries(aux_files 
	pico_stdlib
)

auxcode.c に書かれている5つの関数は、少し上のパラグラフで述べた5つの機能に相当する。auxcode.cmake は、デフォルトの auxcode.c をコンパイルするための、必要最小限の構成である。追加する機能は、これらのファイルを編集し、必要であればファイルを追加する。

auxcode 機能の使用例

ここでは、どのようにして auxcode 機能を使うのか、使用例を挙げて説明する。次のレポジトリーでは、HB01B0 というカメラを MachiKania で使うためのコードを、収めた。
https://github.com/kmorimatsu/hm01b0_machikania
追加したい機能は、以下の通り

1.HM01B0_INIT ステートメント
2.HM01B0_CAPTURE ステートメント
3.HM01B0_DRAW ステートメント
4.HM01B0_REG_WRITE ステートメント
5.HM01B0_ZOOM ステートメント
6.HM01B0_CAPTURE ステートメント
7.HM01B0_ANALYZE([x]) 関数(整数型)

上記の目的のため、次のコードを用意する。

1.上記1-6のステートメントを BASIC コンパイラーが認識できるように、「aux_statements()」関数を編集
2.上記7の関数を BASIC コンパイラーが認識できるように、「aux_int_functions()」関数を編集
3.上記1-7の構文を実行する際に呼び出されるコードを記述
4.カメラを制御するための C コードを、修正して追加
5.MachiKania のビルドの際に、追加の C ファイルがコンパイルされるように、auxcode.cmake を編集

順に見ていこう。

1.ステートメントを認識させる

hm01b0_machikania の auxcode.c の、aux_statements() 関数は次の通り。
int aux_statements(void){
	if (instruction_is("HM01B0_INIT")) return hm01b0_init_statement();
	if (instruction_is("HM01B0_CAPTURE")) return hm01b0_capture_statement();
	if (instruction_is("HM01B0_DRAW")) return hm01b0_draw_statement();
	if (instruction_is("HM01B0_REG_WRITE")) return hm01b0_reg_write_statement();
	if (instruction_is("HM01B0_ZOOM")) return hm01b0_zoom_statement();
	return ERROR_STATEMENT_NOT_DETECTED;
}

ステートメントを認識させるには、ここで
  「if (instruction_is("HM01B0_INIT"))」
のように記述する。続けて、
  「return hm01b0_init_statement();」
の例のように続ける。

「hm01b0_init_statement()」は、次のように書かれている。
int hm01b0_init_statement(void){
	// The first argument is the pointer to video buffer (324*324 bytes)
	return argn_function(LIB_AUXCODE,
		ARG_INTEGER<<ARG1 |
		LIB_AUX_HM01B0_INIT<<LIBOPTION);
}

コメントにあるように、「HM01B0_INIT」ステートメントは、整数型の引数を一つ取る(ポインターを整数として処理)。
  「ARG_INTEGER<<ARG1」
の部分の記述は、そのためのものだ。引数が文字列なら「ARG_INTEGER」ではなく「ARG_STRING」と、浮動小数点型なら「ARG_FLOAT」とする。

「LIB_AUXCODE」は、BASIC コードを実行中に制御を「lib_aux()」に移すために必要なので、そのままにして使う。また、
  「LIB_AUX_HM01B0_INIT<<LIBOPTION」
は「lib_aux()」内で「HM01B0_INIT」ステートメントの実行であることを認識させるために必要なコードで、
  「LIB_AUX_HM01B0_INIT」
等にはそれぞれ、固有の値を割り当てておく。

2.関数を認識させる

「aux_int_functions()」関数は、次の通り。
int aux_int_functions(void){
	if (instruction_is("HM01B0_ANALYZE(")) return hm01b0_analyze_function();
	return ERROR_STATEMENT_NOT_DETECTED;
}

上の「aux_statements()」の例と同様だが、「"HM01B0_ANALYZE("」のように、「(」が付加されている。文字列型関数の場合は「"XXXX$("」のようにして「aux_str_functions()」に記述、浮動小数点型関数の場合は「"XXXX#("」のようにして「aux_float_functions()」に記述する。

「hm01b0_analyze_function()」関数は、次のように記述されている。
int hm01b0_analyze_function(void){
	// The first argument is number of raws to analyze (default 240).
	g_default_args[1]=240;
	return argn_function(LIB_AUXCODE,
		ARG_INTEGER_OPTIONAL<<ARG1 |
		LIB_AUX_HM01B0_ANALYZE<<LIBOPTION);
}

ここで実装する「HM01B0()」関数の引数は実数値で、省略された場合のデフォルト値は240である。そういった場合は、
  「g_default_args[1]=240;」
のようにデフォルト値を指定したのちに、
  「ARG_INTEGER_OPTIONAL<<ARG1」
のように記述して対処する。

3.構文を実行する際に呼び出されるコードを記述する

ステートメントや関数を実行する際に呼び出されるコードは、「lib_aux()」関数内に記述する。
int lib_aux(int r0, int r1, int r2){
	switch(r2){
		case LIB_AUX_HM01B0_INIT:
			hm01b0_init((uint8_t*)r0);
			break;
(略)
		case LIB_AUX_HM01B0_ANALYZE:
			return (int)hm01b0_analyze(r0);
			break;
		default:
			break;
	}
	return r0;
}

この C 関数は、r0, r1, r2 という3つの引数を持つが、これらは、CPU (ARM Cortex-M0+) のレジスター値である。r2 に上で述べた「LIBOPTION」の値が入っているから、それで分岐して使う。

ここで紹介している「HM01B0_INIT」と「HM01B0_ANALYZE」というステートメント・関数は、引数が1つだ。そういう場合は、引数は「r0」に格納されている。なお、引数が2つの場合は第一引数が「r1」、第二引数が「r0」に格納される。引数が3個以上の場合は最後の引数が「r0」に、それ以外の引数は「r1」ポインターで指定される配列に格納される。

ここではそれぞれ、「hm01b0_init()」と「hm01b0_analyze()」という関数を呼び出すようになっている。これらは、別のCファイル(hm01b0.c)で記述されている。

4.C ファイルを追加する
多くの場合、auxcode.c という単一のファイルにすべてのコードを収めることはできないだろう。機能の実装のために、複数の C ファイルを auxcode ディレクトリーに展開することになる。

hb01b0_machikania の場合、auxcode ディレクトリーに含まれるCファイルは次の3つである。
  auxcode/auxcode.c
  auxcode/hm01b0.c
  auxcode/arducam/arducam.c
必要な機能の実装のために、これらのCファイルは別のところからコピーして修正するか、自分で一から書いて使うことになる。

5.C ファイルをビルドの際に認識させる

デフォルトでは MachiKania のビルドの際に「auxcode.c」しかコンパイルされないので、「hm0xb0.c」と「arducam.c」もコンパイルされるように指定する。これには、「auxcode.cmake」ファイルの編集が必要だ。

例では、「auxcode.cmake」ファイルは次の通り。
add_library(aux_files
	auxcode/auxcode.c
	auxcode/hm01b0.c
	auxcode/arducam/arducam.c
)
target_link_libraries(aux_files 
	pico_stdlib
	hardware_dma
	hardware_i2c
	hardware_pio
	hardware_pwm
)
pico_generate_pio_header(aux_files ${CMAKE_CURRENT_LIST_DIR}/image.pio)

「add_library()」に、コンパイルが必要な C ファイルを追加する。それぞれで使用する必要な Pico の機能(hardware_i2cやhardware_pwm等)については「target_link_libraries()」に追加する。例では PIO も使っているので、それに必要な行(pico_generate_pio_header)も追加されている。

C のプログラムを MachiKania にどんどん取り込もう

Raspberry Pi Pico 用の周辺機器には、C でサンプルプログラム等が供給されているものが多い。簡単なものなら BASIC に移植して MachiKania で使えるが、多くの場合は簡単には移植できない。そういった C のコードでも「auxcode」機能を使えば MachiKania でも使えるようになるものは、多いだろう。この機能を利用して、より多くの周辺機器が MachiKania で使えるようになることを期待する。]]>
MachiKania https://www.rad51.net/blog/mycom/?itemid=987 Sun, 02 Mar 2025 18:07:17 PST ITEM987_20250302
MachiKania type PU を公開 https://www.rad51.net/blog/mycom/?itemid=986

MachiKania type PU を、公開しました。
GitHub リリースページはこちら
公式ホームページはこちら

MachiKania type PU は、MachiKania type P の姉妹バージョンです。type P は、ILI9341 等の液晶ディスプレイに表示しますが、type PU では NTSC のビデオ画面に表示するようにしました。これにより、大画面での表示が可能になりました。

typePU2.png

液晶ディスプレイではなく NTSC ビデオ出力にした事で、回路が type P より簡潔になっています(回路図は、GitHubページのpuerulusの項を参照)。NTSC ビデオ出力は、抵抗1本とコンデンサー1個の簡単なものです。上の写真は、私の type PU のプロトタイプ版です(Raspberry Pi Pico は、外してあります)。Pi Pico 用のソケット以外は、micro SD のソケット、NTSC 用のプラグ、タクトスイッチ、圧電ブザーと、少数の抵抗・コンデンサーだけです。

XIAO-RP2040 等のピン数が少ない基板でも画面表示が出来るようになったので、これらの小さな基板を使った組込み開発が容易になりました。現在の所、次のマイコン基板に対応しています。

・Raspberry Pi Pico
・Raspberry Pi Pico W
・Raspberry Pi Pico 2
・Seeed studio XIAO RP2040
・Pimoroni Tiny 2040
・Waveshare RP2040-Zero
・Seeed studio XIAO RP2350
・Pimoroni Tiny 2350
・Waveshare RP2350-Zero

keyboard.png

また、type P と同様、USB キーボードに接続可能です。これにより、MachiKania type PU・NTSC モニター・USB キーボードによるスタンドアローンな BASIC プログラム開発環境を構築することができます。BASIC は今まで通りコンパイラーなので、高速実行が可能です。

開発裏話

Type PU 開発のきっかけは、Twitter でらびやんさんの、Raspberry Pi Pico による NTSC ビデオシグナル作成デモを見た事です。
lovyan03.png
これを、なんとか MachiKania に取り込めないかと言う事で、らびやんさんとライセンスの交渉をし、MIT ライセンスとして使わせていただくことができるようになりました。

その後、ケンケンさんと私の双方で、この NTSC ビデオ信号プログラムを MachiKania に取り込む方法を模索しました。ケンケンさんは Raspberry Pi Pico の1ボードで MachiKania と NTSC ビデオルーチンの両方を実装、私は、2枚の Raspberry Pi Pico ボードをそれぞれ MachiKania と NTSC ビデオルーチンに割り当てて並列で実行する方法です。最終的にケンケンさんがうまく行った方法を取り入れる事になりました。

この、NTSC 版 MachiKania の開発コードは、ケンケンさん命名で、"puerulus"です。Wikipediaによると、puerulusというのはイセエビの幼生で、phyllosoma から一段発生が進んだものらしいです。MachiKaniaの開発コードは、nauplia -> zoea -> megalopa -> phyllosoma -> puerulus と、甲殻類の発生をなぞっています。ちなみに、MachiKania は、待兼山と言う地名にちなんだ造語です。

MachiKania のソースコード管理はずっとオープンでやってきて、初期のころは SVN で、今は Git(GitHub) でソースコードの管理を行っています。puerulus のソースコードと phyllosoma のソースコードで異なるのは、モニター表示部分だけ(NTSC 出力か LCD 出力か)です。ソースコードを別々に管理すると、今後のアップデートの際に同じ変更を両方のコードに対して行う事になり、煩雑なだけでなく、思わぬバグを混入してしまう原因となります。そこで、puerulus のソースコードと phyllosoma のソースコードを統合して一つにし、config の設定を変えることで type PU をビルドするのか、type P をビルドするのか、選択できるようにしました。Type PU の公式版の公開が、ケンケンさんのテスト版の公開から3か月以上遅れたのは、統合化に時間がかかったのが大きな理由です。ソースコードの統合により、Pico だけでなく Pico 2 にも対応できることが分かり、それによる微修正等を行っていたこともありますが。

MachiKania type PU の正式公開に伴って、同じ NTSC ビデオ出力版の type Z とtype M の開発を終了する事になりました。もともと、ずっと新規バージョンを公開していなかったので、実質的に開発は中断状態だったのですが、ケンケンさんとの相談で、完全に開発停止する事になりました。

今後の MachiKania の発展は、type P と type PU で行っていくことになります。使っていただいている皆様、今後とも、MachiKania をご贔屓に、よろしくお願いします。]]>
MachiKania https://www.rad51.net/blog/mycom/?itemid=986 Sat, 28 Dec 2024 15:47:25 PST ITEM986_20241228
Raspberry Pi Picoを使った赤外線リモコンと受信機 https://www.rad51.net/blog/mycom/?itemid=984 20240525-controller.jpg
20240525-receiver.jpg

赤外線リモコン

リモコン(送信機)の回路図は、以下の通り。
20240525-schematic1.png

3V の電池駆動で、いずれかのボタンを押したときに回路図上側の MOSFET(2N7000) がアクティブになり、Pi Pico に給電される仕組み。この回路では、ボタンを押さないときの消費電流は最小限(測定すると、30 μA ほど)に抑えられているため、まったく使わなければ3年ほどは持つ計算。

赤外線 LED の駆動には、Pi Pico の昇圧回路から発生する 3.3 V を使っているため、電池が少々減っても、安定した出力が期待できる。昇圧回路の発振ノイズを軽減するため、47 μF のキャパシターを接続してある。このキャパシターは、発信機と受信機の距離が短いときのシグナル認識を向上させるようだ。LED の駆動は、回路図下側の MOSFET で行っている。LED と直列に接続している抵抗(10-150 Ω)の値をどれぐらいにすればよいのかは、使用する LED によって異なる。私が使った LED では、30 Ωぐらいが一番成績が良かった。なお、使用する LED が発する赤外線の波長は、赤外線リモコンでは一般的に 950 nm 付近が使われるようである。

リモコンのボタン数を作例では 7 個としたが、用途によって最大 25 個まで増やすことができる。各々にダイオードを接続して、MOSFET のゲートに繋げればよい。マトリックスを組めば、より多くのボタンの押下を認識することができるはず(ただし、ソースコードの大々的な変更が必要)。

Pi Pico のソースコードは、以下の GitHub レポジトリーに載せた。自分の用途に応用するには、main.c の「#define BUTTON_INPUT_MASK」の部分と「// Check button」以降の部分を編集して、ビルドする事。
https://github.com/kmorimatsu/ir_controller

赤外線受信機

リモコン受信機の回路図は、以下の通り。
20240525-schematic2.png

この回路図では、赤外線センサーからの入力のみしかないように見えるが、実際は、出力は USB を介して PC に送信される。PC に接続するバーチャルキーボードとして機能する。

赤外線センサーは、手元にある Sharp 製の GP1UD26XK を使用した。既に廃番になっているが、アクティブローで 3.3 V で機能する物であれば、殆どの物が使えると思われる。ただし、38 kHz 点滅の 950 nm 付近の赤外線に反応する物を選ぶこと。

Pi Pico のソースコードは、GitHub に上げた。
https://github.com/kmorimatsu/ir_receiver_keyboard

どの赤外線データーを認識させるかは、input.c 内の check_button() 関数内のコードを編集する。また、バーチャルキーボードとして、どのキーを送出するかを変更するには、main.c 内の hid_task() 関数内、「bool button_0 = check_button(0);」等の記述と、「if ( button_0 )」などの記述以降の行を、編集する。

32 ビットデーターの取得

ここで利用している 32 ビットの送受信データーは、MachiKania を持っている人であれば、IR_RX クラスを用いて、簡単に取得することができる。IR_RX クラスのヘルプファイルに使用例があるので、それをそのまま用いればよい。ただし、MachiKania に赤外線受信モジュールを接続する必要がある。

MachiKania を持っていないけれど、上の赤外線受信機を作成した人なら、次のようにしてデーターを抽出する事が可能。

1.ここから、uf2 ファイルを含むアーカイブをダウンロード
2.uf2 ファイルを、Pi Pico にアップロード
3.Pi Pico が COM ポートとして認識されるので、PuTTY や Tera Term などのシリアルコンソールで接続する
4.赤外線受信機に向けて、赤外線リモコンから送信する]]>
Raspberry Pi Pico https://www.rad51.net/blog/mycom/?itemid=984 Sat, 25 May 2024 15:35:19 PDT ITEM984_20240525
MachiKania type P ver 1.4 を公開 https://www.rad51.net/blog/mycom/?itemid=982
公式ページはこちら
GitHub リリースページはこちら

ReadMeに記載した更新履歴は、次の通りです。
Phyllosoma 1.40/KM-1505 (2024.2.17)
 ・サンプルプログラムに、FILEMAN.BAS(ファイルマネージャー)を追加。
 ・クラスライブラリーに、BUTTON(ボタン操作), GEN3O(源ノ角ゴシック表示), 
  QRCODE(QRCODE表示), TSC2046(タッチパネル操作)を追加。
 ・液晶を使わない場合に、SPI命令でspi1を使う事を可能にした。
 ・PUTBMP命令で、横幅が長い画像を表示する際の不具合を修正。
 ・ファイル一覧表示の際、ファイル更新日時の表示を可能にした。
 ・ファイル一覧表示の際の、ファイル名・ファイル更新日時による表示順に対応。
 ・ILI9488液晶で縦置の際の表示不具合を修正。
 ・FRENAME, MKDIR命令及びFRENAME(), MKDIR()関数の追加。
 ・補助コード(auxcode)を追加できる機能を実装

ファイルマネージャーの同梱と、ファイル一覧の機能向上

今回の目玉機能は、ファイルマネージャーを同梱した事です。これにより、スタンドアローン機としての最低限の機能は、ほぼそろった事になります。PC と連携しなくても MachiKania のみで、一通りの事は出来るようになったと思います。ファイルマネージャーはサンプルプログラムとして、「FILEMAN.BAS」の名で保存されていますので、選択して実行してください。なお、ファイルマネージャーは USB キーボード版で利用できます。

また、ファイル一覧表示の際に、ファイル名順やファイル作成時刻順で表示できるようになりました。今までは、MMC/SDカードに保存のファイル数が多くなると、目的のファイルを見つけ出すのに苦労しましたが、そういった苦労なしで見つけることができるようになりました。加えて、ファイル作成時刻を閲覧する事も出来るようになりました。

auxcode機能

MachiKania で、C で書いたコードを実行する方法として、今まで2つの方法を提供してきました(方法1方法2)。これらの方法では、クラスファイルを作成することができるので、いったんクラス化してしまえば、BASIC プログラムから取り込んで呼び出すことが可能です。ただ、クラス化するにあたって色々とコツが必要で、場合によってはうまくクラス化できないようなケースもあります。

そこで、MachiKania をソースコードからビルドする際に、補助機能を追加してビルドする事で、さまざまな種類の C コードを取り込めるようにしました。「auxcode」と名付けた機能が、それです。

ver 1.4 以降の MachiKania のソースコードには、「auxcode」という名のディレクトリーがあります(GitHub 該当ページはこちら)。デフォルトでは「auxcode.c」と「auxcode.cmake」の2つのファイルがありますが、これを書き換えた後に、MachiKania 全体をビルドすれば、補助機能が追加された MachiKania ができます。次のレポジトリーが、一例です。

https://github.com/kmorimatsu/hm01b0_machikania

これは、HM01B0 カメラを MachiKania で使うためのものです。このレポジトリーにある「auxcode」ディレクりーを MachiKania ソースコードに上書き保存してビルドすると、HM01B0 カメラに対応した MachiKania が作成されます。実行すると「HM01B0_INIT」「HM01B0_CAPTURE」「HM01B0_DRAW」「HM01B0_REG_WRITE」の4つの命令が追加で使えるようになり、それらを用いて HM01B0 カメラを制御したり画面に映像を表示したりできるようになります。

今後、MachiKania の新しいバージョンが公開された際にも、「auxcode」を新しいバージョンのソースコードにコピーしてビルドしなおすことで、将来のバージョンにも対応できます。「auxcode」の書き方は、HM01B0 の例を参考にしてください。リクエストがあれば、書き方についてもブログ記事を書くかもしれません。

追加のクラスライブラリー

BUTTON, GEN3O, QRCODE, TSC2046 の4つのクラスを、クラスライブラリーに追加しました。それぞれ、

・BUTTON は、6つあるボタンの読み取りを容易にする
・GEN3O は、CKNJ16 より大きなサイズのフォントを表示する
・QRCODE は、文字通り QRCODE を画面に表示する
・TSC2046 は、タッチパネルを利用する

際に、便利に使えるものです。今後も、クラスライブラリーを充実させていく予定です。]]>
MachiKania https://www.rad51.net/blog/mycom/?itemid=982 Fri, 16 Feb 2024 19:19:19 PST ITEM982_20240216
MachiKania type P ver 1.3 に、天気予報を喋らせる https://www.rad51.net/blog/mycom/?itemid=981
作例として、天気予報の情報サイトからデーターを取ってきて、今日と明日の天気予報を得るような物を作ってみました。NTPから今日の日付も取ってこられるので、その情報も使います。今日の日付と天気予報は、画面に表示させるのではなくスピーカーで話させるようにしてみました。完成写真は、以下の通りです。小さな箱に、電源スイッチとスピーカーが取り付けられたものです。

2023-09-26-weatherBox.jpg

どんなものか

まずは、どんな動作をするのかの参考に、twitter.com に実行中の動画を載せましたので、ご覧ください(下の画像をクリックすると、twitter.comの該当ポストに移動します;音が出ます)。

2023-09-30-twitter.com.jpg

スイッチを入れておよそ10秒待つと、まず今日の日付と曜日、次に今日の天気予報と最高気温、続けて明日の天気予報と最低気温、最高気温を音声で知らせてくれます。紹介したものは英語のバージョンですが、日本語のバージョンも用意してあります。

箱の中身と、回路

箱の中は、こんな感じです。写真上は、電池・スピーカー・電源スイッチ。下は、Raspberry Pi Pico W。その左にあるDIP-8の石はアンプ IC (NJM2113D)です。

2023-09-30-inside1.jpg

別の角度からです。手前に見えるのは、micro-SDです。アダプターを、基板に半田付けしてあります。

2023-09-30-inside2.jpg

回路図は、下の通りです(クリックで、拡大)。Raspberry Pi Pico Wには、他にMachiKania の基本構成の通り、SDカードを接続しています。液晶ディスプレイは使用しないので、接続していません。

2023-09-30-schematic.png

プログラム

プログラムは、MachiKania BASIC で書かれており、「MACHIKAP.BAS」のファイル名で保存してあります。

useclass JSON,WGET
usevar Min0,Max0,Fnum0,Fstr0
usevar Min1,Max1,Fnum1,Fstr1

out 6,1

if val(strftime$("%Y"))<2023 then ntp

j$=WGET::FORSTRING$("https://dataservice.accuweather.com/forecasts/v1/daily/5day/332097?apikey=[AccuWeather API key]")
o=new(JSON,j$)

Min0=int(o.FQUERY#(".DailyForecasts[0].Temperature.Minimum.Value")+0.5)
Max0=int(o.FQUERY#(".DailyForecasts[0].Temperature.Maximum.Value")+0.5)
Fnum0=o.IQUERY(".DailyForecasts[0].Day.Icon")
Fstr0$=o.SQUERY$(".DailyForecasts[0].Day.IconPhrase")
Min1=int(o.FQUERY#(".DailyForecasts[1].Temperature.Minimum.Value")+0.5)
Max1=int(o.FQUERY#(".DailyForecasts[1].Temperature.Maximum.Value")+0.5)
Fnum1=o.IQUERY(".DailyForecasts[1].Day.Icon")
Fstr1$=o.SQUERY$(".DailyForecasts[1].Day.IconPhrase")

do
  c=coretimer()
  
  setdir "/wav"
  out 6,0
  gosub pwaveb,"todayis1.wav"
  gosub pwaveb,"todayis2.wav"
  gosub pwaveb,"week"+strftime$("%a")+".wav"
  gosub pwaveb,"month"+dec$(val(strftime$("%m")))+".wav"
  gosub pwaveb,"day"+dec$(val(strftime$("%d")))+".wav"
  gosub pwaveb,"forecas1.wav"
  gosub pwaveb,"weath"+dec$(Fnum0)+".wav"
  gosub pwaveb,"temp1.wav"
  gosub pwaveb,dec$(Max0)+"deg.wav"
  gosub pwaveb,"forecas2.wav"
  gosub pwaveb,"weath"+dec$(Fnum1)+".wav"
  gosub pwaveb,"temp3.wav"
  gosub pwaveb,dec$(Min1)+"deg.wav"
  gosub pwaveb,"temp4.wav"
  gosub pwaveb,dec$(Max1)+"deg.wav"
  out 6,1
  
  do until 60000000<coretimer()-c : idle :loop
loop

label pwaveb
  print args$(1);
  PLAYWAVE args$(1)
  print " ... ";
  do while playwave(0)
    idle
  loop
  print "done"
return

天気予報は、AccuWeather から得ています。上のコードの URL の所で「[AccuWeather API key]」は、私の個人用のAPIキーです。AccuWeatherは、登録すれば無料で使えますので、必要ならば登録して API key を取得してください。また「332097」は、私が住んでいる町(カリフォルニア・デービス)の番号です。これを他の番号に変えれば、別の町の情報を得ることができます。

上のコードとほぼ同じものを、GitHubレポジトリーに上げましたので、参考にしてください(ENGLISH.BASがそれ)。

https://github.com/kmorimatsu/machikania-basic/tree/main/weather

URLは、"http://www.rad51.net/projects/weather/tokyo.php"としています。これを使用する分には、AccuWeatherのアカウントは必要ありません。ただし、東京限定です(osaka.phpも使えます)。

GitHubには、「TOKYO.BAS」「OSAKA.BAS」の2つのプログラムも載せてあります。こちらは、日本語で今日の日付・曜日・天気予報を喋るものです。それぞれ、東京・大阪の天気予報バージョンです。

JSONクラスについて

このプロジェクトでは、WGET クラス以外に JSON クラスを用いています。JSON クラスも、WGET と同様に、ver 1.3 でライブラリーに追加しました。JSON 文字列の中から、目的のものを抽出するのに便利です。詳しい使い方は、help.txtを参照してください。

ここでは、JSON クラスをどのように使っているかを説明します。まず、「o=new(JSON,j$)」で JSON オブジェクトを作成しています。「j$」は、web サイトから得られた JSON 文字列です。

続けて、「o.FQUERY#(".DailyForecasts[0].Temperature.Minimum.Value")」のように使っています。「FQUERY#()」は、浮動小数点実数値を読み込むためのメソッドです。「".DailyForecasts[0].Temperature.Minimum.Value"」の部分で、どの情報を読み出すかを指定しています。この例では、「DailyForecasts」をまず見つけ、これが配列なので「[0]」で配列の一番初めの内容を調べます。続けて「Temperature」「Minimum」「Value」順で追っています。「IQUERY()」「SQUERY$()」も同様で、それぞれ、整数値・文字列の内容を調べて読み込むためのメソッドです。

音声データーについて

発声する音声データーは、実行時にその都度作成するのではなく、予めすべての可能性について発声させたものを WAVE ファイルにして保存してあり、その中から選んで再生しています。英語のデーターは https://ttsreader.com/ から取得して、「wav」ディレクトリーに配置しました。日本語のデーターは https://note.cman.jp/other/voice/ から取得して「wavjp」ディレクトリーに配置してあります。]]>
MachiKania https://www.rad51.net/blog/mycom/?itemid=981 Sun, 01 Oct 2023 00:28:30 PDT ITEM981_20231001
MachiKania type P ver 1.3 で、http サーバー https://www.rad51.net/blog/mycom/?itemid=980 WiFi 接続及びインターネット接続が出来るようになりました。この記事では、MachiKania を http サーバーとして利用する方法について述べます。

ver 1.3 では WiFi 機能の追加に伴って13種類の新たな命令・関数が追加されていますが、それらを使ってサーバーを構築するのは、骨の折れる作業です。そこで、需要の高い http サーバーを構築するためのクラス、HTTPD を作成しました。

この、HTTPD クラスを用いれば、簡単に http サーバー(www サーバー)を構築することができます。この記事では、HTTPD クラスの使い方について述べます。

サンプルプログラム

ver 1.3 の配布アーカイブには、HTTPDクラス用のサンプルプログラムが付いています。「HDEAMON.BAS」がそれで、以下の内容です。

useclass HTTPD
h=new(HTTPD,80,"/httproot")
print "server started as http://";ifconfig$(0);"/"
do
  h.START()
  system 201,val(h.GETPARAM$("led"))
  print h.LASTURI$()
loop


REM 次の内容を、"index.htm"のファイル名で保存し、
REM "httproot"ディレクトリーに配置する。
REM ただし、各行冒頭の「REM 」は、削除すること。

REM <html><head><title>Test</title>
REM <meta name="viewport" content="width=1, initial-scale=5"></head>
REM <body>
REM <h5 style="text-align:center"><a href="?led=1">ON</a></h5>
REM <h5 style="text-align:center"><a href="?led=0">OFF</a></h5>
REM </body></html>

11行目以下は、コメントです。このコメントの内容に従って、「index.htm」という名のファイルを用意し、「httproot」ディレクトリーを作成してそこにコピーしてください。「HDEAMON.BAS」を実行すると、下のような表示になるはずです。

2023-09-27-hdeamon.jpg

「192.168.137.109」の所は、環境によって異なります。多くの場合、「192.168」から始まる4つの数字になる筈で、http サーバーが走っているローカルLANのIPアドレスです。この場合、「http://192.168.137.109/」に、ブラウザーからアクセスしてみます。PCでもスマートフォンでも構いません。下は、スマートフォンから接続した時の表示です。

2023-09-27-smartphone.jpg

MachiKaniaの画面は、下のようになります。

2023-09-27-hdeamon2.jpg

ここで、スマートフォンの画面で「ON」「OFF」「ON」の順でゆっくり押すと、Raspberry Pi Pico W の LED が、ついたり消えたりするはずです。MachiKania の画面は、以下のようになります。

2023-09-27-hdeamon3.jpg

どうでしょうか。MachiKania 上に http サーバーが構築できて、PCやスマートフォンからアクセスする事で、MahiKaniaに信号を送ることができるのが、分かると思います。

ほぼ同じ操作を動画にしてtwitter.comに上げましたので、興味があればご覧ください。

2023-09-27-movie.png

より複雑な web ページも、構築可能

上で紹介したサーバーで表示されるのは、たった6行からなるシンプルな HTML ですが、より複雑なページや、画像を含むページを表示可能です。

試しに、役者の阿部寛さんのホームページをローカルな環境の MachiKania type P で構築した http サーバー上にコピーさせていただき(外部公開していません)、ブラウザーからアクセスしてみました。動画を、twitter.comに上げてあります。

2023-09-27-abe.png

ファイル一覧とPCへのファイルダウンロード

HTTPD クラスは、ディレクトリー中のファイル一覧表示機能を持っています。例えば、以下の BASIC プログラムを実行すると、MMC/SDカードの一覧が、Apache のファイル一覧に似た形式で表示されます。

useclass HTTPD
h=new(HTTPD,80,"/")
do
  h.START()
loop

ディレクトリー間の移動も可能です。下は、「/LIB/WGET/」ディレクトリーに移動した時の表示です。表示は左から順に、ファイル名・更新日時・バイトサイズ・属性フラグです。

2023-09-27-wgetdir.png

ファイル名をクリックすると、当該ファイルをダウンロードする事も可能です。この機能を使うと、MachiKania 上のファイルを簡単にPCに取り込むことができます。

HTTPD クラスでサーバーを構築する場合、逆に、ディレクトリー一覧を表示させたくないときもあると思います。そういった場合は、該当のディレクトリーに「index.htm」を作成してください。ファイル内容は、空でも「<html></html>」でも、何でも良いです。

他のタイプのサーバーも構築可能

http サーバー以外のサーバーも、理論的には構築可能です。下は、TELNETサーバーを構築した例です。アルファベットの大文字は小文字に、小文字は大文字に変換して表示される仕様です。

TCPSERVER 23,0
print "Server started at port 23"
do
  do
    delayms 10
    c=TCPACCEPT()
  loop until c
  print "Connected"
  TCPSEND("Hello TELNET server!\r\n",-1,c)
  do while TCPSTATUS(0,c)
    for i=1 to 1000
      delayms 1
      if 0=TCPRECEIVE(&b,1,c) then continue
      i=0
      break
    next
    if 0x40<b and b<0x5b then
      b=b+0x20
    elseif 0x60<b and b<0x7b then
      b=b-0x20
    endif
    if i then b=0
    TCPSEND &b,1,c
    if 0x0d=b then
      b=0x0a
      TCPSEND &b,1,c
    endif
  loop
  print "Closed"
loop

実行中の様子の動画は、twitter.comに上げました。

2023-09-27-telnet.png ]]>
MachiKania https://www.rad51.net/blog/mycom/?itemid=980 Fri, 29 Sep 2023 19:25:34 PDT ITEM980_20230929
MachiKania type P ver 1.3 で、http クライアント https://www.rad51.net/blog/mycom/?itemid=979 WiFi 接続及びインターネット接続が出来るようになりました。この記事では、MachiKania を http クライアントとして利用する方法について述べます。

ver 1.3 では WiFi 機能の追加に伴って13種類の新たな命令・関数が追加されています。それらを使えば様々なインターネット接続(クライアント・サーバー)を行うことができますが、非常に複雑な手続きが必要です。そこで、インターネットの接続で最もよく使う、http プロトコルに関して、クラスライブラリーを用意しました。

ここでは、新規に追加されたクラスのうち、WGET クラスについて説明します。http クライアントを簡易に構築するためのクラスです。

最も簡単な使用方法

WGETクラスは、オブジェクトを作成せずに、スタティックメソッド呼び出しで使います(help.txtを参照)。多くの方が一番よく使うのは、おそらく「WGET::FORSTRING$()」です。以下の例は、もっとも簡単なサンプルプログラムです。

useclass WGET
t$=WGET::FORSTRING$("http://www.rad51.net/projects/typep/")
print t$

Webページにアクセスして、その内容を表示するものです。上のコードを実行すると、結果は以下の例のようになるはずです。
2023-09-24-wget.jpg
「<html>」から「</html>」が、指定のURLから取得した内容です。

多くの場合、「WGET::FORSTRING$()」を使うのが、確実で簡単な方法でしょう。得る情報がテキストなら(HTML, JSON, RSSなど)、この方法で簡単に得ることができます。

バイナリーファイルのダウンロード

「WGET::FORSTRING$()」では、ヌル文字(\0)を含むデーター、例えば画像ファイルの取り込みが出来ません。そういったデーターをインターネットからダウンロードしてくるには、「WGET::FORFILE()」もしくは「WGET::FORBUFFER()」を使います。下は、「WGET::FORFILE()」を使って、TIFFファイルをダウンロードしてファイルとして保存し、表示する例です(TIFFファイルは、16色もしくは256色の、圧縮無しのものに対応)。

useclass WGET,CSWTIF
WGET::FORFILE("temp.tif","http://www.rad51.net/projects/typep/image.tif")
i=new(CSWTIF,"temp.tif")
point 0,200
i.SHOW()

実行結果は、以下の例のようになるはずです。
2023-09-26-wget_forfile.jpg

「WGET::FORBUFFER()」を使う場合は、少し複雑ですが、以下のように書きます。実行結果は、上と同じです。下のコードの「b,4800」で、「b」はバッファーアドレス、「4800」はバッファーの有効バイト数です(ここで使用したTIFFファイルは、4770バイトです)。

useclass WGET,CSWTIF
dim b(1199)
s=WGET::FORBUFFER(b,4800,"http://www.rad51.net/projects/typep/image.tif")
fopen "temp.tif","w"
fput b,s
fclose
i=new(CSWTIF,"temp.tif")
point 0,200
i.SHOW()

セキュアーコネクション(https)も可能

httpプロトコルをセキュアーコネクションで行いたい場合(http ではなく、https)も、WGETを使えます。使い方は同じで、URLに"https://"と書くだけです。

ただし、ドキュメントの wifi.txt にも書きましたが、MachiKania で https サイトにアクセスした場合、通常のブラウザーによる https サイトへのアクセスに比べて、セキュリティーレベルが低いです。MachiKania から https サイトへのアクセスでは、パスワードや個人情報などを送付しないようにしてください。こちらから送付する情報なしでデーターを取得するだけなら、何も問題にする必要はありません。

WGETクラスの利用例

WGETクラスを利用して、天気予報をインターネットから得て知らせてくれる箱を作りました。詳しくは、別記事で説明します
2023-09-26-weatherBox.jpg]]>
MachiKania https://www.rad51.net/blog/mycom/?itemid=979 Fri, 29 Sep 2023 19:25:20 PDT ITEM979_20230929
MachiKania type P ver 1.3 で、ネット接続 https://www.rad51.net/blog/mycom/?itemid=978
公式ページはこちら
GitHubリリースページはこちら

ReadMeに記載した更新履歴は、次の通りです。
・Raspberry Pi Pico W を用いた WiFi 接続に対応。次の命令・関数を追加: 
 DNS$(), IFCONFIG$(), NTP, TCPACCEPT(), TCPCLIENT, TCPCLOSE, TCPRECEIVE, 
 TCPSEND, TCPSERVER, TCPSTATUS, TLSCLIENT, WIFIERR(), WIFIERR$()
・GCOLOR()関数の不具合を修正
・一部USBキーボードでのキー入力不具合に対応
・EOFの時、FGETC()関数が-1を返すようにした
・embed用にXIAO RP2040, RP2040-Zero, and Tiny-2040に対応
・SPIの対応ポートをINIファイルで指定出来るようにした
・SERIALステートメントの第3引数を省略した時の不具合を修正
・例外をトラップして画面表示するようにした
・CORETIMERが電源投入後およそ2000秒後から不具合を起こす事を修正
・ILI9488に対応
・RTC(Real Time Clock)をサポート。次の命令・関数を追加: 
 GETTIME$(), SETTIME. STRFTIME$()
・ファイル保存時の日時設定をサポート
・NTPサーバーによるRTCのセットをサポート
・SYSTEM 201 呼び出しにより、ボード付属のLEDのオン・オフを出来るようにした
・メモリーアロケーションの不具合を修正
・FREMOVE/SETDIR等のファイル関連命令を使用時の、ガベージコレクション不具合を修正
・WAVEプレーヤーの安定性を改善
・クラスのスタティックメソッド呼び出し不具合を修正
・FFINGD$(), FINFO(), FINFO$()の3つの関数を追加。ファイル一覧の作成が可能に
・REM 文に「"」を含む際のコンパイル時の不具合を修正


WiFi 接続機能

ver 1.3 で追加された目玉機能は、WiFi 接続です。WiFi 対応の Raspberry Pi Pico W で MachiKania を利用する事により、インターネットに接続して情報を得たり、イントラネットでサーバーを構築して他の機器と接続したりすることができるようになりました。まずは、ドキュメントのwifi.txtをお読みください。

WiFi接続用のBASIC命令群が多数追加されています。ただし、これらを直接利用してネット接続するコードを書くのは骨が折れるので、ネット接続を容易に行えるクラスを用意しました。

・WGET クラス。インターネットのhttp、httpsサイトから情報を得ることができる。
・HTTPDクラス。http サーバーを構築することができる。

これらに関しては、別途記事を書きましたので、そちらを参照してください(WGETの記事はこちらHTTPDの記事はこちら)。

WiFi機能を使用する場合は、次の点に注意して下さい。

1.Raspberry Pi Pico Wを使用する(Raspberry Pi Picoでは不可)。
2.Raspberry Pi Pico W用のuf2ファイル(pico_w_ili9341/phyllosoma.uf2等)をロードする。
3.MACHIKAP.INIで、WiFi を使うように設定する(「USEWIFI」を有効にする)。
4.MACHIKAP.INIでWiFi接続用のSSIDとパスワードを指定する(「WIFISSID=」及び「WIFIPASSWD=」)。
5.MACHIKAP.INIで、国情報を設定する(日本の場合は、「WIFICOUNTRY=JP」)
6.リアルタイムクロックを利用する場合(下記参照)は、MACHIKAP.INIで「INITIALNTP」を有効にする。

なお、5.のWIFICOUNTRYは、cyw43のソースコード(cyg43-driver/src/syw43_country.h)の60行目辺りからを参考にしてください。

設定がうまく行けば、起動時に次のような表示になります。ただし、「192.168.1.156」と「macserver」の部分は、環境によって異なります。
2023-09-23-MachiKaniaWiFi.jpg
このような表示が確認できれば、MachiKaniaでWiFiを使う準備が整いました。

リアルタイムクロック

リアルタイムクロック(Real Time Clock; RTC)が使えるようになりました。現在時刻は、プログラム中で指定する事も、ネット上のNTPサーバーから取得して設定する事も出来ます。また、ファイル保存時に、作成時刻・日時を設定する事が出来るようになりました。

NTPサーバーを利用して現在時刻を取得する方法で、リアルタイムクロックを使用する場合は、次の点に注意してください。

1.Raspberry Pi Pico Wを使う。
2.Pi Pico W 用のuf2ファイルをロードする。
3.MACHIKAP.INIで、WiFi を使うように設定する(「USEWIFI」を有効にする)
4.MACHIKAP.INIで、タイムゾーンを設定する(日本なら、TIMEZONE=9)
5.MACHIKAP.INIで、起動時にNTPサーバーに接続する様に設定する(「INITIALNTP」を有効にする)

RTCを扱う命令・関数として、GETTIME$(), SETTIME, STRFTIME$() の3つを用意しました。これらの使い方の詳細は、help.txtを参照してください。なお、一連の命令・関数では、日付・時刻を扱うために、ISO-8601 形式の文字列を使います。 ISO-8601 文字列は、次の例のような書式です(日付と時刻の間に「T」が挟まれています)。

2023-09-01T13:00:00(2023年9月1日午後1時0分0秒の場合)

XIAO RP2040, RP2040-Zero, Tiny-2040などの、小型RP2040ボードに対応

Ver 1.2までは、Raspberry Pi Picoや、ピンに互換性のあるYD-RP2040などが対象でしたが、Ver 1.3からは、XIAO RP2040, RP2040-Zero, Tiny-2040といった、ピン数の少ない小型互換ボードでも使えるようになりました。ただし、ピン数がRaspberry Pi Picoより少ないため、組込み機能(embed)での対応です。

RP2040-Zero, Tiny-2040で使う場合、デフォルトではSPI用のポートが取れないので、MACHIKAP.INIでSPI用のポートを設定できるようにしました。多くの場合、以下のように設定すれば使えるようになります。
SPIMISO=4
SPIMOSI=7
SPICLK=6
このように設定すれば、MISOがGP4で、MOSIがGP7で、CLKがGP6で使えるようになります。その他の使い方は、Ver1.2と同じです。上記のように設定したMACHIKAP.INI以外にBASICプログラムを含むMACHIKAP.BASを用意して、convert.phpもしくはconvert_kb.phpを実行してください。

Seeed XIAO RP2040の場合、GP5が使えないため、専用のuf2ファイルを用意しました。machikap-p2-130-RC3.zipに含まれている「xiao_embed」ディレクトリーのものを使用してください。なお、I/Oの割り当ては、下の通りです。

・GP0 I/O bit0 / UART TX / PWM3
・GP1 I/O bit1 / UART RX / SPI CS / PWM2
・GP2 I/O bit2 / SPI SCK / PWM1
・GP3 I/O bit3 / SPI MOSI
・GP4 I/O bit4 / SPI MISO
・GP6 I/O bit6 / I2C SDA
・GP7 I/O bit7 / I2C SCL

ILI9488液晶に対応

ILI9341の2倍の大きさの、ILI9488に対応しました。キャラクター表示の場合60x40文字、グラフィック表示の場合480x320ピクセルの表示が可能です。machikap-p2-130-RC3.zipに含まれている「pico_ili9488」ディレクトリーもしくは「pico_w_ili9488」のものを使用してください。それぞれ、Raspberry Pi Pico用と、Raspberry Pi Pico W用(WiFi用)です。

その他

その他、バグ修正と、色々追加機能があります。

CPUが例外を起こした場合、例外原因などを画面に表示するようにしました。何が不具合が起きた時の原因を調べやすくなりました。

Raspberry Pi PicoとRaspberry Pi Pico Wのボード搭載LEDの制御が、SYSTEMステートメントで行えるようになりました。「SYSTEM 201,1」でオン、「SYSTEM 201,0」でオフです。

MMC/SDカードに存在するファイルの一覧を、BASICプログラム中で得ることができるようになりました。FFINGD$(), FINFO(), FINFO$()の3つの関数を追加しています。使用方法は、help.txtを参照してください。]]>
MachiKania https://www.rad51.net/blog/mycom/?itemid=978 Fri, 29 Sep 2023 19:24:59 PDT ITEM978_20230929
MachiKania type Pで、BASICコードからCで書かれたコードを呼び出す、その2 https://www.rad51.net/blog/mycom/?itemid=977 ひとつ前の記事では、CプロジェクトをHEXファイルに変換し、そこから必要なC関数を呼び出す方法について述べた。この記事では、もう一つの方法について述べる。

HEXファイルに変換する方法においては、複雑なCでのコーディングが必要な多くの事例に対応できる。一つの例として、正規表現エンジンを実装するMachiKaniaクラス(REGEXP クラス)の実装について述べた。

この記事で述べる方法では、Cのプロジェクトから必要なコードを抜き取って BASIC コードに変換してプログラムに埋め込む方法を取る。HEXを介する方法と比べた長所は、以下の通り。

1.一つの BASIC ファイルの中に C コードを埋め込むことができる
2.HEX を介した方法では HEX コードのメモリ上での配置位置を考慮する必要があったが、この方法ではその必要が無い
3.C プログラムの中から必要なものだけを抜き取って BASIC プログラムに埋め込むので、メモリー占有領域を最小限にできる


他方、短所は以下の通り

1.複雑な C プログラムでは対応できない場合がある

従って、それほど大きくない C のプログラムの場合はこの記事で述べる方法が有利である。後に述べる「c_convert.php」スクリプトの実行でエラーが出る、あるいは、作成されたBASIC プログラムが意図したように動作しない場合は、HEXを介する方法に移行すればよい。

BASIC に C コードを埋め込む例(hcw1アプリケーション)

先の記事と同様、次のような C 関数を BASIC から呼び出す例について述べる。
int add_values(int a, int b){
	return a+b;
}

この例を説明するために、GitHubレポジトリーを作成したので、参照していただきたい。Git Cloneした後に「hcw1」ブランチにスイッチし、Commit Log を見ていただければ、説明が分かりやすいと思う。
2023-03-18-log.png
また、この記事では、1から5までの手順ごとに該当レポジトリーへのリンクを付けたので、そちらも見ていただきたい。

1.まずは、Hello, World! から
まず、Cのプロジェクトを一つ作成する必要がある。何でも良いのだが、ここではpico-examplesからhello_usb.cを選んで、若干変更した物から始める事とする。これは、ビルドした後にPi Picoにインストールすれば、USB シリアル接続を通して、コンソール上に「Hello, World!」と表示し続けるプログラムだ(前の記事と同じ)。
#include <stdio.h>
#include "pico/stdlib.h"

int main() {
	stdio_init_all();
	while (true) {
		printf("Hello, world!\n");
		sleep_ms(1000);
	}
	return 0;
}
このプロジェクトをcmake/makeでビルドすると、hello_cw.uf2に加えてhello_cw.hexが作成されることが分かる。このようにして作成されたhexファイルを用いることになる。

2.目的のコードを、プロジェクト内に記述する
Cアプリケーションを記述してテストする環境が整ったので、ここで目的のコードを書いてみる。なお、ひとつ前の記事の方法とは異なり、この記事の方法では、プログラムはRAM上ではなくフラッシュ上に構築する方法を取る。上で述べたadd_values()関数を追加して、テスト結果を表示するようなものにした。
#include <stdio.h>
#include "pico/stdlib.h"

int add_values(int a, int b){
	return a+b;
}

int main() {
	int a=0,b=0;
	stdio_init_all();
	while (true) {
		printf("%d + %d = %d\n", a, b, add_values(a,b));
		a+=1;
		b+=2;
		sleep_ms(1000);
	}
	return 0;
}

3.C コンパイラーの最適化を無効にする
ARM gcc コンパイラーの最適化を無効にするため、CMakeFiles.txtに次の記述を追加している。
add_definitions(-O0)

ひとつ前の記事でも述べたが、この記事で述べる方法でも、C のコードを埋め込もうとする場合、以下の点に注意が必要だ。

a.呼び出そうとするC関数が、必ずビルドオブジェクトに含まれるようにする
b.呼び出そうとするC関数の引数は、4つまで
c.呼び出そうとするC関数の引数の取り扱いに関して、ビルドの際の最適化で標準のARMレジスター使用(R0, R1, R2, R3を使用する)から変更されないようにする


a.の対策のためには、必要な関数がすべて、「main()」関数、もしくはそこから呼び出される関数の中で、最低一度は呼び出される必要がある。でないと、リンクの際に不必要な関数コードとして、削除されてしまう。

また、Cコンパイラー(gcc)が行う最適化のために、関数がインライン展開されてしまう事もあり、そうなると外部から呼び出すことができなくなってしまう。これを防ぐ方法にはさまざまあり、1:目的の関数を「main.c」とは別のファイル内に記述する、2:「__declspec(noinline)」アトリビュートを使う、3:最適化を行わない、などがある。

b.は ARM gcc コンパイラーの規約に関係するもので、これを遵守しないと(引数を5つ以上にしてしまうと)、正常に動作しない。

c.の対策は色々と複雑で、同一のCファイル内で目的の関数を呼び出している場合に変なレジスター使用が起こるようだ。最適化の一つなので、当然ながら最適化を行わないようにすることで回避することができる。

以上の事から、トラブルを防ぐにはgccの最適化を停止することが有効である。CMakeLists.txtに「add_definitions(-O0)」の一行を加えたのは、そのためである。特殊な作例で、実行速度が最大でないといけないようなケースにはこの方法は使えないが、そうでなければ、最適化を停止して使用するのが無難だろう。

4.PHPスクリプトを配置する
作成されたHEXファイルを呼び出すBASICプログラムを自動作成するためのスクリプト「c_convert.php」を用意した。このスクリプトは、PHPで記述されているので、PHPがない場合はインストールが必要である。このPHPスクリプトは汎用であるが、冒頭の記述(13-34行目辺り)を若干編集して使用する。今回の例では、次のようになっている。
class configclass{
	// File names
	public $dis_file='./build/hello_cw.dis';
	public $map_file='./build/hello_cw.elf.map';
	public $hex_file='./build/hello_cw.hex';
	//public $debug_file='./machikap/machikap.bas';
	
	// Functions to be exported
	public $functions=array(
//		'machikania_init',
		'add_values',
	);
	
	// Additional .rodata to be used (function names are excluded)
	public $rodata=array(
	);
	
	// Excluded addresses as .rodata and RAM
	public $excluded=array(
		0x20040000,
	);
};
$dis_file, $map_file, $hex_fileでは、ビルドの際に作成された「*.dis」「*.map」「*.hex」の3つのファイルの位置を指定する。$debug_fileはオプションで、PC-Connect機能を利用してデバッグを行っている際の、BASICファイルの位置を指定する。必要が無い場合は、「//」でコメントアウトしておく。また、$functionsには、BASICから呼び出したいCの関数名を列挙しておく。$rodataには、自動認識されないが必要な部品名を文字列で指定したリストを指定する。逆に、$excludedには必要のない部品の物理アドレスのリストを指定する。通常は、$rodataと$excludedの設定は変更の必要は無いはずだ。

5.Cプログラムのビルドと、PHPスクリプトの実行
ここまで準備できれば、Cプログラムをビルドした後に、PHPスクリプトを実行する。「result.txt」と「log.txt」の二つのファイルが出来ているはずだ。ここでの例のように進めると、「result.txt」の内容は次のようになる。
USEVAR C_RAM
GOSUB INIT_C
END

LABEL INIT_C
  DIM C_RAM(0)
  REM ram vectors
  REM rodata vectors
  REM ram function vectors
  REM callback function vectors
RETURN

ALIGN4
LABEL C_ADD_VALUES
  EXEC $68f0,$6931,$6972,$69b3,$f000,$f802,$bd00,$46c0

REM 28 bytes
LABEL C_FUNCTIONS
EXEC $b580,$b082,$af00,$6078,$6039,$687a,$683b,$18d3,$0018,$46bd,$b002,$bd80,$b580,$b082

REM 0 bytes
LABEL C_RODATA
このBASICプログラムは、C コードを埋め込んで呼び出しできるようにした、必要最小限の構成になっている。目的のコードを、3行目の「gosub INIT_C」と4行目の「end」の間に書けばよい。例えば、次のように変更して、BASICプログラムを完成させてみよう。
USEVAR C_RAM
GOSUB INIT_C

for i=1 to 10
  print a,b,a+b,gosub(C_ADD_VALUES,a,b)
  a=a+1
  b=b+2
next

END

LABEL INIT_C
  DIM C_RAM(0)
  REM ram vectors
  REM rodata vectors
  REM ram function vectors
  REM callback function vectors
RETURN

ALIGN4
LABEL C_ADD_VALUES
  EXEC $68f0,$6931,$6972,$69b3,$f000,$f802,$bd00,$46c0

REM 28 bytes
LABEL C_FUNCTIONS
EXEC $b580,$b082,$af00,$6078,$6039,$687a,$683b,$18d3,$0018,$46bd,$b002,$bd80,$b580,$b082

REM 0 bytes
LABEL C_RODATA
あとは、このBASICプログラムをMMC/SDカードにコピーすれば、実行することができる。実行時のスナップショットは、以下の通り。
2023-03-18-20230318_205201.png

以上が、簡単なCコードをBASICプログラムに埋め込んで呼び出すための手順である。

エラーが出た場合

「c_convert.php」は、ひとつ前の記事で述べた「c_convert2.php」と比べて少し複雑なアルゴリズムを用いていて、C のコードから必要部分を抜き出して BASIC に埋め込む動作をしている。残念ながら、複雑な構造の C コードに関しては、解析がうまく行かず、PHPスクリプトの実行中にエラーになったり、完成した BASIC プログラムが正常に動作しない事が起きうる。そういう場合は、ひとつ前の記事で述べた HEX ファイルを作成する方法の方が対応できる範囲が広いので、そちらを試していただきたい。

どんどん C コードを取り込もう

ひとつ前の記事では、複雑な C プログラムの MachiKania BASIC への取り込みについて述べたが、手続きが複雑であった。簡単な C プログラムならこの記事で書いた方法でより簡便に取り込める。それにより、MachiKania の応用範囲がさらに広くなることを、期待している。]]>
MachiKania https://www.rad51.net/blog/mycom/?itemid=977 Sun, 26 Mar 2023 10:45:14 PDT ITEM977_20230326