arduino mega based midi controller with i2c locks up

Ive built a midi controller using an arduino mega 2560, hiduino, an i2c bus, and 2 dj hero controllers. It's also got 16 digital buttons and 8 analog pots for now, as well as a usb soundcard. I've got everything pretty much working except that the i2c bus keeps locking up. Im using the Wire library and through about as much web searching as I can stand have found there to be a known issue with the Wire library and some i2c setups. I tried to implement the Softi2cMaster library but it wouldnt accept pins 20 and 21 as my SCA and SDA pins, and I didnt want to stray from my buildout, since it would require a fair amount of rework to move the pins around. As a last resort though I could. Does anyone have any advice or pointers on this? A suggestion for what library may work best or a way to make wire stop dying at random times? I'll go ahead and post my current code which is based loosely on the megafighter midi controller

#include <MIDI.h>
#include <Wire.h>
#include <midi_Defs.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define ARDUINO_MEGA
#endif

//#define FASTADC  // defines for setting and clearing register bits
//#ifdef FASTADC
//#ifndef cbi
//#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
//#endif
//#ifndef sbi
//#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
//#endif
//#endif

// MIDI mapping taken from http://www.nortonmusic.com/midi_cc.html
#define MIDI_CC_MODULATION 0x01
#define MIDI_CC_BREATH 0x02
#define MIDI_CC_VOLUME 0x07
#define MIDI_CC_BALANCE 0x08
#define MIDI_CC_PAN 0x0A
#define MIDI_CC_EXPRESSION 0x0B
#define MIDI_CC_EFFECT1 0x0C
#define MIDI_CC_EFFECT2 0x0D

#define MIDI_CC_GENERAL1 0x0E
#define MIDI_CC_GENERAL2 0x0F
#define MIDI_CC_GENERAL3 0x10
#define MIDI_CC_GENERAL4 0x11
#define MIDI_CC_GENERAL5 0x12
#define MIDI_CC_GENERAL6 0x13
#define MIDI_CC_GENERAL7 0x14
#define MIDI_CC_GENERAL8 0x15
#define MIDI_CC_GENERAL9 0x16
#define MIDI_CC_GENERAL10 0x17
#define MIDI_CC_GENERAL11 0x18
#define MIDI_CC_GENERAL12 0x19
#define MIDI_CC_GENERAL13 0x1A
#define MIDI_CC_GENERAL14 0x1B
#define MIDI_CC_GENERAL15 0x1C
#define MIDI_CC_GENERAL16 0x1D
#define MIDI_CC_GENERAL17 0x1E
#define MIDI_CC_GENERAL18 0x1F

#define MIDI_CC_GENERAL1_FINE 0x2E
#define MIDI_CC_GENERAL2_FINE 0x2F
#define MIDI_CC_GENERAL3_FINE 0x30
#define MIDI_CC_GENERAL4_FINE 0x31
#define MIDI_CC_GENERAL5_FINE 0x32
#define MIDI_CC_GENERAL6_FINE 0x33
#define MIDI_CC_GENERAL7_FINE 0x34
#define MIDI_CC_GENERAL8_FINE 0x35
#define MIDI_CC_GENERAL9_FINE 0x36
#define MIDI_CC_GENERAL10_FINE 0x37
#define MIDI_CC_GENERAL11_FINE 0x38
#define MIDI_CC_GENERAL12_FINE 0x39
#define MIDI_CC_GENERAL13_FINE 0x3A
#define MIDI_CC_GENERAL14_FINE 0x3B
#define MIDI_CC_GENERAL15_FINE 0x3C
#define MIDI_CC_GENERAL16_FINE 0x3D
#define MIDI_CC_GENERAL17_FINE 0x3E
#define MIDI_CC_GENERAL18_FINE 0x3F

#define MIDI_CC_SUSTAIN 0x40
#define MIDI_CC_REVERB 0x5B
#define MIDI_CC_CHORUS 0x5D
#define MIDI_CC_CONTROL_OFF 0x79
#define MIDI_CC_NOTES_OFF 0x78
#define MIDI_NOTE_ON 0x90
#define MIDI_NOTE_OFF 0x80
#define NOTE_C0 0x00 // 0
#define NOTE_C1 0x12 // 18
#define NOTE_C2 0x24 // 36

