latency probelms on windows 10 with Micro Pro

Hi there,

I have built a midi foot-switch with 9 buttons ( -> many thanks for Grumpy_Mike for helping developing the code, this topic: http://forum.arduino.cc/index.php?topic=378142.0 ) and a Micro Pro like that one: https://www.sparkfun.com/products/12640

The problem is that I get a lot of latency with that device other than with my usb midi keyboard for example. I am running Windows 10 64bit on this computer with a Focusrite Scarlett 2i4 audio interface. Usually the latency from the MIDI IN of it and the external keyboard is really low.

But with my DIY midi controller the latency is just really big, making it not usable at the moment. I use Cakewalk Sonar Platinum as my DAW, but I don't think it is an issue with that program, as it deals with every other usb midi controller very well.

So I usually start LoopMidi and there a new port, then start Hairless Midi and connect it MIDI IN and MIDI Out there to the Loop Midi port. Then I just have to choose that Loopmidi in my DAW, and everything works as it should, except the latency.

Does anyone have an idea about how this could possibly be fixed? I really tried to find an answer on the internet, but with no success yet.

Thank you already!

Post your program.

What latency are you experiencing and what would be acceptable?

...R

Oh sorry, I forgot the code, so here it is:

// simple switch MIDI trigger
boolean buttonLast[9];
const byte switchPin[] = {2,3,4,5,6,7,8,9,10}; // the 9 pins to use
const byte noteToSend [] = {36,38,40,41,43,45,47,48,50}; // notes to play for each pin
boolean button;

void setup() {
 Serial.begin(115200); // Using Hairless at the default speed
 for(int i=0; i< 10; i++){
 pinMode(switchPin[i], INPUT_PULLUP);
 buttonLast[i] = HIGH; // assume button not pressed at start
 }
}

void loop(){
  for(int i =0; i<9; i++){
   button = digitalRead(switchPin[i]);
    if (button == HIGH && buttonLast[i] == LOW) {
      sendNote(144,noteToSend[i],127);
      buttonLast[i] = button;
      }
    if (button == LOW && buttonLast[i] == HIGH) {
      sendNote(144,noteToSend[i],0);
      buttonLast[i] = button;
     }
  }
}

void sendNote(byte message, byte note, byte velocity){
 Serial.write(message);
 Serial.write(note);
 Serial.write(velocity);
 delay (20);
}

I am not shure how high the latency actually is, but it is much bigger than for me acceptable 10ms. It feels like half a second.

AndiH1213: but it is much bigger than for me acceptable 10ms.

Did you study line 34 ?

...R

I think this delay is happening after the data being sent... So it should not matter for the latency.

Does anyone else have an idea how I could fix this problem? I mean this is really annoying...

AndiH1213: I think this delay is happening after the data being sent... So it should not matter for the latency.

Have you tried removing it?

What happened?

An Arduino can do nothing during a delay().

...R

The delay is there for debouncing the switches I use. If I remove it or set it very low, the latency stays the same.

Any other idea?

AndiH1213:
The delay is there for debouncing the switches I use.

How was I supposed to know that a delay() in a function that sends serial data is intended to debounce a switch. If you need a delay put it somewhere logical.

More importantly, don’t use delay() at all. Use millis() to manage timing without blocking as in Several Things at a Time.

In any case, if the delay() is not causing the latency I suggest you look at the output from your Arduino program on the Arduino Serial Monitor. If there is no latency there it suggests the problem is in your PC software rather than your Arduino code.

…R

Removing the delay just causes the buttons to bounce. For what I want it to do I think the code should be fine. I am new to programming and put that one together with help from the forum (thanks to Grumpy_Mike again), and I basically just want it to work and not be perfect.

The latency issue is just really bothering me. I tried to work through a couple tutorials on fixing the latency through the ftdi drivers, like this one: http://www.instructables.com/id/Lampduino-an-8x8-RGB-Floor-Lamp/step20/Reducing-FTDI-Serial-Latency/

But under the advanced port settings I don't have an option to set the latency, I only have the choice for disable/enable FIFO-buffer and setting receive buffer and transmit buffer. Changing those doesn't have a positive effect, too.

I have the feeling that is has someting to do with those drivers. Hairless Midi also says that FTDI drivers don't seem to be installed, but they are.

Any suggestion?

What if you move line 34 to line 28? That way your only de-bouncing once per loop instead of once per button press/release.

void loop(){
  for(int i =0; i<9; i++){
    button = digitalRead(switchPin[i]);
    if (button == HIGH && buttonLast[i] == LOW) {
      sendNote(144,noteToSend[i],127);
      buttonLast[i] = button;
    }
    if (button == LOW && buttonLast[i] == HIGH) {
      sendNote(144,noteToSend[i],0);
      buttonLast[i] = button;
    }
  }
  delay (20);
}

void sendNote(byte message, byte note, byte velocity){
  Serial.write(message);
  Serial.write(note);
  Serial.write(velocity);
}

You could maybe further improve the code by only setting a flag if button states have changed in the for loop and not execute the delay if no button changes (no need to debounce).

AndiH1213: Any suggestion?

Have you tried my suggestion in Reply #7 to see if the latency manifests itself when you send the data to the Serial Monitor ?

...R

Ok so it seems that I (almost) solved the problem. I had to change the latency in the fdtiport.inf file of the drivers. Right now I am running this Micro Pro as a Leonardo with the drivers coming with the Arduino software.

So with those drivers, the latency on Windows is initially set to 16ms, but I set it to 1.

It is much better right now, but even though I realize a small latency.

I haven’t tried out how to include the millis() function to my code. I just don’t have that much time right now. But I might look into that soon as I am planning to build another midi-foot-controller in the future, using a board like a teensy that can do usb to midi without additional software like LoopMidi + Hariless Midi. I actually bought the Micro Pro as it said it would be compatible to the Arduino Leonardo, but it seems it doesn’t have the same USB to Midi function.

Another problem I have is that the Pro Micro sometimes is not beeing recognized by Hairless Midi any more and I have to restart the programs, reconnect the hardware and sometimes it works again. No clue what is happening there. Having to rely on an additional program to send Midi data kind of sucks :wink:

Anyway, thank you for the help so far!