ソニーSpresenseマイコンのIMUアドオンボード
はじめに
ソニーセミコンダクタソリューションズは、2025年2月26日に、期待のマルチIMU Add-onボードを発売開始しました。これは、IoT(Internet of Things)マイコンボードSpesense(スプレセンス)用のオプションです。そこで、このIMU Add-onボードをSpresenseに接続して、センサ値を読み出してみます。
IMU(Inertial Measurement Unit、慣性計測装置)とは、3次元の慣性運動を計測する装置です。物体の運動は、XYZの3軸方向の加速度と、ロール・ピッチ・ヨーの3軸方向の角速度との、合計6データにて記述できます。IMUは、例えばスマートフォン画面を横に向けたことを検出して横画面表示にするなど、広く用いられています。
このマルチIMU Add-onボードのすごいところは、16個の民生IMUをリアルタイム合成して、地球自転をも検出できる程度の角度安定性を達成したことです。ずっとこのIMUの販売を楽しみにしていました。
セットアップ
このマルチIMU Add-onボード(以下、IMUアドオン)の出力を観測するため、これとSpresenseと接続し、Spresenseにデータ読み出しソフトウェアを書き込みます。
IMUアドオンの商品ケース内には、本体のほかに、ミニスペーサ4個と、プラスチック板4枚が入っていました。IMUアドオンの表面には8個のIMUが、裏面にも8個のIMUが、それぞれ見えます。
私は、このミニスペーサとプラスチック板は何に用いるのかがわかりませんでした。これらは、SpresenseボードとIMUアドオンを水平に保つためのものと判断して、プラスチック板2枚を重ね、これをメインボード下にミニスペーサにて取り付けました。
Spresenseでのソフトウェア開発には、大きくわけて(1) Arduino(アルディーノ)統合開発環境(IDE: integrated development environment)の利用と、(2) ソニーが用意したSDK(software development kit)の利用、の方法があります。前者は、コードのコピーペーストとビルドボタンにて、簡単にSpresenseにソフトウェアを書き込めます。しかし、現在のところ、このIMUアドオンのためのArduinoライブラリはないようです。したがって、このIMUアドオンを利用するため、後者のSDKを用います。
SDKのセットアップ方法は、公式ホームページのSpresense SDK スタートガイド (CLI 版)に詳しく記載されています。ここに書かれた通りに実行して、シリアルターミナル上に「Hello, World!」の文字が表示されるよう、「1. はじめに」から「3.4 シリアルターミナル上での動作確認」まで、セットアップを進めましょう。私は、普段利用のmacOSにこのSDKをセットアップしました。
このセットアップの過程で、ブートローダ更新を促されましたので、指示通り、Spresense firmware v3.3.0にブートローダを更新しました。
特に難しいところはないのですが、すべてのコマンドはsdk
ディレクトリで実行する一方で、コンフィギュレーションに設定するディレクトリはその一つ上の階層spresense
ディレクトリからのディレクトリを指定する点について、私は迷いました。カレントディレクトリからの指定ではないので、zshやbashのタブキー補完が効かなく、やや不便です。
スタートガイドにある通りにコマンド入力してnuttx.spk
ファイルを作成し、flash.sh
コマンドにてSpresenseボードに転送します。このファイル作成には、私のPCで数分の時間がかかりました。
マルチIMU Add-onボードの利用
このSDKには、IMUアドオンのサンプルコードとして、cxd5602pwbimu
とcxd5602pwbimu_logger
が用意されています。これらは、spresense/examples
にあります。この順に試してみます。
cxd5602pwbimu
は、1920 Hzサンプリングなどの固定パラメータで一定時間だけセンサ出力を表示するサンプルコードです。spresense/examples/cxd5602pwbimu/Kconfig
から、実行コマンドはpwbimu
であることがわかります。先の例のhello
の代わりに入力するコマンド名です。
spresense/sdk
ディレクトリにて、次のコマンドを実行し、Spresenseにコードを書き込みます。
tools/config.py examples/cxd5602pwbimu
make
tools/flash.sh -c /dev/tty.usbserial-1110 nuttx.spk
screen /dev/tty.usbserial-1110 115200
ここで、/dev/tty.usbserial-1110
は、このSpresenseボードに割り当てられた私のPCのUSBシリアルポート名です。
sat@imac:~/Documents/github/spresense$ cd sdk
sat@imac:~/Documents/github/spresense/sdk$ tools/config.py examples/cxd5602pwbimu
sat@imac:~/Documents/github/spresense/sdk$ make
Create version.h
LN: platform/board to /Users/sat/Documents/github/spresense/sdk/apps/platform/dummy
Register: pwbimu
Register: nsh
Register: sh
CPP: /Users/sat/Documents/github/spresense/nuttx/boards/arm/cxd56xx/spresense/scripts/ramconfig-new.ld-> /Users/sat/Documents/github/spresense/nuttx/boards/arm/cxd56xx/spresense/scripts/ramconfig-new.ld.tmLD: nuttx
Generating: nuttx.spk
tools/cxd56/mkspk -c2 nuttx nuttx nuttx.spk;
File nuttx.spk is successfully created.
Done.
sat@imac:~/Documents/github/spresense/sdk$ tools/flash.sh -c /dev/tty.usbserial-1110 nuttx.spk
>>> Install files ...
install -b 115200
Install nuttx.spk
|0%-----------------------------50%------------------------------100%|
######################################################################
181152 bytes loaded.
Package validation is OK.
Saving package to "nuttx"
updater# sync
updater# Restarting the board ...
reboot
sat@imac:~/Documents/github/spresense/sdk$ screen /dev/tty.usbserial-1110 115200
NuttShell (NSH) NuttX-12.3.0
nsh>
NuttShell (NSH) NuttX-12.3.0
nsh> pwbimu
0.092992,26.591146,-0.01619748,-0.23048346,0.02748845,-0.07734343,0.33981058,10.76876831
0.093361,26.430176,0.00046417,-0.00264232,0.00019141,-0.61184335,0.34893215,10.55052567
0.093811,26.430176,-0.00673335,0.01806999,-0.00034304,-0.73535728,0.31970680,9.96086502
0.094345,26.430176,-0.07595222,0.18320066,-0.02274963,-0.17296591,0.33223009,10.11776829
0.094842,26.430176,-0.29470262,0.39317381,-0.11702106,0.17736650,0.37389147,10.16028023
...
1.080991,26.236328,0.00015397,0.00139313,-0.00030057,-0.56398875,0.21613172,9.78222084
1.081496,26.236328,0.00086656,0.00183487,-0.00041829,-0.56039059,0.21698044,9.79057312
1.081966,26.237793,0.00050225,0.00172483,-0.00011609,-0.55839735,0.22385406,9.77645874
1.082428,26.235840,0.00025167,0.00153740,-0.00010724,-0.56194043,0.22314039,9.77366066
Elapsed 0.989746288 seconds
1920 samples captured
Finished.
nsh>
ソースコード spresense/examples/cxd5602pwbimu/cxd5602pwbimu_main.c
によると、左からタイムスタンプ、気温、3角速度、3加速度を示すようです。このIMUアドオンには温度センサがついているようです。
for (p = outbuf; p < last; p++)
{
printf("%.6f,%.6f,%.8f,%.8f,%.8f,%.8f,%.8f,%.8f\n",
p->timestamp / 19200000.0f,
p->temp,
p->gx, p->gy, p->gz,
p->ax, p->ay, p->az);
}
次に、cxd5602pwbimu_logger
を実行します。ソースコードによると、サンプリングレートや感度を設定できるほか、出力先もファイルやネットワークが選べるようです。
printf("Usage: nsh> pwbimu_logger ([-s] <rate>) ([-a] <acc range>) "
"([-g] <gyro range>) ([-f] <fifo num>) ([-o] <out dev>) "
"([-d]) ([-h])\n");
printf(SPACE__ "-s: Sampling Rate 1920, 960, 480, 240, 120, 60, 30, 15\n"
SPACE__ "-a: Accel Range 16, 8, 4, 2\n"
SPACE__ "-g: Gyro Range 4000, 2000, 1000, 500, 250, 125\n"
SPACE__ "-f: Fifo size 4, 3, 2, 1\n"
SPACE__ "-o: Output Device 'uart', 'net', "
"/path/to/file.bin, /path/to/file.txt\n"
SPACE__ "-d: Force print the data to UART\n"
SPACE__ "-h: Show this help\n");
先と同様に、このコードを実行してみます。コマンド名はpwbimu_logger
です。
tools/config.py examples/cxd5602pwbimu_logger
make
tools/flash.sh -c /dev/tty.usbserial-1110 nuttx.spk
screen /dev/tty.usbserial-1110 115200
nsh> pwbimu_logger
Start IMU Data logging: Rate:960 Accel DRagne:16 Gyro DRange:500 Fifo:4 Outdev:uart
00299ac7,41cb9c00,3c981d38,bc033675,3bbfbfe2,3f736004,3d938218,4113e5c8
0029eabb,41cb9c00,3cb778b2,3d642fe4,b9191f99,3f76abfe,3d6dba41,4112f6c4
002a3640,41cb9c00,3c930218,3dccfdb5,bbddb754,3eba40e0,3e758e85,4118d7fa
002a8056,41cb9c00,3c5d498e,3ddbf96a,bba6923c,bd9bdd02,3ec86e52,41214017
...
こちらのコードは、連続的に実行されます。出力は、自動では止まりません。規定値は、960 Hzサンプリング、加速度レンジ16、角速度レンジ500、FIFO(first input first output、バッファ)サイズ4です。このコードでは、出力先やフォーマットを変更できるよう、出力関数に関数へのポインタ参照が利用されていて、オプションをつけないときは関数log2uart
が実行されます。この結果は、先ほどと同様にタイムスタンプ、気温、3角速度、3加速度のようですが、これらが16進数で表現されています(なんでだろう…?)。
fprintf(fp, "%08x,%08x,%08x,%08x,"
"%08x,%08x,%08x,%08x\n",
(unsigned int)dat[i].timestamp,
((conv_f2u_t)dat[i].temp).u,
((conv_f2u_t)dat[i].gx).u,
((conv_f2u_t)dat[i].gy).u,
((conv_f2u_t)dat[i].gz).u,
((conv_f2u_t)dat[i].ax).u,
((conv_f2u_t)dat[i].ay).u,
((conv_f2u_t)dat[i].az).u);
私が試した範囲では、ファイルへの出力ができませんでした。cat
コマンドで新規ファイルを作ることができないので、別の方法であらかじめファイルを作成する必要があるようです。
このIMUアドオン向けのArduinoライブラリが公開されたら、迅速にIMUアプリが開発できて、楽しくなるでしょう。例えば、Spresense内蔵GNSSによる、みちびき災害危機管理通報メッセージのデコード機能は、先にSDK版が公表されて、すぐのちにArduinoライブラリが公表されました。
Spresenseにアドオンを追加するのは楽しい
私は、Spresense用のGNSSアドオンも持っています。今後、GNSSアドオンとIMUアドオンを用いた統合測位ができるようになる噂もあるようです。
GNSSアドオンがあると、その中のMRAMを汎用メモリとして利用できます。
System: GNSS RAM (640KB)を汎用メモリとして使用できる機能を追加しました。 詳細は、GNSS RAMメモリ使用機能について をご参照ください。
Spresense内蔵のフラッシュメモリには書き込み回数の寿命がありますが、GNSSアドオンのMRAM(磁気抵抗変化型メモリ、Magnetoresistive Random Access Memory)は、書き込みに対して高耐久です。ただし、MRAMの書き込み速度は、フラッシュメモリの書き込み速度の1/8です。GNSSアドオンボードのGNSS機能とMRAM機能は排他利用です。
また、イーサネットアドオンも持っていますので、ネットワーク経由での長時間観測もできそうです。これらにて、地球自転の長時間観測を目指してみようと思います。
おわりに
Sony SpresenseのマルチIMUアドオンボードを利用してみました。高性能なIMUを利用するのは楽しいです。