UIAPduinoでシリアルモニタ


Arduinoでは出来るのに,UIAPduinoで出来無いことの一つが,シリアルモニタである. UIAPduinoでは,USBからの書き込みは出来るが,bootloaderに書き込まれたソフトでUSBを取り扱っているので,Arduino IDEで作ったユーザーのプログラムの実行時には,USBは使えない. そのために,UIAPduino単体ではシリアルの出力をモニタできないのである. 例えば,ADCなどの結果を出力させたりする際には,PC側からその結果を見たいが,そのような時に,シリアルモニタが便利である.

UIAPduinoで,マイコンの出力をPCから見る方法は,いくつか考えられる. 最も簡単に思い付くのが,別のUSB-シリアル変換を使う方法である. CH32の書き込み機であるWCH-LinkEにもこの機能があり,それらを使うと,Arduino IDEからモニタすることができる. しかし,そのハードを別途用意する必要があり,コストもかかるので,ここではUIAPduinoのみという縛りをつけて,それを実現する方法を考えてみよう.

ch32funでよく行われているのが,デバッグプリントを使う方法で,SWDIOを使ってデータを送って,PCから見ることが出来る. この方法は,一般にはWCH-LinkEをマイコンに接続して行うが,そのかわりにUAIPduinoで書き込み機を作って,同様に使うことが可能である. ch32v003でUSBを使うためのrv003usbには,rvsdio_programmerという書き込み機を作るためのソフトがあり,UIAPduinoにこれを書き込むと,それを使ってデバッグプリントできるようになる. ユーザーのプログラムの実行用とモニタ用で,二つのUIAPduinoが必要になるが. 標準のrvsdio_programmerから,ピン番号とDPUの設定をカスタマイズしたUIAPduino用のバイナリをdownloadする.

wget https://www.uiap.jp/doc/rvswdio_programmer-md5sum-651b141f51da9a29e9988559fc562157.bin

すでに設定してある場合には不要だが,UIAPduinoに書き込みをする権限を設定する.

sudo wget -O /etc/udev/rules.d/99-minichlink-uiap.rules https://raw.githubusercontent.com/YuukiUmeta-UIAP/ch32fun/3bfa603f11d493710f2a811b5a2dfad905d9425c/minichlink/99-minichlink-uiap.rules
sudo udevadm control --reload-rules
sudo udevadm trigger

書き込み用のソフトであるminichlinkは,

wget https://github.com/YuukiUmeta-UIAP/ch32v003fun/releases/download/1.0.0/minichlink-2982dfd-1.0.0.tar.gz
tar -zxvf minichlink-2982dfd-1.0.0.tar.gz
mv minichlink-2982dfd/minichlink .

とすると,minichlinkができる. UIAPduinoのRSTボタンを押しながらUSBにつないで,minichlinkを使って,以下のコマンドで書き込みを行う.

./minichlink -c 0x1209b803 -w rvswdio_programmer-md5sum-651b141f51da9a29e9988559fc562157.bin flash -b

そして,rvsdio_programmerにアクセスする権限を以下のようにして与える.

sudo wget -O /etc/udev/rules.d/99-minichlink.rules https://github.com/cnlohr/ch32fun/raw/refs/heads/master/minichlink/99-minichlink.rules
sudo udevadm control --reload-rules
sudo udevadm trigger

これで,UIAPduinoをrvsdio_programmerとして使うことができるようになった. あとは, ボードをデバッガにするのところに書いてある通りに配線して,

./minichlink -T

とすれば良いはずである. しかし,この手法にはいくつかの欠点がある. まず,Arduino IDEからは使えないことである.現時点では,私はArduinoからSWDIOへの出力の仕方は分らない.一般的なArduinoにはSWDIOは無いので,可能だとしても特殊な使い方が必要になるはずである. また,配線が少し複雑である. シリアルモニタの場合には,GNDと電源とデータの三本で良いのだが, rvsdio_programmerの仕様上,特定のピンを繋いだりする必要がある. Arduino IDEのからシリアルモニタから見ることが出来無いのも,面倒かも知れない.

UIAPduinoの公式サイトでも不完全とのコメント付きで書かれているが, UIAPduinoでUSB-シリアルを作ることができれば,これらの欠点を解消することができる. 実は,rv003usbには,まだ実験的なものではあるが, usb_cdc_uartという,usb-シリアルのソフトがある. これを試してみたので,その使い方を以下に説明する. まず,UIAPduino用にピン番号などを変更しなければならず,usb_config.hを以下のように変更する.

#ifdef QFN20
#define USB_PIN_DP 3
#define USB_PIN_DM 4
#define USB_PIN_DPU 4 //<-5
#define USB_PORT D //<-C

私の場合は,ch32v003_GPIO_branchless.hが見付からないと言われたので,そのフォルダの指定も行った. このプログラムにはバグがあり,そのままでは動かないので,uart_cdc.cを以下のように変更する.

// RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1 | RCC_AHBPeriph_SRAM | RCC_AHBPeriph_DMA1;
RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1;
RCC->AHBPCENR = RCC_AHBPeriph_SRAM | RCC_AHBPeriph_DMA1; //add

特定の機能を有効化するためのレジスタが,おそらく別のIC用のものになっているようなので,これをCH32V003用に修正するのである. これをコンパイルしてUIAPduinoに書き込めば,baudrateが115200のusb-シリアルとして動作するようになる. これのバグを見付けるのに,それなりの時間がかかったが,動いた時は嬉しいものである. 実行用とモニタ用のUIAPduinoに対して,電源とGNDをそれぞれ繋き,実行用のTXとモニタ用のRXを繋いで,モニタ用をUSBに接続すれば,Arduino IDEのシリアルモニタで表示することができた. または,二つともUSBに接続して,実行用のTXとモニタ用のRXを繋いでも良く,余分にUSBポートがあれば,一本の線を追加するだけですむので,こちらの方が良いように思う. このUSB-シリアルはLinuxでは動作することが確認できたが,Windowでは動かない可能性が高いらしい. 手元にWindowsが無いので,確かめられないが. また,バグの報告の仕方も知らないのだが,ブログに書いておけば,誰か報告してくれると期待しよう. 以前,rubyのmatrix.rbに軽微なバグを発見して,ブログに書いたら,いつの間にか誰かが報告してくれていた.

Linux限定かもしれないが, UIAPduinoをUSB-シリアルとして認識させることが出来たので, 一つのUIAPduinoでUSBSerialと例えばADCを共存させることが出来そうである. おそらくch32funを使えば,それほど難しく無いと思うが,ch32funで様々な機能を使うのが大変である. ArduinoからUSB-シリアルをプログラムすることが可能になれば,UIAPduinoを一般のArduinoとほぼ同じ感覚で使うことが出来るようになり,有用性が増すと思われる. しかし,それにはソフトをなんとかする必要があり,なかなか大変な作業になりそうな気がする. Arduinoの設定ファイルは難しそうなので,正直あまりいじりたくない.

2026/3/2追記. windows11で試してみたが,デバイスマネージャーではビックリマークがついていて,プロパティでは「このデバイスを開始できません(コード10)」と表示されているので,やはりwindowsでは動かないようだ.