BLE MIDI randomly disconnects and only works on Linux

PieterP
Posts: 4
Joined: Tue Aug 14, 2018 5:44 pm

BLE MIDI randomly disconnects and only works on Linux

Postby PieterP » Tue Aug 14, 2018 6:43 pm

Hi, I'm trying to use Bluetooth Low Energy to send and receive MIDI messages.

There are 2 main problems:

1. On Linux (using BlueZ 5.50), it works, and the MIDI events show up in my MIDI monitor. However, after some time (ranging from a couple of seconds to many minutes), it randomly disconnects, and doesn't automatically connect again. I have no idea why this is.

2. On Windows 10, I can connect to the ESP32, but even though it says "connected" in the Windows settings, but in the Serial Monitor, it says "Disconnected" 2 or three seconds after "Connected".
Between the "Connected" and "Disconnected", the "notify" fails, because "notifications disabled; ignoring".

On Android, I can see it using the Bluetooth settings, and I can pair, but I can't do anything with it. It doesn't show up when scanning using the MIDI BLE Connect app.
[hr]
I'm using this example and Neil Kolban's BLE library that comes with the ESP32 Arduino Core:

Code: Select all

/*
    BLE_MIDI Example by neilbags 
    https://github.com/neilbags/arduino-esp32-BLE-MIDI
    
    Based on BLE_notify example by Evandro Copercini.

    Creates a BLE MIDI service and characteristic.
    Once a client subscibes, send a MIDI message every 2 seconds
*/

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

#define SERVICE_UUID        "03b80e5a-ede8-4b33-a751-6ce34ec4c700"
#define CHARACTERISTIC_UUID "7772e5db-3868-4112-a1a9-f2669d106bf3"

BLECharacteristic *pCharacteristic;
bool deviceConnected = false;

uint8_t midiPacket[] = {
   0x80,  // header
   0x80,  // timestamp, not implemented 
   0x00,  // status
   0x3c,  // 0x3c == 60 == middle c
   0x00   // velocity
};

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      Serial.println("Connected ++++++++++++++++++++++++++");
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      Serial.println("Disconnected -----------------------");
    }
};

void setup() {
  Serial.begin(115200);

  BLEDevice::init("ESP32 MIDI Example");
    
  // Create the BLE Server
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

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

  // Create a BLE Characteristic
  pCharacteristic = pService->createCharacteristic(
    BLEUUID(CHARACTERISTIC_UUID),
    BLECharacteristic::PROPERTY_READ   |
    BLECharacteristic::PROPERTY_WRITE  |
    BLECharacteristic::PROPERTY_NOTIFY |
    BLECharacteristic::PROPERTY_WRITE_NR
  );

  // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
  // Create a BLE Descriptor
  pCharacteristic->addDescriptor(new BLE2902());

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

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

void loop() {
  if (deviceConnected) {
   // note down
   midiPacket[2] = 0x90; // note down, channel 0
   midiPacket[4] = 127;  // velocity
   pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes
   pCharacteristic->notify();

   // play note for 500ms
   delay(500);

   // note up
   midiPacket[2] = 0x80; // note up, channel 0
   midiPacket[4] = 0;    // velocity
   pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes)
   pCharacteristic->notify();

   delay(500);
  }
}
I added the debug output and a WireShark capture as attachments. (I only have a capture on Linux, Bluetooth capture is not supported on Windows, AFAIK.)

I have no idea how to debug this, so any help or pointers would be greatly appreciated.

Thanks,
Pieter
Attachments
ESP32-BLE-MIDI-Disconnect-Debug-Output-Windows10.txt
The verbose output in the Serial Monitor when trying to pair and connect on Windows 10.
(20.54 KiB) Downloaded 815 times
ESP32-BLE-MIDI-Disconnect-Debug-Output-Linux.txt
The verbose output in the Serial Monitor when pairing and connecting and sending MIDI on Linux.
(18.3 KiB) Downloaded 758 times
ESP32-BLE-MIDI-Disconnect-Linux.pcapng.zip
The WireShark capture for the same run as the verbose text output on Linux.
(2.88 KiB) Downloaded 460 times

chegewara
Posts: 2364
Joined: Wed Jun 14, 2017 9:00 pm

Re: BLE MIDI randomly disconnects and only works on Linux

Postby chegewara » Wed Aug 15, 2018 12:49 pm

For android i prefer this one:
https://play.google.com/store/apps/deta ... dsynthmidi

On esp32 try this, it works on windows and android for me:
https://github.com/nkolban/esp32-snippets/issues/510

PieterP
Posts: 4
Joined: Tue Aug 14, 2018 5:44 pm

Re: BLE MIDI randomly disconnects and only works on Linux

Postby PieterP » Wed Aug 15, 2018 9:38 pm

Hi, thank you for your response.

I tried the first sketch in that GitHub issue, but it doesn't work for me. Windows behaves the same (Windows says connected, ESP says "notifications are disabled", ESP says disconnected, Windows still says connected). Fluidsynth on Android finds the ESP, and it shows up as "MIDI", it says "Port opened OK", but it doens't play anything, I tried an Android MIDI monitor as well, it sees the MIDI device (created by Fluidsynth), but no MIDI events are reported.
Linux is not happy with the security options, it gives errors in dmesg when I connect to it:

Code: Select all

