前回まさかのmicro:bit v1.5(nRF51系)ではTinyGoはADCをサポートしていない件発覚。しかしmicro:bit v2(nRF52系)ではADCが使えるような雰囲気。今回は実際にmicro:bit v2でADCでアナログ電圧を読めることの動作確認をしてみました。v2ならば動くし、性能も良いのよ。
※「GoにいればGoに従え」Go関連記事の総Index
micro:bit v2にターゲットを交換
BBC micro:bitにはいくつかのバージョンが存在しますが、v1.xとv2.xの間のギャップは大きいです。搭載しているNordic社のチップが、nRF51822からnRF82833に変更されてますが、nRF51系とnRF52系のハードの差が大きいのであります。メモリなどもnRF52系は余裕をかましてますが、今回対象のADCもスペックからして異なります。
-
- nRF51系: 10ビットADC
- nRF52系: 12ビットADC
制御方式も異なるみたい。そのため、nRF52用のADC制御の関数はnRF51では使えないっと。知らんけど。
以下に今回実機確認のためのボードの様子を掲げました。治具から取り外したv1.5ボードと取り付けたv2.0ボードが並んでます。上がv1.5で、下が2.0です。裏面をひっくり返すとv2.0の方はv2と書いてあります。表面はよく似ていますが、見分けるコツはオーバルの中に点2つのmicro:bit の「お顔」にあります。
-
- v.1.x系。。。顔も色付き
- v2.x系。。。顔は金色(電極になっていてタッチセンス対応)
上記ではアナログ電圧をテストするために外付けの可変抵抗を取り付けて実験してます。
今回動作確認用のTinyGoコード
TinyGoの通常の(他のチップと同じ)方法でADCから値を読み取ることができます。以下では、P0端子(micro:bitのカードエッジの「大きい5端子」のうち0と書いてある端子)を使うこと以外はすべてデフォルト、お任せにしています。これで5秒に1回、ADCからアナログ値を読み取って標準出力に4桁の16進数で送っています。
package main import ( "fmt" "machine" "time" ) func main() { machine.InitADC() sensepin := machine.ADC{Pin: machine.P0} sensepin.Configure(machine.ADCConfig{}) for { val := sensepin.Get() fmt.Printf("%04x\r\n", val) time.Sleep(time.Second * 5) } }
なお、Goのソースを見た感じでは、実はADCの初期化とか不要なんじゃないかという気がしないでもないです。
なお、16進で出力しているのはちょっとクセのあるビット配置で出力されることが分かったためです。
ビルドして実行
今回からターゲットボードが変わったので、ビルド時のターゲット指定が microbit-v2 に変わってます(編集にVScodeを使っている場合は、VScodeのプラグインでもターゲットとしてmicorobit-v2に変更する必要があります。)
$ tinygo flash -target=microbit-v2
上記で書き込んだ後に、TeratermProでmicro:bit v2からの出力をモニタしたものが以下に(何も指定しないと、出力のボーレートは115200。)
上記は取り付けたボリュームを回しながら値を見ているのですが、nRF52系のADCの最大ビット幅である12ビット分の値が送られてきていることがわかります。ただし、上記を見ると下4ビットに0の下駄を履いてました。有効なのはビット15からビット4みたいです。
Documentation / Reference / Microcontrollers / Machine package / microbit
TinyGoの上記のマニュアル・ページでは、0から0xFFFFまでの16ビットみたいなことを書いてますが、上記を見れば下は常に0みたいっす。
しかたがないので今後はV2でTinyGoの実験続けたいと思いますが、V1.xとV2でLEDが違うのだよな~。やり直す?