2016年8月24日 星期三

★ Blynk 的通知元件 (Notifications)

測試完 Blynk 的顯示元件後, 對 Blynk 的了解又更深一層了. 接下來要繼續測試通知元件 (Notification), Blynk 有三個通知元件 :
  1. Twitter : 傳送訊息到個人的推特
  2. Email : 傳送訊息到指定郵件信箱
  3. Push : 推送訊息到手機 
以下測試程式是在我自己用洞洞板焊接的 Arduino Nano+ESP8266 IOT 模組上進行實驗, 電路圖參考 :

# 製作 Arduino Nano + ESP8266 物聯網模組 (四) : 完結篇



一. 推特元件 (Twitter) :

首先在專案中新增一個 Twitter 元件 :


點一下面板上的 Twitter 元件進入設定畫面 :


這裡有提示使用 Blynk 函式庫傳送推文的方法是呼叫 Blynk.tweet() 函式. 按底下的 "Connect Twitter" 鈕, 要求授權 Blynk 使用我目前在手機上已登入的 Twitter 帳戶, 若要改換帳號, 請按 "點選以切換帳戶" 超連結 :


按 "允許" 鈕 Blynk 即開始連結此 Twitter 帳戶, 成功後會在帳號後面顯示 connected, 同時底下會出現 "Disconnect" 鈕. 若要更換連結帳號, 請先按此鈕切斷連線回到上一步重新連結.


App 部分這樣就 OK 了, 接下來是撰寫設備端韌體程式, 但使用 Blynk.tweet() 函式前須先了解 Twitter 有兩個限制 :
  1. 連續兩個推文內容不可雷同
  2. 連續兩個推文必須至少間隔 60 秒
以下測試程式係參考官網說明文件範例修改而來, 原程式使用一個按鈕來產生中斷以送出推文, 原始範例參考 :

https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Twitter/Twitter.ino#L26

為了簡化程式, 我改為固定每 10 分鐘送出一個推文, 其內容為程式執行後所經歷的秒數, 這樣就滿足 Twitter 的要求了. 程式如下 :

#define BLYNK_PRINT Serial  //Comment this out to disable prints and save space
#include <SoftwareSerial.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <SimpleTimer.h>

SoftwareSerial esp8266(7, 8); //(RX, TX)
ESP8266 wifi(&esp8266); //create wifi object
SimpleTimer timer; //create a Timer object

char ssid[]="EDIMAX-tony";
char pass[]="1234567890";
char auth[]="e80fe6aae0d442518820f61xxxxxx8f5";

void setup() {
  Serial.begin(9600); //Set console baud rate
  esp8266.begin(9600); //Set ESP8266 baud rate
  Blynk.begin(auth, wifi, ssid, pass);
  while (Blynk.connect() == false) {} //wait until connected
  timer.setInterval(10L * 60000L, tweetUptime); //Don't send more that 10 values per second
  }

void loop() {
  Blynk.run();
  timer.run();
  }

void tweetUptime() {
  long uptime=millis() / 60000L; //minutes elapsed
  Serial.println("Tweeting every 10 minutes ;)");
  Blynk.tweet(String("Running for ") + uptime + " minutes.");
  }

此程式使用 SimpleTimer 計時器每 10 分鐘觸發執行自訂函數 tweetUptime() 一次, 送出程式執行到目前所歷經的分鐘數. 結果如下 :


可見確實每十分鐘就送出一次推文.

二. Email 元件 :

此元件可讓我們從硬體設備端送出郵件到任何 Email 信箱位址, 只要呼叫 Blynk 函式庫的 email() 函數即可 :

Blynk.email("my_email@example.com", "Subject", "Your message goes here");

但是此元件與 Twitter 一樣有兩個限制 :
  1. 郵件長度包含標題與內容預設最多不可超過 120 個字元.
  2. 每分鐘最多只能送出一封信件. 
其中第一個限制可以透過修改 BLYNK_MAX_SENDBYTES 常數的預設值加以放寬, 例如 :

#define BLYNK_MAX_SENDBYTES 1200

此指令將傳送總字元數放寬至 1200 字元. 注意, 因為 Blynk 函式庫以 Unicode 處理所傳送之字元, 而 Unicode 所佔 bytes 數至少是 ASCII 的兩倍, 因此若此常數太小, 收到的訊息內容可能有截尾現象 (truncated). 

首先新增 Email 元件 :


點一下 Email 元件進入設定畫面 :


這邊只要輸入要傳送的目的地信箱即可, 事實上這裡不填也沒關係, 因為韌體程式中會指定要傳送到哪一個信箱.

接下來便是韌體程式部分, 參考官網文件範例 :

https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Email/Email.ino#L26

同樣地這裡我將其修改為更簡單的範例, 但為了挑戰 Blynk 對 Email 的限制, 改成每分鐘傳送一封 Email 到指定信箱, 看看結果如何. 傳送 Email 只要呼叫 Blynk.email() 函數即可 :

Blynk.email("郵件位址", "主旨", "郵件內容");

Blynk.email() 一次只能傳一個郵件位址, 若要傳給多個信箱, 要分次呼叫.

程式如下 :

#define BLYNK_PRINT Serial  //Comment this out to disable prints and save space
#include <SoftwareSerial.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <SimpleTimer.h>

SoftwareSerial esp8266(7, 8); //(RX, TX)
ESP8266 wifi(&esp8266); //create wifi object
SimpleTimer timer; //create a Timer object

char ssid[]="EDIMAX-tony";
char pass[]="1234567890";
char auth[]="e80fe6aae0d442518820f61xxxxxx8f5";

