読者です 読者をやめる 読者になる 読者になる

知的好奇心 for IoT

IoT関連の知的好奇心を探求するブログです

WIO NODEとWioアプリを使って外の温度と湿度をWebページに表示させようとした結果

WIO NODE

ノンプログラミングでIoTを実現するWIO NODEを活かしてみようと、温度・湿度センサーのDH11を使ってWiFi温度・湿度計をベランダに設置してみることにしました。

用意したもの

配線した状態

f:id:IntellectualCuriosity:20170326102314j:plain

コネクタにケーブルを接続するだけなので簡単です。

Wioアプリの設定

配線と同じようにWioアプリを設定します。

f:id:IntellectualCuriosity:20170326113644p:plain

※Wioアプリが接続するサーバーには何種類かあるのですが、なぜか最近Global Serverに繋ごうとするとエラーが出ます。Chinese Serverは中国向けに用意されているようなのですが、日本でも普通に使えています。

f:id:IntellectualCuriosity:20170326114624p:plain

API

Wioアプリの設定画面の右上にある3つの縦点をタップしてView APIを選ぶと、用意されたリクエストURLと返り値、テストリクエストを実行するボタンが表示されます。

温度を摂氏で返すAPI

f:id:IntellectualCuriosity:20170326130002p:plain

湿度を返すAPI

f:id:IntellectualCuriosity:20170326125907p:plain

※URL中のaccess_tokenはWIO NODEをアプリに登録する度に発行されるので、WIO NODEを登録し直すことで変更できます。

※説明と違いリクエストが失敗したときのステータスコードは400ではなく404や408が返ってきます。

Webページへの表示

ここまではノンプログラミングでできるのですが、返り値が{"celsius_degree":17.0}という感じのJSON形式なためJavaScriptを使って見やすく表示できるようにしてみました。

Ajaxで温度を取得するURLと湿度を取得するURLのリクエストを出し、返り値でHTMLのテキストを上書きしています。

JavaScript

<script type="text/javascript">// <![CDATA[
var wioURL = "https://cn.wio.seeed.io/v1/node/GroveTempHumD1/";  // APIのURLの共通部分
var accessToken = "62b49dbccedcc11917d4f8c4bcf2985a";            // WIO NODEのアクセストークン
accessToken = "?access_token=" + accessToken;

// 温度取得
var xhrTemp = new XMLHttpRequest();
xhrTemp.onreadystatechange = function() {
  if (this.readyState == 4) {
    var myObj = JSON.parse(this.responseText);
    if (this.status == 200) {
      document.getElementById("celsius_degree").innerHTML = "温度:" + myObj.celsius_degree + "℃";
    } else {
      document.getElementById("celsius_degree").innerHTML = "温度取得エラー Status Code:" + this.status + " " + myObj.error;
    }
  }
};
xhrTemp.open("GET", wioURL + "temperature" + accessToken, true);
xhrTemp.send();

// 湿度取得
var xhrHum = new XMLHttpRequest();
xhrHum.onreadystatechange = function() {
  if (this.readyState == 4) {
    var myObj = JSON.parse(this.responseText);
    if (this.status == 200) {
      document.getElementById("humidity").innerHTML = "湿度:" + myObj.humidity + "%";
    } else {
      document.getElementById("humidity").innerHTML = "湿度取得エラー Status Code:" + this.status + " " + myObj.error;
    }
  }
};
xhrHum.open("GET", wioURL + "humidity" + accessToken, true);
xhrHum.send();
// ]]></script>

HTML部

<div id="celsius_degree">温度取得中...</div>
<div id="humidity">湿度取得中...</div>

このページにも実際にスクリプトを埋め込んで実行できるようにしました。

ベランダの温度と湿度
温度取得中...
湿度取得中...

設置

プログラムができたので、空気穴を開けたおかず容器に機器を入れてベランダの上の方に設置しました。

おかず容器に入れた機器

f:id:IntellectualCuriosity:20170326152211j:plain

問題発生

