MicroMidi / NUX-MIDI-Footswitch

BLE MIDI Footswitch Project for the NUX Mighty Plug / Mighty Air
14 stars 4 forks source link

Is it active? / Mighty Plug Pro support #2

Closed kozerskil closed 1 year ago

kozerskil commented 1 year ago

Hello, this project is really interesting, is it still under active development? Do you know if it will support NUX Mighty Plug Pro?

MicroMidi commented 1 year ago

Thanks for asking. Currently the project is not in an active development state as it works fine with the NUX Mighty Plug / Mighty Air. I'm pretty sure that NUX uses the same MIDI CC-messages for bank switching and volume adjustments for the Mighty Plug Pro as for the Mighty Plug / Mighty Air. If this assumption is right the only necessary change in the code to get the Mighty Plug Pro to work is the adjustment of the MIDI device name for a successful pairing process. Unfortunately I do not have a Mighty Plug Pro for test purposes. But if you like – just give it a try …

kozerskil commented 1 year ago

Great, thanks. Next week I should get my device so I can try

kozerskil commented 1 year ago

So I have my device, looks the advert name is "MIGHTY PLUG PRO" but I cannot connect using ESP32 neither with name nor with MAC. Any advice?

kozerskil commented 1 year ago

In the lof I can see something like:

15:31:53.670 -> Advertised Device found: Name: MIGHTY PLUG PRO
15:31:53.670 -> Found MIDI Service
15:31:53.670 -> Name error
MicroMidi commented 1 year ago

Did you adjust the definition of the MIDI device name in the code like this?:

define MIDI_DEVICE_NAME "MIGHTY PLUG PRO"

Maybe it's a good starting point for testing to use the general client example of the BLE-MIDI-library: https://github.com/lathoub/Arduino-BLE-MIDI/blob/master/examples/MidiBle_Client/MidiBle_Client.ino Does this work in your environment?

kozerskil commented 1 year ago

No, it's not working :(

Found MIDI Service
Name error
Advertised Device found: E (12783) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (12783) task_wdt:  - IDLE (CPU 0)
E (12783) task_wdt: Tasks currently running:
E (12783) task_wdt: CPU 0: nimble_host
E (12783) task_wdt: CPU 1: loopTask
E (12783) task_wdt: Aborting.

abort() was called at PC 0x400ef045 on core 0

Backtrace: 0x40083915:0x3ffbeadc |<-CORRUPTED

Do you have any advice or should I look for a help on the other project?

kozerskil commented 1 year ago

I found it's from here: https://github.com/lathoub/Arduino-BLE-MIDI/blob/master/src/hardware/BLEMIDI_Client_ESP32.h#L197

kozerskil commented 1 year ago

Ok, that was helpful. With the code: BLEMIDI_CREATE_INSTANCE("",MIDI)

That's interesting since in the log I can see:

---------CONNECTED---------
Connected to: MIGHTY PLUG PRO / [mac]

Looks like the name is the same but with BLEMIDI_CREATE_INSTANCE("MIGHTY PLUG PRO",MIDI) it didn't work.

Nevertheless, it's working now :)

MicroMidi commented 1 year ago

This is good news👍. How did you manage to solve the error - with an empty device string? I'm surprised that the device name ist "MIGHTY PLUG PRO" and not "NUX MIGHTY PLUG PRO" - similar to the other NUX devices ... May I ask what ESP32-module you use in your setup?

kozerskil commented 1 year ago

I'm using some ESP32-DevKit clone just like this one: https://botland.store/esp32-wifi-and-bt-modules/8893-esp32-wifi-bt-42-platform-with-module-5904422337438.html Regarding the name, yes, with "" I was able to connect and what I can see in the monitor is Connected to: MIGHTY PLUG PRO. My main issue was that my win10 shows different mac address of the device. When I connected using esp32 I copied the MAC it showed in the monitor and then code works fine with this value.

kozerskil commented 1 year ago

Ok, I've done some testing. Connection is working fine, I can see it on esp end (in the serial monitor), on the NUX end (APP LED is turned on), but the effect is not changing when I push button on esp and esp doesn't notice effect change on NUX. MAybe magic "49" changed? Not sure, will be digging

kozerskil commented 1 year ago

Where did you get the "49" from? I'm looking into this code https://github.com/tuntorius/mightier_amp/blob/main/lib/bluetooth/devices/communication/communication.dart and looks like PRO communication changed significantly. Or maybe you see it otherwise?

MicroMidi commented 1 year ago

