HTML5Experts.jp

JavaScriptエンジニアへのIoTのすすめ:Node.jsとArduinoでスマートデバイスのプロトタイプをしてみよう

ここ、HTML5Experts.jpでも今年になって IoTやWoT関連の話題がことかかず、みさなんも関心を持ち始めていることかと思われます。

私もフロントエンド・エンジニアではありますが、もともと関心があったことと、去年からデータ・ストリームのPaaS (platform as a service) 会社であるPubNubで働いていることもあって、IoTを避けずには通れなくなり、電子工作を始めるようになりました。

そこで、最近東京・渋谷で行われた、東京Node学園で登壇した際に話したテーマ、Hardware Hacking for JavaScript Developers から、ArduinoとNode.jsを使ってプロトタイプする、という内容についてチュートリアル形式で書いてみたいと思います。

Arduinoが変えたMakerムーブメント

みなさん、Arduinoの名前は聞いたことがあると思います。Arduino、もしくはGenuinoとして知られているこのオープンソースのAVRマイクロコントローラ電子工作キットは、既存のマイコンボードと違い、安価で、I/Oポートもあり、USB接続で今すぐ始められます。開発環境(IDE)とサンプルコードなども簡単にダウンロード、インストールできることから初心者でも簡単に電子工作ができるようになったという面では、今までハードウェアに縁がなかったソフトウェアエンジニアが、Makerムーブメントに積極的に参加するようになった火付け役ともいえると思います。

しかし、同じソフトウェアといえども、ウェブエンジニアはどうでしょう?Arduinoで使用される言語はC-ベースのSketchということで敷居が高く感じたり、興味がなかったりするのではないでしょうか?でも、もし馴染みのJavaScriptで好きなことができたら、遊んでみたくなりませんか?

Johnny-Five: JSロボティクス・フレームワーク

そこで紹介したいのが、JavaScript ロボティクス・フレームワークである、Johnny-Five。日本ではまださほど知られていない感じがしますが、オープンソースでディベロッパ・コミュニティの結束も固く、インターナショナル NodeBots Dayなどでユーザ・コミュニティも大きくなってきたこのフレームワークを使えば、JavaScriptをで簡単にプログラマブル電子工作ができるようになります。ここは説明よりも実践してみるほうが理解も深まると思いますので、さっそくチュートリアルを始めましょう!

1. Arduino のセットアップ

用意するハードウェアとインストールの必要なソフトウェア

始めにセットアップから始めます。ArduinoボードをUSBで、コンピュータにつなぎます。Arduino IDEをダウンロード、インストールして、起動させたら、ボードとシリアルポートの設定をします。

メニューのツール > マイコンボードの中のArduino Unoを選択し、 ツール > シリアルポートの中の/dev/tty.usbmodem、もしくはcu.usbmodemという名前が含まれる項目を選びます。

Johnny-FiveはFirmataプロトコルを使ってArduinoと通信をするので、今度はStandardFirmataをインストールします。

メニューからファイル > スケッチの例 > Firmata > StandardFirmataを選択すると新しいウィンドウが開きます。そこから左から2番目にあるアップロードボタンをクリックします。下のGIFアニメーションの通りです。

終わったら閉じ、このIDEはもうこれからは必要ありません。

2. Hello World

まずコンピュータに、Node.jsがすでにインストールされていることを、確認してください。そして適当なディレクトリ (e.g. /j5-hello/) を作ったら、そのディレクトリ内にパーケッジマネージャであるnpmを使って、Johnny-Fiveをインストールします。

$ npm install johnny-five

さっそくJohhny-Fiveを使ってはじめの一歩である、Hello Worldを書いてみましょう。新しい言語やフレームワークを学ぶ際に初めて書くプログラムは”Hello world”という2つの単語を出力する、というのが一般ですが、ここでは、ハードウェア界のHello Worldとも言える「Lチカ」(LEDを点滅させる)をしてみます。

必要なハードウェア

まずはハードウェア側のセッティングです。 部品などどこで買ったらわからない、という方はAmazonなどでキットを買うのをお勧めします。

LEDの基本

LED(発光ダイオード)には、極性があり、その+極をアノード、ー極をカソードと呼びます。普通のLEDには通常、足が二本ついていますので長い方がアノードです。これは回路を作るときに重要になってきますので必ず覚えておいてください!

電気回路の作成

ArduinoからLEDを光らせるための回路はこんな感じになります。ここでは便宜上、電源からつながるプラス側を赤、Groundにつながるマイナス側を黒のワイヤーで示してあります。何色を使っても構いませんが、混乱を避けるために2つの異なる色にすることをお勧めします。

