ESP8266にWebSocketを喋らせてみる

世の中、同じようなことを考える方はいるようで、すでにESP8266+ArduinoIDEでWebSocketライブラリが存在しています。WebSocketが扱えるようになれば、(プログラミングスキルがあれば)クラウド側から好きなタイミングでESP8266に指示をおくることができるようになるはずです。(が、世の中そんなに甘くないんですねぇ〜)

で、今回見つけたWebSocketライブラリは ESP8266-Websocket です。

今回の記事はこれのサンプルを動かしてみよう、と苦戦した記録です。作業PCのOSはUbuntu14.10 LTS 64bit、ArduinoIDEのバージョンは1.6.5です。なお、Ubuntuで動かすにあたっては、

として、/dev/ttyUSB0のアクセス権をユーザーにつけた後、再ログインしないと/dev/ttyUSB0へアクセスできないとしてエラーになります。

Arduinoのライブラリは ~/Arduino/librariesの下に置けばいいようですので、そこにgitでライブラリを引っ張ってきます。

その後、ArduinoIDEで「スケッチ」→「Include Library」→「Manage Libraries」で右上の「Filter your search」で「ESP8266-Websocket」と入力して「INSTALLED」になっていることを確認します。

scrn1

次に、WebSocketClientのデモを動かしてみます。

「ファイル」→「スケッチの例」→「ESP8266-Websocket」→「WebSocketClient_Demo」を選択します。

scren2

ソースの冒頭の

の部分に自分の無線LANのESSIDとパスキーを入力してから、名前を付けて保存します。

このライブラリはおそらくWindows環境で作成されたのでしょう。Linux環境でビルドしようとすると、ファイル名の大文字小文字で失敗します。そのため、ライブラリの中の以下の部分を修正します。

WebSocketClient.h と WebSocketServer.h の

に、

WebSocketServer.cpp と WebSocketClient.cppの

とします。

これでビルドが通るようになりましたが、それでもコネクションに失敗します。禁断のgoto文で接続しに行く部分のみを繰り返すと、何回目か以降は通るようです。ライブラリのWebSocketClient.cppの冒頭にデバッグのための#define文があるので、ここをコメントを外すとデバッグメッセージが出るのですが、これでもハンドシェークの途中で止まっていることはわかるものの、それ以上はなんともわかりません。
これ以上は間にLANアナライザを入れてみてパケット解析しつつ、RFCを読んで何かおかしいのか調べるしかなさそうです。

以下は、現時点でのサンプルプログラムを改造したものです。

WebSocketClient.cppをみると、サーバ側からのヘッダの解釈の実装がまだまだであることがわかります。ひとつの可能性として、どうやらここで止まっていそうです。もうひとつは、パケットの受信バッファの処理がどうも変な感じがします。

いずれにせよ、このライブラリはまだそのままでは使えるものではなさそうな感じです。(ま、よくみると色々と制約があるよ、って書いてあるんですけどね)

WebSocketについてちょっと実験してみた

たまたまWebをさまよっていたら、WebSocketの話が目についたので調べてみた。まあ、HTTPに比べると、一旦リンクを張ってしまえばサーバ側からも通信ができるってのが美味しいところ。

で、ブラウザがWebSocketをサポートしているか確認することができるサイトが

http://www.websocket.org/echo.html

なのですが、ここには自分でHTMLを書いて確認したい場合のためのコードが置いてあったりします。で、これを試してみると・・・テキストエディタに貼り付けたら1行になってしまいました(T_T)

整形しなおしたものをここに置いておきます。

これをコピペしたら今度は1行になるようなことはなかったです。

そして、これをローカルで表示させたらこうなりました。

