Coder Social home page Coder Social logo

esp32-ble-midi's People

Contributors

max22- avatar trdenton avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esp32-ble-midi's Issues

Thanks a lot

Hi,
just wanted to say thanks. This is super handy as the esp32 ist cheap and the library is easy to use. Gonna build a pedal with multiple switches to change scenes and tracks within ableton live when I practice bass guitar :)

Issue / Question with running messages

Hello and thank you for this library! I am currently working on a project where i have a code like this:

`
void onNote(uint8_t channel, uint8_t note, uint8_t velocity, uint16_t timestamp)
{
if (channel == 9) return;

buffer[note] = velocity;

}
`

It basically makes a simple map of notes played in any off the channels except drums (channel 9).

Then let's say I have a simple two track song. One track with a simple hihat running on the drum track and a second track with a simple bass.

When I solo the drums, my buffer dos not get filled, because of the condition. When my bass channel is playing solo. My buffer fills up as it supposed to. Great.

Now when BOTH of the channels play. I always get a 'bleed' from the drum channel into my buffer. The buffer note sometimes get filled by the playing hihat from the drum channel.

I am aware that there is something such as running midi messages, when the message is just 2 bytes long and so the channel stays the same. I looked into your code and presume this is handled very well in your library. I just don't know how to properly debug this. And I don't even know if this might be the issue.

Could you help in any way? Thank you.

Latency measurement

Hi, has anyone measured latency? What sort of numbers can we expect from esp32 with this library?

Docs for all commands

