建立可透過 MCS Lite 控制的 Beacon

本教學將示範建構 IoT 綜合應用系統,以展示如何達成區網內的裝置通訊、以及連接外網的系統組合。在此應用情境中,主要構成元件如下:

  1. IoT gateway:由具有高效處理能力與傳輸效能的 LinkIt Smart 7688 構成。所有在 LinkIt Smart 7688 私有區網內的節點皆透過此 gateway 連接到外部的網際網路。

  2. 終端節點:使用 LinkIt 7697 作為輕量與節能的 IoT 終端平台。

  3. 使用者的移動裝置 (如手機等):作為與終端節點互動以及控制 gateway 的平台。

引用說明

圖示來自 www.flaticon.com,作者為 FreepikGregor Cresnar,使用 CC 3.0 BY 授權。

接下來的章節,將說明上述元件的設置方法;希望藉由這些範例幫助開發者了解其運作機制,並以此為基礎擴充至不同的 IoT 應用場景。

IoT Gateway - 使用 LinkIt Smart 7688 作為私有雲伺服器及 Wi-Fi repeater

作為硬體資源比終端節點更強的平台,gateway 主要功能為資料處理與傳輸。LinkIt Smart 7688 在此例中,被設置為 MCS Lite 伺服器,提供私有雲服務處理區網內產生的資料點。此外,LinkIt Smart 7688 並提供 Wi-Fi repeater 功能,使區網內的節點得以連接網際網路。下列兩篇教學文章說明如何將 LinkIt Smart 7688 設置為 MCS Lite 伺服器以及如何使 LinkIt Smart 7688 運作在 Wi-Fi repeater 的中繼模式:

此外請參閱另一篇教學文件,建立可控制 LinkIt 7697 板上 LED 的 MCS Lite 測試裝置,此裝置也會被應用在本文的綜合範例當中。

測試裝置所包含的重要資訊有:

  • Device id

  • Device key

  • 名為 switch_display 的開/關顯示器通道

  • 名為 switch_controller 的開/關控制器通道

當撰寫 LinkIt 7697 的 Arduino sketch 程式碼時,開發者需提供這些資訊至對應的 MCS Lite API 之中。

IoT 終端節點 - 使用 LinkIt 7697 作為節點裝置與 BLE beacon

請先參閱另外兩篇相關主題的教學:

接下來的範例將整合上述文章,將 LinkIt 7697 設置為可受 MCS Lite 控制的 BLE beacon (用來廣播 MCS Lite 控制頁面的 URL)。在此應用下,當使用者裝置 (如已開啟藍芽的手機) 靠近 7697 節點時,會自動收到 MCS Lite 控制頁面的網址資訊,不需為了連結頁面而手動輸入網址。使用的程式碼整合自前述的兩篇教學,主要修改處將會在下列章節說明。若要取得完成的 sketch 程式碼,請參考文末的參考資料章節。

設置 AP 連線資訊

程式一開始,開發者需設定 IoT gateway 的 SSID 與密碼等連線資訊,讓 LinkIt 7697 能加入區域網路並連接到 MCS Lite 的私有雲服務。

// Assign AP ssid / password here 
#define _SSID "YOUR_AP_NAME" 
#define _KEY "YOUR_PASSWORD"

基於這些資訊,LinkIt 7697 會透過 58 行的程式連線到 gateway 所提供的 Wi-Fi AP:

Serial.print("WiFi.begin(");
Serial.print(_SSID);
Serial.print(",");
Serial.print(_KEY);
Serial.println(")...");
WiFi.begin(_SSID, _KEY);

雖然基於安全理由不建議這麼做,但若開發者欲連接至無密碼設定的 Wi-Fi AP,則需將 58 行的 API 如下修改,才能使 LinkIt 7697 順利連接該 AP:

WiFi.begin(_SSID);

指定 MCS Lite 裝置資訊與 MCS Lite 伺服器的位置

欲取得與 MCS Lite 伺服器的連線,需在 API 中指定伺服器位置以及 LinkIt 7697 測試裝置所對應的 device iddevice key。修改程式碼第 14 行的值以提供正確連線資訊:

MCSLiteDevice mcs("YOUR_DEVICE_ID", "YOUR_DEVICE_KEY", "MCS_LITE_SERVER_ADDRESS", MCS_LITE_SERVICE_PORT);

請依照 MCS Lite 控制頁面的 device id 與 device key 資訊填入前兩個欄位;而描述 MCS Lite 伺服器位置的 IP 與通訊埠欄位,可透過啟動 MCS Lite 伺服器時所顯示的資訊取得。

定義 MCS Lite 通道資訊

建立這個範例的測試裝置時,會定義顯示器與控制器資料通道。因此在 sketch 裡需指定對應的通道資訊以供伺服器識別:

MCSControllerOnOff led("switch_controller"); 
MCSDisplayOnOff remote("switch_display");

設置供 BLE 廣播的 Eddystone URL

