ラベル ESP8266 の投稿を表示しています。 すべての投稿を表示
ラベル ESP8266 の投稿を表示しています。 すべての投稿を表示

2016年1月4日

トイレにRESTfulなAPIを実装してみた

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

あけましておめでとうございます。
プライバシーも一緒に流れるトイレから3年経ちましたが、皆様いかがお過ごしでしょうか。

お正月の三が日、昨今のIoTブームに乗るべく、私もIoTで真に豊かになるものは何かと一生懸命考えた結果、3年前と同じ部屋に辿り着いたことをご報告いたします。

前回はウォシュレットの使用状況をTwitterに投稿するというシステムでしたが、今回はウォシュレットにRESTfulなAPIを付与することで様々な機器から操作することを可能にするシステムを制作しました。


使用したのは巷で話題のESP-WROOM-02(ESP8266)と赤外線LED、上記写真のボードはオリジナルのもの。
(赤外線LEDの足がJST-PHコネクタに吸い込まれているように見えますが、良い子はLEDの足にJSTコンタクトピンを圧着したりしないように。)

このデバイスを電源に接続すると...


http://toilet.local にアクセスし、ウォシュレットを操作可能になります。


API

http://toilet.local/washlet に対して、Key cに以下のValueを設定してPOSTすると、それぞれの動作が実行されます。

Value 動作
rear おしり
soft おしりやわらか
bidet ビデ
stop 停止

また、DELETEメソッドでc=bigとすると流す(大)、c=smallとすると流す(小)が実行されます。
(DELETEなのはお察し)

仕組み

まず、3年前の時に取得した赤外線リモコンコードでは正しく動作しなかったので、改めて取り直し、トイレのリモコンがどのような送信を行っているのかを再検証しました。
リモコンコードはArduino UNOに赤外線受信モジュールを接続して、IRremote Arduino Libraryのサンプルを実行して取得。
結果、流す以外の動作は2回に分けてコードを送信していることが判明。
約6ms、2.9msの送信開始リーダ部の後は、1.5msで1, 0.5msで0のデータ部が続いているのは3年前に調べたのと同じ。






あとは、この通りに38kHzで変調して赤外線LEDを発光してあげるようなコードを書いてESP-WROOM-02に焼けばOK.

コードはこちら
GitHub : 9SQ/RESTful-Toilet

上記リモコンコードのデータもリポジトリに放り込んでいますので、TOTO製トイレリモコン赤外線で遊びたい方は参考にしてください。→ washlet_command.csv

これで、トイレ中にスマホが手放せない人でも、スマホからウォシュレットの操作が可能になりました!

番外編

トイレ引き籠もりのプロに、このシステムについて伺ったところ「ライブ中にタスク切り替えしてブラウザを開くのは厳しい」とのご感想を頂いたので、これについてAndroidアプリを制作することで対処しました。


もちろん、通知領域からボタンひとつで操作可能です。


デレステ中も快適なトイレライフが実現できます。



コードはこちら
GitHub : 9SQ/RESTful-Toilet-App

実際の動作

流石にトイレに座っているお見苦しい姿を晒すわけにはいかないので、流す動作だけ...


このシステムの脆弱性として、トイレの外から使用中の人に物理的な攻撃が可能になるという問題が発見されていますが、今後修正の予定が無いことを予めここに記しておきます。

最後に、今年1年が素敵なIoT(Internet of Toilet)の年になりますよう、お祈り申し上げます。

2015年12月27日

ESP-WROOM-02でYoを送るボタンを作ってみた

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
今年の夏からESP-WROOM-02で色々やっているけど、よく考えたら公開できるものを何も出してなかったので簡単なものを作ってみたり。

ボタンを押すとYoが飛ぶ、という単純明快なボタンです。
誰かにYoを送るも良し、自分のusernameを設定しておいて呼び鈴にするも良し。
Li-Poと充電回路を内蔵しているので、完全ワイヤレス動作も可能。


