Help to output matrix input into midi note output

Trying to set up and old casio keyboard as a midi controller
Using the keypad library to map the keys to functions
Need help in making the keys into midi out messages
Total beginner and hvent had much luck in figuring out how to go about it
Using arduino uno r3

here is the current code
please guide on how to make the above mentioned happen
any help would be appreciated

#include <Keypad.h>


const byte ROWS = 4; //four rows
const byte COLS = 8; //eight columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'53','54','55','56','57','58','59','60'},
  {'61','62','63','64','65','66','67','68'},
  {'69','70','71','72','73','74','75','76'},
  {'77','78','79','80','81','82','83','84'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {13, 12, 11, 10, 9, 8, 7, 6}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
//int notes[] = {
// a, b, c, d, e, f, g, h, i, k, l, m, n, o, p ,q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F
//};

void setup(){
  Serial.begin(9600);
}
  
void loop(){

 int note = customKeypad.getKey();

 //for(int customKey = "a"  ; customKey = "F" ; customKey++) { 

  if (note !=NO_KEY){
    Serial.println(note);

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




You need to use the midi library, I think. I don't think you can use that library with Uno. You may need an Arduino board with "native USB" for example Pro Micro.

i flashed dual moco to my arduino so now it is detected as a midi instrument and the only problem is i dont know how to conert the keypresses into midi information. is this not possible?

That is advanced level. Why do you need help?

Is "dual moco" compatible with standard Arduino midi library?

Im good at following tutorials and tinkering with code that is already there but when it comes to doing something from scratch i cant since ive got minimal coding knowledge and even lesser coding experience

Ok, I suggest you install midi USB and test using some of the example sketches from the library.

midi usb doesnt work when i try to upload one of the sample sketches it doesnt compile and gives the following error


In file included from C:\Users\Admin\AppData\Local\Temp\.arduinoIDE-unsaved20221111-18656-1wkbsn6.91jr\MIDIUSB_write\MIDIUSB_write.ino:9:0:
C:\Users\Admin\Documents\Arduino\libraries\MIDIUSB\src/MIDIUSB.h:18:2: error: #error MIDIUSB can only be used with an USB MCU.
 #error MIDIUSB can only be used with an USB MCU.
  ^~~~~

exit status 1

Compilation error: exit status 1

Like I said:

Looks like the answer is no.

Perhaps someone else in the forum with more midi knowledge than me knows a way to fix this.

My only suggestion right now is to buy a Pro Micro or other native USB Arduino (I would not recommend Leonardo because of its form-factor).

I have moved your topic into the Audio forum section. I hope someone here can give you better advice.

1 Like

Looks like its possible to send midi through my arduino uno r3 but u havent yet figured out how to do so directly from my old-casio-keyboard

here are the steps i followed

I flashed the dualmoco firmware to the arduino and switched it to serial mode
i uploaded the following code to the arduino taken from this webpage

void setup() {
  //  Set MIDI baud rate:
  Serial.begin(31250);
}

void loop() {
  // play notes from F#-0 (0x1E) to F#-5 (0x5A):
  for (int note = 0x1E; note < 0x5A; note ++) {
    //Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
    noteOn(0x90, note, 0x45);
    delay(100);
    //Note on channel 1 (0x90), some note value (note), silent velocity (0x00):
    noteOn(0x90, note, 0x00);  
    delay(100);
  }
}

//  plays a MIDI note.  Doesn't check to see that
//  cmd is greater than 127, or that data values are  less than 127:
void noteOn(int cmd, int pitch, int velocity) {
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}

then i switched back to the midi mode on my arduino and lo behold the notes started playing on my computer


as you can see mocolufa is detected as a midi input and the notes are played back

so it turns out its atually possible to use it as an midi in device but the only trouble is how i can map my hooked up keys to the particular midi messages

i hope this clears somethings up and any replies and suggestion on what can be done are welcome

Good progress!

But looking back at the code you posted originally, it seems only 1 step away from working, at least in some basic way.

Using the code from your first post and keeping the Uno in serial mode, what do you see on serial monitor? The reason I ask that is because of this:

Normally a char literal is only a single character like '4' or 'a', not two characters like '53'. I guess this must be allowed, or the code would not compile. But I don't know how Arduino C would deal with that.

yes i encountered this issue and elswhere on this forum someone else who was trying to do something similar was give the advice of treating them as int variables

if you notice here the note variable is specified as int so i guess thats why it works

the code from the first post works quite well. that is in terms of reacting to keypresses
the serial monitor displays the midi number of the key that is pressed as shown below
image
i press the middle c key on my keyboard and the result is a 60 on the serial monitor and likewise pressing a c on the next octave give a result of 72 on the serial monitor which is accurate because it is shifted up 12 numbers/keys

yes that is what it looks like but i've no clue on how to convert the keypresses into midi messages so any advice on that would be welcome

char hexaKeys[ROWS][COLS] = {
  {'53', '54', '55', '56', '57', '58', '59', '60'},
  {'61', '62', '63', '64', '65', '66', '67', '68'},
  {'69', '70', '71', '72', '73', '74', '75', '76'},
  {'77', '78', '79', '80', '81', '82', '83', '84'}
};

When you use two characters within single quotes, what you get is an integer:
integer = (ASCII value of 1st character) * 256 + (ASCII value of 2nd character)

In the case of '53', that will be (just by coincidence '5' in ASCII is 53 in decimal)
53 * 256 + 51 = 13619
and if you have the IDE preferences set to show all warnings you will see
warning: narrowing conversion of '13619' from 'int' to 'char' inside { } [-Wnarrowing]

If you want to specify the note number directly in decimal, leave off the single quotes. With the keypad library you can use any value from 1 through 255 for a key, zero cannot be used because that is used by the library to indicate that no key has been pressed.

here is the current code

#include <Keypad.h>
const byte ROWS = 4; //four rows
const byte COLS = 8; //eight columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {53,54,55,56,57,58,59,60},
  {61,62,63,64,65,66,67,68},
  {69,70,71,72,73,74,75,76},
  {77,78,79,80,81,82,83,84}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {13, 12, 11, 10, 9, 8, 7, 6}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
//int notes[] = {
// a, b, c, d, e, f, g, h, i, k, l, m, n, o, p ,q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F
//};

void setup(){
  Serial.begin(9600);
}
  
void loop(){

int note = customKeypad.getKey();

 //for(int customKey = "a"  ; customKey = "F" ; customKey++) { 

  if (note !=NO_KEY){
    Serial.println(note);

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

this outputs the midi number correctly to the serial monitor. now the thing that is left to do is to make it a midi message

Since you have the UNO set up to appear as a midi controller to the computer, you should be able to use the Midi library instead of the MidiUSB library.

1 Like

im not sure how do do that any helpful links or code to help with that?
thanks in advance

To start with, you need to look at the MultiKey example sketch for the Keypad library, because you need to know when a key is pressed and also when it is released. The standard getKey() function only tells you when a key is pressed. The library only allows for 10 keys to be pressed simultaneously, if that is not enough then the library will need to be modified.

The MIDI library defaults to using the hardware serial port at the standard 31250 baud rate, so should work directly with the USB interface. Once you have the key number, sendNoteOn() and sendNoteOff() would likely be the proper functions to use, although if you know the correct format for MIDI messages you could write the data to Serial directly and not use the library. I'm not familiar with all the functions available with MIDI, you may be able to use additional buttons and knobs on your Casio keyboard to control the synthesizer program, which would require other types of MIDI messages.

1 Like

I guess @eyh has only 10 fingers, so that should be enough I think :slight_smile:

1 Like

You can probably install the midi (not USBmidi) library from the library manager within the ide. There will almost certainly be some example code installed with the library. You can access that from the examples menu in the IDE.

Please don't post images of the serial monitor. Copy the text from serial monitor (you can freeze scrolling if needed) and paste the text into your forum post, in code tags.