ESP8266
目次:
ESP8266で電力モニターを作る
ARDUINOが動くWI-FIモジュール ESP8266で環境センサーを作る
ARDUINOで消費電流モニターを作る
ESP8266の消費電流を調べる
ESP8266 WI-FI SSID、パスワードのオンライン設定
ESP8266 ARDUINO、WI-FI経由のプログラムアップロード OTA
One Nice Bug Per Day
he wasn't even looking at me and he found me
Sweet Seals For You, Always
Misplaced Lens Cap
macklin celebrini has autism
noise dept.
let's talk about Bridgerton tea, my ask is open
official daine visual archive
Not today Justin
Monterey Bay Aquarium

Discoholic 🪩

blake kathryn

if i look back, i am lost

gracie abrams
hello vonnie

ellievsbear
occasionally subtle
will byers stan first human second
Fai_Ryy

seen from United States

seen from United States

seen from United States

seen from United States
seen from United States

seen from Türkiye

seen from United States
seen from Germany
seen from United Kingdom
seen from United States
seen from United States

seen from Malaysia

seen from United States

seen from Malaysia

seen from Russia
seen from Iraq

seen from Türkiye
seen from India

seen from France

seen from United States
@takehikoshimojima
ESP8266
目次:
ESP8266で電力モニターを作る
ARDUINOが動くWI-FIモジュール ESP8266で環境センサーを作る
ARDUINOで消費電流モニターを作る
ESP8266の消費電流を調べる
ESP8266 WI-FI SSID、パスワードのオンライン設定
ESP8266 ARDUINO、WI-FI経由のプログラムアップロード OTA

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
Arduino
目次:
ARDUINOで電力計:ARDUINO IDE 1.6.0にアップデートする
ARDUINOで消費電流モニターを作る
ESP8266の消費電流を調べる
ESP8266 WI-FI SSID、パスワードのオンライン設定
ESP8266 ARDUINO、WI-FI経由のプログラムアップロード OTA
ESP8266 Arduino、Wi-Fi経由のプログラムアップロード OTA
ESP8266 ArduinoのWi-Fi経由のアップロード機能OTA(Over the Air)を試しました。Wi-Fi経由でプログラムがアップロードでき、速度も速いので非常に便利です。ArduinoのOTA機能はソースコードがGithubに公開され、丁寧な解説もあります。
ArduinoのOTA機能はArduino IDE 1.6.7とArduino 2.0.0から正式サポートされました。Arduino IDE 1.6.5でサポートしているClassic OTAというものもありますが、これは今後非推奨になるとのことですので、この記事では1.6.7でサポートしているOTAについて書きます。
OTAの動作
OTA機能はライブラリーのように自分のプログラムに組み込んで使います。プログラムが置かれるフラッシュメモリーのイメージと合わせてOTAの動作を説明します。
フラッシュメモリー上ではプログラムと、ファイルシステム(spiffs)の領域が取られます。
現プログラムに組み込まれたOTA機能が新プログラムを現プログラムとファイルシステムの間にロードします。
ブートローダーが新プログラムを現プログラムの上にコピーし、
新プログラムが動き始めます。
最初のプログラムはシリアルで書き込む必要がありますが、新プログラムにもOTA機能を組み込んでおけば、これ以降はOTA機能を使ってプログラムを更新していけます。
上記のような動作のため、フラッシュメモリーは現と新の二つのプログラムが ロードできるスペースが必要になります。ESP8266のマニュアルには、OTAを使う場合には最低1MBのフラッシュメモリ領域を推奨すると書いてあります。ESP-WROOM-02には4MBのフラッシュメモリがあり、Arduino IDEで下図のように選択できるので、1MB以上を選択しておきます。
サンプルプログラムを動かす
OTAを使うためには次の二つが必要です。
Arduino IDE 1.6.7とArduino 2.0.0
Python 2.7
Arduino IDEの「ファイル」→「スケッチの例」→「ArduinoOTA」から「BasicOTA」を選択します。
プログラム中のssidとpasswordを自分のWi-Fiルーターのものに変更し、プログラムをビルドし、シリアル経由でボードに書き込みます。シリアルモニターに下記のようにIPアドレスが表示されたらOTAで書き込む準備が完了です。
Arduino IDEを立ち上げ直すと、ツール→シリアルポートにOTAポートが追加されています。
試しに同じプログラムをOTA経由でアップロードしてみます。まず、ツール→シリアルポートでOTAポートを選択し、プログラムをビルドしてボードに書き込むと、OTA経由でアップロードできます。Githubの解説には、ツールメニューの「Upload Using:」と「Upload Speed:」は変えなくていいと書いてあるので、変えませんでした。
自分のプログラムに常にこの「BasicOTA」と同じ機能を組み込んでおけば、OTAだけでプログラムのアップロードが続けられます。
2台以上のESP8266にOTAを組み込んだ時には、次のようにシリアルポートのところにチップIDとIPアドレスの異なる複数台のESP8266が表示されます。ここからESP8266を選んでアップロードすることができます。
OTAの機能
OTAには以下の機能があります。
ポート番号の設定(デフォルトは8266)
アップロードするESP8266のホスト名の指定(デフォルトはesp8266-チップID)
アップロード時のパスワード設定
アップロード開始時、終了時、アップロード中、エラー時のコールバック関数の指定
OTA機能は、頻繁にプログラムの修正、アップロードを繰り返す開発段階で便利な事は言うまでもありません。それに加えて、開発が終わって稼動状態になったものにもOTAを組み込んだままにしておけば、何らかの理由でプログラムの修正が必要になったときにも非常に便利そうです。その時は、分かりやすいホスト名をつけておくことや、第三者にプログラムを書き換えられてしまわないようにパスワードを設定しておくことが必要そうです。
ESP8266 Wi-Fi SSID、パスワードのオンライン設定
Wi-Fi接続に必要なSSIDとパスワードをオンラインで設定してみました。
Wi-FiのSSIDとパスワード(以下、認証情報と呼びます)は、プログラム中に書いていることが多いと思います。自分でプログラムを書いて、自宅など自分の環境で動かす分にはこれで全く問題ないのですが、いつもと違うWi-Fiアクセスポイントにつなぐときなどには、認証情報がオンラインで設定できると便利です。ネットで調べるといくつかの事例が見つかります。その中で以下のサイト「WiFiManager ESP8266 WiFi connection manager library (Arduino IDE)」で紹介されているWiFiManagerを、実際に動かしてみました。
WiFiManager 動作の流れ
保存されている認証情報があれば、その情報を使ってAPに接続する
保存されている情報がないか、あっても接続できなければ、Wi-Fiをスキャンして接続候補となるAPを探し、ESP8266自身がアクセスポイントモードになり、認証情報の入力を待つ
ユーザーがESP8266のAPに接続すると、ESP8266自身が立ち上げたWebサーバーに接続され、表示されているAP候補の中から接続したいAPを選択し、そのパスワードを入力する。
ESP8266は指定されたSSIDとパスワードでAPに接続する
WiFiManagerは上記の動作をするライブラリーになっており、自分のプログラムの先頭でこのライブラリーを呼び出すことで認証情報をプログラム中に書かなくてもWi-Fi APに接続できるようになります。
WiFiManagerのソースコードはGithubに公開されています。
動作確認
WiFiManagerはこのブログを書いている時点でも頻繁に更新されているようです。私が試したバージョンは0.8です。Arduinoはリリース2.0.0かそれ以上に新しいものを使うように指定されていましたので、2.0.0を使いました。
Githubからzipファイルをダウンロードして展開し、WiFiManager.cppとWiFiManager.hをArduinoのライブラリーに追加します。サンプルプログラムの中のAutoConnectというのが基本的なサンプルなので、それをArudino IDEで読み込んでビルドし、実行しました。
シリアルモニターを立ち上げておくと、「Wi-Fiクライアントとしてアクセスポイントへの接続を試みた後、ESP8266をWi-Fi APにしてWebサーバーを立ち上げている」といったメッセージが出力されます。
このWebサーバーにiPhoneでアクセスしました。まずiPhoneの「設定」の中の「Wi-Fi」を開きます。自宅のWi-Fiルーターの他に"AutoConnectAP"というAPが見つかります。これがESP8266なので、これを選択します。
自動的にブラウザーが立ち上がる場合もありますし、そうでない場合はブラウザーを起動します。するとESP8266のWebサーバーに接続され、次の画面が表示されます。
ここで「Configure WiFi」をタップすると、近くにあるWi-Fi APのリストが表示されます。
SSIDをモザイク加工したらモザイクだらけになってしまいましたが、SSIDのリストが表示されています。この中から接続したいAPを選択し、パスワードを入力します。
すると、iPhoneの画面に「認証情報を保存してWi-Fi APに接続している」というメッセージが表示され、ESP8266がWi-Fiに接続されました。
豊富な機能
WiFiManagerには上記の基本機能のほかに以下のような機能があるようです。
Configuration Portalにパスワードをつける。
SSIDとして"ESP"+チップIDという名前をつける。これは複数のESP8266がある場合に便利そうです。
Configuration PortalのIPアドレスを指定する。
Wi-Fi AP接続後、クライアントとして立ち上がった時にDHCPを使わず、IPアドレスを指定する。
信号の弱いAPを候補に表示しない。
MQTTサーバーやblynkのトークンなどを設定する。
強力ともいえますが、豊富すぎる気もします。
プログラムサイズ
WiFiManagerは外からWiFiの認証情報が入力できるライブラリーで、自分のプログラムに組み込んで使います。豊富な機能と引き換えにメモリーを消費してしまいます。そこでプログラムサイズを確認してみました。autoConnectというサンプルプログラムはWiFiManagerを呼び出すだけのプログラムです。これをビルドすると次のようなサイズでしたので、参考にしてください。
最大434,160バイトのフラッシュメモリのうち、スケッチが261,632バイト(60%)を使っています。 最大81,920バイトのRAMのうち、グローバル変数が36,434バイト(44%)を使っていて、ローカル変数で45,486バイト使うことができます。
環境センサーを作る
目次:
環境センサーを作る
マイコンの選択 Arduinoとmbed
Arduinoが動くWi-Fiモジュール ESP8266で環境センサーを作る
ARDUINOで消費電流モニターを作る
ESP8266の消費電流を調べる

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
ESP8266の消費電流を調べる
2016/8/17:IoT用クラウドサービスAmbientを使い、ESP8266の消費電流についてさらに詳細に調べました。詳しくは「ESP8266の消費電流の徹底調査」をご覧ください。
自作の消費電流モニターを使ってESP8266の消費電流を調べました。測定対象にしたのはESP8266を使った温度・湿度ロガーです。このロガーは単三乾電池3本を電源にして3端子レギュレーターで3.3Vを作り、ESP8266を駆動しています。消費電流モニターで使っている電流計モジュールINA226PRCの説明書を参考に、乾電池と3端子レギュレーターの間に消費電流モニターを接続しました。回路図を示します。回路図右下にあるのが電流計モジュールINA226PRCで、この図では省略してありますが、さらにこの右側に消費電流モニターがつながります。
消費電流モニターの回路図は「Arduinoで消費電流モニターを作る」をご覧ください。測定対象と消費電流モニターをつなぐとこんな感じになりました。
立ち上がり部分の消費電流
まず最初に、立ち上がってすぐDeep sleepモードに移行するプログラムを作り、ESP8266の立ち上がり部分の消費電流を調べました。
void setup() { ESP.deepSleep(60 * 1000000, RF_DISABLED); delay(1000); } void loop() { }
測定結果は次のようになりました。
縦軸の単位はmA、横軸は1目盛が5m秒、200目盛で1秒になります。ESP8266のスタート直後には200~300mAの電流が流れるようです。
Wi-Fiアクセスポイント(AP)接続までの消費電流
次は立ち上がりからWi-Fi APに接続するまでの消費電流です。
void setup() { wifi_set_sleep_type(LIGHT_SLEEP_T); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } ESP.deepSleep(60 * 1000000, RF_DISABLED); delay(10000); } void loop() { }
測定結果です。
この測定では立ち上がりからWi-Fi AP接続までに約6.5秒かかっており、その間の消費電流(累積消費電流と呼ぶことにします)は427mA秒でした。Wifi.begin()の中ではWi-Fi APへの接続とDHCPでIPアドレスなどの取得をおこなっており、その処理に427mA秒の電流を消費していることになります。
Deep sleep版温度・湿度ロガーの消費電流
次は温度・湿度ロガーの消費電流です。温度・湿度ロガーのプログラムは次のような流れです。
Wi-Fiアクセスポイントに接続
温度、湿度を測定
クラウド上のサーバーに接続
測定データをサーバーに送信
5分間Deep sleep
5分後にリセットがかかり、1から処理を繰り返す
実際のプログラムはGithubに公開してありますので、そちらをご覧ください。消費電流の測定結果は次の通りです。
このロガーは5分周期で測定・データー送信を繰り返していますが、なるべく長期間ロガーを動かすために、データーを送信した後はCPUをDeep sleepモードにしています。Wi-Fi APに接続してから、温度・湿度を測定し、クラウド上のサーバーに接続し、データーを送信し、Deep sleepモードに移行するまでに約9.5秒かかっています。Deep sleepモードに入ると1.2~1.3mAしか電流を消費していないことが分かります。
5分間の累積消費電流を計算すると835mA秒でした。1時間に2.78mAhの電流を消費します。電池の持続時間は、温度や連続して放電するか間欠的に放電するかなどの使い方などの条件によって変わってくるようですが、仮にアルカリ単三乾電池から2000mAh引き出せるとすると、このロガーは719時間、つまり30日程度動く計算になります。実際には、この原稿を書いている時点でロガーは50日間連続で動き、まだ動き続けています。 ESP8266のDeep sleepはスリープから復帰するときにCPUがリセットされ、プログラムの先頭から実行を繰り返します。つまり周期の先頭で毎回Wi-Fi APに接続します。ここで430mA秒程度の電流を消費する代わりに、Deep sleepに入ると消費電流は1.2~1.3mA程度に下がります。 もう一つの実現方法として、Deep sleepを使わず、Light sleepを設定した上でloop()関数の中でdelay()で待ち時間を設定する方法があります。これについても消費電流を調べました。
Light sleep版の消費電流
プログラムはこんな感じです。
void setup() { Wi-Fi APに接続 } void loop() { 温度・湿度を測定 サーバーに接続し、データーを送信 delay(周期); }
測定結果を示します。
立ち上がりから6.5秒ほどでWi-Fi APに接続し、loop()処理にはいっているようです。delay()している間は少ないときは3mA程度の消費電流ですが、グラフでわかるように結構な頻度で70mAぐらいの電流消費があります。Wi-Fiルーターから周期的に発信されるビーコンを受信しているのではないかと思います。delay()中の消費電流を計算すると15mA秒程度でしたので、Light sleep版を5分周期で動かしたときの5分間の累積消費電流は4,760mA秒程度、1時間で16mAh程度になると思います。5分周期ならLight sleepよりDeep sleepの方が消費電流が低く抑えられます。スリープが32秒以上ならDeep sleepの方が消費電流が低くなると思います。
Arduinoで消費電流モニターを作る
センサー端末のようなIoT機器をバッテリーで長期間動かすために、センサー端末の消費電流の振る舞いが知りたくなります。そこで、ミリアンペア単位の電流値を数ミリ秒間隔で測定し、数十秒記録できるような消費電流モニターを作りました。
2016/7/28: データーをIoT用クラウドサービスAmbientに送信するようにしました。詳しくは「AmbientとESP8266でマイコンの消費電流モニターを作る」をご覧ください。
電流計モジュール INA226PRCを使う
電流値の測定にはストロベリー・リナックス社のINA226PRCというモジュールを使いました。
これは電源ラインの中に小さな値の抵抗(シャント抵抗)を入れ、その両端の電圧を測ることでそこを流れる電流を測定するものです。INA226PRCのシャント抵抗は25mΩで、分解能は0.1mAとのことです。このモジュールに使われている電流センサーはテキサス・インスツルメント社のINA226というチップです。マニュアルによると、チップ自体に複数回測定してその平均をとる機能があり、回数は1回から1,024回まで設定できます。また1回の測定時間も140μ秒から8.244m秒まで設定できます。測定時間を長め目にしたほうがノイズの影響が低く抑えられるようです。ノイズ影響を極力抑えるためには、測ろうとする間隔の範囲内で測定時間×平均回数がなるべく長くなるようにするとよいとありました。例えば20m秒間隔で測定するなら、シャント抵抗両端の電圧値測定と電源電圧測定の時間を共に588μ秒にして16回測定して平均をとるようにすると、トータルの測定時間が(588μ秒 + 588μ秒) * 16 = 18.8m秒と20m秒以内で長くなり、いいようです。ESP8266とINA226とはI2Cで通信します。回路図はとても単純です。
できあがった消費電流モニターの写真です。写真右下がESP8266、左下がUSBシリアル変換モジュール、写真上側が電流計モジュールINA226PRCです。ESP8266とINA226PRCをジャンパーワイヤーでつないでいます。INA226PRCの上に測定対象を接続します。
プログラムはGithubに公開しました。INA226にはキャリブレーションレジスターというレジスターがあります。名前からすると測定値の校正ができそうですが、INA226のマニュアルを見ると単に定数を書き込んでおくと、シャント抵抗両端の電圧から電流値に変換してくれるだけの機能です。INA226をマイコン制御するなら、このレジスターを使う必要はなく、シャント抵抗両端の電圧を読み、プログラムで電流値に変換すればすみます。プログラムはこの電流値を一定間隔で測定し、測定値をバッファーに記録するようにしました。電流値が±0.3mA以上になったら測定対象が動き出したと判断して記録を開始し、バッファーが一杯になったら測定値をシリアルポートにプリントしています。PC側のシリアルモニターでこの出力を表示し、手作業でcsvファイルにして処理するようにしました。
ESP8266のRAMはプログラムで使える領域が50kB程度です。INA226のシャント抵抗電圧値を保持するレジスターは16ビットですので、バッファーはshortの配列にしました。配列サイズを変えながらプログラムをビルドすると、配列サイズが7,000のところで以下のような警告メッセージがでました。
Low memory available, stability problems may occur.
そこで、配列サイズは4,000にしました。測定間隔5m秒で20秒間、10m秒で40秒間の電流値が測定・記録できるようになります。
次はこの消費電流モニターを使ってESP8266の温度・湿度ロガーの消費電流を調べます。
Arduinoが動くWi-Fiモジュール ESP8266で環境センサーを作る
電力モニターで自宅の電気の使用状況が分かるようになったので、室温や湿度と電気使用の関係を調べることにしました。温度や湿度は、居間など人がいる場所に近いところで測定したいのですが、測定場所の近くに電源コンセントやLANの口があるとは限りません。そこで温度や湿度を測定するセンサー端末は電池駆動にして、データーは無線で送るようにしようと考えました。当初想定した全体像は次の図のようなものです。
センサー端末を制御するマイコンも近距離通信モジュールも低消費電力のものを検討し、マイコンはmbed LPC1114、近距離通信はZigBeeを候補にしました。
ESP8266ベースに設計変更
その後、ESP8266というArduinoでプログラムが書けるWi-Fiモジュールが登場しました。Wi-Fiは消費電力がやや多めと言われます。ZigBeeですと例えばモノワイヤレス社の超小型無線モジュール TWE-Liteの消費電流は送受信時15~17mAですが、ESP8266の消費電流は平均80mAだそうです。しかしWi-Fiは無線LANルーターと直接通信ができてゲートウェイが不要になりますし、ESP8266自体の価格も1,000円未満と、全体に安価に環境センサーが作れます。そこで当初の方針を変更し、ESP8266で環境センサーを作ることにしました。全体像は次の図のようになります。
ベースとなるハードウェア構成やArduinoの開発環境は前回の記事「ESP8266で電力モニターを作る」をご覧ください。センサーはボッシュ社のBME280という1チップで温度、湿度、気圧が測れるものを使いました。回路図を次に示します。
できあがったセンサー端末の写真です。単三乾電池3本で動かしています。
前回の電力モニターの記事と同様、プログラム開発時はUSBインターフェース付きのボードを使い、USB経由でプログラムのダウンロードやプリント文でのデバッグをおこない、プログラムが動いたらこちらのボードにESP8266を移してパソコンなしで動作させます。
プログラム
センサー端末とサーバーとのやりとりには二つの方法があります。一つはサーバー側からセンサー端末に「現在のセンサーの値を教えて」というリクエストを出し、センサー端末がそれに答えてサーバーにセンサーの値を返す方法。もう一つはセンサー側から「現在のセンサーの値はこれです」というリクエストを出す方法です。
サーバーからリクエストを出す方法は、センサー端末が常にリクエストを待っていて、リクエストが来たら答えを返す必要があります。制御用のマイコンにはDeep sleepという非常に消費電力の少ない仮死状態のようなモードがあります。通常はスリープする時間を指定してこのモードに入り、スリープしている間は何もできません。Deep sleep状態になるとサーバーからリクエストを出す方法ではリクエストに反応できなくなります。そこでこのセンサー端末は端末側からリクエストを出してセンサーの現在値を送信し、それが終わったら決められた時間Deep sleepするという構造にしました。
プログラムはGithubに公開しました。5分ごとに温度、湿度、気圧を測定し、データーをサーバーに送信しています。Arduino-ESP8266-BME280.inoというファイルがプログラム本体です。プログラム中で#define VERBOSE という行をコメントアウトしてあります。このコメントを外すと立上げ時やデーター送信時に状況をシリアルに出力し、データー送信時にはLEDが点滅するようになり、動作状況が確認できるようになります。動作が確認できたらこの行をコメントアウトすれば、シリアル出力もLEDの点滅もなくなります。一見動いているかどうか分からなくなりますが、少しでも消費電力が抑えられます。
ESP8266のスリープモード
先ほども書きましたが、測定と測定の間はなるべく電力を消費したくないので、ESP8266をDeep Sleepモードに移行させています。「ESP8266 Sleep Mode Function Description」というマニュアルを見るとESP8266にはModem sleep、Light sleep、Deep sleepという三つのスリープモードがあると書かれています。
Modem sleepとLight sleepはESP8266のWi-Fiがステーションモードの時、実行すべき処理がなくなるとESP8266が自動的にこのどちらかのモードに移行します。どちらのモードに移行するかはwifi_set_sleep_type()という関数で指定します。Modem sleepはWi-Fi部分がオフになり、CPUは動作しているのに対し、Light sleepはWi-Fi部分とシステムクロックがオフになりCPUがペンディング状態になってModem sleepよりも更に消費電流が少なくなります。DTIMはWi-Fiルーターから端末に送られるビーコンのことですが、これは話が長くなるので今回は触れません。
一方、Deep sleepはプログラムから明示的にこのモードに移行することができ、消費電流は20μA程度と非常に少なくなります。Deep sleep時に指定したスリープ時間が経過するとESP8266にリセットがかかり、プログラムの先頭から再度動き始めます。つまり、Deep sleepは寝ているときはほとんど電力を消費しませんが、起きたときに毎回ルーターに接続するため、ここで大きな電力を消費します。Deep sleepが電力消費上有利かどうかはスリープする時間に依存することになります。本来は消費電力を測定して決めるべきですが、今回は測定と測定の間はDeep sleepさせることにしました。
サーバー側 IoT用シンプルサーバー「Ambient」
センサー端末は測定した温度、湿度、気圧データーをサーバーに送ります。サーバー側はデーターを受信して蓄積し、グラフ化するシンプルなサーバーを開発しました。サーバーにユーザー登録すると「チャネル」が作られます。端末はこの「チャネル」を指定してデーターを送信します。サーバー側は送られたデーターを「チャネル」ごとに保存し、グラフ化します。次のグラフは12月のある日の我が家の室温、湿度、気圧です。
このサーバーは「Ambient」という名前を付けて https://ambidata.io というアドレスに公開しました。「as is」でよければ使ってみてください。
Arduinoで電力モニター
目次:
自分の家の電気の利用パターンを知りたい
Arduinoと電流クランプを使って電流値を測る
プログラムはステップ・バイ・ステップで動作確認しながら
ArduinoとCC3000でWi-Fiに接続する
データーをHTTP POSTでサーバーに送る
一日の電気利用状況を調べる
今後の予定
Arduino IDE 1.6.0にアップデートする
Google Chartsを使って電気の使用状況をグラフ表示する
長期間動かす
電気料金のシミュレーション
ESP8266で電力モニターを作る
ESP8266で電力モニターを作る
約1年前(2014年12月)にArduino UNOを使って電力モニターを作り、自宅の電力使用の測定を開始しました。このバージョン(第一版と呼ぶことにします)は家の分電盤に電流センサーを取り付け、Arduino UNOで電流値を測定し、CC3000というWi-Fiモジュールを使って測定データーをクラウドに送信しています。送信したデーターはグラフ化し、一日や一か月の電力使用状況が分かるようにしています。今年(2015年)になってESP8266というArduino IDEでプログラム開発ができるWi-Fiモジュールが登場しました。これを使って電力モニターの第二版を作ったので、紹介します。
ESP8266
ESP8266はWi-Fiモジュールで、ArduinoやmbedなどのマイコンとつないでWi-Fi通信ができます。さらに、ESP8266の内部にも32ビットマイコンが搭載されており、Arduinoの開発環境(Arduino IDE)を使ってプログラムを書くことができます。つまりArduinoやmbedなどのマイコンがなくても、このモジュール単体でセンサーを制御し、Wi-Fiでデーターを送信するセンサー端末を作ることができます。今回はこのESP8266で電流センサーの値を読み取り、サーバーに送信してデーターを確認するような電力モニターを作りました。
ベースとなるハードウェア構成は以下のサイトを参考にしました。
・ESP-WROOM-02のArduino環境でI2C制御
また、Arduino開発環境の設定は以下のサイトを参考にしました。
・技適済み格安高性能Wi-FiモジュールESP8266をArduinoIDEを使ってIoT開発する為の環境準備を10分でやる方法
USBでパソコンと通信できる開発用ボード(写真左)と、USBインターフェースをもたないボード(写真右)の2種類を作りました。
パソコンで開発したプログラムは左のボードでデバッグし、プログラムができたらESP8266を右のボードに移すとパソコンなしで動かせます。右のボードのUSBコネクターは電源供給用です。回路図はこんな感じです。開発用ボードはこれにUSBシリアル変換モジュールが加わります。
ESP8266は秋月電子さんのWi-FiモジュールESP-WROOM-02 DIP化キットを使いました。ESP-WROOM-02はESP8266を搭載したパッケージです。ESP-WROOM-02は複数社からブレッドボードに挿せるピッチ変換ボードが出ています。ESP-WROOM-02はモジュール幅が広いため、通常のブレッドボードに載せると配線の余地がなくなるものが多いのですが、秋月さんのDIP化キットは配線のスペースが取れるように工夫されていて、使いやすいです。
家庭用の電力は、多くの場合単相三線式といって2系統で送られてきますので、家全体の電力使用を把握するには2系統を測定する必要があります。ESP8266はAD変換できる入力が1チャネルしかないので、2チャネルのADコンバーターを使うことにしました。
第一版と比べると、Arduino UnoとCC3000を搭載したWi-Fiシールドが1モジュールになっているので、回路も単純で、小型化されました。写真の左が上からArduino UNO、中がCC3000 Wi-Fiシールド、下が電流センサーのインタフェースボードで、これを3段重ねにして使います。この3段構成が右の1ボードになりました。
プログラム
電力モニターのプログラムは第一版のものとほぼ同じ構造です。交流の電流値を測るためには、交流の1周期の電流をさらに細かい周期で何回か測定し、平均(二乗平均平方根)して電流値を求めます。Arduino UNOはマイクロ秒単位のタイマーがあるので、第一版ではこれを使い250マイクロ秒間隔で400回、100ミリ秒間、電流値を測定しました。ESP8266ではTickerという周期処理のライブラリーが用意されているので、これを使いました。ただし、Tickerの最小周期がミリ秒なので、第二版では1ミリ秒間隔で100回、100ミリ秒間測定するようにしました。
単相三線式で送られてくる2系統の電力をそれぞれ30秒に1回測定し、Wi-Fi経由でサーバーに送信しています。サーバー側プログラムは今回全面的に書き直しましたが、これは別の機会に紹介したいと思います。
データーのグラフ化も第一版のものとほぼ同様で、30秒ごとの生データーをグラフ化したもの、30分単位の擬似電力値として表示したもの、1日単位に集計したものを用意しました。「擬似」と書いたのは、電流値×100Vを電力とみなしているためです。本当は力率をかけて計算する必要がありますが、おおよその電力使用の傾向はつかめていると思います。
1日の電力使用状況(30分単位の電力量(概算))
1日の電力使用状況(電流値の生データー)
1ヵ月の電力使用状況
第二版で追加したのは次のグラフです。これは1日の電力利用のパターンを2週間分重ねて表示したものです。24時間の電力利用の傾向が概観できます。よく見ると平日は朝6時前に電気の使用が増えますが、休日はそれが7~8時と遅くなります。また、季節によっても違いがあるでしょう。こういったデーターを蓄積し、通常と違うパターンを見つければ、見守りサービスなどに応用できるかもしれません。もちろん見守りサービスを行う場合は目視でいつもと違うパターンを見つける訳ではなく、機械学習などを使って異常検出をおこなうことになると思います。
ここで開発したサーバーの仕組みを汎用化させて、IoT用のクラウドサービス「Ambient」を作りました。「Ambient」はマイコンからのセンサーデーターを受信し、蓄積し、可視化(グラフ化)するサービスです。よければ使ってみてください。

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
mbedとIFTTTで部屋の温度、湿度をiPhoneに通知する
IFTTTというWebサービスを連携させるサービスがあります。IFTTTは「IF This Then That」の略で、「もし『これ』が起きたら『あれ』をする」といったようにWebサービスを連携させられます。『これ』と『あれ』の部分は従来、FacebookやEvernoteのようなWebサービスでしたが、2015年6月にMaker Channelが登場し、『これ』や『あれ』の部分に自作のサービスが使えるようになりました。この機能を使い、mbedで部屋の温度、湿度を測り、iPhoneに通知するようにしてみました。
IFTTT Maker Channel
IFTTTでは「もし『これ』が起きたら『あれ』をする」の『これ』や『あれ』をチャネルと呼び、前半の「もし『これ』が起きたら」の部分をトリガーチャネル、後半の「『あれ』をする」の部分をアクションチャネルと呼びます。IFTTT Maker Channelの基本的な使い方は、他のブログ、例えば「IFTTTにMaker Channelができました」などを参考にしていただくとして、Maker Channelを使うためにはまずMaker Channelに「コネクト」します。すると連携させるときに使う秘密キーが払い出されます。トリガーを実現するには、以下のURLにHTTP POSTかGETすればいいようです。
https://maker.ifttt.com/trigger/イベント名/with/key/秘密キー
イベント名は好きな名前がつけられます。今回は「temp_humid」というイベント名にしました。IFTTTサイトには「https」と書かれていますが、「http」でも動作しました。また三つまでパラメーターを渡せるようで、サイトには次のようなJSONフォーマットあるいはクエリパラメーターで渡せと書いてあります。パラメーター名はvalue1、value2、value3でないとだめで、これ以外では受け取ってくれないようです。
{ “value1” : “ 値1 “, “value2” : “ 値2 “, “value3” : “ 値3 “ }
IFTTTのレシピを作る
レシピは「もし『これ』が起きたら『あれ』をする」を具体的に記述するものです。IFTTTではウィザードのようなインタフェースが用意されていますので、質問に順番に答えていくとレシピが出来上がります。まず、トリガーチャネルとしてMaker Channelを選択します。次にイベント名を聞かれるので、今回使うことにした「temp_humid」を入力します。次にアクションチャネル選択になるので、ここで「IF Notifications」を選択します。さらに通知文章が入力できるので、それを以下のようにしました。
「今、部屋の温度は {{Value1}} ℃、湿度は {{Value2}} %です。"{{EventName}}"」
最後にこのレシピに「mbedで温湿度を測り、iOSに通知する」という名前をつけました。これでレシピは出来上がりです。
mbed側のプログラム
IFTTT側の準備ができたので、次はmbed側のプログラムです。IFTTTのトリガーチャネル用のライブラリーがあるので、それを利用しました。温度、湿度の測定にはAM2321というセンサーモジュールを使いました。温度と湿度が測定でき、I2Cインタフェースで読み出すことができます。mbedにライブラリーも公開されています。プログラムは最後に掲載しました。秘密キーの部分は実際に払い出されたキーで置き換えます。
動作確認
mbedのプログラムをコンパイル、ダウンロードしてmbedのリセットボタンを押すと、iPhone上に以下のような通知が現れました。
mbedで測定した温度、湿度がiPhoneに通知されていることがわかります。
他のサービスにも連携させてみる
mbedのプログラムをIFTTTにつなぐと、iPhoneへの通知以外にも様々なサービスと連携させることができます。応用としてmbedで測定した温度、湿度をGoogleカレンダーに登録するレシピを作ってみました。mbedのプログラムは変更ありません。IFTTTのレシピ作成でアクションチャネル選択のときに「IF Notifications」の代わりにGoogleカレンダーを選択します。これでmbedのプログラムを動かすと、その時刻にGoogleカレンダーに温度と湿度が記録できました。
このようにmbedをIFTTTのチャネルとして登録すると、IFTTTに登録されている200以上(2015年8月現在)の他のWebサービスと比較的簡単に連携させることができます。
#include "mbed.h" #include "EthernetInterface.h" #include "TCPSocketConnection.h" #include "ifttt.h" #include "AM2321.h" #define EVENT "temp_humid" #define SECRET_KEY "xxxxx-your-secret-key-xxxxx" EthernetInterface eth; RawSerial pc(USBTX, USBRX); // tx, rx AM2321 am2321(p28, p27); // SDA, SCL int main() { char tempbuf[8]; char humidbuf[8]; pc.baud(9600); eth.init(); //Use DHCP eth.connect(); printf("IP Address is %s \n\r", eth.getIPAddress()); TCPSocketConnection socket; // Initialize ifttt object, add up to 3 optional values, trigger event. IFTTT ifttt(EVENT, SECRET_KEY, &socket); // EventName, Secret Key, socket to use am2321.poll(); sprintf(tempbuf, "%.1f", am2321.getTemperature()); sprintf(humidbuf, "%.1f", am2321.getHumidity()); // Send Data using POST ifttt.addIngredients(tempbuf, humidbuf, NULL); ifttt.trigger(IFTTT_POST); eth.disconnect(); while(1) { } }
環境センサーを作る:マイコンの選択 Arduinoとmbed
使ってみて感じるArduinoのいい点と弱い点
電力計はArduinoというマイコンボードを使って作りました。開発環境がとてもよくできていて、ArduinoのWebサイトから開発環境であるArduino IDEをPCにダウンロードすればすぐに使えます。サンプルプログラムも豊富で、ArduinoボードをUSBでPCに接続しておいて、サンプルプログラムをコンパイルすると自動的にプログラムがArduinoボードに送られ、実行されます。LEDを光らせるようなプログラムを送り込めば、すぐに動作が確認できます。さらにArduinoサイトにはデーター入力やインターネット通信などの大量のサンプルプログラムが公開されています。加えて、Arduino Playgroundというコーナーがあり、ユーザーが作ったプログラムなどが公開されています。また、温度や赤外線などのセンサー、イーサーネットなど、Arduinoに接続可能な様々な周辺モジュールも販売されており、周辺モジュールを制御するプログラムも公開されています。
このようにArduinoは開発環境が使いやすいこと、サンプルプログラムが豊富なこと、周辺モジュールが充実していることから、組み込みシステムの専門家でなくても速く、簡単にアイデアをプロトタイプ化できます。
このようなメリットのあるArduinoですが、弱いところもあります。一つはCPU速度で、特に浮動小数点(float)の計算が遅いです。Arduinoで一番ポピュラーなボードであるArduino UNOのCPUでは、floatの変数xとyに対して
y = x / 1023.0;
という計算だけで35μ秒かかりました。センサーから得られるデーターは普通に考えると小数点のある値になりますが、Arduinoではそれを扱うfloatの計算が遅いので、プログラムを書くときには気を使う必要があります。例えば電力計の場合は交流の電流値を250μ秒間隔で測定して電流値を計算しましたが、250μ秒ごとの処理の中ではfloatの計算をしないようにしました。
もう一つ弱いと感じたのはメモリーサイズです。Arduino UNOではプログラムのデーターエリアとして使われるSRAMが2kBしかありません。こちらもプログラムを書くときに気を使う必要があります。
Arduinoボードには私が使ったArduino UNO以外にも多くのプラットフォームがあります。詳しくは以下のサイトなどを参照願いたいのですが、ボードによってはCPUが速いものやメモリーサイズが大きいものがあるようです。
Arduinoシリーズ15種類の違い|まとめ比較表
プロトタイプ開発に適したマイコンとしては、プログラム開発環境が簡単で分かりやすいこと、サンプルプログラムが豊富なことが重要です。センサーや通信などの周辺モジュールが充実していることも重要なポイントです。Arduino以外にプロトタイプ開発に向くマイコンとしてはmbed、Raspberry Pi、Intel Edison、Tesselなどがあります。環境センサーでは低消費電力のボードが提供されていて、開発環境も充実しているmbedを使ってみることにします。
mbed (エンベッド)
mbedは英ARM社のプロセッサーを使ったワンボードマイコンとプログラム開発環境です。ARM社のプロセッサーは低消費電力、高性能で知られ、iPhoneなど多くのスマートフォンやゲーム機などで使われています。ARM社は技術をライセンス提供し、半導体メーカーがライセンスを受けてプロセッサーを製造しています。mbedも同様で、ポピュラーなボードはNXP社が開発したLPC1768を搭載したボードです。
このボードはスイッチサイエンス社のサイトなどで購入できます。価格は2015年7月時点で5,940円です。
mbedの開発環境はWeb上に用意されています。画面は次のような感じです。
ここでプログラムを書き、コンパイルすると実行形式のファイルがパソコンのダウンロードフォルダーにダウンロードされます。mbedボードをUSBケーブルでパソコンにつなぐと、mbedボードがUSBメモリーとして認識されるので、実行形式のファイルをそのメモリーにコピーするとファイルがUSB経由でmbedにダウンロードされ、実行されます。開発環境には豊富なサンプルプログラムがありますが、その中にはmbedボード上のLEDを点滅させるプログラムもあります。それをコンパイルしてボードに送ると動作確認ができます。最初に開発環境を使うときにはユーザー登録が必要ですが、それを含めても10分もあればLEDを点滅させることができます。ユーザー登録からサンプルプログラムの動作確認までは以下のサイトに詳しい説明があります。
mbedを始めましょう!(“Let’s get started!” in Japanese)
Arduinoと同様にmbedもmbedサイトに大量のサンプルプログラムやQ&Aのコーナーがあり、開発者コミュニティーが充実しています。サンプルプログラムを自分の開発環境に取り込んで、それを参考にしてプログラムを作るのも簡単です。例えばHTTPでデーターをGET、PUTするプログラムを作るとすると、mbedサイトに行って「HTTP」で検索すると「HTTPClient_HelloWorld」というそれらしいプログラムが見つかります。そのページにいって、ソースコードなどを調べ、参考になりそうだと思ったら「Import this program」をクリックすると、このプログラムが自分の開発環境にコピーされます。あとはそのコピーを元に自分なりに修正することでプログラム開発がおこなえます。コミュニティーの充実と、コミュニティーの成果を参考にして自分のアイデアを積み上げられる仕組みがmbedの大きな魅力だと思います。
mbedボードにもいろいろなバリエーションがあります。
https://developer.mbed.org/platforms/
高速なもの、低消費電力なもの、周辺インタフェースが豊富なものなどいろいろですし、今でもmbed対応のボードが追加されています。写真は左が一番ポピュラーなLPC1768、真ん中が低消費電力で安価なLPC1114FN28、右はBluetoothを搭載したHRM1017です。
環境センサーでは、電池で動かすセンサーモジュールにはLPC1114FN28が、インターネット経由でクラウドにデーターを送信するゲートウェイにはイーサーネットインタフェースを持つLPC1768がよさそうです。
次はセンサーモジュールとゲートウェイ間の通信を調べます。
環境センサーを作る
Arduinoで電力計を作り、家の電力使用パターンが分かるようになりました。次は気温や室温、湿度などが電力使用とどう関係しているのか調べたくなりました。温度、湿度などのセンサーを作ることにします。
やりたいことの整理
生活環境を数値化できるようなデーターをとりあえず調べることにします。温度、湿度、照度といったところでしょうか。また、人がいるかいないかも電力利用に関係していそうなので、人の動きも調べることにします。定期的にこれらのデーターを調べ、クラウドに送信、蓄積して、可視化したり分析したりできるようにします。人が活動する居間などの場所の状況を調べたいので、センサーは目につくところに置くことになります。電源コードやLANケーブルなどがあると不格好です。電池で動き、データーは無線で送信できるようにします。また、将来的には温度、湿度の計測だけでなく、エアコンや照明の制御もできるといいと思います。箇条書きにすると次のようになります。
温度、湿度、照度、モーションを測り、定期的にサーバーに送信する
センサーはコードレス(電池稼働、無線でデーター送信)
エアコン、照明の制御
実現イメージ
センサーをコードレスにするために、低消費電力のマイコンを使い、BluetoothやZigBeeのような方法でゲートウェイまで送信し、ゲートウェイで中継してインターネット経由でサーバーに送信することにします。図にするとこんな感じです。
ソフトウェアについてはセンサーモジュールとゲートウェイ、Webサーバー間の通信プロトコルをどうするか、データーをどのように蓄積するかなどを考える必要がありそうですが、それはプロトタイプを作りながら考えることにします。
次はマイコンの選択です。
Arduinoで電力計:電気料金のシミュレーション
電力モニターが安定して動作するようになり、4月の電力使用の様子が分かりました。そこで、実績データーを使って東京電力の電気料金プランのシミュレーションをしてみました。
力率を計算する
電力モニターと書いていますが、実際には力率を見ておらず、力率を常に100%と仮定して、次のように計算しています。
電力=電流値×100V×力率(100%)
そこで、東京電力の検針値と比較して平均の力率を計算しました。検針値による4月の電力使用量は、前回検針日の3月27日から今回検針日の前日の4月29日までの34日間で226kWhでした。一方、自作の電力モニターで測った同じ期間の電力使用量は262kWhでした。ここから平均力率を86.3%と計算しました。力率は稼動している機器やその状態によって時々刻々変わりますが、以下のシミュレーションではこの平均力率で補正した電力量を使っています。
自宅の4月の電力使用状況
4月(3月27日から4月29日まで)の日別の電力使用は以下のようでした。
また、1ヶ月の電力使用を時間別に計算すると以下のようになりました。
東京電力の主な家庭向け料金プラン
私は東京電力エリアに住んでいますが、東京電力が家庭向けに提供している主な料金メニューは次の五つです。
従量電灯B・C: スタンダードメニュー
朝得プラン: 深夜1時から朝9時までがお得な料金プラン
夜得プラン: 夜9時から朝5時までがお得な料金プラン
半日お得プラン: 夜9時から朝9時までがお得な料金プラン
土日お得プラン: 土日が一日中お得な料金プラン
この他にも、オール電化住宅向けのプランやエコキュートなどを利用している人向けのプランなどがあります。詳しくは東京電力の電気料金メニューのページをご覧ください。
電気料金は契約アンペア数に応じて決まる基本料金と使った電力量に応じて決まる電力量料金と再生可能エネルギー発電促進賦課金の合計になります。
料金=基本料金+電力量料金+再生可能エネルギー発電促進賦課金
料金の計算式も東京電力のページで確認できます。
4月の使用実績グラフを合わせて見ると、夜9時から朝5時までがお得な夜得プランにすると、もしかしたら今契約している従量電灯Bよりも安くなるかもしれません。我が家は土日と平日の電力使用の差はあまりないので、土日が安くなる土日お得プランはあまり期待できそうにありません。
電力使用の実績値を使って各料金プランの電気料金を計算する
従量電灯B
4月の電力使用実績を使って、各料金プランの電気料金を計算してみます。まず従量電灯Bです。我が家の契約アンペア数は40Aなので、基本料金が1,123.20円、電力使用量は226kWh、単価19.43円の1段目の使用量が120kWh、料金が2,331.6円、単価25.91円の2段目は226-120=106kWh、2,746.46円、3段目はありません。それに燃料費調整額、再生可能エネルギー発電促進賦課金を加えて6,962.88円になりました。
朝得プラン
朝得プランは深夜1時から朝9時までが単価12.19円の割引時間帯で、9時から翌日の1時までが90kWhまでは単価23.93円、90~230kWhまでが31.90円、230kWh以上が36.85円という料金プランです。基本料金は6kVA(100Vなら60A)までが1,296.00円です。燃料費調整額、再生可能エネルギー発電促進賦課金は従量電灯Bと同じです。4月の使用実績では1時から9時までが61kWhでした。
割引時間帯以外の使用は165kWh、1段目90kWh+2段目75kWhです。料金を計算すると、7,347.41円になりました。
同様に夜得プラン、半日お得プラン、土日お得プランを使用実績データーを使って計算したところ、以下のようになりました。
4月の使用実績からすると、従量電灯Bプランが6,962円で最安値です。それ以外の料金プランはどれも7,000円を超えてしまいます。単価の安い割引時間帯にもっと利用が集中していないとスタンダードプランよりもお安くはならないようです。また、4月は年間でも一番電力使用量が少ない月です。特に夏は割引の利かない昼間の時間帯の使用量が多くなるので、春以上に従量電灯プランが有利になりそうです。
Arduinoで電力計:長期間動かす
サーバーをクラウドに移設し、連続して電流値が測定できるようになり、結果もブラウザーでリアルタイムにグラフ化して確認できるようになりました。しかし2日ぐらいは連続動作するものの、その後、Arduinoからサーバーにデーターが送られなくなってしまいます。電力の利用状況は一年ぐらいは継続して調べたいので、電力計は年単位で連続動作できるようにしておきたいものです。ということで今回はWi-Fi通信の安定化の取り組みについて書きます。安定化させるまでに1ヶ月ぐらいかかった記録なので、話が少し長くなりました。
2日程度は連続して動くので、単純なプログラムのバグではなさそうです。Wi-Fiの通信、あるいはWi-Fiを経由したWebサーバーとの通信が不安定で、Arduinoのプログラムが送信できなくなってしまうのだろうと考えました。
データー送信が止まってしまった様子です。0時30分頃を最後にデーター送信が止まってしまい、18時過ぎにArduinoのリセットボタンを押して送信を再開させています。
データー送信が止まったとき何が起こっているか調べる
Wi-Fi通信に使っているのはTI社のCC3000というWi-Fi通信用チップを搭載したSparkFun社のボード(Arduino用シールド)です。
SparkFunはこのボードを使うためのArduino用ライブラリーも提供しています。ソースコードは以下にすべて公開されています。
https://github.com/sparkfun/SFE_CC3000_Library
電力計で使っている主な関数は以下の通りです。
class SFE_CC3000の関数 init() // 初期化 startSmartConfig() // スマホのSmartConfigアプリを使いSSIDと // パスワードを指定してWi-Fiに接続 fastConnect() // SmartConfigで指定したデーターを使ってWi-Fiに接続 class SFE_CC3000_Clientの関数 connect() // サーバーにTCP接続する write() // サーバーにデーターを送信する stop() // サーバーとの接続を切断する
Arduinoの電力計プログラムは次のような構造です。
setup() { // Arduinoの初期化関数 wifi.init(); // CC3000を初期化する if (!wifi.fastConnect()) { // fastConnectでWi-Fiにつなぐ wifi.startSmartConfig(); // だめならSmartConfigでつなぐ } 30秒間隔でタイマー割り込みを設定; 30秒タイマーの割込み処理() { 30秒待ちフラグを解除; } loop() { // Arduinoプログラムの処理ループ 30秒待ちフラグが解除されるのを待つ; クランプ1の電流値を測定; クランプ2の電流値を測定; if (client.connect() == 成功) { // WebサーバーにTCP接続し、成功なら client.write(電流値データー); // 電流値データーを送信する client.stop(); // Webサーバーとの接続を切断する } }
まず、プログラムがどう動いているのかを調べました。そのためにArduinoからパソコンにデバッグメッセージを出力したかったのですが、電力モニターは玄関にある分電盤近くにあり、パソコンを置く場所がありません。そこで、Arduinoに緑と赤のLEDをつけ、それを使ってプログラムの状態を表示するようにしました。次のような感じです。
loop() { // Arduinoプログラムの処理ループ 30秒待ちフラグが解除されるのを待つ; クランプ1の電流値を測定; クランプ2の電流値を測定; 緑のLEDを点ける; if (client.connect() == 成功) { // Webサーバーに接続 緑のLEDを消す; client.write(電流値データー); // 電流値データーをHTTP POSTする client.stop(); // Webサーバーとの接続を切断する } else { 緑のLEDを消し、赤のLEDを点ける; } }
LEDを点灯、消灯する場所を変えながら調べた結果、何らかの理由でWebサーバーに接続できなくなり、その後は30秒ごとにWebサーバーへの接続(connect関数)を試みて失敗することを繰り返していることが分かりました。動作を調べる過程でライブラリーのソースコードを読んだり、Wi-Fiルーターの通信ログを調べたりしました。特に以下の三つの資料は理解の助けになりました。
「Internet of Things Wi-Fi Module API Documentation」
「WiFiの接続手続きのはなし」
「CC3000 Overview」
エラー時の状態を調べ、リカバリーするプログラムを試みる
資料を調べると、CC3000はWi-Fi接続が切れると自動的に再接続を試みるようです。それでもconnect()に失敗するので、CC3000の再接続がうまくいっていないという仮説を立てました。connect()に失敗した時の状態を調べ、その状態に応じてリカバリーするようにプログラムを改修することを考えました。CC3000を管理するオブジェクトには「初期化済み」「Wi-Fiのアクセスポイントに接続済み」「DHCP完了」の三つの状態があります。DHCPは自分のIPアドレスをDHCPサーバーにアサインしてもらう機能です。緑と赤のLEDを使い、connect()に失敗した時の状態を調べると、「初期化済み」「Wi-Fiアクセスポイント接続済み」でDHCPは完了している場合とそうでない場合がありました。Wi-Fiアクセスポイントへの接続とDHCPはfastConnect()というライブラリー関数の中でおこなわれます。そこで、connect()に失敗したときに一旦Wi-Fiの接続を切り、fastConnect()するというプログラムを試しましたが、fastConnect()に失敗し、リカバリーできませんでした。connect()関数の中でサーバーの文字列名からIPアドレスを求める処理と、IPアドレスを指定してサーバーに接続する処理の二つを行っているのですが、ライブラリー関数の中なので、そのどちらが失敗しているのかも分かりません。
Adafruit社のライブラリーを試す
調べている過程で、Adafruitという会社も同じCC3000という通信チップを搭載したArduino用のボードとそのボード用のライブラリーを開発、販売していることが分かりました。ライブラリーインタフェースを調べると、SparkFun社のライブラリーよりも単機能の関数が提供されています。Adafruit社のライブラリーソースコードも以下のサイトにすべて公開されています。
https://github.com/adafruit/Adafruit_CC3000_Library
SparkFun社(以下S社)とAdafruit社(以下A社)の主なライブラリー関数を比較したものが次です。
SparkFun社のライブラリー init() // 初期化 startSmartConfig() // SmartConfig機能 fastConnect() // 前回のデーターを使いWi-Fiに接続 connect() // サーバーにTCP接続する connected() // 接続を確認する write() // サーバーにデーターを送信する stop() // サーバーとの接続を切る Adafruit社のライブラリー startSmartConfig() // SmartConfig機能 begin() // 前回のデーターを使いWi-Fiに接続 checkDHCP() // DHCP完了を待つ getHostByName() // サーバー名からIPアドレスを得る connectTCP() // サーバーにTCP接続する connected() // 接続を確認する write() // サーバーにデーターを送信する close() // サーバーとの接続を切る
特に、今回エラーになるS社のconnect()という関数がA社のライブラリーではgetHostByName()とconnectTCP()という二つの関数に分かれており、問題の切り分けができそうです。S社製ボードにA社製ライブラリーという組み合わせは動くかどうか分かりませんし、両社とも動作保証はしてくれないと思いましたが、Wi-Fi制御チップは同じですし、S社製ボード+A社製ライブラリーで動かしたというブログ記事もあったので、試してみることにしました。
Arduinoボードとやりとりするピン番号がS社のボードとA社のボードでは異なります。例えば割込み要求はS社が2番ピンなのに対してA社のボードは3番ピンを使っています。そこでプログラムの中でピン番号を定義している部分をS社ボード用に書き直し、あとはそのままコンパイルしたところ、S社ボードとA社ライブラリーの組み合わせで動かすことができました!
この状態で連続動作させたところ、S社ライブラリーの時と同じように2、3日でデーター送信が途絶えることが分かりました。さらにこの時、getHostByName()という関数で失敗していることも分かりました。ここでライブラリーのソースコードを読んで内部処理を理解し、リカバリープログラムを書くことも考えたのですが、参考になるサンプルプログラムもなかったので、別のアプローチ、ウォッチドッグタイマーを試みることにしました。
ウォッチドッグタイマーを試みる
ウォッチドッグタイマーは、設定した時間までにタイマーをクリアーしないとシステムをリセットするという時限爆弾のような機能です。Arduinoでプログラムからシステムをリセットする方法は以下のページに解説があります。
http://playground.arduino.cc/Main/ArduinoReset
Arduinoではウォッチドッグタイマーのライブラリーが提供されています。以下のページに解説があります。
http://nongnu.org/avr-libc/user-manual/group__avr__watchdog.html
ライブラリーには次の三つの関数が用意されています。
wdt_enable(value); // ウォッチドッグタイマーを有効にする wdt_reset(); // ウォッチドッグタイマーをクリアーする wdt_disable(); // ウォッチドッグタイマーを無効にする
リセットがされるまでの時間は wdt_enable() のパラメーターで指定し、15m秒から8秒までの時間が設定できます。このライブラリーは「ArduinoのCPUは確実にリセットできますが、シールドと呼ばれる拡張ボードまでリセットできるかは分からない」とArduino公式サイトに書かれていましたが、とりあえず使ってみることにしました。例えばgetHostByName()を呼ぶ前後に下記のようにウォッチドッグタイマーをセットしました。
wdt_enable(WDTO_8S); // 8秒のウォッチドッグタイマーをセット for (ip = 0; cc3000.getHostByName(domain, &ip), ip == 0; ) { // getHostByName() して、ipアドレスが0なら delay (500); // 500m秒待って、再挑戦 } wdt_reset(); // 8秒以内に処理が終わればタイマーをクリアー wdt_disable(); // タイマーを無効化
Wi-Fi通信ライブラリーを呼び出しているところの前後にこのようにウォッチドッグタイマーをセットし、仮にライブラリーの中で止まってしまってもシステムがリセットされ、プログラムが最初から再実行されるようにしました。
ウォッチドッグタイマーを入れてからはデーター送信が止まることなく、連続して動作するようになりました。サーバーにデーターが到着する間隔を調べたのが次のグラフです。
何も問題がなければ30秒ごとにデーターが到着します。グラフではデーターの到着間隔を緑の点で示しており、それが帯状に30秒(右軸)のラインに並んでいます。0時30分頃に到着間隔が3分30秒ぐらいに伸びています。ここでgetHostByName()に失敗し、ウォッチドッグタイマーがクリアーできず、システムがリセットされ、プログラムが最初から再実行され、データー送信が再開しています。
電力モニターはウォッチドッグタイマーを入れることで連続して動作させることができました。ただし、通信の障害はどのタイミングでも起こり得ます。例えばデーター送信の際、データーが途中まで送信された後に障害が発生する可能性もあります。この時、電力モニターの端末であるArduinoはウォッチドッグタイマーにより再起動されますが、サーバー側には中途半端なデーターが残る可能性があります。今回は対処していませんが、サーバー側プログラムでも不完全なデーターは無視するなり削除するなりといった処理が必要になります。
これで連続して電気の利用状況が分かるようになりました。次はグラフ表示を強化します。

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
Arduinoで電力計:Google Chartsを使って電気の使用状況をグラフ表示する
Arduino電力計の最初のバージョンは、Arduinoと電流クランプを使い分電盤で家全体の使用電力(実際には電流値)を測定し、自宅のパソコンにWebサーバーを立ち上げ、Wi-Fi通信でサーバーにデーターを送信するものでした。これだと自宅のパソコンの電源が落とせず、パソコンを使っていない時の使用電力が分かりません。パソコンを使っていない時でも電気の使用量を計測するために、Webサーバーをクラウドに移設しました。
電流値の情報がクラウドに蓄積できるようになったので、次はこれをグラフ表示します。表示するグラフは前回「一日分の電気利用状況を調べる」でグラフ化したのと同様に30秒ごとの電流値と30分ごとの電力値の二つにします。前回は一日ごとのデーターがパソコン上にあり、それをExcelで読み込んでグラフ化していました。今回はクラウド上に蓄積された電流値のデーターをブラウザー経由でグラフ表示するようにします。また、クラウド上には何日分もの電流値データーが蓄積されるので、日付を指定してグラフ表示できるようにします。
Excelで作成した30秒ごとの電流値グラフ
日付の指定
日付の指定はGoogle Analyticsなどのように、カレンダーを使って指定できるようにしたいと考えました。調べるとjQuery UIのDatepickerという機能を使うとカレンダーを表示して日付を入力できるようです。使い方は以下のサイトを参考にしました。
jQuery UIのDatepickerでカレンダーから楽々日付入力
表示させるカレンダーのデザインは、以下のサイトのGalleryタブを押したところにいろいろなデザインテンプレートが用意されています。
jQuery user interface
私はその中から比較的シンプルな「Redmond」というデザインを選び、それに対応するCSSファイルをロードしました。
関数は以下のように記述します。
<script type="text/javascript"> $(function() { $( "#datepicker" ).datepicker({ maxDate: 0, onClose: function(){ makeAjaxCall(); } }); $( "#datepicker" ).datepicker( "setDate", new Date() ); }); </script> <style> .ui-datepicker { font-size: 80%; } </style>
未来の日付を指定しても表示する電力値データーがないので、未来の日付は選択できないよう maxDate: 0 というオプションを設定しました。表示したカレンダーを閉じたときにグラフを表示するよう、onCloseでグラフ表示の関数を呼び出しています。また、何も指定しなくても予め今日の日付を入力するよう setDate というメソッドを呼んでいます。実際にカレンダーを表示したところ、カレンダーが大きすぎると感じたので、font-sizeを80%にすることでカレンダー全体のサイズを小さくしました。Datepickerで使えるオプションなどはDatepicker Widgetに説明があります。
これでカレンダーを表示させて日付を選択する部分は出来上がりです。
グラフ表示
グラフの表示は Google Charts を使います。Google Charts の概要は下記のサイトに詳しい説明があります。
プログラマーズ雑記帳 Google Chart Toolsの使い方
このサイトでGoogle Chartsの概要を理解しました。今回はグラフ表示したい電流値データーがファイルに保存されています。データーをファイルから読んでGoogle Chartsに取り込む部分は下記のページを参考にしました。
Achieving Google Visualization chart reloads using ajax
ajax関数の使い方については下記を参考にしました。
jQuery日本語リファレンス Ajax/API/jQuery
電流値データーは1日分のデーターを1ファイルにしてあり、data20150403.csvのように日付を含んだファイル名にしてあります。Datepickerでグラフ表示する日付を取得し、対応するファイル名を作り、それをパラメーターにしてPHPファイルを起動します。PHPでファイルを読み、JSONフォーマットでデーターを書き出すようにしました。ajaxコールする部分はこんな感じです。
function makeAjaxCall() { var dname = getdatadname(); $.ajax({ url: 'getData.php', data: 'd=' + dname, async: false, success: function(responseData) { var jsonForGviz = eval("(" + responseData + ")"); drawVisualization(jsonForGviz); } }); }
この関数を最初にGoogle Chartsのパッケージがロードされた時と、日付を取得したときに呼び出してグラフを表示しています。
出来上がったグラフは以下のような感じです。
30分単位の電力値グラフは、PHPの中で30秒の電流値データーから30分単位の電力値を計算し、棒グラフ表示しています。正しく計算するためには力率を知る必要があるのですが、とりあえず力率100%と仮定して計算してあります。
Arduino電力計の全体構造は次のようになりました。Arduinoと電流クランプを使い分電盤で家全体の使用電力を測定し、クラウド上のWebサーバーにデーターを送信し、グラフ表示するようになっています。
ここで開発したサーバーの仕組みを発展させて、IoT用のクラウドサービス「Ambient」を作りました。「Ambient」はマイコンからのセンサーデーターを受信し、蓄積し、可視化(グラフ化)するサービスです。よければ使ってみてください。
Arduinoで電力計:Arduino IDE 1.6.0にアップデートする
先日、2015年2月9日頃に Arduino の開発環境 Arduino IDE 1.6.0 がリリースされました。いろいろと強化されているようです。強化内容はリリースドキュメントとその訳を見ていただくとして、さっそくダウンロードして使ってみたので、報告です。
インストールは以下のようにおこないました。
Arduino IDE 1.6.0のインストーラーが古いバージョンを削除してしまうので、その前に今使っているArduinoIDE(私の場合は1.0.6)に追加したライブラリを別の場所に移しておく
Arduinoのダウンロードページにいき、Arduino 1.6.0をダウンロードする(私はWindowsを使っているので、Windows Installerをダウンロードしました)
ダウンロードしたインストーラー(arduino-1.6.0-windows.exe)を起動する
インストーラーを起動すると古いバージョンを見つけて削除(uninstall)するか聞いてくるのでOKをクリックする。
インストーラーが古いバージョンを削除し、1.6.0をインストールする
別の場所に移しておいたライブラリを1.6.0に追加する
以上です。
Arduino IDE 1.6.0ですぐに嬉しいと感じたのは、コンパイルしたときにスケッチ(プログラム)が使用するSRAMの容量をレポートしてくれることです。Arduino UNOはSRAMが2kB、2048バイトしかありません。意識しないでプログラムを書いていると、メモリが足りなくなり、プログラムが動かなくなることがあります。私も電力計の制作で、電流値を測定するプログラムと、HTTP POSTでサーバーに値を送るプログラムの二つを作ってそれぞれ動作確認し、この二つをマージしたところプログラムが動かなくなるという経験をしました。その時は、細かくメモリエリアを削って動作させましたが、コンパイル時にメモリ使用量をレポートしてくれると、自分のプログラムがどの程度メモリを使用しているのか、どのくらいの余裕があるのかが分かり、非常に便利です。ちなみに細かなメモリ削減で動かしたバージョンはグローバル変数に1,688バイト使っていて、ローカル変数などに使えるエリアは360バイトしかないという状況でした。「使えるメモリが少ないので動作が不安定になるかもね」という警告メッセージがでています。
これだとほとんど余裕がなく、ちょっとした機能追加でプログラムが動かなくなってしまいそうです。そこで、プログラムを見直し、メモリ使用量を大幅に削減することにしました。
プログラムを見直してメモリ使用量を削減する
ここまで作ってきたプログラムは250μ秒ごとに電流値を測定し、400サンプリングのデーターを配列に保存していました。これは次のように電流波形を確認するためでしたが、このために整数型×400個、800バイトのメモリを使っていました。
電流値は時間的に変化する値を平均して求めるので、配列に保存する必要はありません。電流波形は確認できているので、400個の電流値を保存することを止め、250μ秒ごとに測定した電流値を一つの変数に足しこんで、最後に400で割って平均を求めるように変更しました。実際には電流値はプラス・マイナスに変化する交流値なので、電流値を二乗して足しこんでいき、最後に400で割って平均し、平方根を取って平均値を求めます。これで配列が不要になり、約800バイトのメモリが節約できました。実際にコンパイルしてみると、配列を使っていたときは1,688バイトのグローバル変数エリアだったものが892バイトに削減でき、警告メッセージもなくなりました。
電流値を配列に保存したバージョン
電流値を一つの変数に足しこんだバージョン
このメモリ使用量のレポートだけでもArduino IDE を 1.6.0 にアップデートするメリットはありそうです。数週間のうちに次の 1.6.1 のリリースも予定されているとのことなので、楽しみです。