void setup() {
  Serial.begin(9600); //Set console baud rate
  esp8266.begin(9600); //Set ESP8266 baud rate
  Blynk.begin(auth, wifi, ssid, pass);
  while (Blynk.connect() == false) {} //wait until connected
  timer.setInterval(1L * 60000L, emailUptime); //Don't send more that 10 values per second
  }

void loop() {
  Blynk.run();
  timer.run();
  }

void emailUptime() {
  long uptime=millis() / 6000L;
  Serial.println("Email every 1 minutes :)");
  Blynk.email("abc@gmail.net", "Running time", String("Running for ") + uptime + " minutes.");
  }

開啟信箱檢查所收到的信件, 發現實際上是每兩分鐘才收到一封信 :


比較起來, Email 是通知時效上較差的方式, 雖然手機也可以收 Email, 但這時代會三不五時看信箱的越來越少了.

三. 推送通知 (Push Notification) :

此元件可讓遠端設備推送通知訊息到手機 App. 新增 Push 元件如下 :


點一下進入設定畫面 :


這裡有兩個選項, 其中 "Notify when hardware goes offline" 預設為 OFF, 若改為 ON, 則當遠端設備離線 (斷電或網路異常), Blynk Cloud 就會發出通知到手機. 而 "Priority" 選項預設為 NORMAL, 若設為 HIGH, 則訊息會比較即時, 但這樣將使手機更耗電, 因為必須開啟一個固定網路連線以避免訊息延遲傳遞. 參考 Google 關於 Android 即時訊息的說明 :

#  Google Cloud Messaging : Setting the priority of a message

跟 Email 的限制一樣, 推送訊息也有兩個限制 :
  1. 訊息內容最多不可超過 120 個字元.
  2. 每分鐘最多只能送出一則訊息. 
跟 Email 一樣, 第一個限制若要放寬可以透過修改 BLYNK_MAX_SENDBYTES 常數的預設值加以放寬 (兩個是一樣的常數), 例如 :

#define BLYNK_MAX_SENDBYTES 256

設備端韌體程式可呼叫 Blynk.notify() 函數向手機 App 推送訊息 :

Blynk.notify("訊息");

我將上面 Email 的範例改為推送訊息, 同樣每分鐘送出一則, 測試看看是否變成兩分鐘, 官網元範例程式參考 :

PushNotification_Button.ino


#define BLYNK_PRINT Serial  //Comment this out to disable prints and save space
#include <SoftwareSerial.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <SimpleTimer.h>

SoftwareSerial esp8266(7, 8); //(RX, TX)
ESP8266 wifi(&esp8266); //create wifi object
SimpleTimer timer; //create a Timer object

char ssid[]="EDIMAX-tony";
char pass[]="1234567890";
char auth[]="e80fe6aae0d442518820f61xxxxxx8f5";

void setup() {
  Serial.begin(9600); //Set console baud rate
  esp8266.begin(9600); //Set ESP8266 baud rate
  Blynk.begin(auth, wifi, ssid, pass);
  while (Blynk.connect() == false) {} //wait until connected
  timer.setInterval(1L * 60000L, notifyUptime); //Don't send more that 10 values per second
  }

void loop() {
  Blynk.run();
  timer.run();
  }

void notifyUptime() {
  long uptime=millis() / 6000L;
  Serial.println("Notify every 1 minutes :)");
  Blynk.notify(String("Running for ") + uptime + " minutes.");
  }

程式上傳執行結果跟 Email 一樣, 變成每兩分鐘才收到通知, 手機會發出聲響, 第一次收到時會詢問是否允許推送到手機面板. 為了擷取這些通知的列表, 我故意在 "設定/通知管理員" 的規則中, 將 Blynk 從 "允許" 改為 "限制" (取得資料後再改回通知或允許), 如下所示 :


這樣之後收到的通知就會被攔截在 "紀錄" 裡了 :


從最後的時間欄可知, 雖然程式每分鐘送出一則通知, 但受到 Google Cloud Messaging 的限制, 偶數分鐘的那則被丟掉了, 結果兩分鐘才會收到一則通知. 然後我拔掉 Arduino 電源, 讓設備離線, 結果真的有收到離線通知, 即上圖最上面 13:58 那一則通知.

上面三種通知元件我覺得以第三種推送通知最實用, 因為只要有上網, 手機收到推送的通知就會發出聲響+震動, 不需要開啟 Email 或 Twitter 去看. 可以在 "設定/音效" 中更改預設的通知鈴聲 :


最好選一個比較響亮的, 這樣才能起到通知的作用. 不過這三種通知方式用途不同, Twitter 與 Push 只能將訊息傳遞給自己; 而 Email 則可以傳遞給自己以外的人.


6 則留言 :

Unknown 提到...

請問老師..可否手機通知...用多組來通知呢?

小狐狸事務所 提到...


Blynk 本來就是手機 App 啊! 您的意思是發出訊息, 簡訊, 或 Line 通知是嗎?

匿名 提到...

老師對不起,我想請問一下,我照你第二節的程式打可是他都顯示我這一行
Blynk.email(“xxxxxxxxx@gmail.com”,“字符串(“正在運行”)+正常運行時間+“分鐘。”) ;





stray '\357' in program
這是為什麼阿

小狐狸事務所 提到...

這些程式都實際測試過, 應無問題, 我好久沒用 blynk 了, 有空我再來重測, 但現在很忙.

小狐狸事務所 提到...

試試看不要用中文, 全部用英文

匿名 提到...

老師,我照你說得全部都改成英文了,但是他現在變成說我這一段


void loop(){
Blynk.run();
timer.run();
}


stray '\357' in program
請問是我匯入的函式庫有問題嗎???
能求解……
謝謝老師 zro