ESP-WROOM-02周りの回路はこんな感じ。(レギュレータとLi-Po充電回路は省略)

構成は、ESP-WROOM-02(写真の緑のボードはオリジナル)と
無接点プッシュスイッチ(コード付) (秋月電子通商)
リチウムイオン電池充電基板(1A) [CHR4056-MCU1A] (aitendo)
リチウムポリマー電池(3.7V/850mAh) (aitendo)

今回使った無接点プッシュスイッチはスイッチ自体に電源を入れてあげる必要がありますが、上記回路図には書いてません。
プッシュスイッチの代わりにリードスイッチやマイクロスイッチにするというのもOK。

ケースは3Dプリンターで出力。
こんな感じで収まります。(まだ裏蓋を作ってない...)


ソースコードはGithubに。
https://github.com/9SQ/esp8266-Yo-button

今回はWiFiClientSecureではなく、WiFiClientを使ってます。
本当はhttpsでPOSTすべきなのですが、まだWiFiClientSecureの動作が微妙で何故かレスポンスを受け取れなかったので、とりあえずhttpでPOSTしてます。
(通信経路が信頼できない場合は使わない方が良いですね)

仕組みとしては、単純にHTTP POSTするだけなので、宛先をYoから別のもの(IFTTTなど)に変更すれば、色々応用が利くはず...

2015年11月14日

Arduino core for ESP8266でHTTPSが叩けるようになっていた件

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
以前から使っている Arduino core for ESP8266 WiFi chip のStaging Version (ver. 1.6.5-1160-gef26c5f) でWiFiClientSecureが使えるようになっていました。

今まではWiFiClientではhttpしか叩けなかったのですが、これでhttpsなWebサーバにもアクセス可能です。
(以前の記事では、espconn_secure_connectを直接叩くことでhttpsなWebサーバにアクセスする方法を紹介していました)

多分、こんなコードでPOSTできるはず!
(現在やってるプロジェクトからhttpsPostの関数だけコピって持ってきたので、全体としては動作確認してませんが、関数自体は問題なく動くことを確認済み)

ちなみに、text=Hello ESP8266!とbat=現在のVCC電圧がPOSTされます。

もっとイケてるコードは examples/HTTPSRequest/HTTPSRequest.ino があるので、そちらを参考にしてください... (GitHubのAPIを叩いてJSONをパースしてる)
→ https://github.com/esp8266/Arduino/commit/2ff8aa08d478aceee39fe4147cb7fcc1eef263f1

以前の記事で、SSLライブラリを有効化して、直接ESP8266のAPIを叩くという方法でHTTPS通信した場合と同様、暗号種は以下の4種対応です。

  • TLS_RSA_WITH_AES_128_CBC_SHA
  • TLS_RSA_WITH_AES_256_CBC_SHA
  • TLS_RSA_WITH_RC4_128_SHA
  • TLS_RSA_WITH_RC4_128_MD5

WireSharkでパケット見た結果↓


ライブラリはlibsslではなく、axTLSという組み込み向けのSSLライブラリを使っています。

axTLS Embedded SSL

これに気づいたのも、おニュー環境のMacにArduino IDEとArduino core for ESP8266のStaging Versionを入れて、以前の記事の通りにplatform.txtの27行目に -lsslを追記しようとしていたら...


axTLSがリンクされていたので、まさか... と思いGitHubのIssuesを遡ってたら、WiFiClientSecureを追加したよ!みたいな会話があったという。

まだステージングなので色々変わるかもしれませんが、とりあえずこれでサクッとhttps使えますね。

2015年8月28日

ESP8266のSSL clientについて

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
ESP-WROOM-02でhttpsなAPIを叩こうとしたらハマったので、まとめておきます。

SDKは1.3.0 (Release date: Aug 08, 2015)を使用しています。
ドキュメントも、これ(esp_iot_sdk_v1.3.0_15_08_08.zip)に含まれている2C-ESP8266__SDK__Programming Guide__EN_v1.3.0.pdfを参照しました。

