ハード側の知識がロクにない状態で、Edisonを活用してモノ作りができるのか?についてレビューしたいとおもいます。
1stインプレッションでわかったこと
- 本体がすげえ小さい、しかもドーターボードも小さい。
- ドキュメントも情報も英語が多い。
- 中身はLinux。マイコンというより画面のないパソコン?
1/17現在の進捗(最終締め切り:1月18日23時59分)
●:Edisonのセットアップ
●:部品の調達(電圧電流センサ、ブレッドボード、ケーブル、コネクタ)
●:開発環境の用意、Node.jsの参考情報の調査
●:ハードウェアの試作
●:サーバー側ソフトウェアの開発(Node.js、mraaライブラリ)
●:ログ出力。CSV形式
●:HTMLでリアルタイム値の表示 → socket.ioを使ってクライアント側に転送
●:クライアント側ソフトウェアの開発(Javascript、グラフ化は別途ライブラリを調達)
●:リアルタイム値の画面表示 → socket.ioを使いました。
●:グラフの作成 → Google Chart APIを使用しました
×:見た目が悪いのを直す →試作なので、レポート作成を優先。見れるので問題なしとします。
●:ログデータの保存をする →CSVを保存する処理を入れました。
紆余曲折してますが、ブラウザで表示できるようになりました。
・1秒毎に電圧と電流を表示
・5秒毎に電圧と電流のグラフを更新
1/18未明、ファイル保存機能を作りました。
もともとEdison側でファイルを保存しているんですが、ファイル保存はブラウザ側の機能を使ってデータの配列をファイルへ書き出すようにしました。見た目には「ログ保存」ボタンが増えただけですが、内部処理はあちこち変更しました。
1/18昼、1秒に1回のサンプリングで一晩ほど運転してみましたが正常に動いています。
ブラウザ側にデータ配列をもたせているためかメモリ使用量が500MB弱まで膨れ上がっています。
実用化するなら、サンプリング周波数を下げるかデータの持ち方を見直す必要がありますね。
本体が小さすぎる。ドーターボードほぼ必須。
ニュースサイトでもSDカードサイズと報道されたとおもいます。
本当に本体が小さいです。
実際にSDカードを隣に並べてみました。ついでに単3電池も並べてあります。
冗談みたいなサイズですが、CPUもRAMもディスクも無線LANもBluetoothも入っています。
無線LANにいたっては5GHz帯も使用可能です。
外部とのI/Fは裏側に70ピンのごく小さなコネクタがあります。
コネクタの種類は公開されてるので入手は可能ですが、小さすぎて気楽にハンダ付けできるレベルではありません。
なので、基本的にはコネクタなどをのせたドーターボードに接続します。
インテルでは2種類のドーターボードを用意しており、今回のレビューでは初心者向けの大きなボードが試作用に提供されています。
これがドーターボードです。Arduinoとほぼピン互換らしいです。
ボードの下に敷いてあるのは、一般的なハガキです。
大きい方のボードですらハガキの3/4しかありません。
小さい方のボードだとフリスクケースにギリギリ入らないくらいだそうです。
側面にはUSB端子が3つ、電源端子が1つ、スイッチが1つあります。
microUSB端子が2つありますが、シリアルコンソール用とEdison直結用です。
セットアップの際にEdisonに入っているLinuxを更新する必要がありますが、そのときは2系統とも使います。USB3.0ポートに接続すると不具合が出るためUSB2.0ポートに繋ぐかUSB2.0ハブを介する必要があります。
セットアップですが、箇条書きにすると4つだけです。
- パソコン側にFTDIとIntelのドライバをインストール
- Edisonのファームウェアを更新
- Edisonのファームウェア設定
- パソコンに開発環境をインストール
4つだけなんですが、それぞれの手順書が英語で公開されています。
英語と言っても手順だけなら中学生でわかるような英語なので、まあなんとかなるとおもいます。
Edisonで動かすソフトウェアの開発ですが、いくつか手段があります。
- Intel製のArduinoIDEで開発する
- Intel XDK for IoTを使ってJavascriptで開発する
- Node.jsをXDKなしで使う
- C言語やシェルスクリプト、LinuxPCとして使う
大本の選択肢は2つ、Intel製のIDEを使うか否かです。
前者2つがIntel製IDE、後者2つがそれ以外です。今回はXDKとNode.jsを使用して開発を行いたいとおもいます。ユーザーインターフェースとしてWebブラウザを使うつもりなので、
クライアント側もサーバー側も同じ言語で開発できたほうが好都合と考えました。
ド素人にはハードルが高い。
Edisonは出たばかりということもあり、あまりハードウェアの情報がありません。
さらにプログラミング言語としてArduinoを使っていないため、さらにハードルが上がりました。
まず1つ目のハードル。
Intel XDK IoT Editionからプログラムを動かすのに苦労しました。
動かすために、以下の手順をこなしました。
- Edisonのファームウェアを最新にする。
……実はファーストインプレッションでやってました。 - PCにIntel XDK IoT Editionをインストールする。
- PCにBonjourをインストールする。
※XDKがインストールすることを要求してきます。ダウンロードリンクまで案内してくれました。 - XDKと同じネットワークに繋がるよう、Edisonの無線LANを設定する。
- Edisonの基板端側のUSBポートをPCに接続する。
なおEdisonの電源はACアダプタを使っています。 - Edisonにログインする。
XDKにSerialTerminalがあるので、そこから処理するのが簡単です。 - PCのIPアドレスを調べる。
今回は192.168.0.11でした。
コマンドラインで「ipconfig」と入力すれば調べられます。 - EdisonのXDKデーモンにPCのIPアドレスを追加する。
「xdk-whitelist --add 192.168.0.11」 - xdkデーモンを再起動する。
……わからない場合はEdisonで「reboot」とタイプしてOSもろとも再起動してください。 - PC側のXDKから、IoT Deviceのリストを'ReScan for Devices'で更新する。
デバイスが見つからない場合は幅の狭いプルダウンリスト、幅が広くなる。
- IoT Deviceにリストアップされなければ、'Add Manual Connection'でEdisonのIPアドレスへ接続する。
- 時刻が合わないので合わせろという指示があるので、手動で時刻を合わせるコマンドを送信する。
ここまでやるのに、実は2時間かかりました。
インテルの公式サイトで情報を探しながらの手探り状態だと、結構手こずります。
日本語の情報が増えればいいんですが……。
2つ目のハードル、言語の問題。
Javascriptなら仕事で使いましたが、Node.jsは使ったことがありませんでした。
Intel XDK IoT Editionでは、Node.jsを使ってプログラムを作ります。
最初の取っ掛かりは容易なんです。
付属していたサンプルコードでLEDを点滅させるのは、プログラムを書く必要すらありませんでした。
3つ目、「ハードとソフトの両面でトラブルの原因を探す必要がある」ということ。
たとえば、電圧/電流を計測するセンサー。
- ハードウェア:「I2Cバスのプルアップ抵抗はどうするの?」
→プルアップ抵抗は、Edisonに内蔵されていました。つまり、プルアップ抵抗は不要です。 - ソフトウェア:「I2Cバスに書き込みしてもレスポンスが来ない」
→EdisonではI2Cバスが複数あり、バスID'6'が正解でした。しかし間違った値でもエラーが出ませんでした。 - ソフトウェア:「I2Cバスでの通信方法がわからない」
→調べました……。勉強しないとわからない部分が多いです。 - ソフトウェア:「取得した電圧の値と、テスターでの電圧が合わない」
→散々調べたあげく、2バイトのデータで上下が逆でした。ハードウェアの仕様です。 - ハードウェア:「表示用のLCDを接続したらI2Cバス全体がダウンした」
→配線ミスでした。 - ソフトウェア:「LCDにデータを書き込んでも表示ができない」
→LCD用のライブラリがなく、独自に制御する必要がありますが……調べるのが追いつきませんでした。
→upmというライブラリに互換性のあるドライバがあったんですが、理解が追いつかず制御できませんでした……今回は時間の都合で制御を諦めました。 - ハードウェア:「USBバスに負荷をかけたら、電圧が急降下した」
→ブレッドボード用の配線が細くて抵抗値が高くなったようです。GND側の配線と、電流センサー側の配線を増やしました。
→→状況の改善は不完全ですが、とりあえず計測できるので続けます。
試作には気楽
今回の試作でキモになったのが、I2C接続の電圧/電流センサーINA226です。
事実上、コレをEdisonに接続しただけという感じです。
ブレッドボード上にレイアウトしましたが、USBケーブルをセンサー直結に配線しなおせばボードすらいらないかと思います。
ブレッドボード中央部、配線が集中してるのがINA226モジュールです。
モジュールにはICチップと小さな抵抗が実装されており、電圧と電流をこれだけで計測できます。
I2Cバスはバス上にプルアップ抵抗が必要ですが、今回はEdisonに内蔵されてました。
左側は表示用の液晶です。これもI2Cバスで接続しています。
液晶は制御ソフトが作れず、今は動かない状態です。(もしくは自分がミスって現物を壊している?)
ボードの右側は、給電用USB-microBコネクタと、負荷用USB-Aコネクタです。
接続するデバイスの自由度を持たせるためにUSBコネクタを付けました。
太い配線を付けたいので、本格的に実装するならUSB-Bコネクタのがよさそうです。
INA226に配線がやたらと多いのは、配線の抵抗値を減らすためです。
ブレッドボード用の配線は先が細く、大電力を流すには抵抗が大きいのです。
※マネする方は乗用車用などの太いケーブルを使ってください。今回は電流が少ないので大丈夫ですが、大電力を流すと最悪は発火します。
ブレッドボードからEdisonへの配線は、4本だけになります。
4本の内訳は、
- 電源(3.3V)
- GND
- I2C:データ(SDA)
- I2C:クロック(SCL)
になります。I2Cバスを動作させるのに必要なのはこれだけです。
今回はArduinoボードごと提供されたのでピンがスカスカになりましたが、
小型のドーターボードで必要な分だけ引き出せばよりコンパクトにすることができます。
性能はいいけど、資料探しが大変
ソフトウェアは、Edison側で動かすサーバーソフト、ブラウザ側で動かすクライアントソフトの2つになります。
サーバー側はIntel XDK IoT Editionで作成しました。
Node.js、つまりサーバーサイドJavascriptを使っています。
助かったのが、ネット上に情報が豊富にあること。
リファレンスも日本語で読めるのは、非常にありがたいです。
サーバーサイドJavascript(Node.js)での開発が初めてでしたが、躓いたのがモジュールのこと。
Node.jsでは機能拡張用のモジュールが無数に存在します。
普通はnpmというツールで必要なモジュールをインストール、ソースコードでrequire('<モジュール名>')と書けばOKでしたが、XDKだとそれで動かない。
なぜか?
……ソースコード作成時にpackage.jsonというファイルを用意して、モジュールが必要ならそこに記述する必要があるのです。
XDKで実行する環境はシリアルコンソールでログインするユーザーとは別のNode.js環境が構築されているようです。
そこにはモジュールがインストールされておらず、必要な分をインストールするのです。
そもそもJavascriptはコンパイルする必要のない言語です。
にもかかわらずXDKにBuildというコマンドがあるのは、必要なモジュールを組み込んだりするための処理が必要だということでしょう。
これがわからなくて、ものすごくタイムロスしました。
最終的に以下のようにしました。
2行目の"name"は、ソースコードの元にしたテンプレートの名前がそのままになっています。
動作には影響しないのでほったらかしです。
9行目の"dependencies"が、必要なモジュールの記述をするセクションです。
記法はJSON形式、中身の作法はnpmのそれと同じです。
ソースコードをアップロードした後にnpmにこのファイルを処理させて必要なモジュールを手配させるようになっている、と思われます。
メッセージが高速で流れるので細かくはわかりませんでした。
XDKは、こういう部分の情報が非常に少ないんです。
英語なら情報があるのかもしれませんが、探しにくい印象がずっと抜けませんでした。
意識して追加したのは、socket.ioとhttpの2つです。
isarrayとcomponent-emitterはデバッグ中にエラーが出て止まってしまうため追加しました。
モジュールか自分が書いたソースコードに依存した箇所があったようです。
httpはNode.jsにWebサーバーをさせるためのモジュール、socket.ioはサーバーとブラウザ間のデータ通信をさせるために入れています。
どちらもNode.jsでは割りと定番のモジュールです。
サーバー側の処理は、起動時の逐次処理と、イベントドリブンの処理を定義しています。
起動時は、
- I2Cバスへアクセスするため、mraaライブラリをrequireでコール
- 使用するI2Cバス(6番)を指定。
- 開発用にログファイルを保存するため、fsライブラリをrequireでコール
- INA226を初期化する
・動作モードを設定
・電流計測用のパラメータを設定 - ログファイルのヘッダを出力。今回は”/tmp/log.txt”へCSV形式で出力
起動時に既存ファイルを上書きしています。少し修正すれば消さずに追記もできます。
本来はファイル名を日付でファイル名を細々と変更するべきですね。 - socket.io用にサーバーを建てるため、httpライブラリをrequireでコール
- socket.ioライブラリをrequireでコール
- ポート8080でWebサーバーを起動。レスポンスは常に200(正常応答)、HTML代わりにダミーメッセージを返すよう設定。
- socket.ioにポート8080を指定して待機させる。
というふうにしています。
あとはクライアント側からアクセスが有ったあとのイベントドリブン処理です。
- クライアントから接続があったら、ログファイル用のヘッダを送信。
受信したクライアントがログファイル用のヘッダにします。 - 1秒毎にINA226から電圧と電流を読み込む。
読み込んだ数値は16ビットの整数なので電圧と電流の形式に変換して渡しています。
書式はカンマ区切りです。そのままCSVに出せます。 - クライアントからメッセージがあった場合は、そのまま返信します。
この機能は参考にしたサンプルを転用したので残っていますが、現状だと不要です。
サーバー側の処理は、全部でこれだけです。
ソースコードは、最終的に104行になりました。サーバーとしては非常に短いコードです。
クライアント側は、ブラウザ上で動くJavascriptを使いました。
一般的なWeb系の技術そのままです。
こっちは仕事で関わってたので、ノウハウが活用出来ました。
HTMLファイルが1つ、Javascriptファイルが1つで実装しました。
<head>でjqueryとsocket.ioを読み込んでいます。
両方共、CDNでミラーリングされているものを使っています。
XDKを動かす以上ネット接続は必ずしていますので、これで問題ないと判断しました。
<body>でも特に難しいことはしていません。
電圧を表示する場所に#rVA、グラフを表示する場所に#gVと#gAのIDを設定してあります。
これらはあとからJavascriptで置き換えます。
置き換え処理にjQueryを使っています。
グラフ部分はtableタグを使ってしまったので、スマホだと右がはみ出す可能性があります。
スマホ対応も狙うのであればtableを使わずにCSSでレイアウトする方がよいと思います。
最初はグラフがないので同じ大きさのダミー画像を作って表示させています。
Windows付属のペイントで数分で作ったやつなので、文字通りの穴埋め用です。
クライアント側の処理はclient.jsというファイルを作って記述しました。
これも80行弱なので、比較的シンプルにできています。
処理内容は、
- socket.ioでサーバー側に接続。
IPアドレスとポート番号は直接書き込んでいます。
ダサいですが、試作なので割りきりました。
この部分はHTMLファイルを表示した際に自動実行します。 - 「ログ保存」ボタンの処理。ボタンが押された時のイベント処理です。
受信データの配列を1つの文字列として結合、log.csvというファイルとして保存させます。
IEのみ独自関数による実装があるためブラウザを判定して処理を分岐しています。 - サーバー側からのメッセージ受信時のイベントドリブン処理
ログファイル用にデータを配列化、CSV形式のデータ分割、リアルタイム値の表示、グラフデータの作成をしています。 - データの配列化は、配列.push(受信データ)としています。
Javascriptの機能を使っています。 - CSV形式のデータ分割は、受信データ.split(",")としています。
これもJavascriptによるものです。分割結果は自動的に配列になります。 - リアルタイム値は、以下のようにしています。
分割データを浮動小数点に変換
HTMLタグと、桁数制限をかけた数値を結合
jQueryで#rVAのID部分を置換 - グラフは5秒に1回、Google Chart APIの旧バージョンを使って作成しています。
IMGタグにAPIのURLとパラメータを記述するだけで、グラフ化した画像を返してもらえます。
実装が簡単な旧バージョンを使いました。 - グラフはIMGタグをjQueryで書き換えています。
画像の生成はGoogleで行ってます。 - グラフデータは、最大でも25件としています。
データ件数が多いとリクエストURLが長くなり、GoogleのAPIが受け入れられる限界を超えてしまうため制限をかけています。 - グラフデータを最新25件だけ取り出す処理はJavascriptのsliceを使っています。
配列の長さ-25から配列の長さ-1まで、という指定をすると最新25件になります。
リクエストURLを短くするために桁数制限も別途かけています。
という実装をしています。
コードは全部自前……ではなく、ネットから参考になる処理を探しながら実装しています。
ある程度はコーディング経験あるんですが、関数とかをすべて把握してるわけではないので調べ物が増えてしまいました。
ログ保存したファイルは、CSV形式になっています。
ブラウザでは25データですが、Excelで開けばデータ全体のグラフを作ることもできます。
※ただしExcelはデータ件数に制限があり32000件で打ち止めになるバージョンがあったと思います。
↑がファイルの中身(の一部)です。
電圧部分が桁数が多くなっているため、画面表示する際は桁数の制限が必要でした。
ちなみにCSV形式なのは、自分が扱い慣れているからです。
JavascriptならJSON形式を使うのも手ですが、ファイル出力するにはCSV形式のが好都合ですし、データが少ないのでCSVでいけると判断しました。
データ順序が不定期に入れ替わったりするならJSONのが便利なんですけどね。
まさにIoT向け。
Edisonは、まさにIoT向けデバイスだなというのが評価です。
今のIntelの方針に沿ってるんですね。
最初からNode.jsが動くし、Wi-Fiも2.4/5GHzの両方に対応してる。
初期設定でOFFになってますがBluetoothも使える。
I/Oも必要十分に揃ってるし、USBにも対応してるからマイコンだとつながらないカメラなんかもつながる。
だからこそ、インターネットで通信してナンボかなと思います。
単体で間に合うなら処理速度以外にメリットが少ないですから。
そこを踏まえて機材選びをするといいんじゃないでしょうか。
最後に。
Edisonのレビューで苦労したことは?と聞かれたら「情報の少なさ」と答えると思います。
調べるのに苦労しました。
EdisonとXDKの両方ともに出てからあんまりたってませんからね。
その点ではハードルの高いデバイスだったなと感じました。
ZIGSOWにログインするとコメントやこのアイテムを持っているユーザー全員に質問できます。