Converting matrix key input to midi note numbers

Converting matrix key input to midi note numbers

I have each key showing a value in serial monitor by printing the variable (keypadkeys) and have mapped my Midi note numbers into 'keyToMidiMap'.

how would I go about assigning the correct midi note number to the value I get (keypadkeys) from the matrix keyboard?

#include <Keypad.h>
//#include <Wire.h> //Include the Wire library to talk I2C


//number of rows on the keypad
//number of columns on the keypad
const byte numRows= 6; 
const byte numCols= 9; 

byte keyToMidiMap[32];

//Code that shows the the keypad connections to the arduino terminals
byte colPins[numCols] = {2, 3, 4, 5, 6, 7, 8, 9, 10}; //Rows 0 to 3
byte rowPins[numRows]= {A0, A1, A2, A3, A4, A5}; //Columns 0 to 3

/*keymap defines the key pressed according to the row and columns just as appears on the keypad*/
char keymap[numRows][numCols]=
{
{'A', 'G','M','S','Y','5','37','43','49'},
{'B', 'H','N','T','Z','6','38','44'},
{'C', 'I','O','U','1','7','39','45'},
{'D', 'J','P','V','2','8','40','46'},
{'E', 'K','Q','W','3','9','41','47'},
{'F', 'L','R','X','4','1','42','48'},


};

//initializes an instance of the Keypad class
Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

void setup()
{
    // initialize the serial communication:
  Serial.begin(115200);

  // Map scan matrix buttons/keys to actual Midi note number. Lowest num 41 corresponds to F MIDI note.
 
  keyToMidiMap[1] = 41;
  keyToMidiMap[2] = 42;
  keyToMidiMap[3] = 43;
  keyToMidiMap[4] = 44;
  keyToMidiMap[5] = 45;
  keyToMidiMap[6] = 46;
  keyToMidiMap[7] = 47;

  keyToMidiMap[8] = 56;
  keyToMidiMap[1 + 8] = 49;
  keyToMidiMap[2 + 8] = 50;
  keyToMidiMap[3 + 8] = 51;
  keyToMidiMap[4 + 8] = 52;
  keyToMidiMap[5 + 8] = 53;
  keyToMidiMap[6 + 8] = 54;
  keyToMidiMap[7 + 8] = 55;

  keyToMidiMap[16] = 64;
  keyToMidiMap[1 + 16] = 57;
  keyToMidiMap[2 + 16] = 58;
  keyToMidiMap[3 + 16] = 59;
  keyToMidiMap[4 + 16] = 60;
  keyToMidiMap[5 + 16] = 61;
  keyToMidiMap[6 + 16] = 62;
  keyToMidiMap[7 + 16] = 63;

  keyToMidiMap[24] = 72;
  keyToMidiMap[1 + 24] = 65;
  keyToMidiMap[2 + 24] = 66;
  keyToMidiMap[3 + 24] = 67;
  keyToMidiMap[4 + 24] = 68;
  keyToMidiMap[5 + 24] = 69;
  keyToMidiMap[6 + 24] = 70;
  keyToMidiMap[7 + 24] = 71;


}

//If key is pressed, this key is stored in keypressed variable
//If key is not equal to NO_KEY, then this key is printed out
//if count=17, then count is reset back to 0 (this means no key is pressed during the whole keypad scan process
void loop()
{
  char keypadkeys = myKeypad.getKey(); 
  if (keypadkeys != NO_KEY)
    {
      Serial.print(keypadkeys);
      
   
     }
      

      }

      
      void noteOn(int cmd, int pitch, int velocity) {
    Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}

maybe a stupid question but WHY have you not simply put the values you assigned to the 'keyToMidiMap' array the 'keymap'?

ie why have two arrays?

If you replace the values in the keymap array with straightforward numbers instead of characters then myKeypad.getKey() will return a number. You could then use that number as the index to an array of corresponding midi note numbers

Thankyou - the answer was simpler than I imagined

So I have replaced with my midi numbers inside the array - Serial monitor only showing 1 decimal place and counting 1-10 for each key. I chose single character/number before thinking i could convert it to the corresponding midi note number to show in serial monitor

Post the code as it is now

Cheers

#include <Keypad.h>
//#include <Wire.h> //Include the Wire library to talk I2C


//number of rows on the keypad
//number of columns on the keypad
const byte numRows= 6; 
const byte numCols= 9; 


//Code that shows the the keypad connections to the arduino terminals
byte colPins[numCols] = {2, 3, 4, 5, 6, 7, 8, 9, 10}; //Rows 0 to 3
byte rowPins[numRows]= {A0, A1, A2, A3, A4, A5}; //Columns 0 to 3