現状

8/28現在、Arduino core for ESP8266はSSL(TLS)でのclientに対応していない。
対応して欲しいという要望&対応したいねという話は出ている。

ESP8266のSDKとしては、SSLに対応している。
※ただし、制約あり(この下に書きます)

処理の流れ

公式によるサンプルコードがEspressifのフォーラムにあるので、それを見るとだいたい分かります。

以下も非常に参考になります。
DSAS開発者の部屋:ESP8266 モジュールの AT コマンドに SSL クライアント機能を追加する
ESP-WROOM-02で、IFTTTをhttps(SSL/TLS)で呼び出す例 - Qiita

大雑把な流れとしては...

//証明書ストアを用意
unsigned char *default_certificate;
unsigned int default_certificate_len = 0;
unsigned char *default_private_key;
unsigned int default_private_key_len = 0;

//espconn, _esp_tcpを定義

LOCAL struct espconn user_tcp_conn;
LOCAL struct _esp_tcp user_tcp;

//接続先のIPアドレスとポートを設定
user_tcp.remote_ip[0] = 192;
user_tcp.remote_ip[1] = 168;
user_tcp.remote_ip[2] = 1;
user_tcp.remote_ip[3] = 128;
user_tcp.remote_port = 443;

//自分のポートを設定
user_tcp.local_port = espconn_port();

//type, state等を設定
user_tcp_conn.proto.tcp = &user_tcp;
user_tcp_conn.type = ESPCONN_TCP;
user_tcp_conn.state = ESPCONN_NONE;

//接続時、再接続時、接続断時のコールバックを設定
espconn_regist_connectcb(&user_tcp_conn, user_tcp_connect_cb);
espconn_regist_reconcb(&user_tcp_conn, user_tcp_recon_cb);
espconn_regist_disconcb(&user_tcp_conn, user_tcp_discon_cb);

//SSLバッファサイズを設定
espconn_secure_set_size(ESPCONN_CLIENT,5120);

//接続する
espconn_secure_connect(&user_tcp_conn);

みたいな感じ?

user_tcp_connect_cb()関数の中でデータ送受信時のコールバックを設定してあげれば良いみたい。

void user_tcp_connect_cb() {
    espconn_regist_recvcb(pespconn, user_tcp_recv_cb);
    espconn_regist_sentcb(pespconn, user_tcp_sent_cb);
}

サーバからの応答は
void user_tcp_recv_cb(void *arg, char *pusrdata, unsigned short length)
のpusrdataに入ってくるので、これを出力するなり判定するなりすると良い。

SSLバッファサイズはデフォルト(espconn_secure_set_sizeを呼ばない場合)で2048バイトになっているので、SSLパケットが2048バイトを超えそうな時は適宜増やしてね、ということらしい。
最大8192バイトらしいけど、8192を設定したらメモリに乗り切れないっぽくて(確保できない?)、espconn_secure_connectの段階でこけました。
公式サンプルコードにあるように5120くらいが限界かな...?

使用できるプロトコル(バージョン)と暗号

たぶん、ここが一番重要で、メモリ周りとかは全然大丈夫だけどespconn_secure_connectした直後にuser_tcp_discon_cbが呼ばれる(接続断される)ような、とあるサービスのAPIサーバがあって、Wiresharkでパケットキャプチャしたら原因が分かりました。

こちらがESP8266からサーバに送信されたClient Hello。


バージョンはTLS 1.1で、Cipher Suitesは以下の4種。

  • TLS_RSA_WITH_AES_128_CBC_SHA
  • TLS_RSA_WITH_AES_256_CBC_SHA
  • TLS_RSA_WITH_RC4_128_SHA
  • TLS_RSA_WITH_RC4_128_MD5


TLS 1.1を拒否ってたり、上記暗号種での接続を拒否ってると