で、ごにょごにょっとしたことを考えているので、自分の理解の範囲で動作を解釈してみます。(間違ってたら指摘いただけると幸いです)

  1. 動作は8行目から始まって、testWebSocket()が呼ばれる。
  2. 13行目のnewでwebsocketのインスタンスを生成。ここでソケットをオープンする。
  3. 14〜17行目はイベントハンドラ。ソケットをオープンすると、この中の14行目のonopenに設定したハンドラが呼ばれる。(先の13行目から呼ばれるところが変な感じがしますが、Javascriptのスコープの特性から14行目で定義している内容を13行目で使用可能なのですね)
  4. 20行目がonopenのイベントハンドラ。この中で、doSend()を呼んでその先でwebsocket.send()でデータを送信している。
  5. websocket.send()の結果、サーバ側からエコーバックが帰ってくる。
  6. エコーバックを受信すると、16行目で定義しているonmessageのハンドラが呼ばれるので、29行目のonMessage()が実行される。この中で、websocket.close()を呼んでコネクションをクローズ。
  7. クローズすると、15行目で定義しているoncloseに対応したハンドラが呼ばれる。

比較的簡単に使えそうですね。
ちょっとだけソケットの使い回しができることを確認してみました。

ソースコードをちょっとだけ弄ります。

変数nに初期値10を設定して、受信時の動作をnの値によって切り替えています。nが0より大きい場合には次のメッセージを送ってnをカウントダウン、nがゼロならソケットをクローズします。
結果は、

Screenshot_soc

となりました。同じソケットを開いたまま11回のメッセージやりとりができていることがわかります。

参考にさせていただいた/参考になりそうなサイト

Covia F4sのその後(とグアムでのプリペイドSIM事情)

Covia F4sを買った話は以前の記事に書きましたが、その後について気づいた点などを書いてみます。

現在はCovia F4sの後継でフラッシュが4GBに、RAMが1MBに増量された(そして色も違う)F4s+が出ていて、実はこっちも持っています。黒が欲しかったのと、某アプリが512MBのRAMではバックグラウンド動作できないためです。
バッテリ容量が小さいのが欠点ですが、手のひらに収まるサイズなのが非常によいところ。F4sの方はF4s+のバッテリ充電器兼いろいろ試してみる対象機になってます。で、お試し機に格下げ(格上げ?)なのでSMS無し版のヨドバシ480円SIMで動かしたりしています。

で、今回、グアムに持っていった(モバイルルータを別途レンタルして使用)のですが、挙動が不審で、何をやってもすぐに再起動。バッテリ充電だけでも再起動。そしてそのうち、反応がなくなって、電池を外して入れなおさざるを得なくなる、という症状が出ました。(F4s+の方は問題なかったのですが・・)

RAM周りのハードウェア異常かと思って、日本に帰国したら修理に出すしかないなぁ、と思っていたら、日本では全く異常がありません。F4sを所有されているかたは要注意かもしれません。

現地SIMがあれば、SIMを入れ替えてどうなるか、とか、SIMを外したらどうなるか、というのも試してみればよかったのかもしれないのですが、日程の関係から今回は現地プリペイドSIMは購入せず。

グアムでのプリペイドSIM事情

ちなみに、グアムではマイクロネシアモール日本語のフロアガイドの2階の真ん中の吹き抜け左側のところ)と、グアムプレミアアウトレットに(店舗一覧。お店はこの地図のMの場所)ドコモパシフィックの店舗があります(今回=2015年7月確認)。どちらも有名なショッピングスポットなので簡単に行けるでしょう。ここでドコモパシフィック(NTTドコモとは別会社です)のSIMを買うことができると思います。(以前、一度アウトレットの方で買ったことがあります)

ドコモパシフィックのプリペイドプランのページはここにあります。ここの記載をみると、プリペイド回線の残高チェック、プリペイド回線間の残高移動、クレジットカードでの残高チャージなどができるようです。また、プリペイドの料金プランはここにあります。SMS、ローカル通話、パケット使い放題3日間で8ドルのようです(が、SIMの価格は入ってないです)。で、10ドル分のプリペイドチャージ付きのSIMが19.95ドルのようです。(追加チャージ用のプリペイドカードは$20、$10、$5の3種類があるようです)