これで外の気温と湿度がいつでもわかるっと思っていたら、設置から半日も経たずにNode is offlineと表示されるようになってしまいました。多少苦労して取り付けた容器を取り外して中を見てみると...何も光っていない...バッテリー切れでした。

そんなに早くバッテリーがなくなるものかと手持ちのUSB電圧・電流・容量計で1時間動作させてみました。

f:id:IntellectualCuriosity:20170326153950j:plain

1時間で66mAh。400mAhのバッテリーだったので最大で6時間ぐらいしかもたないことがわかりました。使えねー。

今回のオチ

WIO NODEにはDeep Sleep機能があり、その間は1mA程度しか電流を消費しないのですが、DH11のWioアプリには定期的にDeep Sleep状態にする機能がありません。Wioアプリとバッテリーで実現させようとしたことが、そもそもの間違いでした。

Raspberry PiのOSアップデートでWDC-150SU2MがLXPanelから使えなくなっていた原因がわかった

Raspberry Pi

2016年の10月ごろ、Raspberry Pi Zero用に小型で安く低消費電力なWiFiアダプタを探していて選んだのがELECOMのWDC-150SU2Mでした。

ELECOM WDC-150SU2Mのスペック

  • 消費電流(最大):150mA
  • 外形寸法(幅×奥行き×高さ):15mm × 8mm × 17mm
  • 質量:約2g
  • 価格:785円(税込)ヨドバシドットコム 2017/3/19現在
  • 写真:

    f:id:IntellectualCuriosity:20170319220722j:plain

 

 Raspberry Piでの使用実績を見つけていない状態だったため、少し心配していたのですが何の問題もなく使えていました。

しかし、デスクトップがLXDEからPIXELに変わったOSにアップデートしたらLXPanelにWiFiの扇型マークが出ずに上下の✖印棒マークになっていました...

WiFiアダプタはチカチカしていてOSに認識はされているようだったので、設定ファイルに直接SSIDとパスワードを記述して使用していました。

設定ファイルの編集

sudo leafpad /etc/wpa_supplicant/wpa_supplicant.conf

記述内容

network={
  ssid="SSID"
  psk="パスワード"
}

 ある時、LXPanelから使えない原因を探ってみようと思い立ち、Google先生にいろいろと質問をしていたら、やっと原因の核心となる回答をもらいました。

LXPanelでWiFiの扇形や上下の矢印を表示しているネットワークを司るプラグインが「dhcpcdui.so」で、デスクトップがPIXELに変更になったタイミングでこのプラグインがアップデートされたようなんです。それでWDC-150SU2Mで使っているチップセットRealTek r8188eu対応が忘れられたみたいなんです。(いわゆるデグレですね)

で、対応方法は以前のdhcpcdui.soに入れ替えるというものでした。

早速、タイムスタンプが2016/05/27のファイルに入れ替えてみると...LXPanelで使えるようになりました!

dhcpcdui.soのパス

/usr/lib/arm-linux-gnueabihf/lxpanel/plugins/dhcpcdui.so

 NOOBSだとVersion 1.9.2以前でデスクトップがPIXELになる前のものです。

過去のNOOBSのイメージは以下からダウンロードできます。

 補足

WDC-150SU2Mのアマゾンのレビューを見ると「電波が弱くて接続が不安定」っと言うような書き込みがあります。

確かに、使っているとWiFiの扇形マークが全部灰色になっている時があって、何か省電力系の制御があるのかなと思っていたら、りんごのマックさんのブログに省電力機能をオフにする記述が書いてありました。

ESP8266(ESP-WROOM-02)とDHT11でIFTTT経由で温度と湿度をツイートする

ESP8266

ESP8266でWebリクエストを送るサンプルとして、安価な温度・湿度センサのDHT11を使ってIFTTT経由で温度と湿度をツイートするスケッチを作ってみました。

DHT11はGrooveコネクタで接続するだけのお手軽品を調達しました。

これならWio Nodeだとブレッドボード要らずで付属のケーブルで繋げるだけです。

 

