最近耳にするようになった「IoT(Internet of Things)」。 しかしARや人工知能と比べると技術ではなく概念であるため漠然 としている感じも否めません。そのためIoTって結局何? という思う方も多いのではないでしょうか。 ただ企業のCMなどでもIoTの文字がやっと見え始めてきたので 、まだまだこれからの分野だと思います。
今回は、 IoTデバイスであるInetel社の極小コンピュータ「 Edison」で加速度を計測し、 その情報をopenFrameworks(以下、oF) にOSC通信で送ってみたいと思います。Edisonについては こちらを参照ください。
(1) Edisonセットアップ
セットアップについては、多くの記事が出回っていますので、ここでは軽く触れさせていただきます。この作業の過程で特に躓いた点は最後にまとめて記述しますので、
・ ファームウェアアップデート
使用したイメージは以下の通りです。
1 |
Weekly-149(edison-image-ww18-15) |
初期設定時はusbケーブルで接続しシリアル通信でログインしま す。
1 |
screen /dev/cu.usbserial-A903BYAS 115200 -L (AA903BYASは環境で変化します) |
接続が完了したらログインします。
1 |
edison login : root |
ログイン後、ファームウェアを書き換えます。
1 |
reboot ota |
・ Edison設定
基本設定とwifi設定( wifiのみの設定はconfigure_edison –wifi)
1 |
configure_edison --setup |
→ifconfigコマンドでネットワーク環境を確認
その後は割り当てられたIPアドレスまたはホスト名でSSHログ インが可能です。
1 |
ssh root@192.168.0.0 |
or
1 |
ssh root@hoge.local |
(2) Edisonの組み立て
Edisonだけでは加速度情報は取得できませんので、 加速度センサーを取り付けます。また、 便宜的にバッテリーを搭載します。今回センサー/ バッテリーはSparkfun社から販売されているものを使用し ました。
加速度センサー
|
|
バッテリー
|
Edisonに付属するネジとナットだと微妙に数量と長さが足り
組み立て後はこのような感じになります。
後述しますが、この状態だと途中で「同じWi- Fiに入っていないから設定し直したいけど、 SSHでログインできない!」 となってもシリアル通信はできないので、ご注意ください。 その場合は、 都度付属のBreakoutボードに付け替えてUSB接続するか 、Sparkfun社から販売されているBase Blockを重ねて組み立てるのも一つの方法です。
ちなみにですが、バッテリーはもって2~3時間程度。 短いですね。。
(3) 送信側の実装(Edison)
それでは加速度情報の取得とOSC通信のためにEdisonにラ イブラリ等を組み込んでいきます。 使用ライブラリは以下の通りです。どちらもC++ となっています。
加速度取得
|
SparkFun_9DOF_Block_for_
(C++)
|
OSC通信
|
OSCpack (C++)
|
加速度取得のライブラリは使用したSparkfun社の加速度セ ンサー(9 Degrees of Freedom)のページからダウンロード可能です。
OSCpackは公式サイトからダウンロード。
今回使用したファイルの一覧は以下の通りです。
SparkFun_9DOF_Edison_Block_
|
今回編集したファイル
|
SFE_LSM9DS0.cpp
SFE_LSM9DS0.h
|
SparkFun_9DOF_Block_for_
|
IpEndpointName.cpp
IpEndpointName.h
NetworkingUtils.cpp
NetworkingUtils.h
OscException.h
OscHostEndianness.h
OscOutboundPacketStream.cpp
OscOutboundPacketStream.h
OscTypes.cpp
OscTypes.h
PacketListener.h
TimerListener.h
UdpSocket.cpp
UdpSocket.h
|
OSCpack
|
それでは9軸センサーのSparkFun_9DOF_ Edison_Block_Example. cppを編集していきます。各軸の値はインスタンス化したimuから読み出せます。加速度であれば、imu->calcAccel(imu-> ax)のようなで値を取得可能です。 このままでもコンパイルすれば9軸の値(加速度、角速度、 地磁気)は取れますが、今回は加速度情報のみを抽出し、 またわかりやすくするため、加速度センサーの各軸の値を合成し、 3軸合成値(S[g])に変換します。3軸合成値にすると、 静止時はほとんど1を示し、投げ上げると0(無重力) に近い値を示します。
1 |
S = sqrt(x * x + y * y + z * z) |
実際のコードは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#include "mraa.hpp" #include "SFE_LSM9DS0.h" #define ADDRESS “送信先のIPアドレス” #define PORT 8000 #define OUTPUT_BUFFER_SIZE 1024 //SFE_LSM9DS0 setup LSM9DS0 *imu; imu = new LSM9DS0(0x6B, 0x1D); imu->readAccel(); imu->readMag(); imu->readGyro(); imu->readTemp(); //OSC setup UdpTransmitSocket transmitSocket( IpEndpointName( ADDRESS, PORT ) ); char buffer[OUTPUT_BUFFER_SIZE]; osc::OutboundPacketStream p(buffer, OUTPUT_BUFFER_SIZE ); //3軸合成値に変換 double s = sqrt( pow((double)imu->calcAccel(imu->ax), (double)2)+pow((double)imu->calcAccel (imu->ay), (double)2)+pow((double)imu->calcAccel(imu->az), (double)2) ); //oscメッセージの生成 p << osc::BeginBundleImmediate << osc::BeginMessage( "/acc" ) << (float)s << osc::EndMessage << osc::EndBundle; //OSCメッセージの送信 transmitSocket.Send( p.Data(), p.Size()); //メッセージの初期化 p.Clear(); |
編集したファイルとライブラリをEdisonに組み込みます。 Edisonを起動し、SSHでログインしましょう。その後はC yberduck などを使用し、 Edisonに割り当てられたIPアドレスで接続すれば簡単にフ ァイル転送できます。
(4) 受信側の実装(oF)
次に受信側となるopenFrameworks側の実装を行いま す。 ofxOscをAddonとして組み込んでおくことを忘れずに行 いましょう。PORT番号はEdison側と合致させます。 今回は受信した加速度情報をとりあえずログ出力させてみたいと思 います。
【ofApp.h】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#pragma once #include "ofMain.h" #include "ofxOsc.h" #define PORT 8000 class ofApp : public ofBaseApp{ public: void setup(); void update(); void draw(); void keyPressed (int key); void mouseMoved(int x, int y ); void mouseDragged(int x, int y, int button); void mousePressed(int x, int y, int button); void mouseReleased(int x, int y, int button); void windowResized(int w, int h); private: //OSCメッセージの受信者 ofxOscReceiver receiver; }; |
【ofApp.cpp】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
void ofApp::setup(){ ofBackgroundHex(0xFFFFFF); receiver.setup(PORT); } void ofApp::update(){ while(receiver.hasWaitingMessages()){ ofxOscMessage m; receiver.getNextMessage(&m); if(m.getAddress() == "/acc"){ float s = m.getArgAsFloat(0); ofLogNotice() << “acc: " << s; } } } void ofApp::draw(){} |
(5) 動作確認
それでは、Edison側のファイルをコンパイルし、 値を受け取れているか確認してみましょう。 まずSparkFun_9DOF_Edison_Block_ Example.cpp以外は実行ファイルにしておきます。 例のような感じです。
1 |
例) g++ -c SFE_LSM9DS0.cpp → SFE_LSM9DS0.o |
それでは、ファイルをコンパイルします。
1 |
g++ SparkFun_9DOF_Edison_Block_Example.cpp SFE_LSM9DS0.o IpEndpointName.o OscOutboundPacketStream.o OscTypes.o UdpSocket.o NetworkingUtils.o -lmraa -o test -std=c++11 |
testという実行ファイルが作成されると思いますので、 そのファイルを実行します。
1 |
./test |
最後にoF側をビルドします。
ログを見ると以下のように加速度情報が受信できていると思います 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[notice] acc: 0.971346 [notice] acc: 1.0368 [notice] acc: 1.04345 [notice] acc: 0.931248 [notice] acc: 0.955241 [notice] acc: 1.06706 [notice] acc: 1.15271 [notice] acc: 0.994248 [notice] acc: 1.07018 [notice] acc: 1.13155 [notice] acc: 1.10851 [notice] acc: 1.14164 [notice] acc: 1.07822 [notice] acc: 1.13733 [notice] acc: 1.20008 [notice] acc: 1.21795 [notice] acc: 1.2453 [notice] acc: 0.969149 [notice] acc: 0.841989 |
Edisonのバッテリーの持ちが非常に短いので、 なんとも言えませんが、
ボールやおもちゃなどの小物などに組み込んだりすると、
Edisonの特徴を生かしたIoTの使い方ができるのではない かと思います。
Tips
・Edisonファームウェアの落とし込み
最新のファームウェアだとEdisonに組み込む際、 メモリがいっぱいですとエラーが出てしまいます。 初期化や隠しファイルなどを削除してもエラーが消えなかったため 、旧バージョンのWeekly-149(edison- image-ww18-15)を組み込みました。