M5STACK(ESP32)でBLE MIDI経由で受信してみよう！

# M5STACK(ESP32)でBLE MIDI経由を受信してみよう！

## 経緯
M5STACKでMIDIを受信してみようという人が居たんだけど、ネイティブBLE MIDIを実装せず、MQTTで実装していたので、BLE MIDIで実装してみた。

## 準備（開発環境）
Arduino IDE 1.8.5
手順は、M5Stackの公式HPにあったMac OSX向けの手順で構築した環境です。
ESP32 Arduino Coreインストール手順
```
mkdir -p ~/Documents/Arduino/hardware/espressif && \
cd ~/Documents/Arduino/hardware/espressif && \
git clone https://github.com/espressif/arduino-esp32.git esp32 && \
cd esp32 && \
git submodule update --init --recursive && \
cd tools && \
python get.py
```
## コード
```c:BLE_MIDI.ino
// M5STACK(ESP32)向け BLE MIDI
// Programed by Kazuyuki Eguchi 2018/04/24

#include <M5Stack.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

#define MIDI_SERVICE_UUID        "03b80e5a-ede8-4b33-a751-6ce34ec4c700"
#define MIDI_CHARACTERISTIC_UUID "7772e5db-3868-4112-a1a9-f2669d106bf3"
#define DEVIVE_NAME "M5"

BLEServer *pServer;
BLEAdvertising *pAdvertising;
BLECharacteristic *pCharacteristic;
int pos = 0;
char midi[5];

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      M5.Lcd.fillScreen(BLACK);
      M5.Lcd.setTextSize(1);
      M5.Lcd.setCursor(10,0);
      M5.Lcd.printf("BLE MIDI Connected.");
    };

    void onDisconnect(BLEServer* pServer) {
      M5.Lcd.fillScreen(BLACK);
      M5.Lcd.setTextSize(1);
      M5.Lcd.setCursor(10,0);
      M5.Lcd.printf("BLE MIDI Disconnect.");
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();
      pos = 0;
      
      if (rxValue.length() > 0) {
        for (int i = 0; i < rxValue.length(); i++)
        {
          Serial.printf("%02x",rxValue[i]);
          midi[pos] = rxValue[i];
          pos++;
          if(pos == 5)
          {
            M5.Lcd.fillScreen(BLACK);
            M5.Lcd.setTextSize(3);
            M5.Lcd.setCursor(10,0);
            M5.Lcd.printf("%02x %02x %02x",midi[2],midi[3],midi[4]);
            pos = 0;
          }          
        }
        Serial.println();
      }
    }
};

void setup() {
  M5.begin();
  Serial.begin(115200);
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setTextSize(1);
  M5.Lcd.setCursor(10,0);
  M5.Lcd.printf("BLE MIDI Disconnect.");

  BLEDevice::init(DEVIVE_NAME);
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());
  BLEService *pService = pServer->createService(BLEUUID(MIDI_SERVICE_UUID));
  pCharacteristic = pService->createCharacteristic(
    BLEUUID(MIDI_CHARACTERISTIC_UUID),
    BLECharacteristic::PROPERTY_READ   |
    BLECharacteristic::PROPERTY_WRITE  |
    BLECharacteristic::PROPERTY_NOTIFY |
    BLECharacteristic::PROPERTY_WRITE_NR
  );
  pCharacteristic->setCallbacks(new MyCallbacks());
  pService->start();

  BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
  oAdvertisementData.setFlags(0x04);
  oAdvertisementData.setCompleteServices(BLEUUID(MIDI_SERVICE_UUID));
  oAdvertisementData.setName(DEVIVE_NAME);
  pAdvertising = pServer->getAdvertising();
  pAdvertising->setAdvertisementData(oAdvertisementData);
  pAdvertising->start();
}

void loop() {
  delay(10);
}
```
## MIDIパッチ

自分は、microKEY AirとM5StackをMacにBLE MIDI接続して、Chromeブラウザで、下記のMIDIパッチでMIDI信号をM5に送って受信しています。

https://mikatahara.github.io/page39.html

![180424-0002.png](https://qiita-image-store.s3.amazonaws.com/0/33220/265f9e6a-d32f-3839-325b-f0bb4f2197d7.png)

## 気になること
コンパイル後のスケッチのサイズが普通の人はぎりぎり

スケッチが1301745バイトを使っています。

以上、ご参考までに