「お前の指定したバージョン、暗号種ではうちに繋げねーぞ」とHandshake Failureが返ってきてServer Helloしてくれない訳です。

HeartbleedとかPOODLEとか色々あった関係で、厳しめなところは繋がらないという感じかなぁ。

このマイコンの性能上、強度の高い暗号アルゴリズムは載せられないのでしょうが、IoT向けを前面に押し出してるからには、もうちょっと頑張ってほしい...

追記その後、Arduino core for ESP8266でWiFiClientSecureが追加され、httpsが叩けるようになりました。

2015年8月26日

ESP-WROOM-02でIoTデバイスっぽいものを作る(1)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

前回(ESP-WROOM-02を使ってみる)の続き。

サンプルを漁ってたらCaptive Portalを使ったものがあったので、早速この機能を使って何か作ることに。
Captive Portal = APに接続したら強制的にWebページ(普通は認証ページなど)を開かせる、公衆無線LANに良くあるアレです。
そして、
1. ESP-WROOM-02をアクセスポイントにできる
2. Captive Portalが使える
3. ESP-WROOM-02がクライアントになれる
ということは...
スマホだけで家のアクセスポイントへの接続設定が出来るIoTデバイスを作れる訳です。

想定
1. 利用者がIoTデバイスの電源を入れる
2. 取説に書いてある特定のSSIDのAPが出現するので、それにスマホで接続する
3. 設定ページが自動的に立ち上がる
4. 家に既設のAPを選択し、パスワードを入力して設定
5. 自動的に再起動して、今度はクライアントとして家のLANにぶら下がってくれる

こういう物が出来れば素敵... というわけで、まずは雛形として使えそうなものを作ってみました。

9SQ/esp8266-wifi-setup (GitHub)

Arduino core for ESP8266を使っているので、前回の記事でも書いたようにArduino IDEへのボード情報の設定が必要です。

実際のスマホでの設定画面はこんな感じ。


その時のシリアルモニタはこんな感じ。


動作としては、
1. EEPROMを読みに行って、設定が存在しない場合はSetup Modeになる
2. 一旦、STA modeで周辺のアクセスポイントを検索して保存
3. AP modeに切り替えて、設定されたSSIDでアクセスポイントを立てる
4. WebサーバとDNSサーバも立てる
5. 接続してきたクライアントはCaptive Portalで設定ページに飛ばす
6. 設定ページから入力されたSSIDとパスワードをURLデコード
7. EEPROMに書き込み
8. 再起動
9. EEPROMを読みに行って、設定されたSSIDのAPに接続する
10. 接続を確立したらWebサーバを立てる
という流れです。

・設定したSSIDのAPに接続できなかったら、再びSetup Modeになります。
・設定後にシリアルモニタに出力されるIPアドレスに接続するとWebサーバが立ち上がってますが、ここにアクセスすると接続設定のリセットが可能です。

あとは、これにセンサーなどを接続してあげれば、同一LAN内からブラウザで値を覗いたり、外部のサーバにデータを定期的に送るようなデバイスが作れると思います。

実はまだ手を入れるところ(接続確立後に何らかの問題で接続断したときの再接続処理など)が結構残っているので、ぼちぼち修正する予定...と並行して次回は実際に何か作ってみたものを載せようと思います。

2015年8月25日

ESP-WROOM-02を使ってみる

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

たいへん出遅れました!
今更ながらESP-WROOM-02をゲットできたので、先人の日本語による資料の恩恵を受けながら、サクッと使ってみます。

ちなみに、aitendoで買いました。2個パックが1100円(税別)。
秋月電子だとbreakout boardが売って無くてつらいのですが、aitendoだと1個120円で売ってます。
スイッチサイエンスだとモジュールが1個あたり864円、ピッチ変換が162円なので、たぶんネットで買える店の中ではaitendoが最安っぽいです。10個以上買うと秋月の方が安くなりますが。(2015年8月25日現在)
#スイッチサイエンスさんは学校とかで買いやすいので、研究などで買うときは使ってます。

