Hey guys,
I am buiding myself a midi keyboard based on an old organ keyboard.
The keyboard has a 4x12 scan matrix and the note range is from F2 - C6.
I am using two 74HC595 shift registers, an arduino uno and a code that i mixed together from two different instructions i found on the internet. Everything works just fine.
Now to my question:
i want to add two buttons that change the octave of the keyboard, one button for octave up and one button for octave down.
Since i am a total newbie to programming i have no idea what to do. I can only think of a solution that is hardware based but that would just waste digital inputs of my arduino.
I hope you can give me some tips and solution approach.
Btw i hope my english isn't to bad, i am german.
This is the code i am working with right now.
#define NUM_ROWS 4
#define NUM_COLS 12
#define NOTE_ON_CMD 0x90
#define NOTE_OFF_CMD 0x80
#define NOTE_VELOCITY 127
//MIDI baud rate
#define SERIAL_RATE 31250
// Pin Definitions
// Row input pins
const int row1Pin = 2;
const int row2Pin = 3;
const int row3Pin = 4;
const int row4Pin = 5;
// 74HC595 pins
const int dataPin = 6;
const int latchPin = 7;
const int clockPin = 8;
boolean keyPressed[NUM_ROWS][NUM_COLS];
uint8_t keyToMidiMap[4][12] =
{
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,
};
// bitmasks for scanning columns
int bits[] =
{
B11111110,
B11111101,
B11111011,
B11110111,
B11101111,
B11011111,
B10111111,
B01111111
};
void setup()
{
// 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);
Serial.begin(SERIAL_RATE);
}
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);
// 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, B11111111); //right sr
shiftOut(dataPin, clockPin, MSBFIRST, bits[colNum]); //left sr
}
else
{
shiftOut(dataPin, clockPin, MSBFIRST, bits[colNum-8]); //right sr
shiftOut(dataPin, clockPin, MSBFIRST, B11111111); //left sr
}
digitalWrite(latchPin, HIGH);
}
void noteOn(int row, int col)
{
Serial.write(NOTE_ON_CMD);
Serial.write(keyToMidiMap[row][col]);
Serial.write(NOTE_VELOCITY);
}
void noteOff(int row, int col)
{
Serial.write(NOTE_OFF_CMD);
Serial.write(keyToMidiMap[row][col]);
Serial.write(NOTE_VELOCITY);
}