為了讓使用者輕易地存取 MCS Lite 網頁控制介面,IoT 終端節點會透過 BLE beacon 機制不斷廣播 MCS Lite 頁面的 URL。當使用者平台 (如手機) 支援 BLE 並裝有能識別 Eddystone URL beacon 的應用程式時,就能自動從節點裝置獲得 MCS Lite URL 的資訊。依照 Eddystone 定義的格式,修改第 44 行程式碼以進行 URL 廣播:

beaconData.configAsEddystoneURL(EDDY_HTTPS, "goo.gl/evYXvt");

由於 Eddystone URL 有長度限制 (17 bytes),開發者可搭配任一縮網址服務將欲廣播的 URL 進行簡化。在此範例中,使用的 URL "http://mylinkit.local:3000" 需被縮短為 "goo.gl/evYXvt" 後,才符合 Eddystone 的長度規範。關於更多 Eddystone URL 的細節,請參考 7697 Beacon 教學的 "使用 LinkIt 7697 作為 Eddystone-URL Beacon" 章節。

使用者平台設定

注意

在進行下列步驟前,請開啟使用者平台的 Wi-Fi 與 BLE 功能,並確認已連接到 IoT gateway。

為了識別 Eddystone 廣播資訊,使用者需安裝支援搜尋 Eddystone URL beacon 的應用程式,以下步驟將採用 Physical Web 應用程式作為示範。

安裝後,若在 LinkIt 7697 附近開啟該應用程式,則會看到 beacon 廣播的 URL 如下:

除了透過開啟應用程式取得 URL 外,亦支援以 widget 模式讀取 beacon 資訊:

點選該 URL 即會被導向 URL 所指的 MCS Lite 控制頁面:

登入 MCS Lite 服務之後,即可透過手機取得與控制 LinkIt 7697 LED 的狀態:

參考資料

以下為 LinkIt 7697 所執行程式的完整 Arduino sketch 碼:

#include <LWiFi.h>
#include <WiFiClient.h>
#include "MCS.h"

#include <LBLE.h>
#include <LBLEPeriphral.h>

// Assign AP ssid / password here
#define _SSID "YOUR_AP_NAME"
#define _KEY  "YOUR_PASSWORD"

// Assign device id / key of your test device
//MCSDevice mcs("YOUR_DEVICE_ID", "YOUR_DEVICE_KEY");
MCSLiteDevice mcs("YOUR_DEVICE_ID", "YOUR_DEVICE_KEY", "MCS_LITE_SERVER_ADDRESS", MCS_LITE_SERVICE_PORT);

// Assign channel id 
// The test device should have 2 channel
// the first channel should be "Controller" - "On/Off"
// the secord channel should be "Display" - "On/Off"
MCSControllerOnOff led("switch_controller");
MCSDisplayOnOff    remote("switch_display");

#define LED_PIN 7

void setup() {
  // setup Serial output at 9600
  Serial.begin(9600);

  // setup LED/Button pin
  pinMode(LED_PIN, OUTPUT);

  // Initialize BLE subsystem
  Serial.println("BLE begin");
  LBLE.begin();
  while (!LBLE.ready()) {
    delay(100);
  }
  Serial.println("BLE ready");
  
  // configure our advertisement data as iBeacon.
  LBLEAdvertisementData beaconData;

  // make an Eddystone-URL beacon that this board casts
  beaconData.configAsEddystoneURL(EDDY_HTTPS, "goo.gl/evYXvt");
  Serial.print("Start advertising Eddystone-URL");

  // start advertising it
  LBLEPeripheral.advertiseAsBeacon(beaconData);
  
  // setup Wifi connection
  while(WL_CONNECTED != WiFi.status())
  {
    Serial.print("WiFi.begin(");
    Serial.print(_SSID);
    Serial.print(",");
    Serial.print(_KEY);
    Serial.println(")...");
    WiFi.begin(_SSID);
  }
  Serial.println("WiFi connected !!");

  // setup MCS connection
  mcs.addChannel(led);
  mcs.addChannel(remote);
  while(!mcs.connected())
  {
    Serial.println("MCS.connect()...");
    mcs.connect();
  }
  Serial.println("MCS connected !!");

  // read LED value from MCS server
  while(!led.valid())
  {
    Serial.println("read LED value from MCS...");
    led.value();
  }
  Serial.print("done, LED value = ");
  Serial.println(led.value());
  digitalWrite(LED_PIN, led.value() ? HIGH : LOW);
}

void loop() {
  // call process() to allow background processing, add timeout to avoid high cpu usage
  mcs.process(100);
  
  // updated flag will be cleared in process(), user must check it after process() call.
  if(led.updated())
  {
    Serial.print("LED updated, new value = ");
    Serial.println(led.value());
    digitalWrite(LED_PIN, led.value() ? HIGH : LOW);
    if(!remote.set(led.value()))
    {
      Serial.print("Failed to update remote");
      Serial.println(remote.value());
    }
  }
  
  // check if need to re-connect
  while(!mcs.connected())
  {
    Serial.println("re-connect to MCS...");
    mcs.connect();
    if(mcs.connected())
      Serial.println("MCS connected !!");
  }
}

Last updated