#define NUM_DI 16
#define NUM_AI 8
#define NUM_LED 2
#define NUM_i2c 2
#define MIDI_CHANNEL 1 // First note, starting from upper left button
#define NOTE NOTE_C0
#define DEBOUNCE
#define DEBOUNCE_LENGTH 25  // Debounce time length in milliseconds
#define UNUSED_ANALOG_PINS A0, A1, A2, A3, A4, A5,A6, A7 
#define i2c_addresses 0x0D, 0x0E
//#define LED_PIN 13
//#define DIGITAL_PIN_ORDER 28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43 // This array size must match NUM_AI above.
//#define ANALOGUE_PIN_ORDER
#define LED_PIN_ORDER 13
#define NUM_UNUSED 8 // NUM_UNUSED must = 16 - NUM_AI

//MIDI_CREATE_DEFAULT_INSTANCE();

int readin[23];
int  last_i2c_button[NUM_i2c];
int i2c_button[NUM_i2c];
int  last_i2c_wheel[NUM_i2c];
int i2c_wheel[NUM_i2c];
int  last_i2c_d_dir[NUM_i2c];
int i2c_d_dir[NUM_i2c];
int last_button = 0;
int last_wheel = 0;
int last_d_dir;
int buttonState = 0;
int val = 0;
byte analogueInputMapping[NUM_AI] = {A8, A9, A10, A11, A12, A13, A14, A15};
byte i2c_mapping[NUM_i2c] = {i2c_addresses};
byte i2c_inputs[NUM_i2c];
byte LEDMapping[NUM_LED] = {ledPin1};
byte LEDOutputs[NUM_LED];
byte unusedAnalogPins[NUM_UNUSED] = {UNUSED_ANALOG_PINS};
byte analogueInputs[NUM_AI];
int lastVal[NUM_AI];
int DigilastVal[NUM_DI];
int lastLEDState[NUM_LED];
int16_t tempAnalogueInput;
byte digitalInputMapping[NUM_DI] = {28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43};
byte digitalInputs[NUM_DI];
byte tempDigitalInput;
byte i = 0;
byte digitalOffset = 0;


void setup()
{

  Wire.begin();
  //MIDI.begin(MIDI_CHANNEL_OMNI);
  Serial.begin(9600);
  for (i = 0; i < NUM_AI; i++) {
    pinMode(analogueInputs[i], INPUT); // Set the pin direction to input.
    analogueInputs[i] = analogRead(analogueInputMapping[i]);  
  }
  for (i = 0; i < NUM_DI; i++) {
    pinMode(digitalInputMapping[i], INPUT);         
    digitalInputs[i] = digitalRead(digitalInputMapping[i]);    
    Serial.print(digitalInputMapping[i]);
    Serial.print(" init reading ");
    Serial.println(digitalInputs[i]);
  }
}

void loop()
{
  for (i = 0; i < NUM_i2c; i++) {
    Wire.beginTransmission(i2c_mapping[i]);
    Wire.write(0);
    Wire.endTransmission();
    Wire.requestFrom(i2c_mapping[i], 23);
    for (unsigned int j = 0; j < 23; j++) {
      readin[j] = Wire.read();
    }
    i2c_button[i] = readin[19];
    i2c_wheel[i] = readin[20];
    i2c_d_dir[i] = readin[21];

    if (last_i2c_button[i] != i2c_button[i]) {
      if (i2c_button[i] == 1) {
        Serial.println("green ");
        Serial.println(i2c_mapping[i]);
        //MIDI.sendNoteOn(36+5,127,1);
      }
      if (i2c_button[i] == 2) {
        Serial.println("red ");
        Serial.println(i2c_mapping[i]);
        //MIDI.sendNoteOn(36+7,127,1);
      }
      if (i2c_button[i] == 4) {
        Serial.println("blue ");
        Serial.println(i2c_mapping[i]);
        // MIDI.sendNoteOn(36+9,127,1);
      }
      Serial.println("button");
      last_i2c_button[i] = i2c_button[i];
    }
       if (last_i2c_wheel[i] != i2c_wheel[i]) {


      if (i2c_d_dir[i] == 0 && i2c_d_dir[i] + i2c_wheel[i] > 1) {
        Serial.println(i2c_wheel[i]);
        Serial.print("wheel moved ");
        Serial.println(i2c_mapping[i]);
        Serial.print("left");
        //MIDI.sendNoteOn(36-1,i2c_wheel[i]/2,1);
      }
      if (i2c_d_dir[i] == 255 && i2c_d_dir[i] - i2c_wheel[i] > 1) {
        Serial.println(i2c_wheel[i]);
        Serial.print("wheel moved ");
        Serial.println(i2c_mapping[i]);
        Serial.print("right");
        // MIDI.sendNoteOn(36-2,i2c_wheel[i]/2,1);
      }
      last_i2c_wheel[i] = i2c_wheel[i];
      last_i2c_d_dir[i] = i2c_d_dir[i];
    }
  }
  checkPots();
  checkButtons();

}



