Skip to main content
2 of 3
Added a diagram and code.
The Phil Lee
  • 201
  • 1
  • 2
  • 5

Is there any reason why using a baud rate of 31250 on an Arduino MIDI project could cause problems?

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?

The Phil Lee
  • 201
  • 1
  • 2
  • 5