なので、10ドルのチャージ付きのSIMカードを買って、『3日間ローカル通話・ローカルSMS・データ使い放題8ドルコース』か『5日間データ使い放題9ドルだけど、通話とSMSは有料』で使うかのどちらかでしょうね。設定はお店の人にやってもらうのがいいでしょう。

ESP8266からherokuにデータを送ってみる

これまでに node.js + herokuでHTTP GETコマンドを使って最低限のデータの出し入れができることを確認しました。つまりherokuで実用性はないとはいえ、サーバ側の構築ができるようになりました。ただ、セキュリティとか実用性とかそういうのは考えてないので、とにかく最低限ですし、そもそもデータベースを使っていないのでプログラムを再起動されると消えてしまいます。そしてそれは頻繁に起こります。なので、あくまで「ちゃんと作ればできることがわかる」というレベルです。

次は、ESP8266からherokuにデータを送って、PCからそのデータを読み取れるか試してみます。簡単に済ますためにESP8266側は先に確認したようにArduino IDEで構築します。heroku側は先の「hello-heroku2」のままにします。

Arduino側のスケッチはサンプルの「ESP8266WiFi」の下の「WiFiClient」を元にしています。一旦、WiFiClientを開いて、名前(今回は「HerokuClient」にしました)をつけて保存します。
その後、ESSIDとWiFiのパスワードの設定、先の「hello-heroku2」に合わせたGETメソッドに合わせたURLの生成の部分を修正します。今回は、起動すると1から順にデータをheroku側にセットするだけとしました。

修正後のソースは以下のようになりました。元のソースはdata.sparkfun.comのサービスにデータを送るようになっていたようですが、今回はそれを変更しています。(コメントは修正していませんので、そのままになっています。また、WiFiの設定関連は当然伏せてありますので、環境に合わせて修正が必要です。)

これで、ESP8266モジュール側をGPIO0をGNDに落とした状態でリセット解除することでブートローダ状態で待機させてから、ArduinoIDEで「マイコンボードに書き込む」とするとコンパイルと書き込みが行われてプログラムが走り出します。
事前にシリアルモニタを起動しておくと、

Screenshot--dev-ttyUSB0

という感じでWiFiのアクセスポイントに接続し、その後herokuへDATAを1から順にセットしている様子が確認できます。(日本語が文字化けしてますが、まあいいでしょう)
PC側からherokuにアクセスすると、

Screenshot-Mozilla Firefox-13

という感じで、ESP8266からセットしたデータを確認することができました。

これでESP8266からherokuへのデータのアップロードと、ブラウザによるherokuにアップロードされたデータの確認ができたことになります。実用にするにはheroku側はデータベース使わないとね、とか、複数のESP8266に対応しないとね、とか、セキュリティ全く無いじゃん、とか、山ほど考慮するべきことがありますが、最低限遊べるレベルには到達したのではないでしょうか。

heroku + node.js + ESP8266 + ArduinoIDEの組み合わせでIoT環境を試すレベルであれば簡単に構築できることがわかりました。もちろん、リソースをかければ本格的な環境にアップグレードすることもできると思います。あとはこの環境をどう使うか、ということですね〜。

Heroku+Node.jsでHelloWorldしてみた(4)

16. クライアントによって異なる動作をさせる

GETメソッドのパラメータが扱えることがわかったので、これで区別させてみたいと思います。まずは適当な作業用のディレクトリを作ります。

次にソースコードを準備します。内容は下記の通りでhello2.jsという名前で保存します。

次に、package.jsonファイルを作成します。

これまでの例と名前の部分しか変わっていません。
作成したら、npmで必要なパッケージをインストールします。

次にProcfileを用意します。これはファイル名に合わせて修正します。

ローカルでアプリを動かしてみます。

ブラウザで「http://localhost:5000/」にまだデータがない旨、表示されます。次に「http://localhost:5000/?DATA=100」としてアクセスした後、再度「http://localhost:5000/」にアクセスすると、セットした値(100)が表示されます。

