本文延續【LinkIt 7697空氣品質偵測並上傳Google表單(空氣盒子2.0)】,本文要進一步把空氣盒子的監測數值分別上傳到MCSLite和ThingSpeak中,並會比較IFTTT、MCSLite和ThingSpeak的優缺點。
本範例程式碼下載請點我
撰寫/攝影 |
許鈺莨 |
前情提要 |
|
時間 |
1小時 |
材料表 |
空氣品質監測基本材料包
(使用LinkIt 7697、Grove 擴充板)
連結: https://robotkingdom.com.tw/product/airbox-kit-linkit-7697-2/Grove -VOC與eCO2 氣體感測器(選配)
連結:
https://robotkingdom.com.tw/product/grove-voc-and-eco2-gas-sensor-sgp30/ |
成本 |
|
難度 |
**** (最高10顆星) |
我們將三套空氣盒子放置在機器人王國的 B1、一樓店面及三樓辦公室,並將空氣盒子的監測數值上傳到雲端。
B1
一樓店面
三樓
之前是將數值透過IFTTT上傳至Google表單,如果讀者有興趣請看【LinkIt 7697空氣品質偵測並上傳Google表單(空氣盒子2.0)】。本文則是要進一步把空氣盒子的感測器數值上傳到 MCSLite 和 ThingSpeak 兩個不同的雲服務中,。為將空氣盒子數值傳上ThingSpeak是新的嘗試,所以會著重ThingSpeak的說明,而因為程式碼比較龐大,所以會重點解釋程式碼,以下本文開始。
筆者針對目前使用過的雲端平台做一些心得感想:
1. 透過IFTTT上傳至Google表單
使用IFTTT的好處就是方便串接兩種不同的服務,而這樣的組合可說是變化多端。設定好之後可以做一套自動化的執行程序(Applets)。例如:當空氣盒子偵測到溫度過高可以傳訊息到LINE中通知。
對於偵測數值有變化進而可以控制裝置,或傳通知訊息的專案,可以使用這個方案,但缺點就是在2020年10月7號後,就會需要付費成專業版,可不受限制可以建立多個個人化的執行程序,若使用免費方案的話,最多只能有 3 個 applet,超過的話就必須刪除,以下就是當時收到建議付費成專業版的郵件內容。
再來是上傳數值的種類,最多只能選擇三種,例如:溫度、濕度、CO2數值,除此之外,筆者還發現,上傳到Google的表單的數值,最多只能顯示2000列,如下圖所示。
2. MCSLite
由聯發科技物聯網雲端平台 MediaTek Cloud Sandbox(MCS)的核心功能改寫而成的輕量化程式,雖然MCS在 2021年4月16日停止了服務,但是MCSLite還是有繼承MCS的部分功能,而且 MCSLite 還可以直接運行於 Windows、Linux、Mac OS 等作業系統,方便不聯外網的區域網路使用。
使用MCSLite優點是可以在網頁中可以創建控制通道和顯示通道,可以透過控制頁面來控制裝置,而在創建產品原型時可以無限制建立,而每個產品原型也可以無限制創建出測試裝置。
其缺點是只能將上傳的資料點存在雲端中,而無法下載成CSV檔或JSON檔等格式,儲存到電腦中。
3. ThingSpeak
ThingSpeak 是由知名MATLAB公司所提供的免費空間,每個註冊帳號可以免費有四個頻道(channel),而每個頻道可有八個自訂欄位(field),這意味著可以上傳八種不同的數值,可以提供很直觀圖表製作的功能,也可以下載CSV檔到電腦中,手機端也有專用 app 來檢視資料。但缺點就是無法像 IFTTT 一樣,可以設定超過一定數值就會推播訊息到裝置中,或像MCSLite可以有控制頁面直接控制裝置。
再來要說明如何將空氣盒子的資料點上傳到MCSLite和ThingSpeak的平台,首先以下說明建立這兩個的平台的註冊流程及通道建立。
上傳資料到 MCSLite
MCSLite從下載解壓縮檔案到註冊流程及通道建立,請由此網頁【5-4 MCS Lite介紹及MCS Lite環境建置】來查閱。
上傳資料到 ThingSpeak
以下為建立ThingSpeak平台通道的詳細步驟:
第一步:註冊 ThingSpeak 帳號
先到 ThingSpeak 網站註冊一個免費帳號
填寫Email信箱、所在地區…等基本資料,再按下Continue。
第二步:建立頻道
註冊成功後,到上方頁面的Channels🡪My Channels
按下 New Channel 即可新增頻道
第三步:新增頻道
寫上頻道名稱,一個頻道可以建立最多8個欄位,代表空氣盒子可以上傳8種不同的數值。填完欄位名稱後,點選最下面的 Save Channel 代表頻道新增完畢。
筆者分別在公司的地下一樓、一樓店面及三樓辦公室個放了一個空氣盒子作環境監測,以下是三個樓層的頻道。
第四步:查詢API Key
由於 ThingSpeak 在此用於接收來自空氣盒子的感測器數值 (被寫入),所以這裡請複製Write API Key,後續程式會用到。
程式說明
本專案的程式是由BlocklyDuino附屬的Arduino IDE 1.8.5開啟,程式下載解壓縮後,請開啟CAVEDU_AirBox_V3_IFTTT_DHT20_1F.ino
檔案。開啟時,其他的檔案都會匯入進來,以下為重要程式說明。
重要程式說明
/**************************************************/
/* Copyright © 2021 CAVEDU. All rights reserved.
The AirBox program is suitable for sensors:
Grove-DHT20:
https://robotkingdom.com.tw/product/grove-%e6%ba%ab%e6%ba%bc%e5%ba%a6%e6%84%9f%e6%b8%ac%e5%99%a8temperature-humidity-sensor-v2-0-dht20-upgraded-dht11-i2c-port/
SPG30:
https://robotkingdom.com.tw/product/grove-voc-and-eco2-gas-sensor-sgp30/
OLED Display 0.96:
https://robotkingdom.com.tw/product/grove-oled-display-0-96/
(Also suitable for Grove-OLED Display 0.96”:https://robotkingdom.com.tw/product/oled-display-0-96/)
Education Kit 001 Button :
https://robotkingdom.com.tw/product/rk-education-kit-001/
You can see the AirBox Technical article:
https://blog.cavedu.com/2021/01/20/linkit-7697-airbox/
https://blog.cavedu.com/2021/11/25/linkit-7697-airbox-2/
*/
/***************************************************/
#include "PMS.h"
#include <SoftwareSerial.h>
#include "U8g2lib.h"
#include <DHT.h>
#include "sensirion_common.h"
#include "sgp30.h"
#include <LRTC.h>
#include <WiFiUdp.h>
#include <ctime>
#include "Wire.h"
#include "MCS.h"
/*============Pins==================*/
#define buttonPin 4
#define PMSTx 2
#define PMSRx 3
//#define DHT11Pin 10
#define DHTTYPE DHT20 // DHT 20
/*====================================*/
//Enter WIFI SSID & Password
#include <LWiFi.h>
char _lwifi_ssid[] = "_lwifi_ssid";
char _lwifi_pass[] = "_lwifi_pass";
//Enter IFTTT_key & Event_name
char IFTTT_key[] = "IFTTT_KEY";
char Event_name[] = "Event_Name";
unsigned long current_time = 0;//record current time
unsigned long previous_IFTTT_time = 0;//Record the last time of IFTTT
int IFTTT_upload_time = 2000;//IFTTT intervals of time
int frame = 0;
/*ThingSpeak value*/
unsigned long previous_ThingSpeak_time = 0;//record current time
int ThingSpeak_upload_time = 1000*60*10;//ThingSpeak intervals of time
String Write_API_key= "Write_API_key";//輸入ThingSpeak的 Write_API_Key
/*MCSLITE value*/
unsigned long previous_mcslite_time = 0;//record current time
int mcslite_upload_time = 1000*60*10;//MCSLITE intervals of time
#define _your_MCSLite_DeviceId "_your_MCSLite_DeviceId" //輸入MCSLite的DeviceId
#define _your_MCSLite_DeviceKey "_your_MCSLite_DeviceKey" //輸入MCSLite的Devicekey
#define _your_MCSLite_IP "_your_MCSLite_IP" //輸入MCSLite的IP
MCSLiteDevice mcs(_your_MCSLite_DeviceId , _your_MCSLite_DeviceKey, _your_MCSLite_IP, 3000);
MCSDisplayInteger _1F_CO2("_1F_CO2");
MCSDisplayInteger _1F_TVOC("_1F_TVOC");
MCSDisplayInteger _1F_PM10("_1F_PM10");
MCSDisplayInteger _1F_PM1_0("_1F_PM1_0");
MCSDisplayInteger _1F_PM2_5("_1F_PM2_5");
MCSDisplayInteger _1F_TEMP("_1F_TEMP");
MCSDisplayInteger _1F_HUMI("_1F_HUMI");
SoftwareSerial PMSSerial(PMSTx, PMSRx);
PMS pms(PMSSerial);
PMS::DATA data;
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
/*Monitor rotate angle
U8G2_R0 0 degrees
U8G2_R1 90 degrees
U8G2_R2 180 degrees
U8G2_R3 270 degrees
U8G2_MIRROR mirror
*/
#define imgWidth 128
#define imgHeight 48
int pms1_0, pms2_5, pms10_0;
int temp;
int humi;
int button_state;
s16 err = 0;
u16 tvoc_ppb, co2_eq_ppm;
//DHT dht11_p10(DHT11Pin, DHT11); //define dht11 PIN
DHT dht(DHTTYPE);
#if defined(ARDUINO_ARCH_AVR)
#define debug Serial
#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM)
#define debug SerialUSB
#else
#define debug Serial
#endif
float temp_hum_val[2];
void setup()
{
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
debug.println("DHT20 test!");
Wire.begin();
dht.begin();
//dht11_p10.begin();
PMSSerial.begin(9600);
LRTC.begin();
SGP30_int();
oled_int();
msclite_channel_int();
pinMode(buttonPin, INPUT);
}
void loop()
{
float temp_hum_val[2] = {0};
button_state = digitalRead(buttonPin);
//temp = dht11_p10.readTemperature();
//humi = dht11_p10.readHumidity();
while (!pms.read(data)) {} //PM2.5 read Data
pms1_0 = data.PM_AE_UG_1_0;
pms2_5 = data.PM_AE_UG_2_5;
pms10_0 = data.PM_AE_UG_10_0;
err = sgp_measure_iaq_blocking_read(&tvoc_ppb, &co2_eq_ppm);
if (err == STATUS_OK) {
Serial.print("tVOC Concentration:");
Serial.print(tvoc_ppb);
Serial.println("ppb");
Serial.print("CO2eq Concentration:");
Serial.print(co2_eq_ppm);
Serial.println("ppm");
} else {
Serial.println("error reading IAQ values\n");
}
sensor_oled_task(); //OLED show sensor value
button_oled_show_time();//Press Button to show time
//IFTTT_pm25_temp_humi_task();//Upload sensor value to IFTTT
upload_to_msclite_task();//Upload sensor value to msclite
upload_to_ThingSpeak();//Upload sensor value to ThingSpeak
}
51,52,55,56,60,66,68,72,74-76,79-85,173-177
- 51~52 第51行,輸入WIFI的SSID。
第52行,輸入WIFI的密碼。
55~56 第55行,輸入IFTTT的金鑰。
第56行,輸入IFTTT的任務名稱。
請看【LinkIt 7697空氣品質偵測並上傳Google表單(空氣盒子2.0)】[註1]文章。
60 輸入上傳感測器到IFTTT的間隔時間(單位為毫秒)。
66 輸入上傳感測器到ThingSpeak的間隔時間(單位為毫秒)。
68 輸入ThingSpeak的Write_API_Key。
- 72 輸入上傳感測器到MCSLite的間隔時間(單位為毫秒)。
- 第74行,輸入MCSLite的DeviceId。
- 第75行,輸入MCSLite的DeviceKey。
- 第76行,輸入MCSLite的IP。請看【5-4 MCS Lite介紹及MCS Lite環境建置】[註2]。
- 79~85 第79~85行,在MCSLite建立的資料通道。
- 173 顯示感測器數值在OLED。
- 174 按下按鈕會顯示時間在OLED。
- 175 因IFTTT只能上傳三種數值,故選了PM2.5、溫度和濕度的數值。而程式前面有雙斜線則是註解,不會跑那一段程式。
- 176 上傳感測器數值到MCSLite。
- 177 上傳感測器數值到ThingSpeak 。
B1程式和一樓與三樓程式幾乎都一樣,所以就以一樓的空氣盒子程式來說明即可。更改完成後,就可以將程式燒錄到LinkIt 7697中,由於程式已整合成可同時把感測器數值上傳到IFTTT、MCSLite和ThingSpeak,若讀者想要上傳到IFTTT,請修改175行的註解。
以下為上傳到MCSLite和ThingSpeak成功的例子。
MCSLite
MCSLite屬於區域網路,無法公開網址,故分享感測器上傳成功的畫面。
ThingSpeak
ThingSpeak 可以公開頻道,在此分享網址給大家看看:
- B1:https://thingspeak.com/channels/1626172
- 1F:https://thingspeak.com/channels/1627706
- 3F:https://thingspeak.com/channels/1627724
FB影片說明
https://www.facebook.com/watch/?v=453900302908283&ref=sharing
那麼以上就是空氣盒子2.0的使用教學,下次見!