ブレッドボードや抵抗についての基本、そしてこの「Lチカ」の回路については初心者でもわかる・できる!Arduinoを使った初めての電子工作実践「部品をつなぐ」セクションで豊田陽介さんが詳しく説明されているので、それを参考にしましょう。

Johnny-FiveでLチカ

では、適当なファイルネーム、例えばblink.jsを作成し下のコードをコピーペーストしてください。

var five = require('johnny-five');
var board = new five.Board();

board.on('ready', function() { var led = new five.Led(13); led.blink(500); });

ターミナルからこのファイルを走らせましょう。

$ sudo node blink.js

正しく作動しましたか?回路が正しく、コードにエラーがない場合は、500ms間隔でLEDが点滅します。

これで、JavaScriptとハードウェアを使う基本を学びましたので、今度は実際にスマートデバイスのプロトタイプを作ってみましょう。

3. スマート照明システムをプロトタイプする

Philips HUEや、LIFXは、ムードや状況によってスマートフォンやタブレットから、明かりの色や照度をカスタマイズできるLED電球です。さっそく Arduinoを使ってこれらのように色を自在に変えられるLEDを作ってみましょう。色を変えるためのコントローラはHTML5を使ってブラウザから操作できるようにしましょう。

JavaScript で Internet of Things

さて、ここで重要なのは、デバイス(ハードウェア)とモバイルUI (HTML5)をインターネットでつなげて、IoT化するということです。Bluetoothなどと違い、インターネットにさえ繋がっていれば、あなたが世界のどこにいようともモバイルから自宅の照明の操作をすることができるのです。この2ウェイ・コミュニケーションを可能にするにはソケット・コネクションが必要になります。ここで、この双方向通信を簡単に行うことにできるPubNubのJavaScript APIを使って、IoTのプロトタイプをしてみましょう。

PubNub はグローバルなデータストリームネットワーク (DSN) で、 このAPIを使ってリアルタイムアプリケーション、IoTデバイスなどを接続、拡張、管理することができます。今から作成するスマートLEDは下の図のようにモバイルデバイス(このプロトタイプの場合はブラウザ)とハードウェアをインターネットでつなげることが可能です。

例えば、サンフランシスコにいるモバイルユーザが東京にあるArduinoを操作する場合:

  1. ユーザがモバイルから「緑い照明にしたい」と送信(パブリッシュ)
  2. メッセージがPubNubのサンスランシスコデータセンターに送信される
  3. データは世界各地のデータセンターと同期
  4. Arduinoが東京データセンターからデータを受信(サブスクライブ)して、LEDを緑に

この全てのオペレーションがわずか¼秒かそれ以下で行われるのが、PubNubの利点です。

このチュートリアルではJavaScriptを使ってプロトタイプを作りますが、PubNubの組み込みとモバイルのSDKを使えば、実際にHUEのようなスマートデバイスを製品化することも可能なのです。

必要なハードウェア

RGBフルカラーLEDの基本

RGB (Red-Green-Blue) フルカラーLEDは、赤、緑、青の3色のLEDが一本になったもので、この三原色の組み合わせで無数の色を作り出すことができます。ほとんどのこのタイプのLEDは、各色のピンが一本づつと共通のカソード(もしくはアノード)の合計4本のピンがあります。このチュートリアルでは、カソードコモンのものを使用しています。

電気回路の作成

Hello World を成功させたからには、この下の図の回路も問題なく作れるのではないでしょうか。がんばってみてください。

ワイヤーを差し込むピンは、単純な「Lチカ」とは違い、PWM (Pulse Width Modulation:パルス幅変調) ピンを使っています。Arduinoボードにラベルされているピン番号の前に「〜」が付いているものがPWMピンになります。

これらと他のピンの違いは、簡単にいえばアナログかデジタルかの違いになります。例えばLEDの場合、一般のデジタルピンにつなぐとオフかオンの2つのステートしか表現できません。Lチカ(点滅)はこのデジタル信号をオンとオフと交互に発しています。しかしRGBフルカラーLEDで無数の色を表現するには、各色の値の組み合わせで色を作り出すので中間の値が必要になりますので、アナログであるPWMピンを使います。

ここで抵抗を220Ωと330Ωにわけてあるのは、同じ抵抗だと赤が強くなるので、抵抗を増やして赤を控えめな明かるさになるように調整してあります。抵抗の計算方法やカラーコードの読み方については、ここで割愛しますが、自分でいろいろ調整してみてください。

IoT リモートコントローラーUIの作成

ブラウザでLEDの色をコントロールするUIを作ってみましょう。

HTML5の“、”R”、”G”、”B”の各色調整をするスライダーバーを描写します。各色は0から255まで(min="0" max="255")の整数の値(step="1")を、つまみで調節できるようなUIにしてみましょう。

