ESP32, IOT物聯網

【ESP32教學】ESP32 與 iPhone (iOS) BLE 低功耗藍牙數據傳輸實作

一、 實驗說明:打造智慧居家人體感應/裝置控制!

在智慧家庭與物聯網(IoT)應用中,無線通訊與手持裝置的互動是非常關鍵的核心功能。傳統藍牙通常適用於大量資料傳輸但較為耗電;若能透過 ESP32 結合 BLE(Bluetooth Low Energy,低功耗藍牙),便能輕鬆打造省電、反應迅速且能與 iPhone/iOS 裝置無縫連線的智慧防護與控制網。

本實驗米羅將帶大家使用 ESP32 開發板 搭配 iPhone / iPad 上的 LightBlue App。透過 BLE 的 GAP 廣播與 GATT 特徵值服務,實作 ESP32 與 iPhone 手機之間的文字與數據雙向傳送與接收!

 

二、 實驗材料準備清單

本篇實作 ESP32 與 iPhone BLE 藍牙通訊專案所需的硬體與軟體如下:

  • ESP32 開發板

  • USB 數據傳輸線

  • iPhone 或 iPad(iOS 行動裝置)

  • LightBlue App(iOS 應用程式)

 

⭐ 一次備齊創客工具! 歡迎直接購買米羅科技的  ESP32 物聯網應用學習套件,免去東奔西跑湊零件的煩惱。內含感測器模組、開發板及基礎電子元件,是學校課堂教學與個人專案開發的最佳首選!

 

三、 核心知識:BLE 低功耗藍牙與 GAP / GATT 運作原理

  1. 低功耗藍牙(BLE)簡介 低功耗藍牙(Bluetooth Low Energy,簡稱 BLE)是藍牙技術聯盟(SIG)所制定的無線通訊規範。與傳統藍牙(Classic Bluetooth)不同的是,BLE 以省電、低功耗、快速連線為主要特性,是目前物聯網與智慧穿戴裝置最熱門的無線通訊協定之一。

  2. BLE 核心協定:GAP 與 GATT 差異 在應用 BLE 時,必須了解兩個核心協定:

  • GAP(Generic Access Profile,通用訪問協議): 主要用來控制裝置連線前的廣播(Advertising)與連線(Connection)。GAP 定義了裝置角色,例如:

    • 外圍裝置(Peripheral / Slave):如 ESP32,負責廣播訊號並提供數據。

    • 中心裝置(Central / Master):如 iPhone 手機,主動掃描並連線至外圍裝置。

  • GATT(Generic Attribute Profile,通用屬性協議): 當兩台裝置建立連線後,GATT 負責定義資料如何組織與傳輸。數據以 Service(服務) 與 Characteristic(特徵值) 的結構進行雙向通訊。

  1. ESP32 BLE 角色與腳位設定 本實驗中,ESP32 充當 GATT 伺服器(Server),iPhone 為 GATT 客戶端(Client)。通訊透過 USB 數據線連接至電腦的序列埠(Baud Rate: 115200)進行監控。

 

四、 實作實驗程式碼:ESP32 與 iOS 雙向通訊

請將以下程式碼複製到 Arduino IDE 中並上傳至 ESP32 開發板:

1. 範例程式碼

#include <BLEDevice.h> 
#include <BLEServer.h> 
#include <BLEUtils.h> 
#include <BLE2902.h> 
#include <String.h> 

BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
uint8_t txValue = 0;
long lastMsg = 0;
String rxload="Test\n";

/*為BLE供應商定義指定的 UUID 編號*/
#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" 
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

/*為BLE服務器編寫一個Callback函式來管理BLE的連接。*/
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };
    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

/*具有BLE功能的Callback函式。 
 *調用時,移動終端向 ESP32 發送數據時,會將其存儲到 reload 中。
 */
class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();
      if (rxValue.length() > 0) {
        rxload="";
        for (int i = 0; i < rxValue.length(); i++){
          rxload +=(char)rxValue[i];
        }
      }
    }
};

