Problem about making a midi keyboard with Arduino

Hi Guys…
Im new to arduino. I want to make a midi keyboard with arduino. but the project needs SHIFT REGISTERS to control the keys.(See the Code).

I have no any shift registers and I cant buy them.

I want make it with arduino mega without shift registers.

please help me to write the code.

if you can edit this code.please edit and give the code…

#define NUM_ROWS 6
#define NUM_COLS 11

#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;
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[] =
{ 
  B11111110,
  B11111101,
  B11111011,
  B11110111,
  B11101111,
  B11011111,
  B10111111,
  B01111111
};

void setup()
{
  int note = 31;

  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);

  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);
    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, 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);
}

I have no any shift registers and I cant buy them.
I want make it with arduino mega without shift registers.
please help me to write the code.
if you can edit this code.please edit and give the code…

I have no any shift registers and I cant buy them.

you have no money ? honestly shift registers are not very hard to come by, even a 4015 dual 4 bit should be available in any electronics parts store worldwide and can be wired up to do the same as a 74xx595.
anyway, look at the code you have now

boolean keyPressed[NUM_ROWS][NUM_COLS];
uint8_t keyToMidiMap[NUM_ROWS][NUM_COLS];

it creates 2x a 2-dimensional array to keep track if a key has been pressed and to convert the key to midi. You should probably make 3x a 1-dimensional array first a pin to key map. then a key-pressed register, and finally a key to midi map.
your code will only become simpler(and faster) since you don't need to scan through the matrix to compare key-states.

To do it without shift registers, use one input pin per key. Make a list of the keys:

const byte KeyPins[] = {2, 3, 4, 5, 6, 7, 8, 9};
const byte KeyCount = sizeof KeyPins / sizeof KeyPins[0];

Then make a list of the matching MIDI notes for each key:

const byte NoteNumbers[KeyCount] = {20, 21, 22, 23, 24, 25, 26,27};

You will probably need an array of booleans to keep track of the previous state of each key:

boolean KeyState[KeyCount];

In setup(), set all the pins to INPUT_PULLUP:

for (int i=0; i<KeyCount; i++)
    {
    pinMode(KeyPins[i], INPUT_PULLUP);
    KeyState[i] = digitalRead(KeyPins[i]);
    }

Then in loop() you can check all of the input pins to see which keys are open (HIGH) and which are closed (LOW).

for (int i=0; i<KeyCount; i++)
    {
    if (KeyState[i] != digitalRead(KeyPins[i])) // if state has changed
        {
        if (KeyState[i])
            {
            // Was HIGH (open), now LOW (closed)
            //  Send MIDI note ON for pin i
            KeyState[i] = LOW;
            }
        else
            {
            // Was LOW (closed), now HIGH (open)
            //  Send MIDI note OFF for pin i
            KeyState[i] = HIGH;
            }
        }
    }

The original program use shift register to save output pins; to scan a colum, it puts the column pin LOW and checks if some row pin goes to LOW → key at row, column is pressed.

So, without using shift register, simply pick NUM_COLS consecutive Arduino Mega output pins and connect the pins to the keyboard columns;

in my program I choose pins from 22 to 22+NUM_COLS-1, you can change the first pin by changing FIRST_COLUMN_PIN

#define NUM_ROWS 6
#define NUM_COLS 11

#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;
const int row5Pin = 6;
const int row6Pin = 7;

// pins FIRST_COLUMN_PIN to FIRST_COLUMN_PIN + NUM_COLS - 1 will be columns
#define FIRST_COLUMN_PIN 22

boolean keyPressed[NUM_ROWS][NUM_COLS];
uint8_t keyToMidiMap[NUM_ROWS][NUM_COLS];

void setup()
{
  int note = 31;

  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

  // rows
  pinMode(row1Pin, INPUT_PULLUP);
  pinMode(row2Pin, INPUT_PULLUP);
  pinMode(row3Pin, INPUT_PULLUP);
  pinMode(row4Pin, INPUT_PULLUP);
  pinMode(row5Pin, INPUT_PULLUP);
  pinMode(row6Pin, INPUT_PULLUP);

  // columns
  setupColumns(FIRST_COLUMN_PIN);  
  
  Serial.begin(SERIAL_RATE);
}

void loop()
{ 
  for (int colCtr = 0; colCtr < NUM_COLS; ++colCtr)
  {
    //scan next column
    scanColumn(FIRST_COLUMN_PIN, 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);
    
    resetColumn(FIRST_COLUMN_PIN, colCtr);

    // 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 setupColumns(int base)
{
  for(int i=0; i < NUM_COLS; i++)
  {
    setOutput(base, i);
    resetColumn(base, i);
  }
}

void setOutput(int base, int colNum)
{
  pinMode(base + colNum, OUTPUT);
}

void resetColumn(int base, int colNum)
{
  digitalWrite(base + colNum, HIGH);  
}

void scanColumn(int base, int colNum)
{
  digitalWrite(base + colNum, LOW); 
}

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);
}