Is 3.0 a "Class-Compliant MIDI-Device"?

Status
Not open for further replies.

foam_FORM

Well-known member
I am having trouble getting my iRig to iPod controller-hack to work. I have some switches on the Teensy 3.0 sending regular MIDI (not usbMIDI) through TX (with a 220ohm resistor, 1/4 watt) but it does not seem to be read by the iRig as anything (yes, I do also have a resistor on VIN). I got the MIDI in and out lights to blink and the iPod beeped a couple of times but no incompatibility msg. or anything. Is this just not a "Class-Compliant MIDI-Device" that Apple is being precious about, or is something wrong on my code/hardware-end most-likely? I would test this on a different MIDI device to troubleshoot but need a male-to-male MIDI-cable for that...has anyone tried this or can verify that 3.0 is class-compliant?
 
I do not understand your question, perhaps due to its unusual use of specific terminology?

You mentioned using MIDI and not usbMIDI. Presumably that means you're Francois Best's library? That would be regular 31250 baud serial MIDI.

The term "class-compliant" is specific to USB MIDI implementations. USB is a very complex protocol which implements numerous abstractions, like 16 endpoints, 4 transfer types, descriptors, and many other details. Which endpoints, which transfer type, what numbers to use in the descriptors and lots of other details can be chosen any number of ways. You don't simply send multi-byte messages from an OUT port and receive them on an IN port with USB. The USB protocol is extremely flexible and quite complex, so a lot of decisions need to made about how to use its features for MIDI.

A USB MIDI implementation is called "class compliant" when it follows the specifications in the USB audio class specs, specifically the "Universal Serial Bus Device Class Definition for MIDI Devices" release 1.0 published by the USB-IF on Nov 1, 1999. Among other things, that spec requires the normal 2 and 3 byte MIDI messages packed into 32 bit fields, and lengthy sysex messages packed with 1 to 3 bytes into similar 32 bit fields, with an additional byte specifying the message type (in some cases redundantly) and a virtual cable number.

Numerous USB MIDI implementations used other (probably simpler) approaches, mostly before this spec was published and the major operating systems provided drivers. In those cases, where MIDI is not "class compliant", the way the messages are packed into USB packets, which endpoints and transfer types are used, and how the descriptors look are all at the whim of the manufacturer (who must obviously provide their own driver).

So it is meaningless to talk of "class compliant" with ordinary serial MIDI. The protocol for regular serial MIDI is very well defined. Francois's library follows that protocol very well.

Teensy's usbMIDI implementation, by the way, is indeed class compliant. I am not aware of any conformance test to prove MIDI class compliance, but I can tell you I wrote the code using the USB-IF's audio class spec and I made every attempt to follow the specification. It's been used successfully by many people with the built-in drivers on Mac, Linux and Windows, so if I made any mistakes that are not strictly class compliant, they would likely be as-yet-to-be-discovered bugs that are extremely rare.

About your project, one thing you might try is reducing those 220 ohm resistors to 47 or 56 ohms, because Teensy 3.0 uses 3.3 volt signals. You mentioned only 1 resistor, but normally transmitting is done with 2 resistors... 1 on the signal and a second connected to Vcc. If you haven't connected the other pin through a resistor to Vcc (3.3 volts on Teensy 3.0), that might also be something to check.
 
Last edited:
I am having trouble getting my iRig to iPod controller-hack to work. I have some switches on the Teensy 3.0 sending regular MIDI (not usbMIDI) through TX (with a 220ohm resistor, 1/4 watt) but it does not seem to be read by the iRig as anything (yes, I do also have a resistor on VIN). I got the MIDI in and out lights to blink and the iPod beeped a couple of times but no incompatibility msg. or anything.
The first I would try is to have the iRig powered from the microUSB while you are testing - some of these devices needs to have external power supply when used with iPod/iPhone while the iPad can provide enough juice without.
 
@PaulStoffregen- I bet the voltage/my resistors are the problem. I do have a resistor on VIN as well as TX-- and in setup I began serial at 31250. I am using MIDI library 2.6 from the "MIDI Library" section. I don't see Francois Best's name anywhere where I am (and the search function is down)-- so I am not sure if it is the same as the one you mentioned. I would think this would be the library you mentioned, however.
 
