tttapa / Control-Surface

Arduino library for creating MIDI controllers and other MIDI devices.
GNU General Public License v3.0
1.24k stars 139 forks source link

Bluetooth issues #879

Open JeffyOLOLO opened 1 year ago

JeffyOLOLO commented 1 year ago

Hi, thanks for such powerful library/framework!

I'm building a MIDI keyboard using ESP32-S (the ESP32-Cam board) and want to use Bluetooth as an interface. But I encountered a few issues.

Testing environment:

Issues: 1) Unstable connection Phone connects to the board from the second time. I do it using Bluetooth MIDI Connect. For the first time I connect and immediately the connection disappears, on the second time it connects successfully. But sometimes I need to repeat this algorithm several times to make it work.

2) [ble2902.c:32] ble2902_get_value(): [MIDIBLE] Unexpected descriptor value length (0) error When connection is successful, there is this error in the log. But everything works, I can play notes. Sometimes it appears in the log during playing, but I couldn't find a pattern.

3) Pipes don't work The board starts, but if I try to do any action it crashes, for example: If I try to press a button, it crashes and reboots. If I try to pair to the board, it also crashes with another error and prints a dump, I can attach it if you are interested. I didn't use any other interface except the usb debug one, so probably this is only a ble problem. The log for the button case:

Program Change   Channel: 1     Data 1: 0x12
Program Change   Channel: 2     Data 1: 0x1b
[  1150][E][ble2902.c:32] ble2902_get_value(): [MIDIBLE] Unexpected descriptor value length (0)
--------- I'm pressing a button -----------
Note On          Channel: 1     Data 1: 0x44    Data 2: 0x7f
Note On          Channel: 1     Data 1: 0x48    Data 2: 0x7f
Note On          Channel: 1
assert failed: xRingbufferReceiveFromISR ringbuf.c:1146 (pxRingbuffer)

Backtrace: 0x40083c89:0x3ffbf2bc |<-CORRUPTED

ELF file SHA256: edf8265d4500a574

Rebooting...

My code: This is the code that I used to reproduce the third issue, but if you comment out usbDbgMidi and pipes code, it will be the code that I used for issues 1 and 2. I can attach PCF8574.h code as well if you think it's important.

#include <Arduino.h>
#include <Wire.h>

#include <Control_Surface.h>

// Inherits StaticSizeExtendedIOElement<8>
// It's similar to MCP23017 code, but it uses read functions instead of write ones.
#include "PCF8574.h"

constexpr ArduinoPin_t I2C_SCL_PIN = 14;
constexpr ArduinoPin_t I2C_SDA_PIN = 15;

BluetoothMIDI_Interface bleMidi;
USBDebugMIDI_Interface usbDbgMidi = 115200;
// Create a MIDI pipe factory to connect the MIDI interfaces to Control Surface
BidirectionalMIDI_PipeFactory<2> pipes;

constexpr uint8_t OCTAVE = 4;
constexpr auto CHORDS_CHANNEL  = CHANNEL_1;

PCF8574 pcf;

NoteChordButton chords[3] = {
  { pcf.pin(0), {MIDI_Notes::Db(OCTAVE), CHORDS_CHANNEL}, Chords::Major },
  { pcf.pin(1), {MIDI_Notes::Ab(OCTAVE), CHORDS_CHANNEL}, Chords::Major },
  { 16        , {MIDI_Notes::Bb(OCTAVE), CHORDS_CHANNEL}, Chords::Major },
};

void setup() {
  Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN);

  Control_Surface | pipes | usbDbgMidi;
  Control_Surface | pipes | bleMidi;
  // Set up instruments
  Control_Surface.begin();
  Control_Surface.sendProgramChange({MIDI_PC::Rock_Organ, CHORDS_CHANNEL});
}

void loop() {
  Control_Surface.loop();
}
JeffyOLOLO commented 1 year ago

I found that the Unexpected descriptor value length error also appears on any action if nothing is connected to the board via Bluetooth.

JeffyOLOLO commented 1 year ago

Note: if remove PCF8574 and Wire code, the issues are still reproducible.

tttapa commented 1 year ago

Thank you for taking the time to submit this report!

I have to admit that I haven't really kept up with the ESP32 for the past two years or so. The MIDI BLE code was written for the ESP-IDF v3.2, and the Arduino Core has since upgraded to v4.4.3, with support for new boards etc., so it wouldn't surprise me if some changes to the code are necessary.

That being said, it's not very high up on my todo list at the moment, unfortunately I have to prioritize other things right now. I can try to quickly comment on the points you raised:

  1. This is going to be the hardest one to debug, because it is intermittent and could be caused by a variety of things. The Bluetooth spec is one thing, the particular Bluetooth implementation of a specific device/app is another. If you notice anything that's wrong with Control Surface BLE implementation or if there's anything you find that makes it more stable, I'll gladly accept a pull request.
  2. The Client Characteristic Configuration attribute (2902) is a two-byte bit field. For some reason, the ble2902_get_value function seems to be called with a handle that points to an attribute of length 0, causing the Unknown descriptor value error. At first sight, this is caused by the BLE client not actually writing the attribute before Control Surface reads it. This is not an issue, so you can safely ignore the message.
  3. This is quite concerning, though. The error mentions xRingbufferReceiveFromISR, which is not a function that Control Surface itself calls directly, and I wasn't able to reproduce it on my end. Could you upload the full source code, the binary and the full stack trace? You can decode it using https://github.com/me-no-dev/EspExceptionDecoder.

I did a quick test using the main version of Control Surface, with arduino-esp32 v2.0.6 (Sparkfun ESP32 Thing), connecting to both the “MIDI BLE Connect” app on Android, and to Ubuntu 22.04. I could send and receive MIDI without issues. This is the code I used:

#include <Arduino.h>
#include <Control_Surface.h>

BluetoothMIDI_Interface bleMidi;
USBDebugMIDI_Interface usbDbgMidi = 115200;
BidirectionalMIDI_PipeFactory<2> pipes;

NoteChordButton chords[] {
  { 0, MIDI_Notes::Db(4), Chords::Major },
};

void setup() {
  Control_Surface | pipes | usbDbgMidi;
  Control_Surface | pipes | bleMidi;
  Control_Surface.begin();
}

void loop() {
  Control_Surface.loop();
}