M5Stack과 iOS 단말기와 통신해 보았습니다.

이번 목표



M5Stack과 iPhone 사이에서 Bluetooth LE 통신.
이번 만드는 프로젝트는 아래와 같다.
  • M5Stack 버튼을 누르면 LCD가 빨간색, 노란색, 파란색으로 바뀝니다.
  • iPhone도 똑같이 3 색의 버튼을 붙이고 버튼을 누르면 색이 바뀐다
  • BluetoothLE로 상호 접속해, M5Stack로 색을 변화시키면 연동해 iPhone의 화면도 바뀐다. 그 반대도 가능합니다

  • 라는 느낌입니다.

    소스는 Github에 게시됩니다.



    BluetoothLE의 기초 지식



    간단하지만 BluetoothLE에서는 다음을 이해해 두면 편리합니다.
  • 장치의 역할로 주변 장치와 중앙이 있습니다
  • 주변 장치는 발신하는 쪽 → 부모기
  • 센트럴은, 진찰하는 측→자기기
  • GATT → 통신의 기반이되는 프로파일
  • write, read, notify의 3개가 있다
  • write는 중앙 → 주변 장치로 데이터를 전달합니다.
  • read는 센트럴 → 주변기기에 읽기 데이터를 요구한다
  • notify는 주변 장치 → 중앙에 통지합니다

  • BluetoothLE 서비스 UUID 얻기



    Online UUID Generator 으로 세 개의 UUID를 만듭니다.
    Bulk Version 1 UUID Generation에서 How Many?를 3으로 입력하여 GENERATE합니다.

    생성된 3개의 UUID는 나중에 사용하므로 삼가해 주십시오. (빨강 테두리)

    M5Stack의 BluetoothLE 주변 해설



    이번에는 M5Stack을 주변 장치로, write와 notify를 사용합니다.
    우선 UUID를 3개 정의합니다.
  • 서비스 UUID → write와 notify를 사용할 수 있다고 iPhone에 알리는 데 사용합니다.
  • write→iPhone에서 데이터를 진찰하는 데 사용합니다.
  • notify → iPhone에 데이터를 보내는 데 사용합니다.
  • setup() 때로 초기화하는데 필요한 initBLE() 에 정리하고 있습니다.loop() 에서 필요한 처리는 loopBLE() 에 정리하고 있습니다.

    버튼을 눌렀을 때 loopLCDcolor() 안에 구현되어 있는 아래 코드로 iPhone에 데이터를 전송하고 있습니다.
    if (deviceConnected) {
      char sendMessage[10];
      lastColor.toCharArray(sendMessage, 10);
      pNotifyCharacteristic->setValue(sendMessage);
      pNotifyCharacteristic->notify();
    }
    

    iOS 앱 측 구현



    먼저 M5Stack을 검색하기 위해 주변 스캔을 수행합니다.
    먼저 CoreBluetooth의 CentralManager 인스턴스를 가져옵니다.
    centralManager = CBCentralManager(delegate: self, queue: nil, options: nil)
    

    Bluetooth 장치의 전원 등을 켜면 func centralManagerDidUpdateState(_ central: CBCentralManager) 가 불립니다.central.state.poweredOn이면 주변 장치 스캔을 시작합니다.
    centralManager.scanForPeripherals(withServices: nil, options: nil)
    

    주변 장치를 발견하면 func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) 가 호출됩니다.
    M5Stack에서 설정한 로컬 이름과 일치하는지 확인하고 함께 있으면 주변 스캔을 중지하고 주변 장치와 연결합니다.
    centralManager.stopScan()
    centralManager.connect(connectToPeripheral, options: nil)
    

    주변 장치를 연결하면 func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral)를 호출하므로 해당 서비스를 검색합니다.
    connectToPeripheral.delegate = self
    connectToPeripheral.discoverServices(nil)
    

    서비스를 얻을 수 있으면 func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) 라고 합니다. 1 서비스마다 불립니다.

    서비스가 notify이면 M5Stack에서 데이터가 전송되므로 대기합니다.
    connectToPeripheral.setNotifyValue(true, for: characteristic)
    

    실제로 M5Stack에서 데이터가 전송되면 func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?)가 호출됩니다.

    마지막으로



    베타 쓰기 코드로 부끄럽지만, M5Stack(ESP32에도 사용할 수 있다)와 iOS 디바이스로 BluetoothLE 통신하고 있는 샘플이 좀처럼 찾기 어려우므로 참고가 된다고 생각합니다.

    좋은 웹페이지 즐겨찾기