11.Bluetooth low energy (BLE) serial port pass-through

พอร์ตอนุกรม Bluetooth Low Energy (BLE, Bluetooth Low Energy) ใช้กันอย่างแพร่หลาย บนแพลตฟอร์ม iOS ของ Apple Classic Bluetooth ต้องมีใบรับรอง MFi เพื่อเชื่อมต่อกับอุปกรณ์ iOS ของ Apple อุปกรณ์บลูทูธพลังงานต่ำไม่มีข้อจำกัดนี้

โปรโตคอลสแต็คและหลักการของบลูทูธพลังงานต่ำจะไม่ถูกทำซ้ำที่นี่ มีบทความและวิดีโอที่เกี่ยวข้องมากมาย กล่าวโดยย่อ บริการบลูทูธมีให้ในรูปแบบของโปรไฟล์ และมีอักขระ N ตัวที่มี ID อิสระ (UUID) อยู่ใต้โปรไฟล์ของแต่ละบริการ อักขระแต่ละตัวมีสิทธิ์ต่างกัน (อ่าน เขียน แจ้ง ระบุ) หลังจากที่ผู้ใช้กำหนดอักขระและรวมเข้ากับสิทธิ์แล้ว ก็สามารถให้บริการที่สมบูรณ์ได้

BLE pass-through คืออะไร คือเพื่อสร้างบริการ BLE และมีอักขระ 2 ตัวอยู่ใต้โปรไฟล์นี้

#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

หนึ่งอันสำหรับ TX (ส่งข้อมูล) และอีกอันสำหรับ RX (รับข้อมูล) สำหรับสิ่งนี้พวกเขามีสิทธิ์ต่างกัน รหัสต่อไปนี้คือการสร้างบริการและอักขระใหม่:

  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);
  
  // Create a BLE Characteristic
  pTxCharacteristic = pService->createCharacteristic(
										CHARACTERISTIC_UUID_TX,
										BLECharacteristic::PROPERTY_NOTIFY
									);
                      
  pTxCharacteristic->addDescriptor(new BLE2902());

  BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
											 CHARACTERISTIC_UUID_RX,
											BLECharacteristic::PROPERTY_WRITE
										);

ถัดไปคือฟังก์ชันการเรียกกลับสองฟังก์ชัน ซึ่งจะดำเนินการเมื่อมีการเชื่อมต่อและเมื่อมีการเขียนอักขระ RX:

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();

      if (rxValue.length() > 0) {
        Serial.println("*********");
        Serial.print("Received Value: ");
        for (int i = 0; i < rxValue.length(); i++)
          Serial.print(rxValue[i]);

        Serial.println();
        Serial.println("*********");
      }
    }
};

สุดท้าย ลูปหลักคือตัวควบคุมการเชื่อมต่อ ซึ่งจะกำหนดว่ามีการเชื่อมต่อหรือไม่และขาดการเชื่อมต่อหรือไม่

    if (deviceConnected) {
        pTxCharacteristic->setValue(&txValue, 1);
        pTxCharacteristic->notify();
        txValue++;
		    delay(10); // bluetooth stack will go into congestion, if too many packets are sent
	  }
    
    // disconnecting
    if (!deviceConnected && oldDeviceConnected) {
        delay(500); // give the bluetooth stack the chance to get things ready
        pServer->startAdvertising(); // restart advertising
        Serial.println("start advertising");
        oldDeviceConnected = deviceConnected;
    }
    // connecting
    if (deviceConnected && !oldDeviceConnected) {
		// do stuff here on connecting
        oldDeviceConnected = deviceConnected;
    }

สำหรับโค้ดที่สมบูรณ์ ดูตัวอย่างไลบรารีอย่างเป็นทางการ: ble_uart และเครื่องมือดีบั๊กสามารถใช้ LightBlue ได้

Last updated