/*創建BLE server流程:
 *1. Create a BLE Server
 *2. Create a BLE Service
 *3. Create a BLE Characteristic on the Service
 *4. Create a BLE Descriptor on the characteristic 
 *5. Start the service
 *6. Start advertising
 */
void setupBLE(String BLEName){
  const char *ble_name=BLEName.c_str();
  BLEDevice::init(ble_name);
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());
  BLEService *pService = pServer->createService(SERVICE_UUID); 
  pCharacteristic= pService->createCharacteristic(CHARACTERISTIC_UUID_TX,BLECharacteristic::PROPERTY_NOTIFY);
  pCharacteristic->addDescriptor(new BLE2902());
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX,BLECharacteristic::PROPERTY_WRITE);
  pCharacteristic->setCallbacks(new MyCallbacks()); 
  pService->start();
  pServer->getAdvertising()->start();
  Serial.println("Waiting a client connection to notify...");
}

void setup() {
  Serial.begin(115200);
  setupBLE("ESP32_BLE"); //初始化BLE並為其命名,藍牙顯示名稱可自行更改
}

/*當手機通過BLE藍牙向ESP32發送訊息時,會通過ESP32的序列視窗顯示出來; 
 *經由ESP32的序列視窗發送訊息後,會通過BLE藍牙發送到手機。
 */
void loop() {
  long now = millis();
  if (now - lastMsg > 100) {
    if (deviceConnected&&rxload.length()>0) {
        Serial.println(rxload);
        rxload="";
    }
    if(Serial.available()>0){
        String str=Serial.readString();
        const char *newValue=str.c_str();
        pCharacteristic->setValue(newValue);
        pCharacteristic->notify();
    }
    lastMsg = now;
  }
}

 

2. Android App 設定與連線操作步驟

  1. 將範例程式編譯並上傳至 ESP32 開發板後,開啟 Arduino IDE 的序列埠監控視窗(鮑率設定為 115200)。
  2. 請至 iPhone App Store 下載並安裝 「LightBlue」 APP。

 

3. 開啟 iPhone 藍牙與 LightBlue APP,在掃描頁面下滑刷新,找到 ESP32_BLE 並點擊配對連線。

 

4. 接收 ESP32 訊息:點擊 Notify 特徵值,點選 Listen for notification 開啟監聽模式,右上角選擇數據格式為 UTF-8-String。在 ESP32 序列視窗發送文字,即可在 iPhone 畫面上接收到訊息。

 

 

5. 傳送訊息給 ESP32:點擊 Write 特徵值,數據格式選 UTF-8-String,點選 Write new value 輸入文字並點 Done 送出,即可在 ESP32 序列視窗看到 iPhone 傳來的訊息。

 

 

五、 初學者常見卡關問題與排錯指南(Troubleshooting)

  1. iPhone 搜尋不到 ESP32 的藍牙名稱?

  • 藍牙廣播確認:請確認程式碼中有正確執行 pServer->getAdvertising()->start()。

  • 權限與開關:請確認 iPhone 的藍牙已開啟,且已授權 LightBlue App 使用藍牙功能。

  1. 為什麼手機收到的內容是十六進位亂碼而非文字?

  • 格式未切換:LightBlue 預設可能顯示 Hex 格式。請點擊頁面右上角的格式選單,將其切換為 UTF-8-String即可正常顯示文字。

  1. 點擊 Notify 之後,ESP32 發送文字卻沒有在手機上顯示?

  • 未開啟監聽:連線進入 Notify 特徵值後,務必點擊「Listen for notification」 啟用監聽模式,否則 APP 不會接收與更新 Notify 傳來的數據。

 

六、 結語與下一篇教學

恭喜你!成功掌握了使用 ESP32 與 iPhone 進行 BLE 低功耗藍牙數據雙向傳輸的技巧。BLE 具備省電與標準化協議的優勢,是未來開發穿戴裝置、智慧家電控制與 IoT 系統的核心基石!

 

ESP32 教學系列|延伸閱讀與章節導覽

 

相關文章