次にherokuの作成済みのリポジトリにデプロイしてみます。

「$ heroku open」として、動作確認してみます。

Screenshot-Mozilla Firefox-10

起動した直後なのでデータがない状態です。
次に、URLを「https://whispering-basin-7319.herokuapp.com/?DATA=12345」としてみます。

Screenshot-Mozilla Firefox-11

データが設定できました。URLを元に戻してリロードし、記憶しているか確認してみます。

Screenshot-Mozilla Firefox-12

データがherokuのサーバ側に記憶されていることが確認できました。

 

heroku+node.jsでHello Worldしてみた(3)

さらに続きです。

14.変数の扱いを見てみる

プログラムを以下のように修正してみました。

ローカルで実行してみます。

リロードするたびに数値が増えます。

Screenshot-Mozilla Firefox-3

次に、デプロイしてみます。

 

ブラウザが開いたのでリロードしてみます。

Screenshot-Mozilla Firefox-4

やはりリロードするたびにカウンタが増えます。しばらくは実行環境が維持されるようです。確か、何時間かで実行環境が消える(表現が適切ではないかも)と書いてあったので永続的な値はデータベースに頼るべきなのでしょうが、実験レベルであれば変数でもいいのかもしれません。

15.GETメソッドのパラメータ渡しをみてみる

hello.jsを以下のように改変。
ここの記事を参考にさせてもらいました。request.param(パラメータ名)で容易に取得できるようです。他にもExpressの使い方でいろいろ参考になる記載がたくさんありますので、後でじっくり読ませてもらいたいと思います。

 

ローカルでテスト。

 

1回目はパラメータなし、2回目以降はパラメータ付きでテストしました。下記は2回目、3回目のスクリーンショットです。

Screenshot-Mozilla Firefox-5

Screenshot-Mozilla Firefox-6

 

日本語(Unicodeでしょう)も大丈夫な感じですね。
herokuにデプロイして試してみます。

 

アクセスして試してみます。

Screenshot-Mozilla Firefox-7

Screenshot-Mozilla Firefox-8

Screenshot-Mozilla Firefox-9

無事にローカルと同様に動作しました。GETメソッドでのパラメータ渡しも簡単にできそうです。

heroku+node.jsでHello Worldしてみた(2)

続きです。

6.Dashboardから新規アプリ作成

ここで、herokuのDashboardを見ると、作成したサンプルアプリが見えています。今回の場合、mysterious-river-xxxxが作成したサンプルアプリです。

screen-1003

また、右上の「+」が新規アプリ作成に使用するボタンのようです。

「+」を押すと新規アプリケーションの名前を聞いてきます。ただ、optionalなので、そのまま「Create App」してみます。

Screenshot-1004

 

whispering-lake-8767」という名前のアプリになったようです。続けてやるべきことが記載されています。これに沿って、アプリケーションのリポジトリを作成してみます。

として、アプリケーションのリポジトリを作りました。

7. Node.jsでアプリケーションを作成

以下の内容のサンプルアプリを作ってみました。内容は参考にさせていただいたこちらのサイトそのままです。ファイル名はhello.jsとしました。

8. package.jsonファイルを作成

次に、packages.jsonファイルを作成します。

 

これで packages.jsonファイルが作成されました。
・・・が、(予想通りですが)依存関係などは手動で追加のようです。

各パッケージのバージョンを調べます。

ということで、packages.jsonファイルを修正します。

9. npmで必要なパッケージをインストール

npmで必要になるパッケージをインストールします。

10. Procfileの作成

Procfileを作成してプロセスタイプを宣言します。

ここまでで以下のファイルが準備できました。

11. ローカルからアプリを動かしてみる。

ローカルからアプリを動かしてみると・・・

となってエラーになってしまいました。
読んでみると、「たいていのミドルウェア(loggerのようなもの)はExpressにはもはやバンドルされてないので個別にインストールしなきゃダメよ。https://github.com/senchalabs/connect#middleware を見てね。」だそうです。

