ここからは、Genuino 101で追加された機能を簡単に紹介したい。

RTC(Real Time Clock)

RTCが内蔵されたので、日付時刻の取得が容易になった。日時に関してはyear()/month()/day()/hour()/minute()/second()で現在のRTCの時刻が取得できるし、設定はsettime()が提供される。

またCurieTimerOneというライブラリが用意され、任意の時間で割り込みを掛けたり、PWM割り込みを行ったりすることも可能だ。Sketchのサンプルも用意されており(Photo37)、直ぐに試す事も出来る(Photo38)。

Photo37:RTCに関してはReadとSetが別々のSketchでサンプル提供される

Photo38:ReadTest Sketchの実行例。初期値を設定していないので、1970年からカウントアップされるのは仕方がない

IMU(Inertial Measurement Unit)

6軸センサーに関係するAPIはCurieIMUでまとめて提供される。こちらは7種類のSample Sketchが用意され、やはり簡単に試すことができる(Photo40)。

Photo39:ちなみにここに含まれて居ない、Curie IMU Orientation Visualizerというサンプルもある

Photo40:Accelerometer(加速度計)のSample Sketch実行中。5秒毎にサンプリングして結果を出力する

BLE(Bluetooth Low Energy)

BLEに関してはCurieBLE Libraryという形でかなり多くのAPIが用意されている。基本的にBLEの場合、一番ローレベルで言えばシリアル通信的に利用できるのだが、serial関数と異なり、実際には通信するお互いのID(UUIDと呼ぶ)を定めるとか、GAP(General Advertising Profile)あるいはGATT(Generic Attribute Profile)として定義されたProfileを利用するなど、規則が厳しいので、UARTの代わりにBLEを……と軽く取り組むと結構大変なことになる。

とはいえ、とりあえず簡単に試せるSketchのSampleが提供されている(Photo41)。一番簡単なところでLEDを試してみよう。必要なのは、BLEに対応したスマートフォン/タブレット(AndroidもしくはiOS)である。筆者はNexus 6を利用した。

Photo41:ここには表示されてないが、ほかに心拍数計(Heart Rate Monitor)のSampleも用意されている

またこのスマートフォンにはBLEの操作が行えるアプリケーションが必要である。Arduino.ccでは"nRF Master Control Panel (BLE)"を薦めているが、iOSではほかに"LightBlue Explorer - Bluetooth Low Energy"などでもいいらしい(筆者はiOSデバイスは保有していないので未確認)。

まずArduino上でLEDのSketchをビルドしてGenuino 101にダウンロードし、ついでにシリアルコンソールも開いておく。後はスマートフォン側の作業だ。以下はNexus 6(Android 6.0.1)環境での例となる。

Bluetoothデバイスの一覧を開く。ここでLEDというデバイスが見つかるはずだ(Photo42)。見つけたらペアリングを済ませておく(Photo43)。次にnRF Master Control Panel (BLE)を立ち上げる。Scannerタブには何も表示されない(Photo44)が、BondedタブにはペアリングしたLEDがあるはずなので、これをConnectする(Photo45)。

Photo42:当たり前だがBluetoothをまず有効にしないと意味がない

Photo43:ペアリングすると名前の変更が可能だが、ここでは放置

Photo44:ちなみにこのソフトを作成したのは、Bluetooth Modemで有名なNordic Semiconductorである。もちろん無償

Photo45:もしPhoto43で名前を変更すると、ここには変更された名前が出てくる

すると3種類のUUIDが表示されるはずだ(Photo46)。LEDの制御は、一番下の"19b10000-e8f2-537e-4f6c-d104768a1242"なので、これをクリックすると展開される(Photo47)。続いて上向き矢印をクリックすると値の書き込み(Photo48)になるので、まず型を"UINT 8"に切り替え(Photo49)、ついで1を書き込む(Photo50)と、Genuino 101のLEDが点灯する(Photo51)。同様に0を書き込むと、消灯する。

Photo46:このUUIDそのものはSketch内で決め打ちで定めているので、Sketchを変更すればUUIDも他のものになる

Photo47:ReadとWriteのPropertyがあることが示される

Photo48:TypeがBYTEのままだとうまくいかない

Photo49:型はいろいろ選べる

Photo50:New Valueに"1"を入れて、"SEND"を押す

Photo51:赤丸で囲った部分のLEDが点灯/消灯する。右のものは電源Onで点灯するLEDなので無関係

というわけでNexus 6からGenuino 101のLEDをBLE経由で操作できるというデモである。シリアルコンソールにはその様子が表示される(Photo52)。

Photo52:Nexus 6から操作を行うと、こんな具合にログが示される

その他

ほかにCurie専用のものとしては、CurieEEPROM(Photo53)があるが、これはAVRベースのArduinoで用意されるEEPROM Libraryが使えないためで、こちらの代替となる。同様に、CurieSoftwareSerialも元々のArduinoのSoftwareSerial LibraryがAVRを前提としたものなので、代替として用意される。

Photo53:使い方はおおむね従来のEEPROM Libraryと同じだが、Curieでは書き込みが32bit Alignでないといけないという制限がある。このため、write()/update()には、これを8bit Alignで行えるようにするwrite8()/update8()という関数が新たに追加された

Photo54:ただこちらは、APIレベルでの見た目は全く一緒であり、どのボード向けにビルドするかの設定でライブラリが切り替わるので、専用と言いつつ既存のSoftwareSerialと基本的には互換である

