Go Down

Topic: Need help with lag (latency) in Arduino Leonardo using MIDIUSB library (Read 324 times) previous topic - next topic

Saul1205MX

Hello,

I'm trying to make a MIDI controller to rescue an old 61-key CASIO keyboard.

Actually, I plan to use it as a normal keyboard, I do not intend to use it as a synthesizer, so after researching, I found that using a MIDI controller as an interface is a viable option.

Based on different tutorials, basically the EvanKale YouTube channel and https://www.musiconerd.com, I have managed to make the 8 x 8 matrix of my keyboard work with its corresponding notes, however, there is a slight delay between the moment the key is pressed and the sound emission (latency).

I have read that it is necessary to use an Arduino based on an ATMEGA32u4 so that it can be recognized as HID, so I am using an Arduino Leonardo.

In order to use the 8x8 array of the switch matrix (keys), I use a 74HC595:
--- 8 pins connected to the inputs Q0, Q1 ... Q7 of the 74HC595
--- 8 pins with Pull Down resistance, connected directly to the Arduino
--- 3 pins (Latch, Clock and Data) connected to 3 digital inputs of the Arduino

I also want to mention that I do not use any "delay".

I hope you can help me, I need to operate the keyboard without any delay.

Thank you very much for your attention, I am not an expert in programming, but I believe that with your good advice I can achieve it. Greetings.

I attach my code.


Code: [Select]
//PullDownTest With MIDIUSB library
#include "MIDIUSB.h"
#define NUM_ROWS 8
#define NUM_COLS 8

// Row input pins
const int row1Pin = 2;
const int row2Pin = 3;
const int row3Pin = 4;
const int row4Pin = 5;
const int row5Pin = 6;
const int row6Pin = 7;
const int row7Pin = 8;
const int row8Pin = 9;

// 74HC595 pins
const int dataPin = 11;
const int latchPin = 12;
const int clockPin = 13;

boolean keyPressed[NUM_ROWS][NUM_COLS];
uint8_t keyToMidiMap[NUM_ROWS][NUM_COLS];

// bitmasks for scanning columns
int bits[] =
{
  B00000001,
  B00000010,
  B00000100,
  B00001000,
  B00010000,
  B00100000,
  B01000000,
  B10000000
};


void noteOn(byte channel, byte pitch1,byte pitch2, byte velocity) {
  byte pitch=(keyToMidiMap[pitch1][pitch2]);
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch1, byte pitch2, byte velocity) {
byte  pitch=(keyToMidiMap[pitch1][pitch2]);
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}


void setup()
{
  //Serial.begin(250000);
  int note = 48;

  for(int colCtr = 0; colCtr < NUM_COLS; ++colCtr)
  {
    for(int rowCtr = 0; rowCtr < NUM_ROWS; ++rowCtr)
    {
      keyPressed[rowCtr][colCtr] = false;
      keyToMidiMap[rowCtr][colCtr] = note;
      note++;
    }
  }

  // setup pins output/input mode
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);

  pinMode(row1Pin, INPUT);
  pinMode(row2Pin, INPUT);
  pinMode(row3Pin, INPUT);
  pinMode(row4Pin, INPUT);
  pinMode(row5Pin, INPUT);
  pinMode(row6Pin, INPUT);
  pinMode(row7Pin, INPUT);
  pinMode(row8Pin, INPUT);
}

void loop()
{
  for (int colCtr = 0; colCtr < NUM_COLS; ++colCtr)
  {
    //scan next column
    scanColumn(colCtr);

    //get row values at this column
    int rowValue[NUM_ROWS];
    rowValue[0] = digitalRead(row1Pin);
    rowValue[1] = digitalRead(row2Pin);
    rowValue[2] = digitalRead(row3Pin);
    rowValue[3] = digitalRead(row4Pin);
    rowValue[4] = digitalRead(row5Pin);
    rowValue[5] = digitalRead(row6Pin);
    rowValue[6] = digitalRead(row7Pin);
    rowValue[7] = digitalRead(row8Pin);

    // process keys pressed
    for(int rowCtr=0; rowCtr<NUM_ROWS; ++rowCtr)
    {
      if(rowValue[rowCtr] != 0 && !keyPressed[rowCtr][colCtr])
      {
        keyPressed[rowCtr][colCtr] = true;
          noteOn(11, rowCtr,colCtr, 127);  // channel, note, velocity
          MidiUSB.flush();
      }
    }

    // process keys released
    for(int rowCtr=0; rowCtr<NUM_ROWS; ++rowCtr)
    {
      if(rowValue[rowCtr] == 0 && keyPressed[rowCtr][colCtr])
      {
        keyPressed[rowCtr][colCtr] = false;
          noteOff(11, rowCtr,colCtr, 127);  // channel, note, velocity
          MidiUSB.flush();
      }
    }
  }
}

void scanColumn(int colNum)
{
  digitalWrite(latchPin, LOW);

  if(0 <= colNum && colNum <= 9)
  {
    shiftOut(dataPin, clockPin, MSBFIRST, bits[colNum]); //shift register
  }
  else
  {   
    shiftOut(dataPin, clockPin, MSBFIRST, B00000000); //shift register
  }
  digitalWrite(latchPin, HIGH);
}




Go Up