が、リンク先を見ても特にloggerに関する記載はないので、ソースコードを

 

として、loggerをコメントアウトして使わないようにしてみました。
すると、

となって、無事起動している模様。ブラウザで見てみると、

Screenshot-Mozilla Firefox

となり、無事に表示されました。

12. herokuでアプリを動かす

herokuで動かしてみます。ログが長いですが、後で見返すときのためにそのままで。

ブラウザで見てみます。

Screenshot-Mozilla Firefox-1

無事に動作しているようです。

※1:「$ heroku create」だけを実行すると、適当な名前でアプリが作成されてしまうようです。リポジトリの名前との関係が今ひとつ理解できていません。
※2:上記の例ではFirefoxでURLを手打ちしましたが、「$ heroku open」でブラウザが開いてアプリを動かしてくれます。

13. メッセージを変えてみる

ソースファイルを以下の通り修正してみました。

herokuにアップロードして確認します。

ブラウザが開いて修正されたことが確認できます。

Screenshot-Mozilla Firefox-2

 

 

 

heroku+node.jsでHello Worldしてみた(1)

ずいぶん前から話題になっている heroku を試してみました。今回は、herokuとnode.jsを使ってHello Worldしてみましたので、その記録です。
JavaScriptを使うのもほぼ初めて、herokuも初めて、当然Node.jsも初めて、という初めてづくしなのでおかしなところもあるかもしれません。環境はLinuxMint17.1 32bitです。

参考にしたのは「2013-07-07 herokuでNode.jsの動く環境構築してみた!」です。基本的には(2)まではこの記事を辿っただけです。(途中からNode.js + Express環境前提での記載になります)

1.herokuのアカウント作成&準備

herokuのサイトでサインアップします。お決まりのメールアドレスをIDとするタイプです。
メールアドレスをIDとして入力すると、そのアドレスに確認用のリンクアドレス付きのメールが送られてきます。そこにアクセスしてパスワードを設定します。

パスワード設定後、ログインすると、どの言語を使うか(Getting Started with Heroku)聞いてきます。

Screenshot-1000

今回はNode.jsを選択してみます。

Screenshot-1001

Node.jsとnpmがインストールされていることが条件のようですので、ここで一旦herokuから離れます。

2.node.jsとnpmのインストール

すでにnodejsコマンドとnpmコマンドはインストール済みなので割愛。
デフォルトで入っているアマチュアパケット無線用のnodeパッケージを削除(中身はないようだけど)して、node.jsをインストールします。

無事にインストールできたようです。

3.heroku toolbeltのインストール

「Getting Started with Node.js on Heroku」のSet upのところで、heroku toolbeltのインストールをします。Debian/Ubuntuを選ぶと、コマンドラインで以下を実行するよう表示されます。

Screenshot-1002

Rubyがインストールされている必要があるようですので、以下の通りコンソールから入力します。

とした後、

としてインストールします。

4.herokuにログイン

問題なく成功したので、Set upのところの「I have installed the Toolbelt」をクリックします。すると次の「Prepare the app」に進みます。

5.サンプルアプリを動かす