ライブラリの追加

DHT11のライブラリはAdafruit社のものを使いました。

Arduino IDEのライブラリマネージャで次の2つのライブラリを追加します。

f:id:IntellectualCuriosity:20170316031341p:plain

f:id:IntellectualCuriosity:20170316031358p:plain

 

IFTTTのアプレット

長くなってしまうのでIFTTTの利用方法は割愛させてください。ごめんなさい。

作ったアプレット(スケッチ)はこんな感じです。

f:id:IntellectualCuriosity:20170316031718p:plain

 

ツイートサンプル

スケッチは長いので、先にツイート例をお見せします。

HDT11は精度が低く、温度で±2℃も誤差があるので27℃なんていう温度になってます...

f:id:IntellectualCuriosity:20170316031935p:plain

 

スケッチ

#include <ESP8266WiFi.h>
#include "DHT.h"

// DHT11の設定
#define DHTPIN 5        // 使用するGPIOピン
#define DHTTYPE DHT11   // DHT 11
DHT dht(DHTPIN, DHTTYPE);

// WiFiアクセスポイントの設定
const char *WIFI_SSID = "<SSID>";
const char *WIFI_PASSWORD = "<PASSWORD>";

// ITFFFの設定
const char *IFTTT_HOST = "maker.ifttt.com";
const char *IFTTT_URI = "/trigger/dht_read/with/key/<自分のMaker keyを設定>";

// DeepSleepのインターバル
const unsigned long DEEP_SLEEP_INTERVAL = 60 * 60 * 1000 * 1000;  // 1時間

void setup() {
  // Wio Nodeを使う場合は以下の2行をコメントアウト(センサーに電源を供給)
  // pinMode(15, OUTPUT);
  // digitalWrite(15,HIGH);
  dht.begin();

  // WiFiに接続
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Waiting for Wi-Fi connection");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\r\nConnected!");
}

void loop() {
  // DHT11から温度と湿度を読み込む
  delay(2000);
  float t = dht.readTemperature();
  float h = dht.readHumidity();
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  Serial.println("Temperature: " + String(t) + "C   Humidity: " + String(h) + "%");

  // IFTTTに温度と湿度を送る
  RequestToIFTTT("?value1=my%20room&value2=" + String(round(t)) + "&value3=" + String(round(h)));

  // DeepSleepに入る
  Serial.println("Go to sleep...");
  ESP.deepSleep(DEEP_SLEEP_INTERVAL, WAKE_RF_DEFAULT);
}

// IFTTTにリクエストを送る
void RequestToIFTTT(String param) {
  WiFiClientSecure client;
  while (!client.connect(IFTTT_HOST, 443)) {
    delay(10);
  }
  client.print(String("GET ") + IFTTT_URI + param +
                       " HTTP/1.1\r\n" +
                       "Host: " + IFTTT_HOST + "\r\n" +
                       "User-Agent: ESP8266\r\n" +
                       "Connection: close\r\n\r\n");
  while (!client.available()) {
    delay(10);
  }
  Serial.println(client.readStringUntil('\r'));
  client.flush();
  client.stop();
}

ESP8266(ESP-WROOM-02)でNTPを使って定期的にヒープサイズを出力する

ESP8266

WIO NODEの謎のリセット問題を調べるために作ったスケッチを公開します。

このスケッチを動かすためには、ESP8266のライブラリの他にNTPClientTimeライブラリをインストールする必要があります。

Arduino IDEのスケッチメニューから[ライブラリをインクルード]-[ライブラリを管理...]を選び、ntpで検索をして2つのライブラリをインストールしてください。