/*keymap defines the key pressed according to the row and columns just as appears on the keypad*/
char keymap[numRows][numCols]=
{
{'60', '66','72','78','84','90','96','102','108'},
{'61', '67','73','79','85','91','97','103'},
{'62', '68','74','80','86','92','98','104'},
{'63', '69','75','81','87','93','99','105'},
{'64', '70','76','82','88','94','100','106'},
{'65', '71','77','83','89','95','101','107'},

};

//int MidiNotes [] = {60, 61, 62, 63, 64, 65, 66, 67, 68, 68, 70};

//initializes an instance of the Keypad class
Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

void setup()
{
    // initialize the serial communication:
  Serial.begin(115200);

}

//If key is pressed, this key is stored in keypressed variable
//If key is not equal to NO_KEY, then this key is printed out
//if count=17, then count is reset back to 0 (this means no key is pressed during the whole keypad scan process
void loop()
{
  char keypadkeys = myKeypad.getKey(); 
  if (keypadkeys != NO_KEY)
    {
      Serial.print(keypadkeys);
   
     }
      

      }

      
      void noteOn(int cmd, int pitch, int velocity) {
    Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}
char keymap[numRows][numCols] =
{
  {'60', '66', '72', '78', '84', '90', '96', '102', '108'},
  {'61', '67', '73', '79', '85', '91', '97', '103'},
  {'62', '68', '74', '80', '86', '92', '98', '104'},
  {'63', '69', '75', '81', '87', '93', '99', '105'},
  {'64', '70', '76', '82', '88', '94', '100', '106'},
  {'65', '71', '77', '83', '89', '95', '101', '107'},

};

A char variable can only hold one character. Can you see a problem ?

raymond_bagdust420:

/*keymap defines the key pressed according to the row and columns just as appears on the keypad*/

char keymap[numRows][numCols]=
{
{'60', '66','72','78','84','90','96','102','108'},
{'61', '67','73','79','85','91','97','103'},
{'62', '68','74','80','86','92','98','104'},
{'63', '69','75','81','87','93','99','105'},
{'64', '70','76','82','88','94','100','106'},
{'65', '71','77','83','89','95','101','107'},

};

@UKHeliBob beat me to it! :wink: should be :

char keymap[numRows][numCols]=
{
{60, 66,72,78,84,90,96,102,108},
{61, 67,73,79,85,91,97,103,103},
{62, 68,74,80,86,92,98,104,104},
{63, 69,75,81,87,93,99,105,105},
{64, 70,76,82,88,94,100,106,106},
{65, 71,77,83,89,95,101,107,107},

};

IMHO

Thanks - My array now looks like that but still doesn't show corresponding number in serial monitor. It's now showing a different character for each key press.

serial monitor:
(CEGHJLMO<<<<@ACGGHHGHGHEGGHJHIJKLMNOPQSTUVWXZY\]^`^ll)

Shall I make a new array with my midi numbers (60-108) and change this keypad array to 1-38 so i can use those as index for the midi note array?

in which case how do I write that in the code (1 =60 2=61 ect)

Once again, please post the code as it is now

#include <Keypad.h>
//#include <Wire.h> //Include the Wire library to talk I2C


//number of rows on the keypad
//number of columns on the keypad
const byte numRows= 6; 
const byte numCols= 9; 


//Code that shows the the keypad connections to the arduino terminals
byte colPins[numCols] = {2, 3, 4, 5, 6, 7, 8, 9, 10}; //Rows 0 to 3
byte rowPins[numRows]= {A0, A1, A2, A3, A4, A5}; //Columns 0 to 3

/*keymap defines the key pressed according to the row and columns just as appears on the keypad*/
char keymap[numRows][numCols]=
{
{60, 66, 72, 78, 84, 90, 96, 102, 108},
{61, 67, 73, 79, 85, 91, 97, 103},
{62, 68, 74, 80, 86, 92, 98, 104},
{63, 69, 75, 81, 87, 93, 99, 105},
{64, 70, 76, 82, 88, 94, 100, 106},
{65, 71,77, 83, 89, 95, 101, 107},

};

//int MidiNotes [] = {60, 61, 62, 63, 64, 65, 66, 67, 68, 68, 70};

//initializes an instance of the Keypad class
Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

void setup()
{
    // initialize the serial communication:
  Serial.begin(115200);

}

//If key is pressed, this key is stored in keypressed variable
//If key is not equal to NO_KEY, then this key is printed out
//if count=17, then count is reset back to 0 (this means no key is pressed during the whole keypad scan process
void loop()
{
  char keypadkeys = myKeypad.getKey(); 
  if (keypadkeys != NO_KEY)
    {
      Serial.print(keypadkeys);
   
     }
      

      }

      
      void noteOn(int cmd, int pitch, int velocity) {
    Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}

Or change the variable type of keymap and keypadkeys to byte

perfect - working now thanks a lot