#include <Keypad.h>

#define ROW_NUM     4 // four rows
#define COLUMN_NUM  4 // four columns

const uint8_t ledPins[] = {15, 2, 4, 5, 18, 19};
const int numLed = sizeof(ledPins) / sizeof(ledPins[0]);

char keys[ROW_NUM][COLUMN_NUM] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte pin_rows[ROW_NUM]      = {13, 12, 14, 27};
byte pin_column[COLUMN_NUM] = {26, 25, 33, 32};

Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);

int kpc = 144;
int transpose = 0;
int midC = 60;

void setup() {
  Serial.begin(115200);
  for (int i = 0; i < numLed; i++) {
    pinMode(ledPins[i], OUTPUT);
  }
}

void ledStatus(char key) {
  for (int i = 0; i < numLed; i++) {
    digitalWrite(ledPins[i], LOW);
  }
  switch (key) {
    case 'A':
    case 'B':
    case 'C':
    case 'D':
    case '*':
    case '#':
      for (int i = 0; i < numLed; i++) {
        digitalWrite(ledPins[i], HIGH);
      }
      return;
    case '0':
      for (int i = 0; i < numLed; i++) {
        digitalWrite(ledPins[i], LOW);
      }
      return;
    case '1':
      digitalWrite(ledPins[0], HIGH);
      return;
    case '2':
      digitalWrite(ledPins[1], HIGH);
      return;
    case '3':
      digitalWrite(ledPins[2], HIGH);
      return;
    case '4':
      digitalWrite(ledPins[3], HIGH);
      return;
    case '5':
      digitalWrite(ledPins[4], HIGH);
      return;
  }
}

void MIDImessage(byte status, byte data1, byte data2)
{
  Serial.write(status);
  Serial.write(data1);
  Serial.write(data2);

  Serial.println();
  Serial.println(status);
  Serial.println(data1);
  Serial.println(data2);
}

void loop() {
  char key = keypad.getKey();
  if (key) {
    Serial.print("key : ");
    Serial.println(key);
    ledStatus(key);

    for (int i = 0; i < LIST_MAX; i++) // scan the whole key list
    {
      if (keypad.key[i].stateChanged)   // find keys that have changed state
      {
        if (keypad.key[i].kstate == PRESSED) // sends MIDI on message when keys are pressed
        {
          digitalWrite(ledPins[5], HIGH);

          switch (keypad.key[i].kchar) {
            case '1':
              MIDImessage(kpc, midC + transpose + 0, 127);
              break;
            case '2':
              MIDImessage(kpc, midC + transpose + 1, 127);
              break;
            case '3':
              MIDImessage(kpc, midC + transpose + 2, 127);
              break;
            case '4':
              MIDImessage(kpc, midC + transpose + 3, 127);
              break;
            case '5':
              MIDImessage(kpc, midC + transpose + 4, 127);
              break;
            case '6':
              MIDImessage(kpc, midC + transpose + 5, 127);
              break;
            case '7':
              MIDImessage(kpc, midC + transpose + 6, 127);
              break;
            case '8':
              MIDImessage(kpc, midC + transpose + 7, 127);
              break;
            case '9':
              MIDImessage(kpc, midC + transpose + 8, 127);
              break;
            case 'S':
              MIDImessage(kpc, midC + transpose + 9, 127);
              break;
            case '0':
              MIDImessage(kpc, midC + transpose + 10, 127);
              break;
            case 'P':
              MIDImessage(kpc, midC + transpose + 11, 127);
          }
        }

        if (keypad.key[i].kstate == RELEASED)  // sends MIDI off message when keys are released
        {
          Serial.print("+++");
          digitalWrite(ledPins[5], LOW);

          switch (keypad.key[i].kchar) {
            case '1':
              MIDImessage(kpc - 16, midC + transpose + 0, 0);
              break;
            case '2':
              MIDImessage(kpc - 16, midC + transpose + 1, 0);
              break;
            case '3':
              MIDImessage(kpc - 16, midC + transpose + 2, 0);
              break;
            case '4':
              MIDImessage(kpc - 16, midC + transpose + 3, 0);
              break;
            case '5':
              MIDImessage(kpc - 16, midC + transpose + 4, 0);
              break;
            case '6':
              MIDImessage(kpc - 16, midC + transpose + 5, 0);
              break;
            case '7':
              MIDImessage(kpc - 16, midC + transpose + 6, 0);
              break;
            case '8':
              MIDImessage(kpc - 16, midC + transpose + 7, 0);
              break;
            case '9':
              MIDImessage(kpc - 16, midC + transpose + 8, 0);
              break;
            case 'S':
              MIDImessage(kpc - 16, midC + transpose + 9, 0);
              break;
            case '0':
              MIDImessage(kpc - 16, midC + transpose + 10, 0);
              break;
            case 'P':
              MIDImessage(kpc - 16, midC + transpose + 11, 0);
          }
        }
      }
    }
  }
}
$abcdeabcde151015202530fghijfghij