<input id="red" type="range" min="0" max="255" step="1" value="0">

これで赤色を調節するスライダーができました。このチュートリアルではCSS部分は省略しますが、スクリーンショットのようなスタイルにするには、GitHubのソースコードgh-pages ブランチを参照してください。

次はJavaScriptでこの値がユーザによって変更された時に、その値をArduino側に反映させるようにします。これを実現させるためにPubNub JavaScript APIで両デバイスを接続させてみましょう。

PubNub JavaScript API を使うには、まず自分のAPIキーを取得を取得したら、CDNライブラリ(もしくはローカルファイル)を読み込みます。

<script src="//cdn.pubnub.com/pubnub-3.7.15.min.js"></script>

そして自分のキーを使ってインスタンスを初期化します。

var pubnub = PUBNUB({
 subscribe_key : '自分の subscribe key',
 publish_key : '自分の publish key' });

UIイベント発生時に自動的にLEDの色を変える仕様にしてみましょう。 スライダーDOMにchangeイベントが発生した時に、変更値をPubNubに publish メソッドを使って送信(パブリッシュ)します。

var red = document.getElementById('red');

red.addEventListener('change', function(){ pubnub.publish({ channel: 'smart-led', message: {color: 'red', brightness: +this.value} }); }, false);

この時の channel 名は何でも構いませんが、のちにこのデータを受信する際にはこれと同じチャンネル名にします。

では次はNode.jsを使ってハードウェア側でこの値を反映させてみましょう。

Johnny-Five と PubNub で Arduino を IoTデバイスに

Johnny-FiveでRGBフルカラーLEDを動かすコードは、いたって簡単。npmでjohnny-fiveをインストールしたら、次のコードを動かしてみてください。

var five = require('johnny-five');
var led;

five.Board().on('ready', function() { console.log('ready');

// RGB LED を初期化 led = new five.Led.RGB({ pins: { // pin 番号 red: 6, green: 5, blue: 3 } });

// テスト led.color({red: 255, blue: 0, green: 0});

led.on(); });

LEDが赤色に光ましたか? 何も起こらない場合はコードと配線などを確かめてください。それでも作動しない場合は、使っているRGB LED がカソードコモンではなくアノードコモンの可能性があります。その場合は、GND(図上の黒のワイヤー)を、Arduinoの5Vのピンに変えてみてください。

「テスト」とコメントされた行をみてください。color メソッドでLEDの色を指定しているのがわかると思います。この場合、赤の値が255で他が0となっているので、LEDを赤で光らせることができます。Johnny-Fiveでは、CSSのcolorプロパティと同じようにRGBの値を0~255で指定することができるのです。RGBの各値を変えながらどんな色になるか実験してみてください。

さて今度は、このRGBの値をブラウザUIからリモートコントロールして、動的にLEDの色を変えてみましょう。

さきほどのUI側からパブリッシュされたデータを受け取って、ハードウェアに反映させるには、PubNub subscribe メソッドで受信(サブスクライブ)しましょう。

まず、npm で pubnub をインストールします。

$ npm install pubnub

フロントエンドと同様に、pubnubインスタンスの初期化します。

var pubnub = require('pubnub').init({
  subscribe_key: '自分の subscribe key',
  publish_key:   '自分の publish key'
});

UI側から送信されたデータは、同じ channel にアクセスすることによって自動的に送信することができます。データが送信された際には、subscribe メソッドの callback が返されます。このコールバック内で送信された色データをLEDに反映させます。

pubnub.subscribe({
  channel: 'smart-led',
  callback: function(m) {
    if(led) {
      r = (m.color === 'red') ? m.brightness : r;
      g = (m.color === 'green') ? m.brightness : g;
      b = (m.color === 'blue') ? m.brightness : b;

  led.color({red: r, blue: b, green: g});

  console.log( 'color change to...' );
  console.log( led.color() );
}

} error: function(err) {console.log(err);} });

送信されたメッセージ、m は、UIから送られたオブジェクト、例えば青の値が150の場合、{color: 'blue', brightness: 150}、となります。次に送信された値が、{color: 'red', brightness: 150} ならば、前の値の青=150はそのままで、ここに赤=150が加わることによって、LEDは紫に近い色になります。さらに赤緑青の3つの値が変われば、LEDはさまざまな色に変わります。

全コードは、GitHubのソースコードmaster ブランチ内の /node/index.jsを参照してください。

さて、これでIoTスマート照明のプロトタイプができあがりました!

Johnny-FiveもPubNubもArduinoだけではなく、他のいろいろなマイクロコンピュータに使うことができます。いろいろなセンサーやカメラなどを組み合わせて、IoTプロトタイプに挑戦してみてください。

では、Happy hacking!

References