ARDUINO NANO 33 BLEのBLEとIMUでBLE MIDIコントローラーを作ってみよう

#概要
ARDUINO NANO 33 BLEの、**BLE**と**IMU**を使ってMIDIコントローラーを作ってみます。

今回のデモの音源は、iOSアプリの**[KORG Gadget 2 Le](https://apps.apple.com/jp/app/korg-gadget-2-le/id1092332319)**で、制御するのは、"Dublin"の**CUTOFF**(CC74)と**PEAK**(CC71)です。

ボードをX軸に倒すとCUTOFFが変わり、Y軸に倒すとPEAKが変わる、というものになります。

#なぜARDUINO NANO 33 BLE?
これまでもM5Stack, M5StickC, Micro:bitでも同じようなものを作ってきましたが、どのプラットフォームで作っても課題があったので、懲りずにこれに手を出してみました。(なお、今回、筆者が利用したのは、~SENSEです。)

#開発環境準備
ARDUINO IDEで下記をインストールしてください。

##ボードマネージャー
- Arduino nRF528x Board

##ライブラリ
- ArduinoBLE
- Arduino_LSM9DS1
- ArduinoSound(Senseのみ)
- Arduino_APDS9960(Sensのみ)
- Arduino_LPS22HB(Sensのみ)
- Arduino_LTS221(Sensのみ)

*ArduinoのHPの[Getting Started](https://www.arduino.cc/en/Guide/NANO33BLESense)には、なぜか"ArduinoBLE"をインストールする記述がないんですよね...

#ソース
```cpp:BLE_MIDI_IMU_CTRL.ino
#include <ArduinoBLE.h>
#include <Arduino_LSM9DS1.h>

 // BLE MIDI Service
BLEService midiService("03B80E5A-EDE8-4B33-A751-6CE34EC4C700");

// BLE MIDI OUT Characteristic
BLECharacteristic midiOutChar("7772E5DB-3868-4112-A1A9-F2669D106BF3",
    BLERead | BLENotify, 5);

//MIDI Buff
uint8_t midiPayload[] = {0x80, 0x80, 0xB0, 0x01, 0x64};

//CC Buff
uint8_t cc[128];

//IMU Buff
float x, y, z;
uint8_t midiX, midiY;

void setup() {
  // initialize serial communication
  Serial.begin(9600); 

  // initialize the built-in LED pin to indicate when a central is connected  
  pinMode(LED_BUILTIN, OUTPUT);

  // begin initialization
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");
    while (1);
  }

  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }

  //BLE Initialize
  BLE.setLocalName("AN33SBLE");
  BLE.setAdvertisedService(midiService);

  midiService.addCharacteristic(midiOutChar);
  BLE.addService(midiService);

  // start advertising
  Serial.println("Bluetooth device active, waiting for connections...");
  BLE.advertise();
}

void loop() {
  // wait for a BLE central
  BLEDevice central = BLE.central();

  if (central) {
    Serial.print("Connected to central: ");
    Serial.println(central.address());
    digitalWrite(LED_BUILTIN, HIGH);

    while (central.connected()) {
      if (IMU.accelerationAvailable()) {
        IMU.readAcceleration(x, y, z);

        midiX = mapAndLimit((int)(x * 1000.0), -500, 500, 0, 127);            
        midiY = mapAndLimit((int)(y * 1000.0), -500, 500, 0, 127);

        notifyCC(74, midiX, 1);            
        notifyCC(71, midiY, 1);

        delay(5);
      }
    }
    
    // when the central disconnects, turn off the LED:
    digitalWrite(LED_BUILTIN, LOW);
    Serial.print("Disconnected from central: ");
    Serial.println(central.address());
  }
}

//NotifyCC
void notifyCC(uint8_t ccNum, uint8_t midiValue, uint8_t sensitivity)
{
    if(abs(cc[ccNum] - midiValue) > sensitivity)
    {
        cc[ccNum] = midiValue;
        
        //Send Note
        midiPayload[2] = 0xb0;
        midiPayload[3] = ccNum;
        midiPayload[4] = midiValue;

        Serial.print("CC");
        Serial.print(ccNum);
        Serial.print(":");
        Serial.println(midiValue);

        //Notify MIDI Data        
        midiOutChar.writeValue(midiPayload, 5);
    }
}

//Map and Limit
uint8_t mapAndLimit(int inputValue, int fromLow, int fromHigh, int toLow, int toHigh)
{
    int tmp, minValue, maxValue;    
    
    if(toLow < toHigh)
    {
        minValue = toLow;
        maxValue = toHigh;
    }
    else
    {
        minValue = toHigh;
        maxValue = toLow;
    }
    
    tmp = inputValue - fromLow;
    tmp = (int)((double)tmp * (double)(toHigh - toLow) / (double)(fromHigh - fromLow));    
    tmp += toLow;
    tmp = tmp < minValue ? minValue : tmp;
    tmp = tmp > maxValue ? maxValue : tmp;
    
    return (uint8_t)tmp;        
}
```
これまでのプラットフォームに比べて、かなりスッキリとしたソースになりました。

#動作所感
かなりキビキビ動いてくれ、ちゃんと「楽器」として使えそうなクオリティに仕上がりました。

#問題点
##1. コンパイルが遅い
M5Stackのときもそうでしたが、結構、イライラさせられました。

##2. その他
おおっぴらに出来ない問題が一つ。その問題のため、今回、デモはありません。
(Switch Scienceが扱わないわけだ...)

#まとめ
モノとしては筋の良いプラットフォームだったんですが、諸事情により、これ以上、このプラットフォームでBLE MIDIコントローラーをいろいろ作る、というのは諦めることにしました。FacebookのArduino Communityにも、このソース公開して、海外のMAKERがいろいろ進化させてくれることを期待して、このプロジェクトは終了することにします。

次はRasberry PIかな...