IoT/WoTという言葉があちこちから聞かれるようになって久しいですが、最近は言葉だけではなくなってきた気がします。新しいマイコンボードや、XXセンサーのデータをクラウドに溜めて○○する商品などが続々と発売され、IoT/WoTのバックエンド専用のサービスまで登場してきています。
これから出てくるサービスやツールは、画面の中からの情報だけでなく、画面の外からの情報を使うことができそうです。逆に画面の外に影響を及ぼすようなことも可能になるかもしれません。解決できる課題の幅がグンと広がってきそうな予感がします。
加えて、先日の村岡さんの記事でも紹介されていたように、JavaScript等のWeb技術で開発できるマイコンボードも続々と登場し、IoT/WoTはWeb開発者にとっても身近なものになりつつあります。
今回はその中でもシンプルで扱いやすい、Espruino Boardを使い、JavaScriptでIoT/WoTに挑戦したいと思います。
ボードを購入するところから、温度センサの値を読み取る方法、Wifiに接続する方法について、ステップバイステップで解説していきます。「IoT/WoT、やってみたいけど敷居が高くてできない!」というWeb開発者の皆様に、一歩を踏み出すお手伝いができれば幸いです。
Espruino Boardとは
冒頭で紹介したとおり、Espruino Boardは、JavaScriptを利用してハードウェア制御ができるマイコンボードです。ざっくり言ってしまえば、ArduinoのJavaScript版のようなもので、まずはこの理解でいきましょう。
「とりあえずJSでハード制御してみる」を実現するには最も簡単で、かつ財布にも優しい選択肢とも言えるマイコンボードです。筆者もこれでIoT/WoTの第一歩を踏み出しました。
他の多くのマイコンボードと違い、自前でJavaScriptの実行環境を実装しているところも熱いポイントです。
また、Espruinoの今後の展開として注目されている、Espruino Picoについても触れておきます。Espruino Picoは、今回紹介するEspruino Boardよりもさらに小さい基盤(USBメモリサイズ)で、Espruino Board同様にJavaScriptでの制御が可能です。2015年春にプレオーダー分が出荷予定となっています。
どうしてJavaScript?
ただWeb開発者が知っている言語だから、というわけではなく、筆者はマイコン上でセンサー等のハードウェアを制御する言語として、JavaScriptは適した言語だと考えています。主な理由としては、イベントドリブンな記述がしやすいことと、setTimeoutやsetIntervalを使って、ループ処理を非同期に逃がすことができることが、挙げられます。
実際にマイコンボードを使ったサービスを運用してみると、マイコンボードにはやらなければならないことが意外とたくさんあることに気づきます。センサーの値を読みとってPOSTするだけでなく、センサー自体の死活監視のためのリクエストを投げるといった、運用のための処理や、Too Muchなリクエストの発生を避けるためにデータを間引いたりする処理がどうしても必要になります。
一例として、多くの言語がサポートする、無限ループを回しつつ、sleepで時間調整をする方法で、以下のような処理を実装することを考えてみましょう。
- 5秒に1回センサーの値を読み込む
- 1分に1回はマイコン自体の死活監視用にPingリクエストを投げる
普通に実装すると、5秒のスリープ処理の入った無限ループを作り、その中でセンサー値の読み取りを毎回実行します。Pingリクエストについてはカウンタ等を用意してIF分を切って実行有無を判定する、という実装になりそうです。やることが増えてくると、困りそうですね。
一方、JavaScriptでは2つのsetIntervalにそれぞれの処理を実装してしまえば事足ります。マイコンボードのようなpoorな環境でこれができるのは、Espruinoを始めとするJavaScriptで開発できるマイコンボードの強みであると筆者は考えています。
メインのテーマではないのでこの辺りで…
Espruinoを使い始める
では早速、Espruinoを使ってみましょう。 ボードを購入するところから、JavaScriptでLEDを光らせるところまでを、以下の流れで解説していきます。
- 必要物品を調達する
- Web IDEをインストールする
- ファームウェアをアップデートする
- JavaScriptコードを実行する
必要物品を調達する
IoT/WoTの”T”はThings、つまりモノです。何をするにもまずは物理的にモノを購入する必要があります。お金もかかる上に届くまでに時間もかかります。新しいツールをタダでダウンロードして、すぐに試せる環境に慣れ親しんだソフトウェア開発者にとっては、最初のハードルかもしれません。
でも大丈夫です。すぐに慣れて、いろいろ買いあさるようになると思います。
最低限必要になるのはコチラです。
- Espruinoボード
- マイクロUSBケーブル(Aタイプ オス/ マイクロBタイプ オス)
そしてWeb開発者であれば必ずWifiに繋ぎたくなるはずなので、以下も用意しておきます。
- CC3000 Wifi モジュール
Espruinoボードは国内販売されていないので、公式サイトにある販売サイトへのリンク一覧の中から何れかを選んで購入します。
オススメはEspruinoとCC3000の両方を取り扱っているAdfruitです。ここで一緒に買うことで、送料を節約することができます。
ちなみに筆者はseed studioより購入しました(当時、AdfruitはEspruinoを取り扱っていませんでした)。送料に積む金額によって配送期間が変わるようです。無料だと2週間程度、30ドル払ったら4日で届きました。
補足 : 公式で推奨されているモジュールとは異なりますが、CC3000については国内販売されているコチラのモデルでも動作することを確認しています。筆者の手元での確認なので保証することはできませんが、国内で調達できるので、コチラを利用するのもアリです。
Web IDEのインストール
Espruinoの上で自分の書いたJavaScriptコードを実行するには、本家から提供されているWeb IDEを使用します。Espruinoとの接続や、ファームウェアのアップデート等もサポートしているので、まずはコレを導入します。Chrome Extensionとして提供されているので、Chrome Webストアからインストールしましょう。
EspruinoとPCを接続
EspruinoのマイクロUSB端子とPCのUSB端子を繋ぎ、WebIDEを立ち上げます。立ち上がったら、画面左上の接続ボタンをクリックします。
ダイアログが表示されるので、接続するシリアルポートを選択します。OSやマシンによって選択すべき項目が異なるため、下記を参考に選択します。
- Windowsの場合 : COM# のうち、数字が一番大きいもの
- Mac OSXの場合 : /dev/tty.usbmodem1234 (1234はマシン依存)
- Linuxの場合 : ttyACM0/ttyUSB0
Web IDEの左側のコンソールにConnectedと表示され、Espruinoのアスキーアートが表示されれば成功です。
ファームウェアのアップデート
JavaScriptのコードを書く前に、まずはEspruinoのファームウェアをアップデートしておきます。出荷時期によってこの作業の要否は分かれますが、自前でJavaScriptの実行環境を実装している関係上、ファームウェアが古いと思わぬエラーが発生したりもするので、アップデートしておくことをおすすめします。
- WebIDEの右上の歯車アイコンをクリックして、設定画面を開きます。
- 設定メニューのFLUSHERを選択し、Flush Firmwareボタンをクリックします。ダイアログが表示されます。
- ダイアログの指示通り、EspruinoのBTN1(USBコネクタから遠い方のボタン)を押しながら、RSTボタン(USBコネクタ寄りのボタン)を押します。
- ボード上の青色のLEDがゆっくり点滅するはずです。
- ダイアログのNEXTをクリックし、デバイスを選択します。
- ファームウェアの更新が始まり、ボード上のLEDが激しく点滅を繰り返します。
- 完了後、ダイアログのNEXTボタンをクリックした後、ボードのRSTボタンを押します。
- 再びWebIDE左上の接続ボタンをクリックして、Espruinoと接続します。
以上でファームウェアのアップデートは終了です。
JavaScriptコードを実行する
いよいよEspruino上でJavaScriptコードを実行します。 Espruinoボード上のLEDを光らせてみましょう。 WebIDEの左側のコンソールに、下記コードを打ち込んでEnterを押してみます。
LED1.write(true);
Espruinoボード上の赤いLEDが点灯しました。 続いて下記を入力してEnterを押します。
LED1.write(false);
予想通り、LEDを消灯することができます。簡単ですね。
こんな風に対話的にプログラムを実行することができるのは、Espruinoの一つの特徴と言えると思います。Webインスペクタのコンソールのような感覚でコードを動かして試すことができるので、デバックや開発途中のお試し実行に重宝しています。
さて、ここでプログラムについても少し解説をしておきます。
LED1.write(true);
Espruinoに備え付けられているLEDやGPIOのピンは、ビルトインのグローバルオブジェクトとして、あらかじめ登録されています。上記のコードで言うとLED1がそれにあたります。このオブジェクトに対して、書き込み(‘write’)や読み込み(`read’)の命令を投げることで、LEDやピンの入出力をコントロールすることができる、という仕組みです。
Espruinoで温度を計る
前項までで、Espruinoの上でJavaScriptを実行する準備が整いました。ここからはセンサ等と組み合わせてEspruinoを使う方法について解説します。まずは温度センサ「DS18B20」を使い、Espruinoで温度を計ってみましょう。
なお、この段階からはハンダ付け等の電子工作的な作業が必要になります。筆者が以前に書いた記事になりますが、以下を参考に、Espruinoをセンサー等のモジュールに繋げる準備を行います。(ピンヘッダを取り付ける、と聞いてピンとくる方は読み飛ばしてもらって問題ありません)
また、ブレッドボードやワイヤー等、電子工作の基礎的な事柄については、以下の記事にて非常に丁寧にまとめられています。
調達
- 温度センサ「DS18B20」: おなじみ秋月電子さんより通販、店頭にて購入することができます
- 4.7kΩ抵抗 : 通販であればこちらも秋月電子さんより購入することができます。ただし、100本単位の購入になってしまうので、そこが気になるという方は千石電商秋葉原本店B1F等のバラ売りをしているお店で購入しましょう。
結線
温度センサ「DS18B20」には3つの端子がついています。それぞれの役割は、平らな面をこちらに向けて左から、GND、DATA、Vddとなります。GNDはグランドと結線するための端子、Vddは電源をとる端子です。温度のデータはDATA端子から読み取ることができます。
次のように結線してみましょう。
- 温度センサのDATAとVddを4.7kΩの抵抗で繋ぐ。
- 下記表の通り、Espruinoと温度センサを繋ぐ。
Espruinoのピン | 温度センサの端子 |
---|---|
GND | GND |
A1 | DATA |
3.3v | Vdd |
【写真だとこんな感じです】
プログラム
結線ができたら、次はプログラムです。先ほどはWeb IDEの左側のコンソールを使いましたが、今回は複数行のプログラムを実行する必要があるので、Web IDE右側のエディタを利用します。
以下のプログラムをWeb IEDの右側のエディタに記述してみましょう。温度センサから読み取った値を、1秒毎にコンソールに出力するプログラムです。
// センサーモジュールをセットアップ var ow = new OneWire(A1); var sensor = require("DS18B20").connect(ow); // 1秒ごとに温度を表示 setInterval(function() { // getTemp メソッドで温度を取得 console.log(sensor.getTemp()); }, 1000);
記述したプログラムを実行するには、書き込みボタンをクリックします。
温度センサの値がコンソールに出力されました。センサー部分を指で摘んだり、コタツの中にセンサを入れたりすることで、温度の変化を確認することができます。
ここでプログラムについて解説します。
ポイントは3行目のrequire("DS18B20")
と7行目のsensor.getTemp()
です。
7行目のsensor.getTemp()
の命令一つで温度センサの値[℃]が取得できていることに注目してください。
本来、温度センサを始めとする電子部品から読み取れるのは、電圧の値です。ここから意味のある値、つまり温度を取得するには、センサの仕様を元に、電圧値に対して何らかの計算をしてやらなければなりません。
上記プログラムでは、最初にrequireしたDS18B20モジュールがこの辺りの計算を全て隠蔽してくれているので、末端のプログラムではgetTemp()
の命令一つで温度値を取り出すことができるようになっています。下図のようなイメージです。
Espruinoでは各種ハードウェアに対応するモジュールが多数提供されており、電圧値等の生データを意識せずに、センサーの値を取得することができるようになっています(モジュール一覧)。
そしてこれらのモジュールはオープンソースとしてEspruinoDocsというリポジトリで管理されています。ここにプルリクエストを送ることで、誰でもモジュールを開発/公開することができます。筆者も最近、IoT向けプロトコルといわれているMQTTのクライアントモジュールに機能追加を行い、取り込んでもらいました。自分で自分の好きなプロダクトに手を加えられるのは、オープンソースの醍醐味ですね。
Web IDEについてもう少し
とりあえず温度センサの値を取得することに成功したので、ここでWeb IDEの使い方について、もう少し触れておきます。
コンソールとエディタの併用
例えば先ほどの温度センサのプログラム実行中に、コンソールにて下記プログラムを実行してみます。
clearInterval();
1秒毎に行われていた温度センサの値のコンソール出力が止まります。 続いて、温度を取得する命令を実行してみましょう。
sensor.getTemp();
温度が表示されました。
エディタで書き込んだコードに対して、自分の好きなタイミングで任意のコードを実行することができます。まさに、Webインスペクタのコンソール的な使い方ですね。
resetメソッド
画面左側のコンソールにてreset();
を実行することにより、書き込んだプログラムの内容をリセットすることができます。コンソールにていろいろやりすぎてわけが分からなくなってしまったときや、単純にEspruino上で実行中のプログラムの動作を止めたい場合に使用します。
Wifiに接続する
いよいよEspruinoをインターネットに繋げます。 冒頭の「Espruinoを使い始める>必要物品を調達する」で紹介した、CC3000 Wifi Moduleを用意しましょう。こちらにもピンヘッダを付ける必要があります。
結線
ピンが多いですが、慌てずに落ち着いて結線しましょう。少なくとも、GNDとVBatだけは絶対に逆にしてはいけません(多分壊れます)。
Espruinoのピン | CC3000のピン |
---|---|
GND | GND |
VBat | VIN |
B3 | IRQ |
B4 | VBEN(CS) |
B5 | CS |
B6 | MOSI(DIN) |
B7 | MISO(DOUT) |
B8 | CLK(SCK) |
プログラム
下記プログラムをWeb IDEのエディタに貼付け、wifiConfig
のssid
とkey
を、接続可能なWifiのSSIDとパスワードに編集します。
// wifi接続情報 ssidとパスワード var wifiConfig = { ssid: "", key: "" };// コネクション確立時のコールバック function onWifiConnect(s) { if (s=="dhcp") { // GETリクエストを投げる : 公式の Hello World! と返してくれるURL require("http").get("http://www.pur3.co.uk/hello.txt", function(res) { var data = ""; res.on('data', function(chunk) { // 細切れのデータを変数に足し込む data += chunk; }); res.on('close', function(){ // レスポンスが全部返ってきたら溜め込んだデータをコンソールに出力 console.log(data); }); }); } }
// CC3000Wifiモジュールに繋ぐ var wlan = require("CC3000").connect(); // wifiネットワークに繋いで、GetRequestを実行 wlan.connect( wifiConfig.ssid, wifiConfig.key, onWifiConnect);
書き込みボタンを押して、プログラムを実行します。Wifiに接続しに行くので、少し実行に時間がかかります。
コンソールに”Hello World!”と表示されました。この文字列は、Espruino本家がGetリクエスト用に用意しているURLから取得したものです。
しばらくWifiに接続していると、多少熱くなりますが大丈夫です。ただ、配線を悪い感じで間違った場合は、触った瞬間に尋常ではない熱さを感じることができます。すぐに電源を抜きましょう。当然ですが誤配線は故障やケガの原因になりますので、慎重に、落ち着いて結線することが大事です。
では、プログラムについて解説します。
26行目と28行目にて、Wifi接続処理を行っています。connectメソッドが2つ出てきているのが少しややこしいですが、26行目のrequire("CC3000").connect()
のconnectメソッドはCC3000Wifiモジュールとの接続を意味し、28行目のwlan.connect()
のconnectメソッドはWifiネットワークへの接続を意味しています。
後者28行目のWifiネットワークへのconnectメソッドは、SSIDとパスワード、そして接続完了後に実行されるコールバックを引数に取ります。今回のプログラムでは、onWifiConnect
が呼び出され、このコールバックの中でGETリクエストが実行されます。
10行目でGetリクエストを実行しています。インターフェイスは、node.jsのhttpモジュールのgetメソッドと同様です。http://www.pur3.co.uk/hello.txtに対してGetリクエストを実行し、レスポンスをコンソールに表示しています。
今回のサンプルはGETリクエストでしたが、もちろんPOSTリクエストを投げたり、EspruinoをWebサーバとして動かすことも可能です。
参考
まとめ
駆け足でしたが、Espruinoを購入し、温度センサで温度を測り、Wifiに繋ぐところまでたどり着きました。 センサーとインターネットに繋がれば、とりあえずセンサー情報をクラウドに上げて、それをブラウザで面白おかしく表示するようなサービスは作れます。これを機に、とりあえず何でもよいから作ってみるのはいかがでしょうか。
筆者も会社のトイレの空き状況をブラウザで見れるサービスを作ったり、すだちの木に水を上げるとマスコットが喜ぶ玩具等々をEspruinoで作って運用しています。実際に作って運用してみると、本当にいろいろなことに気づきます。この手のサービスやシステムを設計するにあたっての勘所や注意すべきこと、開発当初は思いもよらなかったサービスの”効果”等、とにかくいろいろなことに気づかされます。もちろんハードウェアの専門家になることが目的ではないのですが、とても勉強になりますよ。
ちなみに、Espruinoは日本語ドキュメントが少ないことがネックです。なんとかできないものかと、去年ひっそりとEspruino Advent Calendar 2014なるものを作りました。(ところどころ挫折していますが)これらを参考に、一緒に面白いものを作っていけたらと思います。
最後に、Web開発者がIoT/WoTに挑戦してみる理由について、筆者の思うところを少しだけ。
これからはIoTだ!WoTだ!大きなビジネスチャンスだ!乗り遅れるな!……と、そういった現実的なものもよいとは思いますが、筆者個人としては、Web開発者がIoT/WoTに挑戦してみる理由は、「その方が面白いものが作れそうだから」で十分なのではと思っています(記事の冒頭ではえらそうなこと言っていますが)。
これまでのWebサービスは、人間にインプットしてもらった情報を収集して、それを便利で面白い形にしてアウトプットするものが多かったように思えます。紙でやっていたことをシステムに落としたようなものです。でも、たくさんのインプットがなければ面白くも便利にもならないし、面白くも便利でもなければ誰も情報をインプットをしてくれません。様々なサービス、システムがこんな鶏と卵のような悩みと戦ってきたのだと思います。
でも、インプットをするのが人だけでなく、モノが自ら語ってくれたら、少なくとも有益なインプットを作り出すことはできますよね。情報さえそろえば後はそれをどう見せるか、それは我々Web開発者の土俵です。面白いものが作りやすくなるのではないかと思っています。
で、面白いことをやっていたら、結果儲かっていた。となったら、ラッキーだなと。 エンジニアが勉強する理由なんてそんなものでよいのでは、と最近考えています。 (あ、でもこの辺の市場が拡大することは間違いないと思いますよw。実際、この手のサービスのお仕事のお話をいただく機会が増えてきています^^)
というわけでIoT/WoT。言葉自体は流行っていますが、取り組んでいる人はまだまだそう多くはありません。 これを機に、まずはEspruinoで、面白いモノを作っていきましょう。