Last edited:
You can fairly easily work out what resistance is needed.

MIDI is a 5mA current loop, with an assumed voltage drop across the opto's LED of 1.7V. The receiving device will also have a 220ohm resistor in the loop.

So to work out the resistance required in the transmit circuit, it would be (Vcc-1.7)/0.005 - 220

So for 5V: (5-1.7)/0.005-220 = 440ohms, split between Tx and Vcc return.

For 3.3V operation: (3.3-1.7)/0.005-220 = 100ohms, split between Tx and Vcc return.

So 50ohms in each would be ideal, but in practice it's not that critical. 57 or whatever in each is fine.

Putting only one set of 50 in there is going to be more current, and you risk damaging the MIDI in at the other end. Don't do that.

If you don't have any 50ish ohm resistors, you can always parallel some larger resistors to get down to a lower value. 4x220ohm in parallel would give you 55ohms.
 
You can fairly easily work out what resistance is needed.

MIDI is a 5mA current loop, with an assumed voltage drop across the opto's LED of 1.7V. The receiving device will also have a 220ohm resistor in the loop.

So to work out the resistance required in the transmit circuit, it would be (Vcc-1.7)/0.005 - 220

So for 5V: (5-1.7)/0.005-220 = 440ohms, split between Tx and Vcc return.

For 3.3V operation: (3.3-1.7)/0.005-220 = 100ohms, split between Tx and Vcc return.

So 50ohms in each would be ideal, but in practice it's not that critical. 57 or whatever in each is fine.

Putting only one set of 50 in there is going to be more current, and you risk damaging the MIDI in at the other end. Don't do that.

If you don't have any 50ish ohm resistors, you can always parallel some larger resistors to get down to a lower value. 4x220ohm in parallel would give you 55ohms.

@ploveday: Yes. Read: "@PaulStoffregen- I have 5x 10ohm resistors..." I put 50ohms on BOTH, signal and VIN, yes, yes, and yes. I also went ahead and got a legit 47ohm 1/4watt resistor from radioshack and still no-go. I can get usbMIDI to work fine.

@PaulStoffregen: does the USB being connected to the CPU (for power) interfere with normal MIDI communication at all when configured with Francois Best's MIDI? I have my MIDI audio cable going into a cheap MIDI>USB adapter as well as the USB connection into another USB port (for power). I suspect the driver in this adapter could also be confusing the MIDI signals coming from Teensy..
 
You can fairly easily work out what resistance is needed.

MIDI is a 5mA current loop, with an assumed voltage drop across the opto's LED of 1.7V. The receiving device will also have a 220ohm resistor in the loop.

So to work out the resistance required in the transmit circuit, it would be (Vcc-1.7)/0.005 - 220

So for 5V: (5-1.7)/0.005-220 = 440ohms, split between Tx and Vcc return.

For 3.3V operation: (3.3-1.7)/0.005-220 = 100ohms, split between Tx and Vcc return.

So 50ohms in each would be ideal, but in practice it's not that critical. 57 or whatever in each is fine.

Putting only one set of 50 in there is going to be more current, and you risk damaging the MIDI in at the other end. Don't do that.

If you don't have any 50ish ohm resistors, you can always parallel some larger resistors to get down to a lower value. 4x220ohm in parallel would give you 55ohms.

Does it matter what the mA of my wall wort is when taking into account how many ohms I should have for the 2 resistors? I have a 600mA power supply I would like to use (4.7V) but will probably end up sticking a couple of resistors on that as well to bring it down.
 
No, not at all.

Just make sure you feed that into the Vin on the Teensy, it will regulate it down to 3.3V, and also make sure you don't use the 4.7V directly for anything interfacing to the Teensy - use the 3.3V output from its regulator (which is available on one of the pins). The Teensy 3 is not 5V tolerant, and you run a real risk of damaging it if it gets 4.7V on any of its pins.

