LoginSignup
5
2

More than 1 year has passed since last update.

[Unity]M5StickCとBLE通信(iOS実機/macOSエディタ

Posted at

Unity と M5StickC で BLE通信(iOS/macOSエディタ

  • Unity の iOSアプリや、mac エディタで、M5StcikC や M5Stack などと Bluetooth Low Energy で通信する事ができました
  • M5StickC から Unity に通知したり、Unity から M5StickC に書き込む事で、相互にデータを送受信する事が可能です
  • 下の動画↓では、M5StickC のボタンを押すと Unity 内の数字が増え、Unity 内のボタンを押すと M5StickC の数値が増える事を確認できます

サンプル

  • リポジトリはこちらです↓

M5StickC の実装

  • 基本的に、BLE周りの処理は M5StcikC は M5Stack と同じです
  • スケッチはこちら

設定

  • M5StickC や M5Stack は Peripheral として動かします
  • Server 名は "M5StickC" や "M5Stack" などわかりやすい名前であれば何でも良いです
  • SERVICE_UUID と CHARACTERISTIC_UUID は適当に決めます
  • 今回は、1つの Characteristic で送受信します
#define SERVICE_UUID        "FE55"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
#define SERVER_NAME         "M5StickC"

Write のコールバック

  • BLECharacteristic の getValue で書き込まれた値を取得します
class MyCallbacks: public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) {
    std::string value = pCharacteristic->getValue();
    M5.Lcd.setCursor(0, 160);
    M5.Lcd.setTextSize(5);
    M5.Lcd.println(value.c_str());
  }
};

setup ble

  • MyCallbacks をコールバックとして登録した Characteristic が追加された Service を作成し、Advertising を開始して、Unity から接続できるようにします
void setup() {
  BLEDevice::init(SERVER_NAME);
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());
  BLEService *pService = pServer->createService(SERVICE_UUID);
  pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_WRITE_NR |
                                         BLECharacteristic::PROPERTY_NOTIFY |
                                         BLECharacteristic::PROPERTY_INDICATE
                                       );
  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->addDescriptor(new BLE2902());

  pService->start();
  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();  
}

値の通知

  • ボタンが押されたら、Characteristic に値を設定し、通知します
void loop() {
  if(M5.BtnB.wasPressed()) {
    pCharacteristic->setValue(counter);
    pCharacteristic->notify();
    counter += 1;
  }
  M5.update();
}

Unity の実装

スキャンの開始

  • CoreBluetoothManager のシングルトンのインスタンスを取得します
  • poweredOn になることを確認して、スキャンを開始します
manager = CoreBluetoothManager.Shared;
manager.OnUpdateState((string state) =>
{
    Debug.Log("state: " + state);
    if (state != "poweredOn") return;
    manager.StartScan();
});

接続したいデバイス名のデバイスを見つけたら接続する

manager.OnDiscoverPeripheral((CoreBluetoothPeripheral peripheral) =>
{
    if (peripheral.name != "")
        Debug.Log("discover peripheral name: " + peripheral.name);
    if (peripheral.name != "M5StickC") return;

    manager.StopScan();
    manager.ConnectToPeripheral(peripheral);
});

デバイスに接続したらサービスを探す

manager.OnConnectPeripheral((CoreBluetoothPeripheral peripheral) =>
{
    Debug.Log("connected peripheral name: " + peripheral.name);
    peripheral.discoverServices();
});

対象の uuidの サービスが見つかったら characteristic を探す

manager.OnDiscoverService((CoreBluetoothService service) =>
{
    Debug.Log("discover service uuid: " + service.uuid);
    if (service.uuid != "FE55") return;
    service.discoverCharacteristics();
});

usage が notify の characteristic が見つかったら通知を有効にする

  • 通知を有効にすることで、M5StickC からデータを受け取ることが可能になります
manager.OnDiscoverCharacteristic((CoreBluetoothCharacteristic characteristic) =>
{
    string uuid = characteristic.uuid;
    string usage = characteristic.propertis[0];
    Debug.Log("discover characteristic uuid: " + uuid + ", usage: " + usage);
    if (usage != "notify") return;
    characteristic.setNotifyValue(true);
});

characteristic から通知があったら、データを受け取る

  • リアルタイムで受け取れるのですが、メインスレッド保証ではないです
  • そこで、一度変数に格納して、Update関数などでUIに反映させます
manager.OnUpdateValue((CoreBluetoothCharacteristic characteristic, byte[] data) =>
{
    this.value = data;
    this.flag = true;
});

Manager の動作開始

  • コールバックの設定が終わった後に、Start関数を呼ぶことで、Bluetooth機能を起動します
manager.Start();

書き込み

  • 書き込み先の characteristic に書き込みます
  • System.Text.Encoding.UTF8.GetBytes を使って、文字列からバイト配列を取得します
private int counter = 0;
public void Write()
{
    characteristic.Write(System.Text.Encoding.UTF8.GetBytes($"{counter}"));
    counter++;
}

おわりに

  • M5StickC や M5Stack と Unity が外部機器無しで通信できるようになる BLE はとても便利です
  • Swift で実装しているので、iOS実機、macエディタ向けの Native Plugin を同時に開発できました
  • エディタでも動くので、動作検証が容易になります
5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2