Groovy-IoTとkikoriでGroveのセンサーを繋いでみました
はじめに
Groovy-IoTは、大宮技研さまが開発/販売されている、Grove仕様のセンサーやデバイスをUSB経由で使用するための開発用アダプタボードです。電子工作の知識がなくても、センサやデバイスをPCやMacOSまたはRaspberry Piに接続することで、データを取得したり、デバイスをコントロールすることができます。
特徴の数々はこちらに紹介されています。
Groovy-IoTボードが9月から販売開始となったということで、試用する機会を頂戴しました。ちょっと遅くなりましたがレポートします。購入はマルツから可能とのことです。
Groveとは
Grove Systemとは、SeeedStudio社により提供されているデバイスが使用している仕組みです。共通の4ピンのコネクタを使って接続を行います。信号の種類として、GPIOやシリアル、SPIやI2C、アナログ信号など、複数の種類がありますので、目的に合わせてコネクタの位置や設定を適切に選択する必要があるので少し注意が必要です。
ハードウェア
Groovy-IoTボードを観察してみます。ボードには、4つのGroveコネクタ、そしてmicro USBが用意されています。
Groveコネクタにはそれぞれ、
- I2C
- UART
- GPIO1
- GPIO2
とシルクでラベルが振られています。
基板には赤いジャンパーピンが挿入されており、5Vと3.3Vを切り替えるようです。デフォルトでは3.3Vが選択されている状態のようです。
表にはバージョン番号、裏にはURLが記載されています。裏側には部品は無しです。シンプルですね。
試してみる
MacBook ProにGroovy-IoTボードを接続してみました。ハードウェア的にはMCP2221 USB-I2C/UART Combo
として認識されます。
UARTとあるので、シリアルを利用できるようです。接続すると下記のようにデバイスノードが作成されました(macOSの場合)。ドライバのインストール無しにシリアルを認識できるのは大変良いですね。
$ ls -l /dev/cu.usbmodem1421 crw-rw-rw- 1 root wheel 20, 5 Sep 18 13:46 /dev/cu.usbmodem1421
ソフトウェア
Groovy-IoTには、サポートするソフトウェアとしてkikoriが用意されています。 https://gitlab.com/myst3m/kikori
HTTPやWebSocketのインターフェースを通して、Groovy-IoTに接続したデバイスを利用することのできる仕組みとのことです。gitlab.comでソースも公開されています。コンパイル済みのファイルが用意されているので、そちらを使ってみることにします。Closureで記述されているので、Java環境が必要です。使い方はREADMEに説明があります(英文ですが)。
こちらの説明のとおりコンパイル済みファイルをダウンロードして準備します。
$ wget https://theorems.co/kikori/kikori-system-latest.tar.gz $ tar xfz kikori-system-latest.tar.gz
kikoriとGroovy-IoTを接続する
デバイスをkikoriに認識させるには、設定が必要です。どのポートをどう使うのか、どんなデバイスが接続されているのかを登録する必要があります。今回試した範囲では、examplesフォルダに用意されているファイルをそのまま使用することができました。設定の内容はリンク先を参照してください。
設定ファイルとして、examples/reference.clj
を使用してkikoriを起動してみます。あらかじめMacBookにGroovy-IoTを接続しておきます。
こんな感じで起動しました。ConfigureするかY/Nのプロンプトが表示されるので、Yと入力しておきます。
$ ./kikori run examples/reference.clj ...snip... CLASSPATH: .:./kikori-1.0.0.jar ============ Device Configuration ============ {:system {:PCB "1.0.0", :power :5.0}, :GP1 nil, :GP3 nil, :sensors {GP0 {:name "GP0", :bus :GP0, :id "423e75ca-1b9f-459b-a5fd-8b2e38779945", :module :GPIO, :configured? true}, ADC2 {:name "ADC2", :bus :GP2, :id "fc81ec02-f222-45c8-98cc-8efa85a564fc", :module :ADC2, :configured? true}, BME0 {:addr 0x76, :name "BME0", :module :BME280, :bus :I2C, :id "01664d2f-3016-4a12-ab14-ea57aa4f3024", :configured? false}, BME1 {:addr 0x77, :name "BME1", :module :BME280, :bus :I2C, :id "30dff654-855a-4e6f-9c4c-89bd06fb45be", :configured? false}, D6T44L0 {:addr 0xa, :name "D6T44L0", :module :D6T44L, :bus :I2C, :id "741d60e2-55a6-4555-8b54-fd04c3fee972", :configured? false}, ADXL3450 {:addr 0x53, :name "ADXL3450", :module :ADXL345, :bus :I2C, :id "15e3ed81-8112-4651-8d06-d7f8b3568fc3", :configured? false}, GPS {:name "GPS", :module :GPS, :bus :UART, :id "5b9df2fe-85a0-4385-8a48-91d5b28d0ea3", :configured? false}}, :uart {:path "/dev/tty.usbmodem142301", :baud-rate 9600}, :GP2 :ADC2, :GP0 :GPIO, :product-id 0xdd, :vendor-id 0xd8} ============================================== Configure the device with above ? (Yes [Y] or No [N]) y Booted Web server on 0.0.0.0 : 3000 Welcome to Kikori shell ! - Run (quit) when you want to exit. groovy-iot>
GPIOやADCという表示が見えます。その他、型番から推測するに、
- BME280 : 気圧温度センサー(I2C接続)
- D6T44L : 放射温度計(I2C接続)
- ADXL3450 : 6DOF(加速度&ジャイロ)センサー(I2C接続)
- GPS : GPS(シリアル接続)
に対応しているようです。UART(シリアル)は、デバイスノード名が使用するUSBポートにより変化するので適切に設定する必要があるようです(ウォーニングが出ていました)。
デバイスを用意する
Groovy-IoTを試すには、何か実際にGroveに対応したセンサーなどが必要です。今回は、SeeedStudioのGrove IoT Kit、そしてM5GO IoT Starter Kitに含まれているセンサーを使ってみることにします。
- タッチセンサー
- 温度センサー
- 照度センサー
- LED
- 環境センサー(BME280) ←M5GO IoTキットに付属のセンサー
タッチセンサー
まずはGPIOに接続する例としてタッチセンサーを試してみます。GP0がGPIOとして定義されており、そして回路図を調べるとGroovy-IoTのGPIO1というGroveコネクタには、GP0とGP1が配線されているようです。キットに含まれているケーブルを使用してGPIO1コネクタに接続します。
kikoriが起動している状態では、HTTP経由でセンサーにアクセスすることができます。curlを使用してアクセスしてみます。
$ curl -s 'http://localhost:3000/read?target=GP0' | jq . { "result": "success", "value": [ 0 ], "target": "GP0" }
valueが0として読むことができました。
続いて、センサーに触れた状態で、再度curlでアクセスしてみます。
$ curl -s 'http://localhost:3000/read?target=GP0' | jq . { "result": "success", "value": [ 1 ], "target": "GP0" }
今度は1として読むことができました。無事アクセスできているようです。
次はアナログタイプのセンサーです。
温度センサー
アナログタイプのセンサーを接続するためには、ADCとして設定されたポートに接続する必要があります。ADC2がGP2を使用するよう設定されていました。GP2とGP3は、GPIO2コネクタに配線されていますので、アナログタイプのセンサーはGPIO2コネクタに接続します。
ADC2からデータを取得してみます。サンプル数を指定します。そしてそのデータを平均化するよう指定しています。
$ curl -s 'http://localhost:3000/read?target=ADC2&type=mean&sampling=12' | jq . { "result": "success", "value": 504, "target": "ADC2", "type": "mean", "sampling": "12" }
504という値が取得できました。
温度を変えてみるため、指先で温めて再度データを取得してみます。
$ curl -s 'http://localhost:3000/read?target=ADC2&type=mean&sampling=12' | jq . { "result": "success", "value": 519, "target": "ADC2", "type": "mean", "sampling": "12" }
数値が大きくなったことが確認できました。センサーが反応しているようです。
照度センサー
同様にアナログタイプとして照度センサーを試してみます。同様にGPIO2に接続します。
明るい時
$ curl -s 'http://localhost:3000/read?target=ADC2&type=mean&sampling=128' | jq . { "result": "success", "value": 621, "target": "ADC2", "type": "mean", "sampling": "128" }
暗い時
$ curl -s 'http://localhost:3000/read?target=ADC2&type=mean&sampling=128' | jq . { "result": "success", "value": 128.765625, "target": "ADC2", "type": "mean", "sampling": "128" }
数値の変化が確認できました。
LED
入力ではなく出力もできるようですので、センサーではなくLEDを光らせてみます。
Groveキットに、LED用の基板が入っています。これをGPIO1に接続します。
GP0を使用して、writeコマンドをHTTPで送信します。1を送ると点灯します。
$ curl -s 'http://localhost:3000/write?target=GP0&value=1' | jq . { "result": "success", "target": "GP0", "value": "0" }
0を送ると消灯となります。
$ curl -s 'http://localhost:3000/write?target=GP0&value=0' | jq . { "result": "success", "target": "GP0", "value": "0" }
電子工作の定番、Lチカをやってみます。シェルのwhileループで交互に点滅させます。
$ while true; do > curl 'http://localhost:3000/write?target=GP0&value=0' > sleep 0.5 > curl 'http://localhost:3000/write?target=GP0&value=1' > sleep 0.5 > done >/dev/null
環境センサー(BME280)
I2Cタイプのセンサーとして、M5GO IoTキットに入っていた環境センサーにBME280が入っていましたので、試してみたところGroovy-IoTでも使えました。I2Cとシルクの入った専用のGroveコネクタに接続します。
idとしてBME280を指定して、sensorというパスでアクセスしてみます。ちゃんと気圧と温度が取れているようです。湿度は数値が入っていませんね。
$ curl -s 'http://localhost:3000/sensor?ids=BME0&ids=my-sensor' | jq . { "BME0": { "pressure": 1011.7045230117417, "temperature": 22.120117237471277, "humidity": 0 } }
一覧を取る
scanでセンサーの一覧を取得できます。
$ curl -s http://localhost:3000/scan | jq . { "result": "success", "v": [ { "name": "GP0", "module": "GPIO", "bus": "GP0", "async": false }, { "name": "ADC2", "module": "ADC2", "bus": "GP2", "async": false }, { "name": "BME0", "module": "BME280", "bus": "I2C", "async": false }, { "name": "GPS", "module": "GPS", "bus": "UART", "async": true } ] }
一度に全部取得する
idを指定せず、sensorにアクセスすると全部一気に取得することもできるようです。
$ curl -s 'http://localhost:3000/sensor' | jq . { "GP0": [ 0 ], "ADC2": [ 620 ], "BME0": { "pressure": 1011.7045230117417, "temperature": 22.120117237471277, "humidity": 0 } }, "GPS": { "result": "error", "msg": "Timeout" } }
ただし、GPSは接続していないので、エラーになっています。
まとめ
Groovy-IoTボードを試してみました。シンプルなハードウェアですが、kikoriというソフトウェアレイヤを使用することで、HTTP/WebSocketのインターフェースが使えるようになります。使用するデバイスを決めたら、適切に設定を行い、kikoriを起動する必要があります。今回はいくつかのセンサーやLEDについてHTTPでのアクセスを試してみました。普通にJSONでデータが取れるので、あとはWeb開発の手法で開発を行うことができるでしょう。
kikoriについての記載が大宮技研さんのWebにはほとんどありませんが、Gitlabのソースツリーに英文のドキュメントが用意されています。これを読み解くことでなんとか利用することができた感じです。組み合わせて使用可能なセンサーやデバイスについて、具体的な情報が提供されているとより良いのではないかなと感じました。事例や資料の充実に期待したいところです。