So basically, the voltage used for MIDI will still be 3.3V (from the Teensy's regulator), so that's the value you need to use for the calculations.

Putting resistors on the incoming power supply will likely cause problems (by limiting the available current too much), so I wouldn't suggest doing that.

- Peter
 
I have now trouble-shat all of my hardware and found a good external power supply (5v and 550mA thru USB). The MIDI interface I have procured will track my Omnichord MIDI but not the 3.0. usbMIDI and blink both work fine. It could be my MIDI-jack but I am really doubting that (will troubleshoot to make sure anyway)...have you had any problems with certain code not being universal? I noticed that the older MIDI references refer to HEX a lot more than any posts I read about Teensy/Arduino. Could this code be a problem (Francois Best's)? I am using MIDI library 2.6 because 3.1.1 gives me errors when compiling.

#include <MIDI.h>

const int channel = 1;

void setup() {
MIDI.begin();
}

void loop() {
int note;
for (note=10; note <= 127; note++) {
MIDI.sendNoteOn(note, 100, channel);
delay(200);
MIDI.sendNoteOff(note, 100, channel);
}
delay(2000);
}
 
I do not understand your question, perhaps due to its unusual use of specific terminology?

You mentioned using MIDI and not usbMIDI. Presumably that means you're Francois Best's library? That would be regular 31250 baud serial MIDI.

The term "class-compliant" is specific to USB MIDI implementations. USB is a very complex protocol which implements numerous abstractions, like 16 endpoints, 4 transfer types, descriptors, and many other details. Which endpoints, which transfer type, what numbers to use in the descriptors and lots of other details can be chosen any number of ways. You don't simply send multi-byte messages from an OUT port and receive them on an IN port with USB. The USB protocol is extremely flexible and quite complex, so a lot of decisions need to made about how to use its features for MIDI.

A USB MIDI implementation is called "class compliant" when it follows the specifications in the USB audio class specs, specifically the "Universal Serial Bus Device Class Definition for MIDI Devices" release 1.0 published by the USB-IF on Nov 1, 1999. Among other things, that spec requires the normal 2 and 3 byte MIDI messages packed into 32 bit fields, and lengthy sysex messages packed with 1 to 3 bytes into similar 32 bit fields, with an additional byte specifying the message type (in some cases redundantly) and a virtual cable number.

Numerous USB MIDI implementations used other (probably simpler) approaches, mostly before this spec was published and the major operating systems provided drivers. In those cases, where MIDI is not "class compliant", the way the messages are packed into USB packets, which endpoints and transfer types are used, and how the descriptors look are all at the whim of the manufacturer (who must obviously provide their own driver).

So it is meaningless to talk of "class compliant" with ordinary serial MIDI. The protocol for regular serial MIDI is very well defined. Francois's library follows that protocol very well.

Teensy's usbMIDI implementation, by the way, is indeed class compliant. I am not aware of any conformance test to prove MIDI class compliance, but I can tell you I wrote the code using the USB-IF's audio class spec and I made every attempt to follow the specification. It's been used successfully by many people with the built-in drivers on Mac, Linux and Windows, so if I made any mistakes that are not strictly class compliant, they would likely be as-yet-to-be-discovered bugs that are extremely rare.

About your project, one thing you might try is reducing those 220 ohm resistors to 47 or 56 ohms, because Teensy 3.0 uses 3.3 volt signals. You mentioned only 1 resistor, but normally transmitting is done with 2 resistors... 1 on the signal and a second connected to Vcc. If you haven't connected the other pin through a resistor to Vcc (3.3 volts on Teensy 3.0), that might also be something to check.

@PaulStoffregen - I am using MIDI library 2.6 because 3.1.1 gives me an "error compiling" message in "Teensyduino" 1.07 (1.12 will install but never updated itself for some reason). I am fairly certain it is the library set-up (or the outdated teensyduino.exe) that is my hang-up...any insight on this? Thanks so much for putting up with us MIDI-controller noobs..
 
The latest version of the DIN MIDI library seems to be 3.2:
Code:
/*!
 *  @file        MIDI.h
 *  Project        MIDI Library
 *    @brief        MIDI Library for the Arduino
 *    Version        3.2
 *  @author        Francois Best 
 *    @date        24/02/11
 *  License        GPL Forty Seven Effects - 2011
 */
In Arduino 1.0.3+Teensyduino 1.12, with the board set to Teensy 2.0, the example program MIDI_Input suplied with that library compiles correctly. Set to Teensy 3.0, there are compilation errors as follows:
Code:
In file included from F:\Arduino\arduino-1.0.3-teensyduino112\hardware\teensy\cores\teensy3/WProgram.h:15:0,
                 from F:\Arduino\arduino-1.0.3-teensyduino112\hardware\teensy\cores\teensy3/Arduino.h:1,
                 from MIDI_Input.pde:13:
F:\Arduino\arduino-1.0.3-teensyduino112\hardware\teensy\cores\teensy3/wiring.h:89:22: error: conflicting declaration 'typedef unsigned int word'
In file included from MIDI_Input.pde:1:0:
F:\Arduino\sketches\libraries\MIDI/MIDI.h:65:18: error: 'word' has a previous declaration as 'typedef uint16_t word'

Since 'word' occurs exactly once in MIDI.h (the typedef) and not in any function declarations, simply commenting it out (line 65) allows succesful compilation with Teensy 3.0.
Code:
//typedef uint16_t word;
 
The latest version of the DIN MIDI library seems to be 3.2:
Code:
/*!
 *  @file        MIDI.h
 *  Project        MIDI Library
 *    @brief        MIDI Library for the Arduino
 *    Version        3.2
 *  @author        Francois Best 
 *    @date        24/02/11
 *  License        GPL Forty Seven Effects - 2011
 */
In Arduino 1.0.3+Teensyduino 1.12, with the board set to Teensy 2.0, the example program MIDI_Input suplied with that library compiles correctly. Set to Teensy 3.0, there are compilation errors as follows:
Code:
In file included from F:\Arduino\arduino-1.0.3-teensyduino112\hardware\teensy\cores\teensy3/WProgram.h:15:0,
                 from F:\Arduino\arduino-1.0.3-teensyduino112\hardware\teensy\cores\teensy3/Arduino.h:1,
                 from MIDI_Input.pde:13:
F:\Arduino\arduino-1.0.3-teensyduino112\hardware\teensy\cores\teensy3/wiring.h:89:22: error: conflicting declaration 'typedef unsigned int word'
In file included from MIDI_Input.pde:1:0:
F:\Arduino\sketches\libraries\MIDI/MIDI.h:65:18: error: 'word' has a previous declaration as 'typedef uint16_t word'

Since 'word' occurs exactly once in MIDI.h (the typedef) and not in any function declarations, simply commenting it out (line 65) allows succesful compilation with Teensy 3.0.
Code:
//typedef uint16_t word;

Yes! This "word" does seem to be my problem...however I am not sure how to get in and // it out. Do I need to open up the .h file with a specialized prog.? Again, very much on the noob-side here (but can learn fairly quickly).
 
OK what I did was right-click the file and hit "edit" and inserted // before typedef uint16_t word: however it is giving me a much longer error message now. Where did you find library 3.2? I was looking on the MIDI Library pjrc page...
 
OK what I did was right-click the file and hit "edit" and inserted // before typedef uint16_t word: however it is giving me a much longer error message now. Where did you find library 3.2? I was looking on the MIDI Library pjrc page...

That depends on what program started when you right clicked ;) if it was a plain text editor then fine; if it was a wordprocessor then oops.

http://playground.arduino.cc/Main/MIDILibrary
 
If you want to eliminate issues with the library for initial testing, you could always just send some MIDI events to the serial port directly, which may help isolate whether this is a hardware of software problem. The following (untested) code assumes you are using Serial1, but can be changed to 2 or 3 (depending which UART pins you have connected your MIDI out to):

Code:
void setup()
{
  Serial1.begin(31250);
}

#define NOTE_OFF 0x80
#define NOTE_ON 0x90

uint8_t channel = 1;
uint8_t vel = 100;

void loop()
{
  for (uint8_t note=10; note <= 127; note++)
  {
    Serial1.write(uint8_t(NOTE_ON + (channel-1)));
    Serial1.write(note);
    Serial1.write(vel);
    delay(200);
    Serial1.write(uint8_t(NOTE_OFF + (channel-1)));
    Serial1.write(note);
    Serial1.write(vel);
  }
  delay(2000);
}
 
I have MIDI connected to PIN 1 on 3.0...I may try pin10 after I troubleshoot the other more-likely variables..thanks again!
 
Status
Not open for further replies.
Back
Top