Electronic – arduino – ny reason why using a baud rate of 31250 on an Arduino MIDI project could cause problems

arduinobaudratemidi

I have a 600 pulse per revolution optical encoder (and some other stuff) connected to an Arduino Uno (tried it on r2 and r3) through the interrupt pins 2 and 3.

While waiting for a my MIDI jack to arrive in the mail, I tried connecting my setup to my computer through the USB-serial port, along with hairless-midi and loopMidi. Loopmidi is a virtual MIDI port, and hairless-midi bridges serial ports with MIDI ports – virtual or otherwise. I used a baud rate of 115200, because I figured it couldn't hurt to go too high. Everything seemed to work pretty well in Mixxx. Really well, actually. It seemed very responsive and accurate. The encoder didn't miss a beat, no matter how fast I span that thing.

So I was pretty excited when the MIDI jack arrived. I put it in my breadboard and changed

Serial.begin(115200);

to

Serial.begin(31250);

and tested it out in Mixxx. Now, if I spin the encoder moderately quickly in one direction, the virtual record will move in that direction and then suddenly spin the other way and then back again. I assume that the encoder is missing pulses?

I tried it in two different $6 usb-midi cables as well as in my M-Audio Fast Track Ultra.

Then I thought that maybe it had something to do with the lower baud rate (115200 vs 31250). I changed the rate to 38400 and went through USB serial. It worked great. I even tried 19200. Perfect. Even at 9600, it worked.

Why is this happening? Is the usb-serial circuitry in the Arduino, along with some free software, really more reliable than a midi cable and a $300 audio interface, even when the arduino is set to very low baud rates? Or is there something about the weird 31250 baud rate that causes problems in the Arduino?

I haven't had a chance to try to use the 31250 rate through the usb-serial, because hairless midi doesn't allow that rate.

EDIT:
Here's the relevant part of the code, and the relevant part of the circuit. There are a few other components, which might be making the problem worse, but even without those components, the optical encoder does not work at 31250.

    enum PinAssignments {
  encoderPinA = 2,   // rigth
  encoderPinB = 3,   // left
};

volatile int encoderPos = 0;  // a counter for the dial
unsigned int lastReportedPos = 0;   // change management

boolean A_set = false;              
boolean B_set = false;

void setup() {

  pinMode(encoderPinA, INPUT_PULLUP); 
  pinMode(encoderPinB, INPUT_PULLUP); 

// encoder pin on interrupt 0 (pin 2)
  attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
  attachInterrupt(1, doEncoderB, CHANGE);
    Serial.begin(31250);
}

void loop() {

 if (encoderPos != lastReportedPos){
   Serial.write(0xB0);
   Serial.write(0x27);
   Serial.write(64 + encoderPos - lastReportedPos);
   encoderPos = 0;
   lastReportedPos = encoderPos;

 }


}

// Interrupt on A changing state
void doEncoderA(){

    A_set = !A_set;

    // adjust counter + if A leads B
    if ( A_set && !B_set ) 
      encoderPos += 1;




}

// Interrupt on B changing state, same as A above
void doEncoderB(){

    B_set = !B_set;
    if( B_set && !A_set ) 
      encoderPos -= 1;

  }

the basic circuit

It's weird. Another possibility: does the weird baud rate somehow mess with the hardware interrupts?

EDIT again:
I ran mixxx in mididebug mode and span the record in one direction. This was in the log:

Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x41" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x41" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x41" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3E"
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F"
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F"
... for a while and then ...
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x41" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x41" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x41" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x41"
...
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x41" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x41" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F" 
Debug [Controller]: "MIDI status 0xB0 (ch 1, opcode 0xB), ctrl 0x27, val 0x3F"

So it goes from repeating 63 with an occasional 62 to suddenly repeating 65 with an occasional 66. A velocity of 64 means the wheel isn't moving. 63 means moving counterclockwise one pulse. 65 is clockwise one pulse . Or vice versa depending on how the thing is wired.

Does that imply that the problem is in the arduino and not in the midi adapter(s)?

Best Answer

Your baud rate is not an integer divisor of your MCU clock. The baud rate is divided from the MCU's clock. It is easy to get 9600, 19200 and other rates with an integer divisor of the clock. for example, if you have a 6.144MHz crystal, to get 19200 you need to divide by 3200.

For the odd data rates in various applications (Audio, analog video, and many others) specific crystals are used in order to get an integer divisor, for example, an NTSC circuit might have a 5.034963MHz crystal for generating the various sync signals, see

Crystal oscillator frequencies - WikiPedia

If your MCU has an internal clock generator, try adjusting it to a different value in order to get an integer divisor, otherwise, the bit error will be too high.