> For the complete documentation index, see [llms.txt](https://cavedu.gitbook.io/linkit-7697/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cavedu.gitbook.io/linkit-7697/linkit-7697-arduinoide/kai-fa-zhi-nan/shi-yong-ble-di-gong-hao-lan-ya/zhou-bian-zhuang-zhi.md).

# 周邊裝置

低功耗藍牙的**周邊裝置**會提供各種服務與資料，讓**主控裝置**連接後進行存取。

更進一步來說，周邊裝置需要提供一個 GATT 伺服器，才能夠讓主控裝置連接。 所謂的 GATT 伺服器，是包含了一組由**服務**（service）和**資料特性**（characteristics）共同形成的**屬性**（attributes）的集合。

一個服務，比如說「心率測量服務」，會用一個 UUID 代表。一個服務由數個資料特性所構成，而資料特性會提供實際的數值資訊供主控裝置讀寫。比如說，心率測量服務會包含多個資料特性，其中一個稱做「心率測量值」的資料特性，讓主控裝置可以進行讀取心率測量的數值。

如果想進一步瞭解 GATT 以及各種服務的內容，可以參考 [Bluetooth.com](https://www.bluetooth.com/specifications/generic-attributes-overview) 或是[這篇文章](https://learn.adafruit.com/introduction-to-bluetooth-low-energy/gatt#services-and-characteristics).

所以說，在創建 GATT 伺服器之前，必須先定義好相關的服務與資料特性列表。要注意的是，因為服務與資料特性是可以在任何時刻被主控裝置存取的，應將實際定義的服務與資料特性定義在全域空間當中，以確保它的生命週期。比如說：

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

// 在全域空間定義一個只有一個資料特性的服務
LBLEService ledService("19B10010-E8F2-537E-4F6C-D104768A1214");
LBLECharacteristicInt switchCharacteristic("19B10011-E8F2-537E-4F6C-D104768A1214", LBLE_READ | LBLE_WRITE);
```

`其中，`

* `19B1001`**`0`**`-E8F2-537E-4F6C-D104768A1214` 是服務的 UUID，這個 UUID 會被主控裝置用於搜尋與確認服務的內容。
* `19B1001`**`1`**`-E8F2-537E-4F6C-D104768A1214` 是資料特性的 UUID，主控裝置可以依據此 UUID 來確認讀寫的資料內容。要注意的是，GATT 當中資料特性是沒有型別概念的，所以開發者需要自己根據服務與資料特性的定義，來解析要讀寫的資料內容。為了便於解析資料，像是 LBLECharacteristicInt 這樣的資料特性類別，提供了對應的 `setValue()` 方法，可以直接使用這個方法來寫入整數。

當定義並且設定好 GATT 相關的屬性內容之後，需要建立起服務跟資料特性之間的關聯，方可建立並執行 GATT 伺服器：

```
void setup() {
    // 將 switch 這個資料特性添加到 LED 這個服務當中
    ledService.addAttribute(switchCharacteristic);

    // 將 LED 這個服務添加到 GATT 伺服器之中
    LBLEPeripheral.addService(ledService);
```

接著，若要啟動 GATT 伺服器，需要呼叫：

```
LBLEPeripheral.begin();
```

{% hint style="danger" %}
請注意，當 `begin()` 被呼叫之後，就不能夠再添加其他的服務與資料特性，也不能夠改變服務與資料特性之間的關聯。
{% endhint %}

此時周邊裝置已經準備就緒，可以被主控裝置連線。可以透過呼叫 `isWritten()` 來檢查一個資料特性是否有被主控裝置寫入，如下：

```
void loop() {
  delay(100);
  if (switchCharacteristic.isWritten()) {
    const char value = switchCharacteristic.getValue();
    switch (value) {
      case 1:
        digitalWrite(LED_BUILTIN, HIGH);
        break;
      case 0:
        digitalWrite(LED_BUILTIN, LOW);
        break;
      default:
        Serial.println("Unknown value written");
        break;
    }
  }
}
```

在接下來的段落中，我們會簡單的示範，要怎麼樣連線至 `SimplePeripheral` 範例所創建出來的 BLE 裝置。

### SimplePeripheral 範例 <a href="#peripheraldevicessimpleperipheral-fan-li" id="peripheraldevicessimpleperipheral-fan-li"></a>

請在 IDE 的選單中選擇 **`File > Examples > LBLE > SimplePeripheral`** 並且上傳此範例到 LinkIt 7697。這個範例會等待主控裝置連線，並不斷檢查主控裝置是否有改變 switch 這個資料特性的數值。根據主控裝置寫入的數值是 1 或是 0，此範例會開關開發板上面的內建 LED 燈。在接下來的段落中，我們會示範怎麼用 [AppInventor](http://ai2.appinventor.mit.edu/) 來建造一個可以連接到此範例的 Android 手機程式。

### 匯入 AppInventor 範例程式 <a href="#peripheraldevices-hui-ru-appinventor-fan-li-cheng-shi" id="peripheraldevices-hui-ru-appinventor-fan-li-cheng-shi"></a>

可以透過 iOS 或 Android 的 GATT 程式庫來連結到此範例。在這個段落中，將會示範怎麼用 AppInventor 這個圖形化的程式開發環境來撰寫一個連接到此範例的 Android 手機程式。請依照下列步驟操作：

* 從[此連結](https://github.com/MediaTek-Labs/Arduino-Add-On-for-LinkIt-SDK/raw/master/middleware/third_party/arduino/hardware/arduino/mt7697/libraries/LBLE/examples/SimplePeripheral/BLE_LED.aia)下載 AppInventor 的專案檔，檔名為：**BLE\_LED.aia**。
* 請造訪 [AppInventor ](http://ai2.appinventor.mit.edu/)網站並且登入。開發者可以使用自己的 Google 帳號登入。
* 在網站的介面選單當中，請選擇 **`Projects > Import project (.aia) from my computer`**

![](https://3972650740-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY4gduUSLWOCI23CXUWej%2Fuploads%2FRXYllamMeNJKup4AdmhV%2Fimport_aia_project.png?alt=media\&token=c524bb7f-9c87-4dbd-9aa4-e1ea0db91054)

* 上傳剛剛下載的 **BLE\_LED.aia** 專案檔。<br>

### 連線至 BLE 周邊 <a href="#peripheraldevices-lian-xian-zhi-ble-zhou-bian" id="peripheraldevices-lian-xian-zhi-ble-zhou-bian"></a>

在連接到 BLE 周邊裝置時，我們需要指定 BLE 裝置位置。然而，此裝置位置在每一片LinkIt 7697 開發板上面都是不一樣的。為了讓開發者可以比較容易指定此裝置位置，請先執行 `SimplePeripheral` 範例。此範例會在 Arduino Serial Monitor 上面顯示出 LinkIt 7697 開發板的裝置位置。

* 請用 baud rate **9600** 開啟 Serial Monitor，並觀察開發板輸出的 Device Address，如下：

![](https://3972650740-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY4gduUSLWOCI23CXUWej%2Fuploads%2FS9SHKrxr7cCi5WcyQeS2%2Fble_device_address.png?alt=media\&token=5ae3f74d-772c-488a-b90d-1c88aabb1f06)

* 在 **AppInventor** 當中，切換到 **Blocks** 顯示介面，並且參考下圖，找到 `addr` 這個積木的位置：

&#x20;

![](https://3972650740-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY4gduUSLWOCI23CXUWej%2Fuploads%2FSJUhjtsgX59vl7687t5e%2Fappinventor_addr_block.png?alt=media\&token=2be471c2-72e3-4741-b485-13e11cad0b95)

* 從 Arduino Serial Monitor 拷貝裝置位置到 `addr` 積木當中。請注意，AppInventor只接受大寫的位置字串，如： `D7:00:00:2B:88:8C`. 如果修改為小寫的字串，它將會連線失敗。&#x20;

![](https://3972650740-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY4gduUSLWOCI23CXUWej%2Fuploads%2FCCPcDV4F0WxIX9xaK4Do%2Fappinventor_set_addr.png?alt=media\&token=07eada72-f110-4c49-9fec-1a04fc7ac9df)

* 接下來，在 **AppInventor** 選單當中，選擇 **`Build > App (provide QR code for .apk)`**`：`

![](https://3972650740-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY4gduUSLWOCI23CXUWej%2Fuploads%2F66mY5X1L6VeLHmNzWSfS%2Fappinventor_build.png?alt=media\&token=240c2be3-8a79-4be4-96ff-175bb2c96bc6)

* 下載並安裝 QR Code 所含有的連結中的 **BLE\_LED.apk**。手機程式的名字應該會叫做 **BLE Light**。
* 執行安裝好的 BLE Light 程式，然後按畫面上的 **Connect** 按鈕。
* 如果連線成功，畫面上的 **ON** 跟 **OFF** 按鈕將會被啟用
* 點擊 ON ，開發板上面的 LED 應該會發光。
* 點擊 OFF，開發板上面的 LED 應該會熄滅。