The author of the Mightier-app published an Excel-Sheet with all the MIDI messages for the Mighty Plug 2 / Mighty Air. That was the starting point for my development efforts for these devices. You're right - it seems that the Mighty Plug Pro uses a complete different set of MIDI commands based on MIDI-SysEx messages. I'm not familiar with Android app development and wasn't able to find the part of code in the app source code, that defines the MIDI message format for the Mighty Plug Pro, yet. Maybe it is worth a try to ask the developer of the Mightier app to help out? I've already implemented a SysEx-message-based solution in my other footswitch projekt for the Vox ADIO amp. This code base should be easily adjustable to the Mighty Plug Pro - if we know the MIDI message formats for this device ...

kozerskil commented 1 year ago

Mightier Amp is written in dart, it's rather easy to read. I can try to go through the code and combine it with your other project

MicroMidi commented 1 year ago

I asked on facebook in the NUX Mighty Plug/Pro group for help on the MIDI commands for this device. The author of the Mightier app is also member of this group - probably he will help out ...

MicroMidi commented 1 year ago

... the author of the Mightier App responded to my question in the facebook-group: NUX provides an desktop app for the Mighty Plug Pro ("MightyEditor") and this app has a feature to list all the MIDI commands of this device. Maybe you could give it a try ... ?

kozerskil commented 1 year ago

Ok, I have it. Could you check with your device what should I be looking for? https://postimg.cc/gallery/tR9FndX

kozerskil commented 1 year ago

Ok, that works :)

      byte adioEffect[] = { 0x80, 0x80, 0xc0, CurrentEffect };
      MIDI.sendSysEx(sizeof(adioEffect), adioEffect, true);
kozerskil commented 1 year ago

The last missing puzzle is

