I am trying to build a MIDI keyboard from an old toy but I am having a problem following all the guides. The toy keyboard button matrix has the diodes the WORNG WAY. Can this be solved in code?
Can You post schematics for the keyboard?
Handling it from the code ought to be possible. The controller doesn't care if the keyboard is up side down, mirror turned etc.
Alternative perspective: the wiring you used is not the correct one for this specific matrix configuration. There is no “wrong way”, you can just change the polarity of all pins and it will work just fine.
Here is the toy keyboard matrix. When drawing it I realized the diodes where fine LOL
So it is just coding now!
Edit: Updated pic
which arduino are you using?
Pro Micro 5V 16mhz Atmega32u4
I Updated the matrix schematics I uploaded earlier.
here is the first skitch I tried. (no response from keys)
// Here's the CODE:
// works with keyboards with matrix 7x8
#define matrix1 7
#define matrix2 8
#include "MIDIUSB.h"
int octave = 0; // add or subtract 8 for one octave
bool currentState[matrix1 * matrix2];
bool requestState[matrix1 * matrix2];
void setup()
{
//-----matrix1 number of pins-------
pinMode(A0,INPUT); //1
pinMode(A1,INPUT); //2
pinMode(A2,INPUT); //3
pinMode(A3,INPUT); //4
pinMode(14,INPUT); //5
pinMode(15,INPUT); //6
pinMode(16,INPUT); //7
//-----matrix2 number of pins-------
//each matrix2 pin must be one above the previous one
pinMode(2,INPUT); //1
pinMode(3,INPUT); //2
pinMode(4,INPUT); //3
pinMode(5,INPUT); //4
pinMode(6,INPUT); //5
pinMode(7,INPUT); //6
pinMode(8,INPUT); //7
pinMode(9,INPUT); //8
}
void loop()
{
readKeys();
writeKeys();
delay(1);
}
void readKeys()
{
for(int i=0; i<matrix2; i++)
{
//---------matrix2 pins-----------
pinMode(2,INPUT);
pinMode(3,INPUT);
pinMode(4,INPUT);
pinMode(5,INPUT);
pinMode(6,INPUT);
pinMode(7,INPUT);
pinMode(8,INPUT);
pinMode(9,INPUT);
pinMode(i+2,OUTPUT); // <--i+2 (this is your first pin number)
digitalWrite(i+2,LOW);
delayMicroseconds(1000);
//you have to repeat this finction matrix1 times
requestState[i*matrix1+0] = !digitalRead(A3);
requestState[i*matrix1+1] = !digitalRead(A2);
requestState[i*matrix1+2] = !digitalRead(A1);
requestState[i*matrix1+3] = !digitalRead(A0);
requestState[i*matrix1+4] = !digitalRead(15);
requestState[i*matrix1+5] = !digitalRead(14);
requestState[i*matrix1+6] = !digitalRead(16);
}
}
void writeKeys()
{
for(int i=0; i<matrix1 * matrix2; i++)
{
if(requestState[i]==true && currentState[i] == false)
{
noteOn(0, 36+octave+(i*matrix2)%matrix1 * matrix2+i/matrix1, 64);
currentState[i] = requestState[i];
}
if(requestState[i]==false && currentState[i] == true)
{
noteOff(0, 36+octave+(i*matrix2)%matrix1 * matrix2+i/matrix1, 64);
currentState[i] = requestState[i];
}
}
MidiUSB.flush();
}
void noteOn(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOn);
}
void noteOff(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOff);
}
The second skitch I tried gave me a response from some keys.
#define matrix1 4 // rows
#define matrix2 8 // columns
#include "MIDIUSB.h"
int octave = 24; // add or subtract 12 for one octave
bool currentState[matrix1 * matrix2];
bool requestState[matrix1 * matrix2];
void setup()
{
//-matrix1 number of pins-
pinMode(10,INPUT); //1
pinMode(11,INPUT); //2
pinMode(12,INPUT); //3
pinMode(13,INPUT); //4
//-matrix2 number of pins-
//each matrix2 pin must be one above the previous one
pinMode(2,INPUT); //1
pinMode(3,INPUT); //2
pinMode(4,INPUT); //3
pinMode(5,INPUT); //4
pinMode(6,INPUT); //5
pinMode(7,INPUT); //6
pinMode(8,INPUT); //7
pinMode(9,INPUT); //8
}
void loop()
{
readKeys();
writeKeys();
delay(1);
}
void readKeys()
{
for(int i=0; i<matrix2; i++)
{
//--------matrix2 pins----------
pinMode(2,INPUT);
pinMode(3,INPUT);
pinMode(4,INPUT);
pinMode(5,INPUT);
pinMode(6,INPUT);
pinMode(7,INPUT);
pinMode(8,INPUT);
pinMode(9,INPUT);
pinMode(i+2,OUTPUT); // <--i+2 (this is your first pin number)
digitalWrite(i+2,HIGH);
delayMicroseconds(1000);
//you have to repeat this finction matrix1 times
requestState[i*matrix1+0] = digitalRead(10);
requestState[i*matrix1+1] = digitalRead(11);
requestState[i*matrix1+2] = digitalRead(12);
requestState[i*matrix1+3] = digitalRead(13);
}
}
void writeKeys()
{
for(int i=0; i<matrix1 * matrix2; i++)
{
if(requestState[i]==true && currentState[i] == false)
{
noteOn(0, 25+octave+(i*matrix2)%(matrix1 * matrix2)+i/matrix1, 64); //kept it as 25 since the first note on my piano is F
currentState[i] = requestState[i];
}
if(requestState[i]==false && currentState[i] == true)
{
noteOff(0, 25+octave+(i*matrix2)%(matrix1 * matrix2)+i/matrix1, 64); //kept it as 25 since the first note on my piano is F
currentState[i] = requestState[i];
}
}
MidiUSB.flush();
}
void noteOn(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOn);
}
void noteOff(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOff);
}
And here is what i came up with.
#define matrix1 8 // rows
#define matrix2 7 // columns
#include "MIDIUSB.h"
int octave = 24; // add or subtract 12 for one octave
bool currentState[matrix1 * matrix2];
bool requestState[matrix1 * matrix2];
void setup()
{
//-matrix1 number of pins-
pinMode(A3,INPUT); //1
pinMode(A2,INPUT); //2
pinMode(A1,INPUT); //3
pinMode(A0,INPUT); //4
pinMode(15,INPUT); //5
pinMode(14,INPUT); //6
pinMode(16,INPUT); //7
pinMode(10,INPUT); //8
//-matrix2 number of pins-
//each matrix2 pin must be one above the previous one
pinMode(2,INPUT); //1
pinMode(3,INPUT); //2
pinMode(4,INPUT); //3
pinMode(5,INPUT); //4
pinMode(6,INPUT); //5
pinMode(7,INPUT); //6
pinMode(8,INPUT); //7
}
void loop()
{
readKeys();
writeKeys();
delay(1);
}
void readKeys()
{
for(int i=0; i<matrix2; i++)
{
//--------matrix2 pins----------
pinMode(2,INPUT);
pinMode(3,INPUT);
pinMode(4,INPUT);
pinMode(5,INPUT);
pinMode(6,INPUT);
pinMode(7,INPUT);
pinMode(8,INPUT);
pinMode(i+2,OUTPUT); // <--i+2 (this is your first pin number)
digitalWrite(i+2,HIGH);
delayMicroseconds(1000);
//you have to repeat this finction matrix1 times
requestState[i*matrix1+0] = digitalRead(A3);
requestState[i*matrix1+1] = digitalRead(A2);
requestState[i*matrix1+2] = digitalRead(A1);
requestState[i*matrix1+3] = digitalRead(A0);
requestState[i*matrix1+4] = digitalRead(15);
requestState[i*matrix1+5] = digitalRead(14);
requestState[i*matrix1+6] = digitalRead(16);
requestState[i*matrix1+7] = digitalRead(10);
}
}
void writeKeys()
{
for(int i=0; i<matrix1 * matrix2; i++)
{
if(requestState[i]==true && currentState[i] == false)
{
noteOn(0, 25+octave+(i*matrix2)%(matrix1 * matrix2)+i/matrix1, 64); //kept it as 25 since the first note on my piano is F
currentState[i] = requestState[i];
}
if(requestState[i]==false && currentState[i] == true)
{
noteOff(0, 25+octave+(i*matrix2)%(matrix1 * matrix2)+i/matrix1, 64); //kept it as 25 since the first note on my piano is F
currentState[i] = requestState[i];
}
}
MidiUSB.flush();
}
void noteOn(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOn);
}
void noteOff(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOff);
}
The keyboard dose not act as expected LOL it has a life of its own. Ghosting keys and Screaming hahaha. I think I am close
// Define the MIDI notes for each button (8x8 grid)
const int midiNotes[8][8] = {
{36, 37, 38, 39, 40, 41, 42, 43},
{44, 45, 46, 47, 48, 49, 50, 51},
{52, 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, 85, 86, 87, 88, 89, 90, 91},
{92, 93, 94, 95, 96, 97, 98, 99}
}; ( The code defines a 2D array called midiNotes. This array represents an 8x8 grid, where each element represents a MIDI note number. this is C2 -C7 i don't know which ones you need but your array should be lined in rows and columns with these identifiers or else id think the buttons represent buttons note notes ) you shouldn't have to define it as matrix 1-7 and 2-8 it's done with pin mode, i understand it as such, you have 15 wires 1-7 should be output and 8-15 should be input_pullup so that when a button is pressed an output reaches its destination on an input and which pins are connecting should tell the array which note to apply (if you use your multimeter and do a diode test the wires that go on red should be outputs rest is input and you should count your wires from the lowest note as number one and the black on the lowest note as the first black after the last red so (wire number 8 or 9 depending on how the rows and columns stack)
read this How a Key Matrix Work
its usually 1b is this 2c is that but you can think of it as output wire 3 in pin this to input wire 10 in pin that is this midi note and it gets told which note this combo is with the array
IT WORKS!
#include <MIDI.h>
#include <Keypad.h>
#include <USB-MIDI.h>
// This is required to set up the MIDI library.
USBMIDI_CREATE_DEFAULT_INSTANCE();
// Set up the MIDI channel to send on
#define MIDI_CHANNEL 1
#define MIDI_LED LED_BUILTIN
const byte ROWS = 8;
const byte COLS = 7;
char keys[ROWS][COLS] = {
{36,44,52,60,68,76,84},
{37,45,53,61,69,77,85},
{38,46,54,62,70,78,86},
{39,47,55,63,71,79,87},
{40,48,56,64,72,80,88},
{41,49,57,65,73,81,89},
{42,50,58,66,74,82,90},
{43,51,59,67,75,83,91},
};
byte rowPins[ROWS] = {A3,A2,A1,A0,15,14,16,10}; //connect to the row pinouts of the kpd
byte colPins[COLS] = {2,3,4,5,6,7,8}; //connect to the column pinouts of the kpd
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup() {
MIDI.begin(MIDI_CHANNEL_OFF);
//Serial.begin(9600);
pinMode(MIDI_LED, OUTPUT);
}
void loop() {
// Fills kpd.key[ ] array with up-to 10 active keys.
// Returns true if there are ANY active keys.
if (kpd.getKeys())
{
for (int i=0; i<LIST_MAX; i++) // Scan the whole key list.
{
if ( kpd.key[i].stateChanged ) // Only find keys that have changed state.
{
switch (kpd.key[i].kstate) {
case PRESSED:
digitalWrite(MIDI_LED, HIGH);
//Serial.print(kpd.key[i].kchar,DEC);
//Serial.println(" Pressed");
MIDI.sendNoteOn(kpd.key[i].kchar, 127, MIDI_CHANNEL);
break;
case HOLD:
break;
case RELEASED:
MIDI.sendNoteOff(kpd.key[i].kchar, 0, MIDI_CHANNEL);
digitalWrite(MIDI_LED, LOW);
break;
case IDLE:
break;
}
}
}
}
} // End loop
Edit: Updated code.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.