aitendo
Wi-Fiモジュール(技適マック付き/2PCS) [ESP-WROOM-02P] 1100円(税別)
WiFiモジュール変換基板(A) [IFB1518-A] 120円(税別)
WiFiモジュール変換基板(B) [IFB1518-B] 120円(税別)

秋月電子通商
Wi-Fiモジュール ESP-WROOM-02 [ESP-WROOM-02] 550円(税込)

スイッチサイエンス
ESP-WROOM-02 Wi-Fiモジュール 864円(税込)
ESP-WROOM-02ピッチ変換済みモジュール《フル版》 ボードのみ 162円(税込)
ESP-WROOM-02ピッチ変換済みモジュール《シンプル版》 ボードのみ 162円(税込)

さて、注文して届いたモジュールをbreakout board(ピッチ変換基板)にハンダ付けします。
今回はaitendoの変換基板(A)と(B)を1個ずつ買ったので、どっちも付けて比較。
温調ハンダごてだと引きハンダで綺麗に付けやすい。


ブレッドボードに刺すときは2枚を跨がせるか、基板の下をジャンパワイヤーで配線すれば良し。


上の写真では、LED(GPIO4)と気圧センサーLPS25H(SDA=GPIO12, SCL=GPIO14)を接続しています。
ボタンの青がRST、黄色がGPIO0に繋がっているので、黄色を押しながら青を押すとUART Download Modeに入ります。

あとは、先人たちの資料を読みながら、今回はArduino IDEでプログラムを書いていきます。

ググれば色々出てきますが、この辺りが参考になりました。
「ESP-WROOM-02」をArduinoで開発 - おかゆ日和
ESP8266 - ESP-WROOM-02 の Arduino 環境で I2C 制御 - Qiita
ねむいさんのぶろぐ | 技適マーク付きESP8266モジュール ESP-WROOM-02 を使ってみる

LEDのON/OFFをブラウザから操作するのは、サンプルのESP8266WiFi → WiFiWebServerで実現できました。
気圧計は、通常のArduino向けに書かれたコードと、WiFiWebServerを組み合わせて簡単に作れます。

気圧計LPS25HをArduinoで読み取るコードは以下が使えると思います。
Arduinoで遊ぶページ | 大気圧・温度センサモジュールの実験

Raspberry Piで読み取るコードを以前Pythonで書いていたので、これも処理の流れの参考にできるかな。
9SQ/raspi_lps25h.py | Raspberry PiとLPS25Hで気圧取得

ちなみに、I2CはSCLをGPIO14にすればSDAはどのピンでも良いみたいです。
上記Qiita投稿ではSDAをGPIO4に繋げてるみたいですが、私はGPIO12でも動きました。
データシートではGPIO2がSDAになってるんですが、ここは起動時にプルアップしないといけないので、使わなくていいなら使わない方が楽。

GPIOについては、4, 5, 12, 13, 14, 16が使えるよーっという投稿をどこかで見かけた気がしますが、実際には0, 2, 15, 1(U0TXD), 3(U0RXD)も使えます。
ただし、これらのピンは起動時、プログラミング時に使用するピンなので使う際は工夫が必要です。

というわけで、そういうのを踏まえてESP-WROOM-02用のPINOUT DIAGRAMを作ってみました。

PDF版ダウンロード (893KB)

修正ポイントがあったら、記事へのコメントなどで教えてください。
ライセンスはCC0です。(いろんな所で使いやすいように)
著者表記・バックリンク不要ですが、してくれたらそれはそれで嬉しいのでお好みでどうぞ。
※PDFへの直リンクはダメです。

続き→ ESP-WROOM-02でIoTデバイスっぽいものを作る(1)
続き2→ ESP8266のSSL clientについて
続き3→ ESP-WROOM-02でYoを送るボタンを作ってみた