I'm making an old keyboard with no board or speaker into a midi interface, but I have encountered a problem with it.
All keys in the button matrix work correctly for the most part except that when a key from column 8 is active column 9 gets disabled , and both columns 10 and 11 work correctly. Column 9 does work when 8 is not active
I'm using an Arduino Pro Micro so that I can use its native HID function.
The only clue i have is that the problem occurs on the last data pin in the first shift register and the first pin on the second.
Code:
#include "MIDIUSB.h"
#define NUM_ROWS 6
#define NUM_COLS 11
// Pin Definitions
// 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;
// 74HC595 pins
const int dataPin = 8;
const int latchPin = 9;
const int clockPin = 10;
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 setup()
{
int note = 36; //left most key on keyboard
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);
}
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);
// process keys pressed
for(int rowCtr=0; rowCtr<NUM_ROWS; ++rowCtr)
{
if(rowValue[rowCtr] != 0 && !keyPressed[rowCtr][colCtr])
{
keyPressed[rowCtr][colCtr] = true;
noteOn(rowCtr,colCtr);
}
}
// process keys released
for(int rowCtr=0; rowCtr<NUM_ROWS; ++rowCtr)
{
if(rowValue[rowCtr] == 0 && keyPressed[rowCtr][colCtr])
{
keyPressed[rowCtr][colCtr] = false;
noteOff(rowCtr,colCtr);
}
}
}
}
void scanColumn(int colNum)
{
digitalWrite(latchPin, LOW);
if(0 <= colNum && colNum <= 7)
{
shiftOut(dataPin, clockPin, MSBFIRST, B00000000); //right sr
shiftOut(dataPin, clockPin, MSBFIRST, bits[colNum]); //left sr
}
else
{
shiftOut(dataPin, clockPin, MSBFIRST, bits[colNum-8]); //right sr
shiftOut(dataPin, clockPin, MSBFIRST, B00000000); //left sr
}
digitalWrite(latchPin, HIGH);
}
void noteOn(int row, int col)
{
midiEventPacket_t noteOn = {0x09, 0x90 | 1, keyToMidiMap[row][col], 127};
MidiUSB.sendMIDI(noteOn);
MidiUSB.flush();
}
void noteOff(int row, int col)
{
midiEventPacket_t noteOff = {0x08, 0x80 | 1, keyToMidiMap[row][col], 127};
MidiUSB.sendMIDI(noteOff);
MidiUSB.flush();
}
Circuit / Example Output: