ArduinoでUIAPduinoのUSB serialを使う

少し前から取り組んでいたUIAPduinoのUSB機能をrv003usbを通してArduinoから使うという試みが,ようやく一部は動くようになったので,それについて説明したい. 今回,これまでに構築してきたUIAPduino用のArduino環境に対して,rv003usbを組み込むことによって, USBの機能として最も有用であろうUSB serialを,Arduinoから動かすことに成功した. 動きそうなコードを書くのは,それほど苦労はしないのだが,それがArduino上で動くようにするまでには,いくつものバグを取り除く必要があり,かなり時間がかかってしまった.

まず行ったのが,USBを使うオプションを追加するために,boards.txtにメニューを加えることである. Suzuduinoなどのコードを参考にして,usb_flagsのパラメータを変更できるようにした. rv003usbのファイルは,cores/arduino/rv003usbに配置し,usb_config.hもここに入れた. rv003usbが参照している USBのライブラリは, cores/arduino/libに置いた. この段階で,rv003usb.Sをコンパイルする時にエラーが出たが,platform.txtでSファイルに対するオプションをうまく設定したら,このエラーは解決したが,次のエラーが出た. rb003usbのファイルは変更したくなかったが, rv003usb.hについては, _Static_assertがうまく動かなかったので,それを含む二行をコメントアウトして, 外部のコードから呼び出す三つの関数 usb_handle_user_in_requestとusb_handle_other_control_messageとusb_handle_user_dataの宣言の前にexternを加える という二つの変更が必要だった.

ch32funやrv003usbは主にC言語で書かれている. そのため,C++のArduinoにそれらの定義をincludeするときには,extern “C”{ }で囲んでおく必要がある. その辺りを誤魔化しながらクリアしていたのだが,改めてC言語のソースとC++のソースを意識して,必要な部分に宣言を加えたら,なんとかコンパイルが通るようになった.

megaavrなどを参考にして,CDC.hとCDC.cppを定義して,上で触れたrv003usbの三つの関数を呼び出すことにより,ようやくUSBでのserialを実現することができた. 通常のserialとUSB serialはArduino.hで判断して切り替えている. Serial1で通常のserialも使えるようにしたので,同時にも使えるはずである.

通常のserialとADCを使ったプログラムのbinファイルが4.4kバイトなのに対して, USB serialとADCを使ったプログラムのbinファイルは4.9kバイトと, それほど変らないので,十分実用に耐えるだろう. ただ,残念なのがWindowsからはrv003usbのCDCが使えないことである.

ArduinoからUSBが使えるようになったことで,私の目指していたUIAPduinoの環境は,完成にかなり近付いたと言えるだろう. 今後に改良したい点としては, 公式ページを参考にして,リセットで書き込みモードになるようにすることと, HIDでのデバッグを可能にすることかな. SPIもまだバグが残っているし.

[2025/3/26追記] ソースコードもいろいろと手を加えたので,チェックしてみたら,rv003usb.hの内容を変更しないでもUSBが使えるようになっていた. ArduinoとC言語とC++の関係は,難しい.

Read more...

environment of the Arduino, by the ch32fun, for the UIAPduino

先日から,UIAPduinoのためのch32funによるArduinoの環境の開発を進めている. AlexanderManderaさんの環境は, そのような環境の一つであるので,そのコードを調べてみたところ,以下のようにして作られていることが分かった. まず,その中心となる開発環境の ch32funは,古いversionであるch32v003funを使っている. そして, ArduinoCoreAPIを組み込んでいるが,特にその中のHardwareSerialを書き換えて,Serialを実現している. コンパイルのオプションなどを指定しているplatform.txtなどは arduino-wch58x を参考にして作られている. i2c関係はhalというフォルダに入っているので,hardware abstraction layerのことだろうが,そのコードの起源は分からなかった.

この環境の利点を活かしつつ,UIAPduinoが使い易くなる環境を作りたいと考えていたが,少しずつ形になって来たので,そのことについて説明したい. 今回,新たな環境を構築するにあたって, 最新のch32funを使い,Arduinoの基本的な機能をArduinoと同じように使えるようにすることを,基本的な目標とした. また, 部品として使うch32funやArduinoCoreAPIなどのファイルは,できるだけ変更せずそのまま利用して,手を加えたファイルがどれかが分かりやすいようにする方針とした.

個人的に使うArduino環境は,~/Arduino/にファイルを置くことによって作ることができる. UIAPduinoに書き込みができるように, ~/Arduino/tools/minichlink/に,UIAPduinoのminichlinkを置き, ~/Arduino/hardware/wch/001/の下に,様々なファイルを配置して,Arduino IDEから使えるようにした. platform.txtは主にarduino-wch58xなどを,boards.txtはUIAPduinoなどを参考にして,作成した. cores/arduino/ch32fun/とcores/arduino/api/には,オリジナルのフォルダの内容をそのまま使った. ch32funが参照するcores/arduino/funconfig.hの中には,

#define FUNCONF_SYSTICK_USE_HCLK 1

を指定すると,以前起こったdelayなどが1/8になる問題が解消された. variants/CH32V003/pins_arduino.hには,ch32funのピンの定義を活かしつつ,Arduinoのピンの指定方法への橋渡しをするように記述した. コンパイルの後のリンクのときに,定義の一部が参照できないというエラーが出て,Arduino.hなどをいろいろといじって動くようになったが,よく理解できていない. cores/arduino/wiring_digital.cppやwiring_analog.cppは,ch32funのarduino-likeな書き方を最大限活用して,比較的コンパクトに書くことが出来た. その中で,以前の環境では使えなかったADCやPWMを実装した. ADCを簡単に使うためのコードは,extralibs/ch32v003_GPIO_branchless.hにも含まれているのを見つけたが,他の部分が干渉しそうだったので,funAnalogReadなどを使う方が無難だと判断した. PWMは,ピンのsetting変更は行わずに,とりあえず十個ぐらいのピンで使えるように書いたが,pinのmodeをOUTPUTでは無く,OUTPUT_AFにしないといけないことに気がつくのに,時間がかかってしまった. UIAPduinoでは,PWMは3つのピンで出来ると書いてあって,USBやRSTやSWIOで使うピンを除外しても7つは使えると思うけど,さらに相補的な出力を除いても4つになるのに,なぜA1がPWMを使えないことになっているのかな. 相補的な出力も,単独で使う場合には普通に使えるっぽいので,活用すれば良いように思うけど,何か理由があるのかも知れない. Serialはch32fun.cなどのコードを参考にしてcores/arduino/SerialUART.cppを作って,api/HardwareSerialとapi/RingBufferを活用して実現した. rv003usbのuart_cdc.cで作ったシリアル変換をつかって動作チェックをしたのだけど,そこに残ったバグに気が付くのにも苦労した. i2cについては,ArduinoCoreAPIを使っているmageavrのWire.cppから, ch32funのextralibs/ssd1306_i2c.hを参考に作った関数を呼び出すようにして,それらのファイルをlibraries/Wire/の中に入れた. SPIについては,同様にmegaavrのSPI.hとSPI.cppを変更して,ch32funのextralibs/ch32v003_SPI.hの関数を呼び出すようにした. しかし,リンクのときに, undefined reference to `operator delete(void*, unsigned int)' と出てしまう. あと少しで動きそうだけど,Arduinoのversionのせいかも知れない.

新たに作った環境の十分な動作チェックはまだだが,最低限の機能についてはArduinoとほぼ同じ感覚で使えるようになったと考えている. 以前の環境に比べて,以下の点が進歩したと思う. まず,ADCとPWMが新たに使えるようになり,i2cがWireから使えるようになった. SPIも,あと一歩だと思うけど,私はあまり使わないので,今は許して下さい. 細かい点では,ADCなどの指定がArduinoと同じようにできるようになったし, SerialはArduinoCoreAPIを変更しないで実現した. 欠点としては,少しコンパイルサイズが大きくなった点が気になるが,ch32funを新しくした影響なのかな. 新たに作った環境でblink.inoをコンパイルしたときの,binファイルのサイズは2040byteとなり,以前に比べて二割ほど大きくなったが,WCHの環境よりはるかに小さいので,十分使えるレベルだと思う. serialとi2cを使うプログラムは,13.9kだったので,まあflashには収まるサイズになった. 多数の機能を使ったら,flashのサイズを超えるかも知れないので,今後の検証が必要だろう.

次のステップとして,rv003usbを使えるようにできないかを模索する予定である. それには,ArduinoIDEのファイルの扱いについて,さらに理解を深めないといけないだろう. メニューからオプションでUSBを使う指定をしたときだけ,rv003usbを組み込むようにしたいけど,そのためには,どこにどうファイルを配置すれば良いのかを調べる必要がある. CDCまたはHIDを使ったprintを使えるようになれば,実用性が非常に大きくなるだろう. バグが減ってきたら,いずれは何らかの形で公開したいが,githubの使い方を覚えるのも面倒なので,どうしようかな.

Read more...

Arduinoからch32fun

Arduino IDEからch32funを使ってCH32V003を使う方法を探している. AlexanderManderaさんの環境は,arduino IDEからch32funを使えるようにしたものなので,これを使うと,Arduino IDEからch32funを通して,UIAPduinoを使うことができる. しかし,しばらく更新されておらず,古いversionのch32funを使っているし,まだ実装されていない機能も多いので,改良が必要である. 似たようなやり方で,最新のch32funをArduino IDEから使えるようにできないかと考えている. 特にrv003usbをArdiuno IDEから使えるようになれば望ましい.

そこで,ch32funとArduino IDEのコンパイルの仕方を少し調べてみた. ch32funでは,Makefileの中でincludeされているch32fun.mkに従ってコンパイルが行われる. 一方,Arduino IDEでは,arduino-builderが,platform.txtに書かれている情報に基づいて,C++のコードの生成とコンパイルが行われる. つまり,ch32funでmake buildを行ったときの出力を見て,それそplatform.txtに移植すれば,Arduino IDEを使ってコンパイルできるようになる.

純粋なarduinoについての設定は,/usr/share/arduino/hardware/arduino/avr/の中でされている. ユーザー独自の環境を作るときには,~/Arduino/hardware/wch/001/などを作って,そこに似たような構造のファイルを配置すれば良い. そこに,AlexanderManderaさんやUIAPduinoやch55xduinoのファイルを参考にして作ったファイルを配置して,最新のch32funを組み込んで,blink.inoのコンパイルはできるところまではできた. 書き込んで見ると,delayの時間が1/8ぐらいになっている気がするけど,まあいいか. 後でソースを少しずつ読み解いて,原因を調べよう.

rv003usbも組み込めないかなと思って, ~/Arduino/hardware/wch/001/librariesにrv003usb関係のファイルを入れたら,多少の進展はあったが,エラーが出てしまう. rv003usb.Sの処理のところで,うまく他のファイルを参照することが出来ていないようだが,もう少しいじれば,なんとかなりそうな気がする. 時間が出来たら,ch32funやarduinoの設定を検証して,また挑戦してみよう.

Read more...

UIAPduinoでADC

先日,UIAPduinoでserialとi2cを使ったら,flashの容量オーバーになってしまった. 一方,serialとADCを使った適当なプログラムをコンパイルしたら,9kバイト程度だったので,これなら十分にflashに書き込めた. 少し戸惑ったのがピンの指定で,例えば,analogRead(1)だと,ピン番号が1のA0では無くA1になるようだ. analogRead(A1)などとしても動くのだろうが,内部ではA1は0xc1などと表されているようだ. ADCを使うプログラムなら,容量が小さくできるch32funやAlexanderManderaさんの環境を使わずにすむのだが,それらではどの位のサイズになるのか知りたくなるものである. しかし,AlexanderManderaさんの環境では,ADCは実装されていない. 仕方が無いので,自分で書いてみた. 以下の内容の~/.arduino15/packages/alexandermandera/hardware/wch/0.0.2/cores/arduino/wiring_analog.cppというファイルを作る. #include "Arduino.h" #include "ch32v003fun.h" #include "wiring_private.h" static int write_resolution = 8; static int read_resolution = 10; void analogWrite(pin_size_t pin, int val){} void analogWriteResolution(int bits){} int analogRead(pin_size_t pin) { uint8_t adc2gpio[] = {0,0,2,3,3,3,3,3}; uint8_t adc2pin[] = {2,1,4,2,3,5,6,4}; uint8_t gpio = adc2gpio[pin & 0x07]; GPIO_TypeDef* port = gpioRegister(gpio); uint8_t p = adc2pin[pin & 0x07]; // ADCCLK = 24 MHz => RCC_ADCPRE = 0: divide by 2 RCC->CFGR0 &= ~(0x1F<<11); // Enable GPIO* and ADC RCC->APB2PCENR |= (0x04 << gpio) | RCC_APB2Periph_ADC1; // P*p is analog input chl n port->CFGLR &= ~(0xf<<(4*p)); // CNF = 00: Analog, MODE = 00: Input // Reset the ADC to init all regs RCC->APB2PRSTR |= RCC_APB2Periph_ADC1; RCC->APB2PRSTR &= ~RCC_APB2Periph_ADC1; // Set up single conversion on chl n ADC1->RSQR1 = 0; ADC1->RSQR2 = 0; ADC1->RSQR3 = pin; // 0-9 for 8 ext inputs and two internals // set sampling time for chl n ADC1->SAMPTR2 &= ~(ADC_SMP0<<(3*pin)); ADC1->SAMPTR2 |= 7<<(3*pin); // 0:7 => 3/9/15/30/43/57/73/241 cycles // turn on ADC and set rule group to sw trig ADC1->CTLR2 |= ADC_ADON | ADC_EXTSEL; // Reset calibration ADC1->CTLR2 |= ADC_RSTCAL; while(ADC1->CTLR2 & ADC_RSTCAL); // Calibrate ADC1->CTLR2 |= ADC_CAL; while(ADC1->CTLR2 & ADC_CAL); // start sw conversion (auto clears) ADC1->CTLR2 |= ADC_SWSTART; // wait for conversion complete while(!
Read more...

UIAPduinoでI2C

AHT10という温度と湿度を読み取れるセンサーを,UIAPduinoを使ってI2Cから読み取って,Serialに出力させるプログラムを作ってみた. センサーの使い方を調べていたら,ArduinoにAdafruitのライブラリがあって,データシートを読むよりも,これを参考にやってみることにした. まずは,UIAPduinoの環境でAdafruit_AHT10を使ってやってみようとしたら,プログラムはコピペですぐに書けたが,プログラムのサイズがflashに入らないとエラーが出た. 噂には聞いていたが,WCHのArduinoはかなり大きくなってしまう. それではと,Adafruitのライブラリを外して,SerialとWireを初期化して,コンパイルしたら,もうサイズがギリギリになっている. センサーに初期化コマンドを送るところまで書いたら,サイズオーバーである. 仕方が無いので,ch32funを使うのはややこしいので,AlexanderManderaさんの環境を使うことにした. I2Cの使い方は,標準的なArduinoとは違うのだが, ~/.arduino15/packages/alexandermandera/hardware/wch/0.0.2/cores/arduino/hal にI2Cのサブルーチンがあり, ~/.arduino15/packages/alexandermandera/hardware/wch/0.0.2/examples/CH32V003-I2C-1 にある例を参考にしたら,それほど苦労せずにプログラムすることができる. それより,AHT10のライブラリを読み解いて,移植する方が面倒かな. 湿度と温度を読み取ってシリアルに出力すプログラムを書いて,コンパイルしたら12kバイトぐらいである. 思ったよりも大きくなったが,十分なサイズである. そのプログラムが以下のものである. calibrationはうまくいかなかったので,その終了判定はコメントアウトしている. #include "hal/wch-hal-i2c.h" #define AHT10_I2CADDR_DEFAULT 0x38 ///< AHT10 default i2c address #define AHT10_CMD_CALIBRATE 0xE1 ///< Calibration command #define AHT10_CMD_TRIGGER 0xAC ///< Trigger reading command #define AHT10_CMD_SOFTRESET 0xBA ///< Soft reset command #define AHT10_STATUS_BUSY 0x80 ///< Status bit for busy #define AHT10_STATUS_CALIBRATED 0x08 ///< Status bit for calibrated #define LED_BUILTIN 2 uint8_t data[10] = {0}; void setup() { delay(20); Serial.
Read more...

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のからシリアルモニタから見ることが出来無いのも,面倒かも知れない.
Read more...

UIAPduinoをch32funで使う方法

UIAPduinoの開発環境として,初心者にとって最も簡単なのはおそらくArduino IDEである. 新しい種類のマイコンを使うたびに,そのマイコンの仕様を勉強するのは大変だが, arduinoは,マイコンの種類をあまり意識せずに使えるという点で,優れていると思う. UIAPduinoのArduino環境は,WCH社のArduino環境を用いており,少い重いという欠点がある. また,USBを使ったプログラムを作ることができない.

もう一つのUIAPduinoの開発環境が,ch32funであり,軽くて機能も充実しているが, ch32funでプログラムを組むには,CH32V003について多少の知識が必要となる. 実は,UIAPduinoのUSBによる書き込みは,ch32funのrv003usbを使ってソフト的に実現している. 同様に,ch32funでrv003usbを使うと,USBを利用するようなプログラムも作ることができる. ちなみに,PlatformIOでは,ch32funを使うことができるらしいが,私は使ったことが無い.

ch32funでUIAPduinoを使うには, UIAPduinoのbootloaderは,ch32funのbootloaderとProductIDが異なるので,minichlinkでの書き込み時のコマンドにオプションを指定する必要がある. そこで,ch32fun/ch32fun.mkの中の

FLASH_COMMAND?=$(MINICHLINK)/minichlink -w $< $(WRITE_SECTION) -b

という行を,

FLASH_COMMAND?=$(MINICHLINK)/minichlink -c 0x1209b803 -w $< $(WRITE_SECTION) -b

に変更する. すると,普通のch32funと同様にUIAPduinoを使うことができる. minichlinkをUIAPduinoのものと入れ替えても良いのだが.

ch32funでUIAPduinoを使うもう一つの方法を紹介しておこう. AlexanderManderaさんの環境は,arduino IDEからch32funを使えるようにしたものなので,これを使うと,Arduino IDEからch32funを通して,UIAPduinoを使うことができる. Arduino IDEでファイル-環境設定として,追加のボードマネージャのURLに

https://alexandermandera.github.io/arduino-wch32v003/package_ch32v003_index.json

を入れて, ツール-ボード-ボードマネージャで"ch32"などと検索すると,“WCH Boards"が出てくるので,インストールするとこの環境が使えるようになる. そして,UIAPduinoを使えるように,以下のようにして書き込みソフトをUIAPduinoのもので上書きする.

cp ~/.arduino15/packages/UIAP/tools/minichlink-2982dfd/1.0.0/minichlink ~/.arduino15/packages/alexandermandera/tools/minichlink/1.0.0/

この環境を UIAPduinoの環境と比較をしてみよう. ファイル-スケッチ例-01.Basics-Blinkの例に,

#define LED_BUILTIN 2

を加えてUIAPduinoでコンパイルすると,6972バイトとなる. スケッチ-コンパイルしたバイナリを出力としてできるbinファイルのサイズは7140バイトである. ツール-ボード-WCH Boards-CH32V003として,環境を変えた場合のbinファイルは1640バイトである. ファイルサイズは四分の一となり,プログラムがかなりコンパクトになってることが分かる. ch32funがベースになっているので,うまく設定すればrv003usbも使えるかも知れない. このように,UIAPduinoの環境よりも,こちらの方が良いようにも思えるが,必ずしもそうとは言えない. この環境では,digital IOとSerialはarduinoと同じように使えて,i2cは少し違う形式で使うことができるが,analog IOなどはまだ使えない. また, ch32funも古いものを使っており, しばらく更新が止っているので,進展はあまり望めないように思われる. digital IOとSerialしか使わなくて良い場合を除いて,UIAPduinoの環境を使っておくのが良いのでは無いだろうか. なお上の例で,ピン番号の代わりにPC0などを使う場合には,C0としなければならないことに注意しないといけない.

Read more...

UIAPduinoを試してみた

安価でそれなりの性能のマイコンとして,WCH社のCH32V003を時々使うようになった. 最初はICを基板に半田付けして使っていたが,特に3.3Vで使いたい時には,三端子レギュレータなども使わなければならないので,面倒に感じていた. CH32V003を使ったマイコンボードとしては,WeAct Studioの開発ボードを見付けたので,少し使ってみたが,USBを使うためにはチップ抵抗を三つ半田付けしなければならないことが判った. そのままでUSBを使うことができるCH32V003のマイコンボードとしてUIAPduinoというものがあり,興味はあったが入手経路が限られていたので見送っていたが,なんと開発者の方から連絡があって,譲ってもらえることになった. 昨日届いたのだが,同じ日にUIAPduinoについての記事が出ていたので読んでみたが,興味深いものだった. 積極的に普及活動を行っているようで,大いに感謝したい. 早速,少し使ってみたので,Debian13でのArduino IDEからUIAPduinoを使う方法を説明したい. まずはArduino IDEをaptでインストールする. sudo apt install arduino arduinoを立ち上げると,UIAPduinoには関係しないが,dialoutのgroupに追加するかを聞かれるので,addを指定する. ここでインストールされるarduinoのversionは1.8.19であり, UIAPduinoの公式ページによると,このversionは動作確認されていないそうだが,aptで簡単に使えるversionで使えた方が良いので,以下ではこのversionについて説明する. UIAPduinoを使えるようにするために,ファイル-環境設定として,追加のボードマネージャのURLに https://github.com/YuukiUmeta-UIAP/board_manager_files/raw/main/package_uiap.jp_index.json を入れて, ツール-ボード-ボードマネージャで"uiap"などと検索すると,UIAPduinoが出てくるので,インストールする. そして,USBでの書き込み権限を与えるために,以下のコマンドを実行する. 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 インストール作業は基本的にはこれで終了であるが,このversionでは書き込み時にエラーが出るので,少し後に説明するような修正が必要である. それでは,実際の使い方である. 新しいUIAPduinoをUSBに接続すると,二つのLEDが点灯し,一つのLEDが点滅する. 明るさがゆるやかに変化するので,PWMでも使っているのかな. arduino IDEではボードの種類を,ツール-ボード-CH32V EVT Boards Support-Pro Micro CH32V003と選択する. 別のボードをインストールしている場合には,“CH32V EVT Boards Support"が複数出てくることもあるが,その下に"Pro Micro CH32V003"だけがあるものを選択する. 一番簡単な例として, ファイル-スケッチ例-01.Basics-Blinkを選んで,LEDをon/offするプログラムを呼び出す. setup()よりも前に, #define LED_BUILTIN 2 という行を追加する. ボードのピン番号の2の代りに,ICのピンの名前のPC0でも良い. しかし,いざ書き込みをしようとすると,コンパイルが終った後に, 書き込み中にエラーが発生しました:設定パラメータの「upload.params.quiet」が見つかりません というエラーが出てしまう. これを回避するためには,設定ファイル ~/.arduino15/packages/UIAP/hardware/ch32v/1.0.42/boards.txt の適当な場所に, CH32V00x_EVT.upload.params.quiet= CH32V00x_EVT.upload.params.verbose= という行を追加して,arduinoを立ち上げ直せば良い. すると,書き込み時には
Read more...

picoRuby

ESP32を使うときには,私は主にmicropythonを使っていた. C言語よりはpythonの方が楽なので. micropythonでは,binaryを書き込んだら,pythonのコードをマイコンが実行してくれる.

esp32ではmrubyというrubyを使うことも出来るが,rubyのコードをPC側でコンパイルしてマイコンに書き込む必要がある. 手順も複雑なので,素人向では無いと感じて,手を出さなかった. mrubyも進化しているようで,mruby/cという小さなRAMで動かせるものも開発されているが,大まかな使い方はmrubyと同じようである.

mruby/cについて調べていたら,picoRubyというものもあることを知った. microの次はnanoなのに,それを飛ばしてpicoになったのは何故かなと思ったら,raspberry pi pico用に開発されたものだからのようだ. 使い方はmrubyと似ているのかなと予想したが,micropythonと同じように使うことができる. それなら使ってみようかなということで,試してみることにした.

raspberry pi picoが必要だが,手元にあるRP2040-zeroを使うことにした. まず,binaryをここから最新のものをdownloadして,展開する. pico用とpico2用があるが,今回は前者に対応しているのでそれを選ぶ. daily buildなどは無いようなので,最新のコードのbinaryが必要な場合は,自分でbuildしないといけない. BOOTを押しながらUSBに接続すると,RPI-RP2というmediaがマウントされるので,そこにuf2ファイルをコピーする. インストールはこれで終了である.

しばらく待ってからRESETを押すと,/dev/ttyACM0が出来ているので,ターミナルソフトで接続する. linuxだと,例えば以下のコマンドである.

gtkterm -p /dev/ttyACM0 -s 115200

lsなどの簡単なコマンドや,rubyを使うためのirbが使える. まずは簡単な計算をやってみて,micropythonと同じ感覚で使えることを感じた. Lチカをしようと思ったけど,RP2040のLEDは簡単では無いようなので,電圧のON/OFFをやってみた.

pin = GPIO.new(1, GPIO::OUT)
10.times{pin.write(1);sleep 1;pin.write(0);sleep 1}

esp32用のpicorubyもあるけど,binaryが無かったので,今回は見送った. binaryも公開して貰えると,素人でも始めやすくなって,使う人が増えると思うので,公開してくれると助かるけどな. しかし,esp32用のpicorubyは,netには対応していないようである. esp32のwifiが使えるようになったら,micropythonの代わりにpicorubyを使って行きたい. 開発が進むのを待つことにしよう.

Read more...

WeActStudioのCH32V003開発ボード

WCH社のCH32V003というマイコンを時々使うようになった. 当初は,ArduinoにWCHサポートをインストールして使っていたが,ソフトで実装したUSBを使うことができるch32funを使うようになった. 特にUSB用のbootloaderを書き込むと,以降はWCHLinkを使わずにUSBから書き込みが出来て便利である. しかし,マイコンそのものを使ってUSBを使えるようにするには,USBを繋げるようにしたり,3.3Vを作ったり,33Ωと1.5kΩの抵抗を接続したりしないといけないので,それなりの手間がかかる. そこで,CH32V003を使ったマイコン開発ボードを試してみることにした. いくつかの開発ボードが作られているようだが,小型で手に入りやすいという理由から,WeActStudioのものを使ってみることにした.

WeActStudioからは様々なボードが発表されており,それらはAliexpressから入手できる. 今回はCH32V003F4U6 Mini Core Boardを選んで, USBは通常は電源の供給のみであるが,回路図を確認すると,少し改造するとUSB通信が出来るように設計されていることが解る. 基板のUSBと書いてあるところの近くに三つの空きのランドがあるが,USBという文字に近い方の二つには33Ω,残りの一つに1.5kΩのチップ抵抗を半田付する. そして,ch32funのrv003usbでは,以下のように設定する.

#define USB_PORT D
#define USB_PIN_DP 3
#define USB_PIN_DM 4
#define USB_PIN_DPU 5

WCHLinkをつなぐための端子もあるので,それを使ってプログラムすることができ, rv003usbのbootloaderを使う場合にも,最初はそれを使って書き込む. 空きのランドの形が,半田で繋いで短絡しやすいようになっていたので,最初は短絡して試したがうまくいかず,回路を追い掛けたら抵抗が内蔵されていないので,それを半田付する必要があることに気が付いた.

PD5がUSBのDPUに使われてしまうために,USBを利用するときには,使えるピンの数は3つ減ってしまう. DMを3.3Vに直結すれば,PD5を開放できるのだが,それはこのボードでは簡単には実現出来無い. また,PD7がNRSTとして使われているために,スイッチとコンデンサに接続されており,これらを切り離してPD7を独立した入力ピンとして使えないのも残念なところである. そのため,実質的に使えるピンの数は,14である.

WeActStudioのCH32V003開発ボードでUSBを使うためには,二種類のチップ抵抗を用意して,それらの三つを半田付するというのが,少し面倒だが,ICから準備するよりはかなり楽になる. CH32V003を使ってUSBが扱えるマイコンボードであるUIAPduinoは,安価な上に半田付なども無しでUSBからプログラムを書き込めるようなので,このマイコンでUSBを使おうとしている人は,このボードの方が良いかも知れない. 入手経路が限られているために,これまで使ったことは無いのですが.

Read more...