Getting Started with Node.js on Heroku」の「Prepare the app」「Deploy the app」「View logs」に沿って操作していけばサンプルアプリは容易に動きます。
詳細は省略。その後の説明は、

  • ログは「$ heroku logs –tail」で確認可能
  • Procfileにはアプリを起動するためのコマンドを記述する。プロセスタイプの「web」に続いて、node.jsの場合には「node ファイル名.js」。webはherokuのHTTPルーティングスタックを使うためのもので、デプロイされた時にWebトラフィックを受信する、ということみたい。
  • package.jsonにはアプリケーションの依存関係を記述する。ファイルは「$ npm init」で作成できる。packages.jsonはアプリケーションのherokuで動かす際のNode.jsのバージョンと、アプリケーションの依存関係の両方を決定する。アプリケーションがデプロイされると、herokuはpackages.jsonを読み込んでnpm installコマンドを使って適切なバージョンのnode.jsと依存ファイルをインストールする。
  • アプリケーションをローカルで動かすためには「$ foreman start web」とするが、LinutMint17.1では「node」コマンドはアマチュアパケット無線用のNodeとなっており、node.jsは「nodejs」コマンドで起動することになっているため失敗してしまう。.bashrcに「alias node nodejs」と記述して新しいterminalで起動してもダメ。「$ sudo ln -s nodejs node」としてからだと、

    となってやはりうまくいかない。
    ぐぐるさんに聞いてみると・・・同じ課題の人がいるようです。前の方の「2.node.jsとnpmのインストール」を修正しました。
    改めて試してみましたが、

    となってうまくいきません。(気を取り直して再起動すると、Synapticがherokuとheroku-toolbeltのアップデートを要求してきましたが、その後でもやはりダメ・・・)
    「$ npm install」したあと「$ npm init」で package.json を作りなおしたらうまくいった模様。
  • その他、herokuの外のサービスとして長大なログを取るもの、コンソール起動の仕方(ワンライナーを動かすなど)、環境変数の渡し方・取得の方法、データベースの使い方などの記載があります。

(2)へ続きます。

EMW3165モジュール

Hack a Dayの記事からですが、EMW3165というIoTモジュールが登場しているようです。記事のタイトルでは、「NEW PART DAY: THE ESP8266 KILLER」となっています。

データシートによれば、

  • 100MHz動作のCortex-M4コア
  • 2MBのSPIフラッシュと512KBのオンチップフラッシュ
  • 128KBのRAM
  • GPIOが22ピン

というのが概要です。STM32F4とSDIO接続のWiFiチップ、SPIフラッシュ2MBの組み合わせのようですので、いつぞやのEMW3162モジュールと大差ありませんが、今回特筆すべきは価格かもしれません。Seeed studioに出ている価格では$7.95なので、ESP-WROOM-02では容量が足りない、という場合には選択肢に上がってくるかもしれません。(もっとも、FCCとCEマーキングしかないので、日本では使えません)

ただ、本質的な部品点数ではESP8266の方が少なくなる(当たり前ですが・・)ので、「ESP8266 KILLER」というにはちょっと役不足な感じがします。

技適マーク付きESP8266モジュール入手

早く技適マーク付きESP8266モジュール欲しいな〜、と思ってググっていたら、スイッチサイエンスESP-WROOM-02の技適マーク付きの扱いがあることを発見。さっそくポチってしまいました。7/10に注文して、今日7/11には入手。速くて便利。

いま改めて気づいたのですが、スイッチサイエンスのプレスリリースが出たのも7/10だったんですねぇ。そちらにはピッチ変換済みモジュールに関する記載もありました。
モジュールは1.5mmピッチのSMD実装前提の形状ですので、慣れてない人はピッチ変換済みモジュールのほうがお手軽でしょう。

ESP-WROOM-02

よくみると、ESP-WROOM-02って、ESP-12にあった青色LEDがなくなってます。まあ、消費電力追い込む場合にはLEDも邪魔ですから、それはそれで良しかと思いますが、デバッグ中は不便そうです。

一方で、CerevoからもESP-WROOM-02とピッチ変換基板が発売されています。Cerevoって聞き覚えあるけど何だっけ、と一瞬考えてしまいましたが、ustreamなどの機器で結構名前が出ていた会社です。Cerevoの中の人もきっとESP8266の可能性が気になっちゃったんでしょうねぇ。ブログの記事にまでなっちゃってます。

話をESP-WROOM-02に戻します。さて、こいつならシールド環境などという面倒くさいことを言わずにあれこれできます。これからいろんな人が懐に暖めていたアイデアが花咲くことと思います。自分もアイデアだけはある(あ、部品もある)んですが、なかなか時間が・・・というのと、体調崩してしまっているのでどうなることでしょう。