ライブラリマネージャー (NTPClientとTimeライブラリをインストール

f:id:IntellectualCuriosity:20170311235518p:plain

スケッチ

#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <Time.h>

//  WiFiSSIDとパスワードをセット
const char *WIFI_SSID = "<SSID>";
const char *WIFI_PASSWORD = "<PASSWORD>";

//  NTP用
WiFiUDP ntpUDP;
const char *NTP_SERVER = "ntp.nict.jp";  // 情報通信研究機構(NICT)の公開NTPサーバー
const int TIME_OFFSET = 9 * 60 * 60;  // UTC+9h (JST)
NTPClient timeClient(ntpUDP, NTP_SERVER, TIME_OFFSET);
const unsigned long NTP_INTERVAL_TIME = 24 * 60 * 60 * 1000;  // 時刻を合わせる周期 24h
unsigned long ntp_interval;

void setup() {
  Serial.begin(74880);
  Serial.println("\r\nReset Reason: " + ESP.getResetReason());  // 前回のリセットの理由を出力
  Serial.println(String("Free Heap Size: ") + ESP.getFreeHeap());  // フリーヒープサイズを出力

  // WiFiを接続する
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Waiting for Wi-Fi connection");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\r\nConnected!");

  // NTP関連の初期化
  timeClient.begin();
  timeClient.update();
  setTime(timeClient.getEpochTime());
  printLog("Program Start!");
  ntp_interval = millis();
}

void loop() {
  // ここにメインのプログラムを書く

  // 定期的に時刻を合わせフリーヒープサイズを出力
  if (millis() - ntp_interval > NTP_INTERVAL_TIME) {
    timeClient.update();
    printLog(String("Free Heap Size: ") + ESP.getFreeHeap());
    ntp_interval = millis();
  }
}

// ログ出力
void printLog(String st) {
  char dt[21];
  sprintf(dt, "%04d/%02d/%02d %02d:%02d:%02d ", year(), month(), day(), hour(), minute(), second());
  Serial.println(String(dt) + st);
}

実行例 (外部リセットをかけた後)

シリアルモニタの速度を74880にすると文字化けせずに表示されます

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v09f0c112
~ld

Reset Reason: External System
Free Heap Size: 46888
Waiting for Wi-Fi connection.....
Connected!
2017/03/12 01:09:33 Program Start!
2017/03/13 01:09:33 Free Heap Size: 46496

WIO NODEで謎のリセットが繰り返される。USB電源には注意!

ESP8266 WIO NODE

秋葉原秋月電子の店頭で何気なくWIO NODEを見かけて、その場でスマホを取り出し仕様をチェックしたときには「これで、Raspberry Piよりずっと安くコンパクトにIoT機器が作れる!」っと喜び勇んでいました。

しかし、Arduino IDEでプログラミングして機器に組み込んで運用してみると...、取り付け時は動作しているのに時間が経つと動かなくなっている...。

最初はプログラミングの問題でメモリリーク的な事が発生しているのかと思ったのですが、トラ技に載っていた「ESPスタータ・キットXブレッドボードボードで作るIoT実験ボード」では問題が起きない...。WIO NODEでいったい何が起きているのだろう...。

そんなある時、ESP8266 core for Arduinoのドキュメントを眺めていたらESP-specific APIsという項目に前回のリセット理由を返すESP.getResetReason()を見つけました。

早速setup()の中に記述してみると...

記述例

Serial.println("/r/nReset Reason: " + ESP.getResetReason());

表示例

Reset Reason: Power on

「Power on ???」そう言えばトラ技の記事には電源に47μFのデカイ電解コンデンサが付いているのに、不安定な場合は470μFってカッコ書きがあった...。

手持ちのUSB電源アダプタ4種類では、リセット頻度が変わるだけで全滅でした。

試しに千石電商で購入していたリチウムイオンポリマー電池を繋げてみると...リセットが起きない!マジですかっ!!!

組み込もうとしていたIoT機器は常時動作している必要があってしかもAC電源がある場所であったため、電源にUSB電源アダプタを選択していました。

結局、USB電源アダプタとリチウムイオンポリマー電池の両方を繋げてバッテリーを充電する状態にしても安定して動作することがわかったので、費用がかさむのですがバッテリー交換を無くしてメンテナンスフリーにできる方法を選ぶことにしました。

 

WIO NODEで使うセンサやアクチュエーターをWioアプリでテストする

