ESP32-DEVC-HOMEとThingSpeakを利用してIoT実験を行ってみました。
http://www.microfan.jp/esp32/esp32-devc-home
ESP32-DEVC-HOMEには、標準でBME280環境センサーが搭載されているので、ThingSpeakのセンサーノードとして利用しました。
ESP32-DEVC-HOME
BME280による環境(温度、湿度、気圧、露点)データを、ボード上のOLEDディスプレイに表示するとともに、ThingSpeakのサーバーに送付します。
ThingSpeakサーバーでは、蓄積したデータをグラフ化するなどできます。
ThingSpeakの計測データの可視化
1ノードのセンサーデータを蓄積してグラフ化するだけだとIoTとは言えないけどね。:-)
OLEDディスプレイの利用法は以下のページをご参照ください。
http://www.microfan.jp/esp32/workshop/oled-monitor
プログラム例の以下の値はご利用環境に合わせて書き換えてください。
このシステムでは、ThingSpeakの可視化機能を利用して温度などを見られるけでなく、ボード上のOLEDで現在の温度等を確認することができます。
#include <WiFi.h> #include <U8x8lib.h> #include <BME280I2C.h> #include <Wire.h> const char* ssid = "YOURSSID" ; const char* password = "YOURPASSWORD" ; const char* server = "api.thingspeak.com" ; // or "184.106.153.149" // 作成した書き込み用チャネルのAPI Keyを以下に記述すること String apiKey = "YOURCHANNELAPIKEY" ; U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE) ; BME280I2C bme ; WiFiClient client ; #define PRESSURE_HPA 1 // ヘクトパスカル void setup() { u8x8.begin() ; u8x8.setFont(u8x8_font_artossans8_r) ; while (!bme.begin()) { delay(1000) ; } WiFi.begin(ssid, password) ; while (WiFi.status() != WL_CONNECTED) { delay(500) ; u8x8.print(".") ; } u8x8.println("\n\nWiFi connected.") ; } void loop() { float temp ; // 温度 float hum ; // 湿度 float pres ; // 気圧 float dew ; // 露点 // 気圧(hPa)、温度(摂氏)、湿度を取得 bme.read(pres, temp, hum, true, PRESSURE_HPA) ; dew = bme.dew(true); // 露点(摂氏)を取得 // 測定値をOLEDディスプレイに表示 u8x8.clear() ; u8x8.println("Env. Monitor") ; u8x8.println("IoT: ThingSpeak\n") ; u8x8.print(temp) ; u8x8.println(" C") ; u8x8.print(hum) ; u8x8.println(" % RH") ; u8x8.print(pres) ; u8x8.println(" hPa") ; if (client.connect(server, 80)) { // ThingSpeakサーバーにHTTPプロトコルで接続 // サーバーへの送付データを作成 String postStr = apiKey ; postStr += "&field1=" + String(temp) ; postStr += "&field2=" + String(hum) ; postStr += "&field3=" + String(pres) ; postStr += "&field4=" + String(dew) ; postStr += "\r\n\r\n" ; client.println("POST /update HTTP/1.1") ; client.println("Host: api.thingspeak.com") ; client.println("Connection: close") ; client.println("X-THINGSPEAKAPIKEY: " + apiKey) ; client.println("Content-Type: application/x-www-form-urlencoded") ; client.print("Content-Length: ") ; client.println(postStr.length()) ; client.println("") ; client.print(postStr) ; } client.stop() ; delay(60 * 1000) ; // 最低でも15秒間隔(ThingSpeakの制限)をあけること }
上記の例は、プログラムでThingSpeakサーバーにHTTPプロトコルで直接書き込む方法でしたが、Arduino用のライブラリが提供されており、もう少しスマートに利用することができます。
ThingSpeakライブラリは以下のURLで公開されています。
https://github.com/mathworks/thingspeak-arduino
ThingSpeakライブラリは、Arduino IDEのライブラリマネージャで簡単にインストールできるようになっています。
ライブラリマネージャの検索枠にThingSpeakと入力すると、ライブラリ項目を簡単に見つけることができます。
ライブラリマネージャを使用したThingSpeakのインストール
ThingSpeakのライブラリは、現時点(2017/08)ではESP32に対応していません。
しかしながらESP8266には対応しているので、ESP32でもライブラリの軽微な変更で利用できるものと考えました。
実際には、ライブラリの中に検証していないMPUでの使用を制限する記述がありますが、そこにESP32を追加するだけで、ライブラリを使用したスケッチのコンパイルと実行ができました。
皆さんが試してみるときにはすでに対応しているかもしれないので、まずはThingSpeakライブラリを利用してコンパイルしてみて、エラーが出るようであればライブラリを以下のように修正してみてください。
ライブラリの変更点:
ThingSpeak.hの変更は2点で、両者ともESP32をサポートアーキテクチャとして追加するものです
ThingSpeak.hの57行あたりの1行を下記に変更
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM)
ThingSpeak.hの76行あたりに下記の2行を追加
#elif defined(ARDUINO_ARCH_ESP32) #define TS_USER_AGENT "tslib-arduino/1.3 (ESP32)"
また、library.propertiesの9行目あたりの1行を下記に変更
architectures=avr,esp8266,esp32,sam,samd
プログラム例の以下の値はご利用環境に合わせて書き換えてください。
#include <WiFi.h> #include <U8x8lib.h> #include <BME280I2C.h> #include <Wire.h> #include <ThingSpeak.h> const char* ssid = "YOURSSID" ; const char* password = "YOURPASSWORD" ; const char *server = "api.thingspeak.com" ; // or "184.106.153.149" // 作成した書き込み用チャネルの番号を以下に記述すること unsigned long channelNumber = YOURCHANNELNUMBER ; // 作成した書き込み用チャネルのAPI Keyを以下に記述すること const char *apiKey = "YOURCHANNELAPIKEY" ; U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE) ; BME280I2C bme ; WiFiClient client ; #define PRESSURE_HPA 1 // ヘクトパスカル void setup() { u8x8.begin() ; u8x8.setFont(u8x8_font_artossans8_r) ; while (!bme.begin()) { delay(1000) ; } WiFi.begin(ssid, password) ; while (WiFi.status() != WL_CONNECTED) { delay(500) ; u8x8.print(".") ; } u8x8.println("\n\nWiFi connected.") ; ThingSpeak.begin(client) ; } void loop() { float temp ; // 温度 float hum ; // 湿度 float pres ; // 気圧 float dew ; // 露点 // 気圧(hPa)、温度(摂氏)、湿度を取得 bme.read(pres, temp, hum, true, PRESSURE_HPA) ; dew = bme.dew(true) ; // 露点(摂氏)を取得 // 測定値をOLEDディスプレイに表示 u8x8.clear() ; u8x8.println("Env. Monitor") ; u8x8.println("IoT: ThingSpeak\n") ; u8x8.print(temp) ; u8x8.println(" C") ; u8x8.print(hum) ; u8x8.println(" % RH") ; u8x8.print(pres) ; u8x8.println(" hPa") ; // サーバーに送るデーターを設定 ThingSpeak.setField(1, temp) ; ThingSpeak.setField(2, hum) ; ThingSpeak.setField(3, pres) ; ThingSpeak.setField(4, dew) ; // 設定されたデータをサーバーに送信 ThingSpeak.writeFields(channelNumber, apiKey) ; delay(60 * 1000) ; // 最低でも15秒間隔(ThingSpeakの制限)をあけること }