注意事項 - Genuino 101はUSBが鬼門

ということで、EEPROM以外は既存のArduino UnoのSketchがそのまま動作すると思われるGenuino 101であるが、USB-Serial関連でちょっと難点がある。1つは、電源投入からUSB-Serialの起動まで時間を要するケースがあることで、USB-Serialの機能が立ち上がるまで待つことが推奨されている。具体的に言えば、Arduino Unoだと

void setup() {

  Serial.begin(9600);

}

で、Serialの初期化は終了だが、Genuino 101では

void setup() {

  Serial.begin(9600);

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

}

という具合に、Serialが利用可能になるまでsetup()の中で待機するコードを追加することになる。ちなみにArduino Unoでこれを実行しても支障がない(直ぐにwhileループから抜ける)ので、別に追加する事による悪影響はないのだが、既存のコードを利用する場合は初期化ルーチンにこれを追加するのが好ましい。

これと関連する話だが、Genuino 101のUSBポートは非常にピーキーである。ほとんどの場合でUSB 3.0ポートは使えない。Photo55は、USB 2.0ポートにGenuino 101を繋いだ状態で正常に動作することを確認したうえで、USB 3.0ポートに差し替えて再ダウンロードを行った例だが、こんな具合に通信が不可能である。ちなみにデバイスマネージャで見ると、ちゃんとCOM4:は存在している。

Photo55:"Master Resetボタンを押せ"というので押したのだが、復帰しないままタイムアウトになった形

また、USB 2.0ポートなら安心というわけでもなく、USB 2.0のHubを挟んだら通信不能になったケースもある(動いたケースもあるので不可解なのだが)。厄介なのが、デスクトップPCでマザーボード上にUSB Hubチップを搭載してポート数を増やしている場合で、こうなるとUSBのRoot Hubに直結しているポート以外では使えないなんてこともある。

もっといってしまえば、筆者の環境ではちゃんと動作したのは、IntelのICHに直結されているUSB 2.0ポートのみであり、オンボードで搭載されるASMediaなどのUSBコントローラに繋がるポートでは全滅だった。

USBドライバの不安定さにも問題がある。"Cannot open DFU device 8087:0aba on PC"というエラーメッセージが出て、そもそも通信できない(必ずしもUSB 3.0ポートだけではなく、2.0ポートでも出る場合があるらしい)という現象がいくつかレポートされている。

根底にあるのは、Arduino Uno R2から利用できる様になったDFU(Device Firmware Upgrade)Driverにある。DFUそのものはUSB-IFで2004年に仕様が策定されているもので、Photo56がそのシーケンスだ。ファームウェアをダウンロードし終わったら通常の通信モードに復帰できる仕組みである。Arduino Unoなどではこれがちゃんと動作するのだが、どうもGenuino 101のドライバではこれが正しく動作する環境が極めて限られているようだ。

Photo56:ファームウェアをロード後、USBのみをリセットして通信を継続できる仕組み

Arduino ForumのThreadを見ると、すくなくともIntelもこの状況を把握しており、Arduino LCCのメンバーと共同で解決しようと努力しているようだが、いまの所はまだ現象は解決していない。このあたりは将来解決することを期待するのみだ。

あと、若干のバッドノウハウを紹介したい。このUSBドライバに絡んで、フォーラムの別のThreadで、ドライバを入れなおしたら動作したという話がでた。ドライバの場所は

C:\Users\<ユーザー名>\AppData\Local\Arduino15\packages\Intel\tools\arduino101load\1.6.4+1.18\drivers

にあり、ここのdpinst-x86.exe(32bit)ないしdpinst-amd64.exe(64bit)を起動して再インストールすれば良いという話だったのだが、やってみたところUSBポートそのものが消え、不明のUSBデバイスが出現してどうしようも無くなるという現象に直面した。ということで、ドライバの入れなおしはお勧めしない。

もう一つのバッドノウハウだが、GPIOやADCはいずれもレベルシフタを介して接続されている。レベルシフタの入力電圧は最大5.5Vということになっているのだが、ここにうっかり10Vで信号発生器の出力を与えてしまった。その結果どうなるかというと、Digital I/Oに関しては全く問題なく動作した。

ところがAnalog Inputについては、その10Vの信号をピンに繋ぐとUSBの接続が解除される(ピンを切り離すと復活する)という謎の振る舞いをした。10Vなんぞを突っ込む方が悪いのはわかっているのだが、Arduino UnoやGalileo Gen2では全く問題なく動作したのでつい油断していた。そんなわけで、定格外動作を行った場合の振る舞いが若干違うということは念頭において欲しい。

まとめ

一通りGenuino 101を試してみた。総じてうまく使えるというか、Arduino Unoよりも価格が高いが、それ以上に性能や機能が強化されている印象で、センサーハブとして使うにも手ごろである。

最近は同程度の価格でRaspberry Pi 3が入手できてしまうから、どっちを使うか悩む人もいるだろうが、デバイスを直接いじりたい(別にOSは要らない)という筆者の様な人種には、やはりArduino/Genuinoの手軽さは魅力であり、既存製品とほぼ同等の使い勝手なのは魅力的である。難点はやはりUSBまわり。ただこれはソフトウェア側の問題に思えるので、いずれは解決することを期待したいと思う。