MIDI.setHandleSystemExclusive([](byte * SysExArray, unsigned SysExSize)

For me it's not beeing called at all. Does it require any additional configuration? I've been looking into your other project and it looks pretty straighforward https://github.com/MicroMidi/VOX-Adio-Air-MIDI-Footswitch/blob/main/src/VOX-FS-MIDI-Client-GenericESP32-OLED.ino

MicroMidi commented 1 year ago

This is a callback method that will be invoked, when the Vox Amp sends Midi messages to the footswitch. This happens when an effect bank is switched at the amp or the volume knob is adjusted. This method syncronizes the display of the footswitch with the changes that are applied directly at the amp. Hope this helps ...Gesendet von meinem Smartphone

kozerskil commented 1 year ago

Yes, that's my understanding. And since Plug Pro is accepting PC with sendSysEx I was expecting I'll receive the callback call on program change directly on the Plug Pro. It doesn't happen though.

MicroMidi commented 1 year ago

... very interesting. So the effects of the MP Pro are changed with SysEx messages ...

kozerskil commented 1 year ago

Ok, I made it to have the callback called. When I change the preset on the Plug PRo, the callback is not beeing called, but when I ask from an esp about the preset it is beeing called. Here is the request:

      byte adioEffect[] = { 0x80, 0x80, 0xf0, 0x43, 0x58, 112, 12, 2, 0x80, 0xf7 };
      MIDI.sendSysEx(sizeof(adioEffect), adioEffect, true);

the values are comming from https://github.com/tuntorius/mightier_amp/blob/main/lib/bluetooth/devices/communication/plugProCommunication.dart#L110 Since I'm thinking about much simplier solution (next and prev is just enough for me) I'll probably stop my digging here. But if you'd like to do something more, I'm keen to help/test on my device.

Thank you for all your help! I was thinking to implement something like this before I found you repo and now I see that without you work and help it wouldn't be possible ;)

MicroMidi commented 1 year ago

Thanks for all your investigations and feedback - highly appreciated🙏. I'm surprised that your approach with SysEx-messages works to switch through the presets - your screenshots of the desktop app shows that a MIDI "program change" is the relevant command for that. And I guess that switching through the presets at the NUX device will also generate a MIDI "program change" message - so if you want to "catch" those messages in the ESP32-code you need to implement a "setHandleProgramChange()" callback method ... But this is all just guessing. I’m thinking about getting a MP Pro device myself to implement support for this device in my project. Probably in combination with an ESP32/S3 microcontroller that supports wireless BLE-MIDI and USB-MIDI in parallel. We’ll see if I find the time for that. If I can be at any help in your project - just let me know!

tuntorius commented 1 year ago

Mighty Plug Pro channels are set using Program Change messages. I'm not familiar with the library you're using, but I think it can't be right that you're trying to send a PC message using the sendSysEx method. There must be a specific method for PC messages.

The code from Mightier Amp you linked is for requesting the current channel, not setting it. The code for setting the channel is at line 245.

kozerskil commented 1 year ago

The code from Mightier Amp you linked is for requesting the current channel, not setting it. The code for setting the channel is at line 245.

Yes, I know. My last comment was about requesting the preset and having the callback called. To make a PC I use this:

      byte adioEffect[] = { 0x80, 0x80, 0xc0, CurrentEffect };
      MIDI.sendSysEx(sizeof(adioEffect), adioEffect, true);

and my understanding is that's what you do here: https://github.com/tuntorius/mightier_amp/blob/main/lib/bluetooth/devices/communication/plugProCommunication.dart#L246 https://github.com/tuntorius/mightier_amp/blob/main/lib/bluetooth/devices/communication/communication.dart#L101

But it's not clear for me how to send the payload. You say you are not using sendSysEx?

tuntorius commented 1 year ago

I'm not using SysEx. The setChannel method from the first link is calling createPCMessage from the second link. No SysEx is involved here. If you look a bit further at the source in the second link. There are 2 SysEx functions. None of those are called from SetChannel or CreatePCmessage functions.

Currently, your code is creating a PC message and wrapping it in a SysEx message. That won't work.

kozerskil commented 1 year ago

Ok, you are right. For some reason the old code worked as well, but now, it's working both ways with this code:

void myProgramChange(byte channel, byte program) { Serial.print("Program Change, ch="); Serial.print(channel, DEC); Serial.print(", program="); Serial.println(program, DEC); }

MicroMidi commented 1 year ago

@kozerskil and @tuntorius : Thanks so much for all your investigations on implementing support for the MP Pro in this library. Such a great community with so many talented people here at GitHub🙏. The only part that is still missing is the adjustment of the master volume. Based on the NUX documentation it seems that MIDI control change messages are used for that functionality. Is it possible to adjust the volume at the MP Pro and does the MP Pro send MIDI messages one volume change adjustments? I already created a pull request on the BLE-MIDI library that will support identifying the name of the connected MIDI device. If this functionality is incorporated in this library I will be able to determine whether the connection is established to an old NUX MP 2 or a new NUX MP Pro – and send the appropriate MIDI messages to the device. We’ll see when this will happen…

tuntorius commented 1 year ago

Unfortunately, both devices don't have proper master volume. For MP-2 there's just amp volume. MP Pro has a master volume at midi cc 73, but it's a per channel volume. It won't keep your setting it you change to another channel. Worse, it won't remember the volume of channel 1 if you change to channel 2 and then back. Even worse - this "master" volume is not tied to the physical buttons volume and also, pressing the buttons will not emit any midi messages.

I implemented master volume for the MP 2 in mightier amp, but it's fake. It simply scales down the volume of the amp.

MicroMidi commented 1 year ago

Thanks again @tuntorius for sharing your detailed knowledge of the NUX devices in this project👍. It looks that it's a relatively easy task now to adjust my code for the MP2 to support the MP Pro, too. I'll publish new the code here in this project as soon as I finished my work.

I also implemented a "fake master volume" in my code for the MP 2 when an analog effect pedal is attached: As soon as the volume pedal changes its volume level I store the respective value in a global variable. When the user changes the channel at the footswitch or at the device I apply this volume level to the new channel. This is not a real master volume functionality as the channels have very different volumes itself - based on the configured amp and gain settings. But in practice I find this volume adjustment a very useful feature as a general volume level is assured for all channels and fine tuning can be applied with the volume pedal...

MicroMidi commented 1 year ago

I published a first beta version of the code supporting the NUX Mighty Plug Pro. You will find it here: https://github.com/MicroMidi/NUX-MIDI-Footswitch/blob/main/src/beta/NUX-Pro-FS-MIDI-Client-GenericESP32-OLED.ino

All I had to do is to ...

As I don't own a Mighty Plug Pro myself it would be great if someone could test the code - thanks in advance for your support👍

kozerskil commented 1 year ago

Ok, I tested it. Program changes are working as expected. Callback is working as expected. I have no way to test volume changes. There is still an issue with initial connection, for me there is no device name I can provide here MIDI_DEVICE_NAME, it only works with empty value or MAC.

MicroMidi commented 1 year ago

Thanks for testing, @kozerskil🙏. Do you have a display attached to the ESP32-module and does the channel at the ESP32 change when you press the channel-switch button at the NUX device? If not, then this line should be modified ... https://github.com/MicroMidi/NUX-MIDI-Footswitch/blob/46e5591a8faf10cb8da6b93d6ef17fbd7a53f8c5/src/beta/NUX-Pro-FS-MIDI-Client-GenericESP32-OLED.ino#L185 ... to "CurrentEffect = Channel;"

I definitely recommend to attach an analogue volume pedal to the ESP32 module. It's a nice feature to switch the channels with the footswitch though - but without volume adjustment it almost unusable as the volume level is so different on all channels. With an attached volume pedal the volume level of the pedal is applied to the new channel, when a channel switch occurs and you can apply further fine tuning of the volume with the pedal. This works really nice - and makes the solution complete…

kozerskil commented 1 year ago

Ok, finally, after receiving all the goods from aliexpress, here is my solution: https://youtu.be/RgiLf9BnJXk Thanks @MicroMidi for your awsome work!