void checkPots() {
  for (i = 0; i < NUM_AI; i++) { 
    tempAnalogueInput = analogRead(analogueInputMapping[i]);
    if (abs(tempAnalogueInput - lastVal[i]) >= 8) { // is it noise?
      lastVal[i] = tempAnalogueInput;
      Serial.print("reading analog ");
      Serial.print(analogueInputMapping[i]);
      Serial.println(lastVal[i] / 8);
      // MIDI.sendControlChange(MIDI_CC + i, tempAnalogueInput >> 3, MIDI_CHANNEL);
    }
  }
}

void checkButtons() {
  for (i = 0; i < NUM_DI; i++) {
   tempDigitalInput = digitalRead(digitalInputMapping[i]);
    if (digitalInputs[i] != tempDigitalInput)
    {
#ifdef DEBOUNCE 
      delay(DEBOUNCE_LENGTH); 
      if (tempDigitalInput == digitalRead(digitalInputMapping[i])) {
        DigilastVal[i];
        Serial.print("Temp digi input");
        Serial.print(tempDigitalInput);
        Serial.print(" from ");
        Serial.println(digitalInputMapping[i]);
#endif
        digitalInputs[i] = tempDigitalInput;  // Record the new digital input state.
        if (digitalInputs[i] == 0) { // Moved from HIGH to LOW (button pressed)
          if (digitalInputMapping[i] != LOW) { //digitalInputMapping[i]{
            Serial.println("MIDI send NoteOff H 2 L"); 
          } else {
           
          }
        }
        // Moved from LOW to HIGH (button released)
        else
        {
          if (digitalInputMapping[i] != HIGH) //digitalInputMapping[i]
          {
            Serial.println("MIDI send NoteOn L 2 H");

          } else {
            Serial.println("MIDI send NoteOff L 2 H");

          }
        }
#ifdef DEBOUNCE
      }
#endif
    }
  }
}

I tried to implement the Softi2cMaster library but it wouldnt accept pins 20 and 21 as my SCA and SDA pins

Because they are the hardware I2C pins!

or a way to make wire stop dying at random times?

It only dies if you do something wrong, or the device you are talking to doesn't respond.

  for (i = 0; i < NUM_AI; i++) {
    pinMode(analogueInputs[i], INPUT); // Set the pin direction to input.
    analogueInputs[i] = analogRead(analogueInputMapping[i]);  
  }

Analog pins are input only. Why do you think you need to tell an input only pin that it is an input? The pinMode() function does nothing to analog pins. It does f**k around with the digital nature of the pin, which is useless when you are using it as and analog pin.

Why would you be setting the mode of the pin whose name is in analogueInputs, when the pin numbers clearly are defined in analogueInputMapping?

byte i = 0;

Stupid. One letter names should not be used for global variables.

    Wire.requestFrom(i2c_mapping[i], 23);
    for (unsigned int j = 0; j < 23; j++) {
      readin[j] = Wire.read();
    }

Does requestFrom() block until there are 23 bytes? I don't think so. Reading the 23 bytes that may not have arrived you doesn't strike me as a good idea.