M5StackでBluetooth通信をする

# M5StackのBluetooth通信の方法です

　こちらの記事をベースにして、手法を確認しています。

https://qiita.com/From_F/items/66099d488a324ad38d40

# 他の端末とデータをやり取りしたい

例えば、iOSなどのデバイスとBluetooth通信することができます。
今回はM5Stackを親機、他のデバイスを子機とするパターンです。

# 方法


### 必要なライブラリのインポート。

```
#include <M5Stack.h>
// Bluetooth LE
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
```

### Bluetooth通信に必要なプロパティを記述します
サーバーと送信用のキャラクタリスティック、
接続状態の確認Bool値、
通信のUUIDを設定しています。
uuidgeneratorというWebサイトでユニーク・ユーザー・IDを生成できます。

```
BLEServer *pServer = NULL;
BLECharacteristic * pNotifyCharacteristic; 
bool deviceConnected = false;
bool oldDeviceConnected = false;
#define LOCAL_NAME                  "myLocalName"
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID                "222c2ad6-9f59-11ec-b808-0242ac120002"
#define CHARACTERISTIC_UUID_RX      "222c2ad6-9f59-11ec-b808-0242ac120002"
#define CHARACTERISTIC_UUID_NOTIFY  "222c2ad6-9f59-11ec-b808-0242ac120002"
```

### Bluetooth通信の初期設定

接続状態のコールバック関数と、
受信した時のコールバック関数を書いてから、
通信の初期設定を行なっています。
サーバーを立てて、通信サービスを作り、送信時と受信時のキャラクタリスティックをサービスから作っています。
送信時と受信時のキャラクタリスティックに、UUIDを登録しています。
そして、通信のアドバタイズをスタートします。

```
// Bluetooth LE Change Connect State
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };

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

Bluetooth LE Recive
class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();
      if (rxValue.length() > 0) {
        String cmd = String(rxValue.c_str());
        Serial.print("Received Value: ");
        Serial.println(cmd);
      }
   }
};

// Bluetooth LE initialize
void initBLE() {
  // Create the BLE Device
  BLEDevice::init(LOCAL_NAME);

  // Create the BLE Server
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pNotifyCharacteristic = pService->createCharacteristic(
                        CHARACTERISTIC_UUID_NOTIFY,
                        BLECharacteristic::PROPERTY_NOTIFY
                        );
  
  pNotifyCharacteristic->addDescriptor(new BLE2902());

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

  pRxCharacteristic->setCallbacks(new MyCallbacks());

  // Start the service
  pService->start();

  // Start advertising
  pServer->getAdvertising()->start();
}
```

### 接続状態の確認

以下をloop()内で呼んで、コールバックで接続が変更したことが通知されていないか確認し、
接続が切れていれば再度アドバタイズしています。

```
void loopBLE() {
    // disconnecting
    if (!deviceConnected && oldDeviceConnected) {
        delay(1000); // give the bluetooth stack the chance to get things ready
        pServer->startAdvertising(); // restart advertising
        Serial.println("startAdvertising");
        oldDeviceConnected = deviceConnected;
    }
    // connecting
    if (deviceConnected && !oldDeviceConnected) {
    // do stuff here on connecting
        oldDeviceConnected = deviceConnected;
    }
}
```

以下をloop()内で呼んで、データを送信します。
StringをCharの配列にして送っています。

```
void loopSendData() {
    delay(1000);

    M5.Lcd.setCursor(0, 0); 
    
    if (deviceConnected) {
      dataString = String("hello");
      M5.Lcd.print(dataString);

      char sendMessage[5];    
      dataString.toCharArray(sendMessage, 5);      
      pNotifyCharacteristic->setValue(sendMessage);
      pNotifyCharacteristic->notify();
    }
}
```

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)