I understand that BLEMidiServer.noteOn(0, 69, 127) where channel=0, note=69, and velocity =127 but where are other BLEMidi commands documented? If I want to change the value of CC02 (Breath Control) for instance is there a BLEMidiServer.controlChange(0, 2, 100) [channel, controller#, value]?

Constant disconnect/reconnect cycles after resetting the device

If I pair my device via BT to my Windows 10 PC everything works fine until I power cycle my ESP32. After power cycling I get stuck in a constant loop of BT connect/disconnect which is only solved by removing a pairing the ESP32 board again.

Anyone solve this?

MMC Play does not work

Hi,
tried to get MMC messages to work with FL Studio Mobile, to no success. Sending notes works, mmc play does not.
I use WeMos D1 Mini ESP32 and FL Studio Mobile on an iPhone.

Connection problems after reconnect

After restarting the esp32 (so every time it's off power and then powered on again or when being reset) MIDIBerry, which I use for midi routing, and thus my DAW don't receive any MIDI commands anymore. They do however receive them again correctly, if i go into the windows settings and remove the BLE device and then reconnect it again. Unfortunately this would be quite inconvenient, if I'd have to reconnect the device every time it got unpowered.

Is this a thing with the library or with my code?

#include <ShiftRegister74HC595.h>
#include <BLEMidi.h>

ShiftRegister74HC595<1> sr(12, 27, 14);
int sensor;
int b1 = 25;
int b2 = 33;
int b1n = 0;
int b2n = 1;
int i = 0;

void setup() {
  BLEMidiServer.begin("Basic MIDI device");
  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
}

void loop() {
  sensor = ceil(analogRead(26) / 32.0);
  sr.set(1, !sr.get(1));
  sr.set(3, round(i / 1000.0));
  i++;
  if (i == 1000) {
    i = 0;
  }
  if (BLEMidiServer.isConnected()) {
    if (!digitalRead(b1) && !b1n) {
      BLEMidiServer.noteOn(0, 69, 127);
      b1n = 1;
    } else if (digitalRead(b1) && b1n) {
      BLEMidiServer.noteOff(0, 69, 127);
      b1n = 0;
    }
    if (!digitalRead(b2) && !b2n) {
      BLEMidiServer.noteOn(0, 67, 127);
      b2n = 1;
    } else if (digitalRead(b2) && b2n) {
      BLEMidiServer.noteOff(0, 67, 127);
      b2n = 0;
    }
  }
}

Hui Transport messages

Hallo. Gibt es eine möglichkeit aus dem hui protokoll die transport funktionen( play , stop , aufnahme ) zu empfangen und auch zu senden?

Danke

Background scan for midi server. Any interest?

I have added a background scan in BLEMidiClient. The idea is to connect immediately on turning on the instrument. Is there any interest? I have no experience with uploading on github.

Pitchbend

Hello!

Thank you for making this library and the examples are great!

I can't explain the feeling of accomplishment I got just from making it okay the midi key over to my Android phone, super cool!

Can you help me figure out how I would send pitchbend messages? I tried multiple ways with the header information files, but I couldn't get it to work.

Thanks in advance,

Marlow

Not receiving simultaneous events/polyphony

My system:
Esp32
Macbook Pro late 2015 15"

Issue happens when sending quantized midi chords from a DAW (tried with Reaper 6 and Pro Tools First) .

If the DAW send a 3 note chord, with the 3 notes starting at the exact same tick, Esp32 will recognize only 1 of the 3 note on events (the first sent from the DAW, I suppose).

The same thing applies both to simultaneous note off events or mixed note on and off events (for example, a note off event on one note happening at the same time as a note off event of other note).

This may cause stuck notes or avoid some note(s) being triggered since if a note on events is received simultaneously with a note off event, only one of them is received by ESP32.

Summing up, when multiple events are sent by the DAW simultaneously, only one is recognized and the others aren't received/recognized by ESP32.

My specific project is building a bluetooth midi receiver to control some synthetizers through my DAW wirelessly. My workaround for now is to slightly shift the midi notes so there's never 2 events happening at the same time.

Recent MacOS & iOS won't discover BLE device

Hi there!
Have been playing a lot with this library but recently found that recent MacOS and iOS devices won't discover the ESP32 BLE device at all. The same code works perfect on earlier MacOS versions (ie: High Sierra) but won't even discover the Bluetooth device in the list in Ventura. Same with an iPhone 14. On the other hand, all the Android and Windows devices tested so far work flawlessly.
Doing some research, seems to be related to a security issue, as Apple might have included a new requirement, not allowing BLE devices without encryption/authentication schemes. This is the only hint I have.
Can you help me understand if it is possible to configure the BLE connection with a PIN and/or other security parameters?
Thanks!

Client Scan Crashes ESP32

Hi Max,

Thank you so much for putting this library together.

I am looking to connect to the Yamaha BLE MIDI dongle using your library. Unfortunately, it crashes when it is looking for the BLE Device.

The Service UUID and characteristics are correct for the BLE MIDI dongle I am using.

Here is the code I used.

#include <Arduino.h>
#include <BLEMidi.h>

void setup() {
Serial.begin(115200);
while ( !Serial ) delay(200);
Serial.println();
Serial.println("Initializing BLE");

BLEMidiClient.begin("YamahaBT01"); // Device's Name looking to connect
// BLEMidiClient.enableDebugging();  // Debugging

}

void loop() {
int nDevices = BLEMidiClient.scan(); // CRASHES ESP32
if(nDevices > 0) {
Serial.print("Devices ");
Serial.println(nDevices);
}
}

I also looked at Neil's code that tries to create a server, not a client — it crashes too.

My goal is to send program change and cc control over BLE to the Yamaha dongle.

Any help is greatly appreciated.

best,
\ carlos

turnThruOff

Hello, I could not find the following function so that it does not return the incoming data. MIDI.turnThruOff();
I would appreciate help.

Request example

Hi,

Could you create example code for one potentiometer as 10 bits or 14 bits for esp32-s3 devkit c?

No application detecting the device

Hello,

I can´t get any application to recieve the signals, that I send, except for MIDIOX but that software is only used to check if any signals are recieved. But softwares like MIDIberry don´t see the input at all, while softwares like Voicemeeter and MIDI Mixer see the inputs but don´t recieve the send signals.
What am I doing wrong?

`
#include <Adafruit_MCP23X17.h>
#include <Wire.h>
#include <SPI.h>
#include <driver/adc.h>
#include <BLEMidi.h>
#include "Convert.h"

#define ADDRESS 0x20
#define REGISTER_A 0x00
#define REGISTER_B 0x01
#define OUTPUT_SET 0x00
#define BANK_A 0x12
#define BANK_B 0x13

#define SIZE 8
#define POTS_SIZE 4
#define CONTROL_CHANGE_RANGE 127
#define SENSI_POTS 15

Convert converter;
Adafruit_MCP23X17 mcp;

String ledAdr[SIZE] = {"B7", "A0", "B5", "B4", "B3", "B2", "B1", "B0"};
String btnAdr[SIZE] = {"B6", "A1", "A2", "A3", "A4", "A5", "A6", "A7"};

int leds[SIZE] = {0,0,0,0,0,0,0,0};
int buttonsOld[SIZE] = {0,0,0,0,0,0,0,0};
int buttons[SIZE] = {0,0,0,0,0,0,0,0};
boolean btnToggle[SIZE] = {true, true, true, true, false, false, false, false};

int sda_pin = 7;
int scl_pin = 6;

int[POTS_SIZE] oldValue = {0,0,0,0};
int[POTS_SIZE] value = {0,0,0,0};
int[POTS_SIZE] maxPotValue = {3500, 3500, 3500, 3500};

void setup() {
/**

  • Setup for Serial line
    */
    Serial.begin(115200);
    Serial.println("ESP32 MIDI Controller");

/**

  • Setup for GPIO Expander
    */
    Wire.setPins(sda_pin, scl_pin);
    Wire.begin();
    if(!mcp.begin_I2C(0x20, &Wire)) {
    Serial.println("Error in connecting with GPIO Expander");
    }

//Configure Pull Ups(Input)
for(int i = 0; i < SIZE; i++) {
int pos = calculateMcpPos(btnAdr[i]);
mcp.pinMode(pos, INPUT_PULLUP);
}

//Configure Pull Downs(Output) and Turn them off
for(int i = 0; i < SIZE; i++) {
int pos = calculateMcpPos(ledAdr[i]);
mcp.pinMode(pos, OUTPUT);
mcp.digitalWrite(pos, 0);
}

/**

  • Setup for ADC
    */
    adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_6);
    adc1_config_channel_atten(ADC1_CHANNEL_1, ADC_ATTEN_DB_6);
    adc1_config_channel_atten(ADC1_CHANNEL_2, ADC_ATTEN_DB_6);
    adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_6);

/**

  • Setup for MIDI over Bluetooth
    /
    Serial.println("Initializing bluetooth");
    BLEMidiServer.begin("Basic MIDI device");
    Serial.println("Waiting for connections...");
    /

    while(!BLEMidiServer.isConnected()) {
    Serial.println("Waiting for connections...");
    delay(1000);
    }
    Serial.println("Connected!");
    */
    }

void loop() {
if(BLEMidiServer.isConnected()) {
midiChecker();
}

updater();
checker();
}

void updater() {
for(int i = 0; i < SIZE; i++) {
buttonsOld[i] = buttons[i];
}

updateButtonStates();
updateLedStates();
}

void checker() {
checkButtonsAndUpdateLeds();
}

void midiChecker() {
checkPotsAndSendMIDI();
}

/**

  • BUTTON LOGIC
    */
    void checkButtonsAndUpdateLeds() {
    for(int i = 0; i < SIZE; i++) {
    boolean released = buttonReleased(i);
    boolean pressed = buttonPressed(i);
    boolean toggleBtn = btnToggle[i];

    if(toggleBtn && released) {
    toggleLed(i);
    }
    else if(!toggleBtn && released) {
    turnLedOff(i);
    }
    else if(!toggleBtn && pressed) {
    turnLedOn(i);
    }
    }
    }

boolean buttonReleased(int num) {
if(buttonsOld[num] == 1 && buttons[num] == 0) {
return true;
}
else {
return false;
}
}

boolean buttonPressed(int num) {
if(buttonsOld[num] == 0 && buttons[num] == 1) {
return true;
}
else {
return false;
}
}

void updateButtonStates() {
for(int i = 0; i < SIZE; i++) {
String curAdr = btnAdr[i];
int pos = calculateMcpPos(curAdr);;

if(!mcp.digitalRead(pos)) {
  buttons[i] = 1;
}
else {
  buttons[i] = 0;
}

}
}

/**

  • LED LOGIC
    */
    void toggleLed(int num) {
    int cur = leds[num];
    if(cur == 0) {
    leds[num] = 1;
    sendMIDIon(num);
    }
    else {
    leds[num] = 0;
    sendMIDIoff(num);
    }

updateLedStates();
}

void turnLedOn(int num) {
leds[num] = 1;
sendMIDIon(num);
updateLedStates();
}

void turnLedOff(int num) {
leds[num] = 0;
sendMIDIoff(num);
updateLedStates();
}

void updateLedStates() {
for(int i = 0; i < SIZE; i++) {
String curAdr = ledAdr[i];
int pos = calculateMcpPos(curAdr);

mcp.digitalWrite(pos, leds[i]);

}
}

/**

  • MIDI LOGIC
    */
    void checkPotsAndSendMIDI() {
    //Update Values
    for(int i = 0; i < SIZE_POTS; i++) {
    oldValue[i] = value[i];
    }
    value[0] = adc1_get_raw(ADC1_CHANNEL_0);
    value[1] = adc1_get_raw(ADC1_CHANNEL_1);
    value[2] = adc1_get_raw(ADC1_CHANNEL_2);
    value[3] = adc1_get_raw(ADC1_CHANNEL_3);

//Check for changes and send MIDI accordingly
for(int i = 0; i < SIZE_POTS; i++) {
if((oldValue[i] - value[i]) > SENSI_POTS) {
sendMIDIPots(i);
}
}
}

void sendMIDIPots(int num) {
if(BLEMidiServer.isConnected()) {
Serial.println("SENDED CONTROL");
BLEMidiServer.controlChange(0, (77 + num), mapPotValueToMIDI(value[i]));
}
}

double mapPotValueToMIDI(int curValue) {
double divider = (double)CONTROL_CHANGE_RANGE / (double)curValue;
return (double)curValue * divider;
}

void sendMIDIon(int num) {
if(BLEMidiServer.isConnected()) {
BLEMidiServer.noteOn(0, (69 + num), 127);
}
}

void sendMIDIoff(int num) {
if(BLEMidiServer.isConnected()) {
BLEMidiServer.noteOff(0, (69 + num), 127);
}
}

/**

  • OTHER LOGIC
    */
    int calculateMcpPos(String adr) {
    int pos = 0;

if(adr.charAt(0) == 'B') {
pos += 8;
}
pos += adr.charAt(1) - '0';;

return pos;
}

String generateBinaryFromLedStates() {
String binary = "";
for(int i = 0; i < SIZE; i++) {
binary += String(leds[i]);
}

return binary;
}

int binaryToHex(char *binary) {
int decimal = converter.binaryToDecimal(binary);
String hex = converter.decimalToHexa(decimal);
return hex.toInt();
}
`

Concurrently connect to two devices

Is there a way to connect with both a server and a client, and filter their commands.
When I tried only one of the connections was active.

I am trying to add a neopixel strip to my midi piano and use it with Synthesia.

Anyway, thank you for this library.

MIDI host via USB?

Apologies if I'm misinterpreting the usage of this package, but I have a Casio Privia PX-770 that has a type B USB class compliant port that typically can be plugged into a MIDI host for MIDI usage (e.g. iPad or Mac/PC software). What I'm trying to do is see if the Casio type B USB can be plugged into a ESP32, which can then be used to transmit MIDI over BLE to a host (e.g. iPad or Mac/PC). So type B USB <> micro USB on ESP32, then BLE wirelessly to host.

Is this possible? Thanks in advance.

Crashing after update

After I updated bordmanager and library, my ESP32S3 keeps crashing when starting the server („ BLEMidiServer.begin("Basic MIDI device");“).

Callbacks are never called

Hello Maxime.
Using your example code 04-Dump-Messages.ino with an ESP32 az-delivery-devkit-v4 board I found the following:
1: Callbacks for connect and disconnect were never called.
2: The board freezes on disconnect, ie it refuses to establish another connection.

I have fixed my problem by defining the callbacks before calling .begin()
I also added a restart command to the disconnect callback. At least it can be used as a temporary solution.

I hope you find this useful. Thanks for sharing your code.
Example shown below.
Best regards
Kim

void setup() {
Serial.begin(115200);
BLEMidiServer.setOnConnectCallback( {
Serial.println("Connected");
});
BLEMidiServer.setOnDisconnectCallback( {
Serial.println("Disconnected");
ESP.restart();
});
BLEMidiServer.begin("MIDI device");
BLEMidiServer.setNoteOnCallback(onNoteOn);
........

No succesful connection in Client mode

Hi Max22.

I try to connect a ESP32 pico in client mode to a Roland AX-edge (a MIDI keyboard with syntetizer and Bluetooth LE v4.1) like server.

I run the example code of clientBLE and ESP32 shows by Serial (debug enabled) that it is connected to AX-Edge but AX-Edge does not notify any comunication with ESP32. I can notice that because when AX-edge has a succesful connection, the Bluetooth icon changes into black background, and this does not happen when I try to connect with ESP32. I haven't had any problem of connection when I try to connect to AX-Edge with tablets, smartphones or pc windows, only with ESP32 and this library.

If I modify slightly the example code by adding a noteOn callback and I try to send any note from AX-edge to ESP32, there is no response. Only callbaks of connect and disconnect events work.

I checked the UUID services and characteristics of this library and they are OK with Midi BLE definiction and they are the same as AX-Edge UUID.

I have doubts whether the library really notifies its characterists to an external device or something else regarding notificating back to the external device to acomplish the comunication.

I cannot offer you any debug from AX-edge because I cannot take any log or debug feedback from the device.

Can you help me please?

Thank you for your help and for the library.

make BLEMidiServer.sendMessage() public

Please make the BLEMidiServer.sendMessage() method public, so we can send messages like this:

uint8_t midiMessage[] = {
    0xF0, // sysex
    0x00,
    0x21,
    0x3C,
    0x00,
    0x10,
    0x33,
    0x60,
    0x5A,
    0x00,
    0x7F,
    0xF7 // end of sysex
};
BLEMidiServer.sendMessage(midiMessage, sizeof(midiMessage));

ble connect and disconnect problem

Even after the newer update, the code gets stuck and the ble device doesn't show up.
Had to reset the board every time, I encounter this bug

Wish to subscribe to "subscription" events.

I am using MIDIServer to allow my Mac laptop, my iPad or iPhone to connect to my ESP32 device. Your library is WONDERFUL for this, by the way,..

In all cases I can see an unsubscribe event happen (I enabled debugging inside the Nimble library) when I disconnect from within the computer/mobile app.

But I don't receive a disconnect event unless I actually turn off bluetooth on the device.

Because of this, I think that I need to have the ability to be notified of the "subscribe" events inside Nimble so that I can close the bluetooth connection from the ESP device side when the client unsubscribes. Unless I am mistaken, you are not passing those up thru your library so that I can subscribe to them.

Any assistance or advice would be appreciated. I want the ESP32 device to recognize when it is no longer being used so that it can again advertise to receive new connections.

thank you!
Carl Lance

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.