lathoub / arduino-usbmidi Goto Github PK
View Code? Open in Web Editor NEWAllows a microcontroller, with native USB capabilities, to appear as a MIDI device over USB to a connected computer
License: MIT License
Allows a microcontroller, with native USB capabilities, to appear as a MIDI device over USB to a connected computer
License: MIT License
The MIDI_DIN2USB example doesn't seem to work properly.
Versions used:
Setup (tested working using another library):
If I press a key on the MIDI keyboard, I see a message coming in in the MIDI monitor on the PC. Only the first byte is correct however:
90 00 00
80 00 00
Adding some Serial.println() statements in the onSerialMessage() method confirms that message
contains the correct channel, data1 and data2. The length attribute is 0 however. Forcing it to 3 before sending it out to MIDICoreUSB.send() results in correct MIDI note on/off messages. This won't work for messages with different lengths of course.
So I have another unusual issue. I am again using an ATmega32U4. It is connected to a PC USB port and everything works as intended until I hibernate the computer. The MIDI device keeps receiving power from the computer and begins hanging on USB sends while the computer is hibernated, and when it's powered back on it acts normal again once the Windows login screen loads. The hangs cause around 1/4 second delay before the program loop can proceed, and the pro micro's LED which lights up on a USB send stays lit the entire time the computer is hibernated.
If I comment out the USB MIDI .begin() as well as the USB sends, the computer does not keep sending power to the device when it goes into hibernation, powering the device off as it hibernates.
If I power cycle the device while the PC is hibernated, it will power on and will work as normal. After the PC is powered back on and the ATmega32U4 communicates with the computer it will hang again if the computer is hibernated (it will actually communicate for a brief time during the PC's boot sequence and as soon as the boot proceeds on, it will begin hanging for the rest of the boot until Windows comes up).
Is there a way to tell the device to only send USB data if there is an established connection to prevent the hanging?
I suggest adding MidiType:: to each of the types below to prevent ambiguities with user defined types:
static uint8_t type2cin[][2] = { {InvalidType,0}, {NoteOff,8}, {NoteOn,9}, {AfterTouchPoly,0xA}, {ControlChange,0xB}, {ProgramChange,0xC}, {AfterTouchChannel,0xD}, {PitchBend,0xE} };
static uint8_t system2cin[][2] = { {SystemExclusive,0}, {TimeCodeQuarterFrame,2}, {SongPosition,3}, {SongSelect,2}, {0,0}, {0,0}, {TuneRequest,5}, {SystemExclusiveEnd,0}, {Clock,0xF}, {0,0}, {Start,0xF}, {Continue,0xF}, {Stop,0xF}, {0,0}, {ActiveSensing,0xF}, {SystemReset,0xF} };
Hi!
I am trying to make my device show 2 different USB-MIDI ports to the computer.
Is this possible?
I am trying like this:
USBMIDI_CREATE_DEFAULT_INSTANCE()
USBMIDI_CREATE_INSTANCE(4, MIDIOUT)
and then
MIDI.begin(MIDI_CHANNEL_OMNI);
MIDI.turnThruOff();
MIDIOUT.begin(MIDI_CHANNEL_OMNI);
MIDIOUT.turnThruOff();
But I only see the first MIDI port.
In the examples I see that there is one for a Hardware MIDI and USB midi ports, but I don't see an example with 2 USB ports.
Thanks!
I 've been experimenting with this library along with the FortySevenEffects library. I was attempting to use an Arduino as a USB -> DIN midi interface so I could send DX7 patches from Dexed to a VolcaFM. It seems as if the SysexMaxSize
is not customizable in the same way that it is for say serial midi (snippet below).
I'm OK with C, but when it comes to C++ templates and macros, I get completely lost. It seems like it might be possible and my limited knowledge might be keeping me from seeing it.
Custom settings subclass and instantiation for serial midi:
struct MySettings : public midi::DefaultSerialSettings
{
static const unsigned SysExMaxSize = 1024; // Accept SysEx messages up to 1024 bytes long.
};
MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial1, MIDI_S, MySettings);
I am getting an error that I cannot resolve.
/Users/temporary/Documents/Arduino/libraries/USBMIDI/src/usbmidi_pluggableusb.cpp:13:10: fatal error: PluggableUSB.h: No such file or directory
#include <PluggableUSB.h>
I see other posts online about this issue, but nothing that has helped me, are you able to offer some clarity or a fix or workaround?
Thank you!
I did test example MIDI_DIN2USB from USB-MIDI library v1.12 with Arduino Pro Micro (Leonardo)
Sending control change B0,07,7f from PC to Arduino USB MIDI.
logging of the (modified) sketch printed out the correct bytes were received from Arduino USB,
but they were not forwarded to my MIDI device.
For testing, i was just connecting MIDI DIN out -> MIDI DIN in on my Arduino board.
(The way then would be PC -> Arduino USB -> Arduino DIN out -> Arduino DIN in -> Arduino USB -> PC)
I sended again from PC -> USB
3 times nothing was received from serial MIDI.
When sending the same control change to USB the 4th time, it got fancy:
Suddenly data was received from Serial MIDI but not the original data, (see logging below)
It was forwarded to USB and on the PC but it received b0,00,00 like hell
It did not stop to send it again and again, I had to unplug the usb cable to stop it.
All best
Uli Schmidt
here the sketch and logging:
#define VERBOSE
#include <USB-MIDI.h>
USING_NAMESPACE_MIDI;
typedef USBMIDI_NAMESPACE::usbMidiTransport __umt;
typedef MIDI_NAMESPACE::MidiInterface<__umt> __ss;
__umt usbMIDI(0); // cableNr
__ss MIDICoreUSB((__umt&)usbMIDI);
typedef Message<MIDI_NAMESPACE::DefaultSettings::SysExMaxSize> MidiMessage;
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDICoreSerial);
void setup() {
#ifdef VERBOSE
Serial.begin(115200);
#endif
MIDICoreUSB.setHandleMessage(onUsbMessage);
MIDICoreSerial.setHandleMessage(onSerialMessage);
MIDICoreUSB.begin(MIDI_CHANNEL_OMNI);
MIDICoreSerial.begin(MIDI_CHANNEL_OMNI);
// MIDICoreUSB.turnThruOff();
// MIDICoreSerial.turnThruOff();
}
void loop() {
MIDICoreUSB.read();
MIDICoreSerial.read();
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void onUsbMessage(const MidiMessage& message) {
MIDICoreSerial.send(message);
#ifdef VERBOSE
printMsg("usb ", message);
#endif
}
void onSerialMessage(const MidiMessage& message) {
MIDICoreUSB.send(message);
#ifdef VERBOSE
printMsg("ser ", message);
#endif
}
#ifdef VERBOSE
void printMsg(const char* from, const MidiMessage& message) {
Serial.print(from);
Serial.print(message.type, HEX);
switch (message.type & 0xf0) {
case 0xf0: // sysex
Serial.print(" SysEx size=");
Serial.println(message.getSysExSize());
return;
case 0xc0: // ProgramChange - 1 byte messages
case 0xd0: // AfterTouchChannel
Serial.print(" ");
Serial.print(message.data1, HEX);
break;
case 0x80: // NoteOff - 2 byte messages
case 0x90: // NoteOn
case 0xa0: // AfterTouchPoly
case 0xb0: // ControlChange
case 0xe0: // PitchBend
Serial.print(" ");
Serial.print(message.data1, HEX);
Serial.print(" ");
Serial.print(message.data2, HEX);
break;
default:
break;
}
Serial.print(" len=");
Serial.print(message.length);
Serial.print(" valid=");
Serial.print(message.valid);
Serial.print(" channel=");
Serial.println(message.channel, HEX);
}
#endif
01:18:10.615 -> usb B0 7 7F
01:18:12.436 -> usb B0 7 7F
01:18:14.015 -> usb B0 7 7F
01:18:14.015 -> ser B0 B0 B0
01:18:14.015 -> ser B0 30 30
01:18:14.015 -> ser B0 30 30
01:18:14.015 -> ser B0 30 30
01:18:14.015 -> ser B0 30 30
01:18:14.015 -> ser B0 30 30
01:18:14.015 -> ser B0 30 30
01:18:14.015 -> ser B0 30 30
......................... goes on forever!
Reproduce like this:
Install MIDI and USB-MIDI, the latter pulls in also MIDIUSB.
Load the example NoteOnOffEverySecond.
The computer connected to the MCU via USB detects MIDI device Arduino zero, but no MIDI is received, and no midi notes are received by the MCU. This example works perfectly: MIDIUSBwrite, it uses the MIDIUSB library. So I will use that library now.
Device used: SAMD21 MINI, using profile "Arduino-zero (native USB).
Hey, maybe you can take some of your time looking into my problem.
I am using an Arduino Due to receive MSC data (SysEx Messages) from the MA2 onPC Software. I only want to read this data by using the .setHandleSystemExclusive() function and not have to call MIDI.read() additionally in the loop function because i don't need to read other midi data than SysEx. The problem that occurs if i leave MIDI.read() out is that the ma2 onPC Software crashes. If the line is left in the code, everything works perfectly.
Is it really absolutely necessary to call .read() periodically to clear some buffer or something?
#include <USB-MIDI.h>
USBMIDI_CREATE_DEFAULT_INSTANCE();
void setup()
{
MIDI.begin(1);
}
void loop()
{
MIDI.read(); //If this line is left out, the program crashes
}
I would really appreciate a helpful answer and thank you for investing the time in creating this library👍
Hello, first of all thank you very much for this great work!
When I tried your “example\SysEx” on the Arduino Due platform, I found that the package was not complete.
Image below is from MIDI Monitor on macOS
And I try to use USBPcap to capture the USB port data( file below can be open by wireShark)
seems only first 3 byte transport stable
Would it be possible to make this library work with the ESP32 S2 and S3? Both support native USB.
Thanks
Does this library support to be a USBMIDI, while a other library is functioning as a HID device at once over the same USB-port?
Arduino-USBMIDI/src/USB-MIDI.h
Lines 76 to 77 in 3cc162d
mPacket.header = MAKEHEADER(cableNumber, cin);
I installed the example code "AllEvents" on my Arduino Leonardo.
Most time, I do not get the Midi-NoteOn-Message from this example on my USB-Port. I Checked it with midi-ox unter windows 10 and even unter Ubuntu.
It seems that sending a MIDI-SendRealTime message like "MIDI.sendRealTime(MidiType::Clock);" corrupts a following Midi-Message most times.
I disabled the output on serial port an still got this error.
I changed the MIDI-sendRealTime - Message from "Clock" to "Start". I get still this error.
I added a second MIDI-sendRealTime-Message in the example code. I only see the first MIDI.sendRealTime-Message in midi-ox.
I don't have a clue.
Regards Bernd
Does this library support the ATTiny85? I tried to compile the same code that runs fine on ATmega32u4, but I get the following error.
In file included from C:\Users\<user>\Documents\Arduino\libraries\USB-MIDI\src/USB-MIDI.h:26:0,
from C:\Users\<user>\Desktop\myMIDI\test_jul09a\test_jul09a.ino:10:
C:\Users\<user>\Documents\Arduino\libraries\MIDIUSB\src/MIDIUSB.h:18:2: error: #error MIDIUSB
can only be used with an USB MCU.
#error MIDIUSB can only be used with an USB MCU.
^
In file included from C:\Users\<user>\Documents\Arduino\libraries\USB-MIDI\src/USB-MIDI.h:26:0,
from C:\Users\<user>\Desktop\myMIDI\test_jul09a\test_jul09a.ino:10:
C:\Users\RDCUser\Documents\Arduino\libraries\MIDIUSB\src/MIDIUSB.h:25:26: fatal error: PluggableUSB.h:
No such file or directory
#include "PluggableUSB.h"
I have seen another project (USBMIDI) that seem to emulate MIDI over USB using the V-USB library and works for ATTiny85 and the Digispark boards. If it does not support, is it easy to make modifications to support Digispark? I am not sure if its even worth - if the performance suffers as there will be another layer in between.
Hi, I'm working in a MIDI instrument that I would like to support both serial & midi clock + messages, like any other industrial instrument.
I haven't seen any example on the whole internet, would you provide one?
Use cases:
Hey! Not really an issue as much as just a question. I'm using a Metro M0 Express, I'm wondering if theres a way to change the name that applications see when this is plugged in, currently programs see it is "Metro M0 Express" But i'm not sure where or how it see's that info and if theres a way to change it?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.