[  +0,089796] Bluetooth: hci0: security requested but not available

Garageband on iOS also sees the device, but I can't connect to it.

I haven't been able to compile the second sketch. Is this for the Arduino environment, or do I need to compile it using ESP-IDF?

chegewara
Posts: 2364
Joined: Wed Jun 14, 2017 9:00 pm

Re: BLE MIDI randomly disconnects and only works on Linux

Postby chegewara » Thu Aug 16, 2018 5:15 am

Second one is for esp-idf, but you can reuse only part of code in first listing. Try to copy/paste part of code that is about secured connection. You can also see how it looks like in this repository for arduino (secured connection).

PieterP
Posts: 4
Joined: Tue Aug 14, 2018 5:44 pm

Re: BLE MIDI randomly disconnects and only works on Linux

Postby PieterP » Thu Aug 16, 2018 9:58 am

I tried using the setup part of the second program in the first one. This is what I ended up with:

Code: Select all

/*
  Based on:
    BLE_MIDI Example by neilbags
    https://github.com/neilbags/arduino-esp32-BLE-MIDI

    Based on BLE_notify example by Evandro Copercini.

    Creates a BLE MIDI service and characteristic.
    Once a client subscibes, send a MIDI message every 2 seconds
*/

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

uint8_t note = 64;

BLECharacteristic *pCharacteristic;
bool deviceConnected = false;

uint8_t midiPacket[] = {
  0x80,  // header
  0x80,  // timestamp, not implemented
  0x00,  // status
  0x3c,  // 0x3c == 60 == middle c
  0x00   // velocity
};

class MyCallbacks: public BLEServerCallbacks, public BLECharacteristicCallbacks {
    void onConnect(BLEServer* pServer) override {
      deviceConnected = true;
      Serial.println("Connected!");
    };

    void onDisconnect(BLEServer* pServer) override {
      deviceConnected = false;
      Serial.println("Disonnected!");
    }

    void onWrite(BLECharacteristic* pChar) override {
      std::string value = pChar->getValue();
      const uint8_t * const data = reinterpret_cast<const uint8_t * const>(value.data());
      size_t len = value.size();
      Serial.print("Write: ");
      for (size_t i = 0; i < len; i++)
        Serial.printf("%02x ", data[i]);
      Serial.println();
    }

    void onRead(BLECharacteristic* pChar) override {
      Serial.println("Read");
      pChar->setValue("");
    }
};

void setup() {
  Serial.begin(115200);

  static MyCallbacks cb;

  BLEDevice::init("TEST");
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(&cb);

  BLEService* pService = pServer->createService("03b80e5a-ede8-4b33-a751-6ce34ec4c700");
  pCharacteristic = pService->createCharacteristic("7772e5db-3868-4112-a1a9-f2669d106bf3",
                                                    BLECharacteristic::PROPERTY_READ   |
                                                    BLECharacteristic::PROPERTY_NOTIFY |
                                                    BLECharacteristic::PROPERTY_WRITE_NR
                                                  );

  pCharacteristic->setCallbacks(&cb);

  pCharacteristic->addDescriptor(new BLE2902());
  pService->start();


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


  BLESecurity *pSecurity = new BLESecurity();
  pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_BOND);

  ESP_LOGD(LOG_TAG, "Advertising started!");
}

void loop() {
  if (deviceConnected) {

    note = note + random(-5, 5);
    note &= 0x7F;
    
    // note down
    midiPacket[2] = 0x90; // note down, channel 0
    midiPacket[3] = note;
    midiPacket[4] = 127;  // velocity
    pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes
    pCharacteristic->notify();
    // play note for 500ms
    delay(500);

    // note up
    midiPacket[2] = 0x80; // note up, channel 0
    midiPacket[3] = note;
    midiPacket[4] = 0;    // velocity
    pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes)
    pCharacteristic->notify();

    delay(500);
  }
}
  • Ubuntu Linux 16.04 (BlueZ 5.50): still works, still plays the notes, but also still disconnects after a short period of time
  • iOS 11.4.1: can connect to the ESP using Garageband, and it plays the notes. No disconnects encountered yet.
  • Android 8.1.0: can connect to it using Fluidsynth and it plays the notes, but once it disconnects, I cannot connect to it again, and I have to reboot my phone.
  • Windows 10 (1803) : still the same problem as described in my first post: it connects and immediately disconnects, but still says "connected" in the Windows settings.
I'll try a different Windows and Linux machine to see if it has the same problems.

How did you test it under Windows? How did you connect it? What MIDI software did you use?

Thank you.

PieterP
Posts: 4
Joined: Tue Aug 14, 2018 5:44 pm

Re: BLE MIDI randomly disconnects and only works on Linux

Postby PieterP » Tue Aug 21, 2018 8:13 am

Any ideas? How can I debug problems like this?

chegewara
Posts: 2364
Joined: Wed Jun 14, 2017 9:00 pm

Re: BLE MIDI randomly disconnects and only works on Linux

Postby chegewara » Tue Aug 21, 2018 5:12 pm

I dont know what to say. Your code perfectly works on my samsung s9+ with android 8.0. Fluidsynth connects as many times as i want without issues.

On windows ive been using MIDIberry. Also, your code tested and works fine. Windows 10 pro. More, windows auto-reconnect because devices are paired.

Who is online

Users browsing this forum: Google [Bot] and 41 guests