以前、BlynkのWebHookを使ってThingSpeakにデータを送る方法の記事を書きましたが、ThingSpeakにはArduinoライブラリが用意されているので、今回は素直にライブラリを使ってみたいと思います。
ハードウェア
Machinistにデータを送る記事と同じものを使いました。
簡単に説明すると、使ったパーツはこれです。
配線はこんな感じです。
ソフトウェア
ライブラリ
肝心のThingSpeakのArduinoライブラリはこれです。
このライブラリを使うとThingSpeak.setField([フィールド番号], [値])
でデータをセットした後、ThingSpeak.writeFields([チャネル], [書き込み用APIキー])
を実行することで簡単にデータをThingSpeakに送ることができます。
他にはBME280用のAdafruitのライブラリを2つ使ってます。
スケッチ
スケッチはMachinistにデータを送るのに使ったプログラムのデータを送信するファンクションだけを入れ替えています。該当部分のコードが37行から16行と半分以下になっているほか、JSONデータを作る必要もなく簡単さを実感できます。
/* * BME280 sensor program for ThingSpeak using ESP8266 * October 02, 2019 * By Hiroyuki ITO * https://intellectualcuriosity.hatenablog.com/ * MIT Licensed. */ #include <Wire.h> #include <ESP8266WiFi.h> #include <Adafruit_BME280.h> #include <ThingSpeak.h> #define DS_INTERVAL 1 // Deep Sleep Interval Time (minutes) #define WIFI_SSID "YourNetworkName" #define WIFI_PASS "YourPassword" #define THING_SPEAK_CHANNEL YourChannelID #define THING_SPEAK_API_KEY "YourWriteAPIKey" #define VCC_PIN 13 // Sensor VCC Pin // Global Objects Adafruit_BME280 bme; // I2C String temperature; String humidity; String pressure; /* * Get Sensor Data */ void GetSensorData() { // Sensor Power ON pinMode(VCC_PIN, OUTPUT); digitalWrite(VCC_PIN, HIGH); // Initialize BME280 delay(10); bme.begin(0x76); // SDO GND(Open):0x76 VDD:0x77 // Sensor Measurement temperature = String(bme.readTemperature(), 1); // xx.xC humidity = String(bme.readHumidity(), 1); // xx.x% pressure = String(bme.readPressure()/100.0, 0); // xxxxhPa Serial.println("Temperature:" + temperature); Serial.println("Humidity :" + humidity); Serial.println("Pressure :" + pressure); // Sensor Power OFF digitalWrite(VCC_PIN, LOW); } /* * Send Sensor Data */ void SendSensorData() { // Initialize ThingSpeak WiFiClient client; ThingSpeak.begin(client); // Set the fields with the values ThingSpeak.setField(1, temperature.toFloat()); ThingSpeak.setField(2, humidity.toFloat()); ThingSpeak.setField(3, pressure.toInt()); // Write to the ThingSpeak channel int res = ThingSpeak.writeFields(THING_SPEAK_CHANNEL, THING_SPEAK_API_KEY); if (res == 200) { Serial.println("Channel update successful."); } else{ Serial.println(String("Problem updating channel. HTTP error code ") + res); } } void setup() { Serial.begin(74880); // Connect to WiFi Serial.print("Connecting to " WIFI_SSID); WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASS); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWiFi connected"); GetSensorData(); SendSensorData(); // Go to deep sleep delay(1000); Serial.println(String("Go to sleep for ") + DS_INTERVAL + " minutes"); ESP.deepSleep(DS_INTERVAL*60*1000*1000, WAKE_RF_DEFAULT); } void loop() { }
ThingSpeakからデータを読み出す
Machinistはデータを書き込むことしかできませんが、ThingSpeakにはデータを読み出すAPIも用意されています。
PCでこのブログを見ている方は右側のサイドバーにベランダや部屋の温湿度などが表示されていることに気付いたかも知れないですね。サイドバーの表示はThingSpeakのAPIを利用して表示しているんです。
チャンネルの「API Keys」タブに表示されている「Read API Key」と「Channel ID」があれば、次のようなJavaScriptでデータを表示することができます。
<div id="bme280_time">時刻取得中...</div> <div id="bme280_temperature">温度取得中...</div> <div id="bme280_humidity">湿度取得中...</div> <div id="bme280_pressure">気圧取得中...</div> <script type="text/javascript">// <![CDATA[ getBME280Data(); var ret_interval_getBME280Data = setInterval(getBME280Data, 60000); // Millisecond function visibilityChangeHandlerGetBME280Data() { if (document.hidden) { clearInterval(ret_interval_getBME280Data); } else { location.reload(false); } } document.addEventListener('visibilitychange', visibilityChangeHandlerGetBME280Data, false); function getBME280Data() { var readAPIKey = "YourReadAPIKey"; // ThingSpeak Read API Key var channelID = "YourChannelID"; // ThingSpeak Channel ID var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { var json = JSON.parse(this.responseText); var t = parseFloat(json.feeds[0].field1); var h = parseFloat(json.feeds[0].field2); var p = parseFloat(json.feeds[0].field3); var dt = new Date(json.feeds[0].created_at); var str = dt.toLocaleString(); document.getElementById("bme280_temperature").innerHTML = " 温度:" + t.toFixed(1) + "℃"; document.getElementById("bme280_humidity").innerHTML = " 湿度:" + h.toFixed(1) + "%"; document.getElementById("bme280_pressure").innerHTML = " 気圧:" + p.toFixed(0) + "hPa"; document.getElementById("bme280_time").innerHTML = str.slice(0,-3) + "現在"; } } } xhr.open("GET", "https://api.thingspeak.com/channels/" + channelID + "/feeds.json?api_key=" + readAPIKey + "&results=1", true); xhr.send(); } // ]]></script>
このスクリプトを実行すると、次のような表示でデータが1分毎に更新されます。
データを取り出す用途がある場合はThingSpeakがいいですね。
おしまい