ESP8266 WIO NODE

WIO NODEをArduinoとして使用して独自のIoT機器を作る場合でも、IOSAndroidのWioアプリは自作したセンサやアクチュエーターの単体動作を簡単にテストするためのツールとして非常に有用です。

今回は、Wioアプリに用意されている汎用機能をテストしてみます。

 

WIO NODEのコネクタピン情報

WIO NODEのコネクタピンはWio Node - Seeed Wikiの後ろの方のResoucesの中にある回路図に書かれています。

回路図ではわかり難いので、WikiにあったWIO NODEの図に書き込んでみました。

f:id:IntellectualCuriosity:20170213091018p:plain

黄色のGPIO3とGPIO5/ADCが汎用機能で信号用として使われています。

 

Generic Digital Inputのテスト

デジタル入力のテストはスライドスイッチで確認しました。

f:id:IntellectualCuriosity:20170213092148j:plain

黄色の信号線を真ん中に繋いで、スイッチを左上にすると黒のGNDに右下にすると赤の+3.3Vに繋がるようにしています。白線は繋いでいません。

f:id:IntellectualCuriosity:20170213092912p:plain

Wioアプリでスライドスイッチを繋いだポートに上のアイコンをドラッグしてファームウェアを更新すると、メニューのView APIから機能を試すことができます。

2番目の「Read the input state of a generic digital input device」の「GET」ボタンを押すとスライドスイッチの状態(1:on, 0:off)が表示されます。

f:id:IntellectualCuriosity:20170213094706p:plain f:id:IntellectualCuriosity:20170213094641p:plain

 

Generic Digital Outputのテスト

デジタル出力のテストはLEDで確認しました。

f:id:IntellectualCuriosity:20170213095056j:plain

LEDの足の長い方(アノード)に黄色の信号線を繋いで、短い方(カソード)に330Ωの抵抗を介して黒のGND線を繋いでいます。

赤線と白線は繋いでいません。

f:id:IntellectualCuriosity:20170213095725p:plain

WioアプリでLEDを繋いだポートに上のアイコンをドラッグしてファームウェアを更新すると、メニューのView APIから機能を試すことができます。

2番目の「Control a generic digital output by writing 1 to pull it high and 0 to pull it low.」で入力欄に1(オン)か0(オフ)を入力して「POST」ボタンを押すとLEDを点けたり消したりすることができます。

 

Generic PWM/Analog Outputのテスト

PWM出力のテストはデジタル出力と同じ回路で確認しました。

PWMは一定電圧の入力から、パルス列のオンとオフの一定周期を作り、オンの時間幅を変化させる電力制御方式です。

f:id:IntellectualCuriosity:20170213101934p:plain

WioアプリでLEDを繋いだポートに上のアイコンをドラッグしてファームウェアを更新すると、メニューのView APIから機能を試すことができます。

2番目の「Output a PWM wave on specified IO. The default frequency is 1KHz.」で入力欄にパルスがオンになっている割合を0.0~100.0の範囲で入力して「POST」ボタンを押すと、疑似的に出力電圧を制御することができます。

「0」の時の計測値

f:id:IntellectualCuriosity:20170213102940j:plain

「50」の時の計測値

f:id:IntellectualCuriosity:20170213103148j:plain

「100」の時の計測値

f:id:IntellectualCuriosity:20170213103208j:plain

 

Generic Analog Inputのテスト

アナログ入力のテストはボリュームで確認しました。

f:id:IntellectualCuriosity:20170213104111j:plain

ボリュームの真ん中に黄色の信号線を繋いで、両端にそれぞれ黒のGNDと赤の+3.3Vを繋いでいます。

白線は接続していません。

f:id:IntellectualCuriosity:20170213110022p:plain

アナログ入力はWIO NODEの右側のPORT1のみ利用できます。

Wioアプリで右のポートに上のアイコンをドラッグしてファームウェアを更新すると、メニューのView APIから機能を試すことができます。

1番目の「Read the ADC measurement of a generic analog device. The full range is 0~1023.」はボリューム値を1~1024で表示します。(なぜか0~1023ではないんです。)

2番目の「Read the voltage of the measuring point.」ではボリュームの値を電圧で表示します。(なぜか0V~3Vで表示されます。)

ボリュームがVCC(3.3V)側の時の表示

f:id:IntellectualCuriosity:20170213110748p:plain f:id:IntellectualCuriosity:20170213110809p:plain

ボリュームが真ん中付近の時の表示

f:id:IntellectualCuriosity:20170213110844p:plain f:id:IntellectualCuriosity:20170213110851p:plain

ボリュームがGND側の時の表示

f:id:IntellectualCuriosity:20170213110915p:plain f:id:IntellectualCuriosity:20170213110923p:plain

 

Grove WIO NODEのファームウェアの戻し方 Windows編

ESP8266 WIO NODE

Grove WIO NODEは1,100円程度で購入できるESP8266ベースのWiFi付きIoT開発環境で、専用のIOSアプリやAndroidアプリを使ってノンプログラミングで様々なセンサーやアクチュエーターを利用することができます。

でも、この製品の面白いところはArduino IDEを使って自由にプログラミングできる裏技を使えることです。

ネット上にはGrove WIO NODEをArduinoとして使うための日本語の記事は幾つかありましたが、元のファームウェアに戻す方法は見当たらなかったので書いてみたいと思います。

 

用意したもの

 

今回はWindows 10で行いますが、戻す方法が書いてあるAdvanced User GuideにはPythonを使ったLinuxMacユーザーのための記述もあります。

 

ファイルのダウンロード

以下のファイルをAdvanced User Gudeに書かれてあるリンクからダウンロードします。(一応、ダウンロードリンクを転記しておきます。)

ダウンロードが終わったら「FLASH_DOWNLOAD_TOOLS_v2.4_150924.rar」と「Esp8266sdk1.4.1.zip」を解凍しておきます。

 

接続

WIO NODEとUSBシリアル変換モジュールをブレッドボードを介して接続します。赤の電源ラインは接続しないので気を付けてください。WIO NODEの電源はマイクロUSBかバッテリーコネクタで供給します。また、白と黄色の通信ラインはクロスして接続します。

f:id:IntellectualCuriosity:20170206004226j:plain f:id:IntellectualCuriosity:20170206004236j:plain

次にUSBシリアル変換モジュールとWindows PCをUSBケーブルで接続します。

接続するとデバイスマネージャーに「USB Serial Port」が出てくるのでCOMポート番号を覚えておきます。

f:id:IntellectualCuriosity:20170206005157p:plain

 

Flash Toolの実行

FLASH_DOWNLOAD_TOOLS_v2.4_150924.rar」を解凍したフォルダにある「ESP_DOWNLOAD_TOOL_V2.4.exe」実行します。(V2.3と表示されることはスルーで!)

f:id:IntellectualCuriosity:20170206012020p:plain

ダウンロードしたファイルを「Download Path Config」に、覚えておいたCOMポート番号を「COM PORT:」に、他の赤枠は図の通りに設定します。

次にWIO NODEのFUNCTION(FUNC)ボタンを押しながらRESET(RST)ボタンを押して、RESET(RST)ボタン、FUNCTION(FUNC)ボタンの順で放してファームウェアの書き込みモードにします。その後、Flash Toolの「START」ボタンを押すとファームウェアの書き込みが始まります。緑バックで表示されているのDownloadと謎の漢字がFINISH完成と表示されたら終了です。(Flash Toolの「START」ボタンを押した後にWIO NODEのボタン操作に手間取っていると書き込みに失敗するので、手順を修正しました。)

おつかれさまでした!

 

補足

Advanced User Guideをご覧になった方は気付いていると思いますが、実はこの方法、WIO NODEでなくても行えます。試しにトランジスタ技術2016年9月号に載っていた「ESPスタータ・キットXブレッドボードで作るIoT実験ボード」に書き込んでみたら、WIO NODEとして使うことができました。