/*
NAME:                 5  switches to MIDI Output 
 WRITTEN BY:           TOM SCARFF
 DATE:                 19/9/2009
 FILE SAVED AS:        midi_trumpet.pde
 FOR:                  Miduino ATmega168
 CLOCK:                16.00 MHz CRYSTAL                                        
 PROGRAMME FUNCTION:   5 switches representing trumpet valves to MIDI 
 
 
 
 IMPORTANT:
 The Miduino might not start if it receives data directly after a reset,
 because the bootloader thinks you want to upload a new progam.You might 
 need to unplug the MIDI IN cable until the board is running your program. 
 Also when programming the Miduino disconnect the MIDI IN cable.
 
 HARDWARE NOTE:
 The Midi IN Socket is connected to the Miduino RX through an 6N139 opto-isolator
 *
 * To send MIDI, attach a MIDI out Female 180 Degree 5-Pin DIN socket to Arduino.
 * Socket is seen from solder tags at rear.
 * DIN-5 pinout is:                                         _______ 
 *    pin 2 - Gnd                                          /       \
 *    pin 4 - 220 ohm resistor to +5V                     | 1     3 |  MIDI jack
 *    pin 5 - Arduino Pin 1 (TX) via a 220 ohm resistor   |  4   5  |
 *    all other pins - unconnected                         \___2___/
 *
 */


#define startNote 48       // Start note of C
#define ON_Threshold 100  // Set noise threshold level before switching ON
#define OFF_Threshold 100 // Set LOW level to switch OFF
#define ON_Delay   10       // Set Delay after ON-Threshold is reached, to measure velocity (max volume) of note

//variables setup

int pressureSensor;
byte switchCombination;
byte n;
byte midiByte;
byte MIDIchannel;
byte velocity;

byte channel;
byte status=0;
byte statusType;
byte statusTest;
byte volume_now=0;
byte volume_past=0;
byte x;
byte startTest=0;
byte runningStatus;
byte Flag;
byte LedPin = 13;   // select the pin for the LED
byte runStatusFlag=0;
byte realTimeTest;
byte count;



void setup() {
  pinMode(4, INPUT); // Set Inputs for 4 way DIP Switch
  pinMode(5, INPUT); 
  pinMode(6, INPUT); 
  pinMode(7, INPUT); 

  pinMode(8, INPUT); //  V5  Set Inputs for 5 Valve Switches
  pinMode(9, INPUT); //  V4
  pinMode(10, INPUT);//  V3 
  pinMode(11, INPUT); // V2
  pinMode(12, INPUT);  //V1

  digitalWrite(4, HIGH); // Set inputs Pull-up resistors High
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);

  digitalWrite(8, HIGH); // Set inputs Pull-up resistors High
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
  digitalWrite(11, HIGH);
  digitalWrite(12, HIGH);

  pinMode(LedPin,OUTPUT);   // declare the LED's pin as output

  for (x=1; x<=4; x++){
    digitalWrite( LedPin, HIGH );
    delay(300);
    digitalWrite( LedPin, LOW );
    delay(300);
  }



  Serial.begin(31250);  //start serial with midi baudrate 31250
  Serial.flush();
}


void loop() {

  // Read 4-way DIP switch
  MIDIchannel=digitalRead(4) + (digitalRead(5)<<1) + (digitalRead(6)<<2) + (digitalRead(7)<<3);



  pressureSensor = analogRead(0);
  

  if(pressureSensor > ON_Threshold){
    delay(ON_Delay); // Delay X mS before measuring Velocity
    velocity = analogRead(0)/8;
    
    readSwitches();
    getNoteOn(switchCombination);

    do{
      pressureSensor = analogRead(0);
      velocity = pressureSensor/8;
    }
    while(pressureSensor > OFF_Threshold);

    readSwitches();
    getNoteOff(switchCombination);

  }




}
//_______________________________________________________________________________________________

//  Send a three byte midi message  
void midiSend(byte status, byte data1, byte data2) {
  digitalWrite(LedPin,HIGH);  // indicate we're sending MIDI data
  Serial.print(status, BYTE);
  Serial.print(data1 + startNote, BYTE);
  Serial.print(data2 , BYTE);
  digitalWrite(LedPin,LOW);  // indicate we're sending MIDI data
}
// Functions:



//---------------------------------------------------------------------------------------------------
void readSwitches(){

  // Read Valve 1 to 5  switches
  switchCombination=digitalRead(8) + (digitalRead(9)<<1) + (digitalRead(10)<<2) + (digitalRead(11)<<3)  + (digitalRead(12)<<4); 
}

//____________________________________________________________________________________________________

void getNoteOn(byte var){



  switch (var) {
  case 31:
    midiSend((0x90 | MIDIchannel), 0, velocity);

    break;

  case 3:
    midiSend((0x90 | MIDIchannel), 1, velocity);
    break;

  case 11:
    midiSend((0x90 | MIDIchannel), 2, velocity);
    break;

  case 19:
    midiSend((0x90 | MIDIchannel), 3, velocity);
    break;

  case 7:
    midiSend((0x90 | MIDIchannel), 4, velocity);
    break;

  case 15:
    midiSend((0x90 | MIDIchannel), 5, velocity);
    break;

  case 23:
    midiSend((0x90 | MIDIchannel), 6, velocity);
    break;

  case 29:
    midiSend((0x90 | MIDIchannel), 7, velocity);
    break;

  case 17:
    midiSend((0x90 | MIDIchannel), 8, velocity);
    break;

  case 5:
    midiSend((0x90 | MIDIchannel), 9, velocity);
    break;

  case 13:
    midiSend((0x90 | MIDIchannel), 10, velocity);
    break;

  case 21:
    midiSend((0x90 | MIDIchannel), 11, velocity);
    break;

  case 28:
    midiSend((0x90 | MIDIchannel), 12, velocity);
    break;

  case 0:
    midiSend((0x90 | MIDIchannel), 13, velocity);
    break;

  case 8:
    midiSend((0x90 | MIDIchannel), 14, velocity);
    break;

  case 16:
    midiSend((0x90 | MIDIchannel), 15, velocity);
    break;

  case 4:
    midiSend((0x90 | MIDIchannel), 16, velocity);
    break;

  case 12:
    midiSend((0x90 | MIDIchannel), 17, velocity);
    break;

  case 20:
    midiSend((0x90 | MIDIchannel), 18, velocity);
    break;

  case 30:
    midiSend((0x90 | MIDIchannel), 19, velocity);
    break;

  case 18:
    midiSend((0x90 | MIDIchannel), 20, velocity);
    break;

  case 6:
    midiSend((0x90 | MIDIchannel), 21, velocity);
    break;

  case 14:
    midiSend((0x90 | MIDIchannel), 22, velocity);
    break;

  case 22:
    midiSend((0x90 | MIDIchannel), 23, velocity);
    break;

  default:
    break;  

  }

}

//____________________________________________________________________________________________________

void getNoteOff(byte var){



  switch (var) {
  case 31:
    midiSend((0x80 | MIDIchannel), 0, velocity);

    break;

  case 3:
    midiSend((0x80 | MIDIchannel), 1, velocity);
    break;

  case 11:
    midiSend((0x80 | MIDIchannel), 2, velocity);
    break;

  case 19:
    midiSend((0x80 | MIDIchannel), 3, velocity);
    break;

  case 7:
    midiSend((0x80 | MIDIchannel), 4, velocity);
    break;

  case 15:
    midiSend((0x80 | MIDIchannel), 5, velocity);
    break;

  case 23:
    midiSend((0x80 | MIDIchannel), 6, velocity);
    break;

  case 29:
    midiSend((0x80 | MIDIchannel), 7, velocity);
    break;

  case 17:
    midiSend((0x80 | MIDIchannel), 8, velocity);
    break;

  case 5:
    midiSend((0x80 | MIDIchannel), 9, velocity);
    break;

  case 13:
    midiSend((0x80 | MIDIchannel), 10, velocity);
    break;

  case 21:
    midiSend((0x80 | MIDIchannel), 11, velocity);
    break;

  case 28:
    midiSend((0x80 | MIDIchannel), 12, velocity);
    break;

  case 0:
    midiSend((0x80 | MIDIchannel), 13, velocity);
    break;

  case 8:
    midiSend((0x80 | MIDIchannel), 14, velocity);
    break;

  case 16:
    midiSend((0x80 | MIDIchannel), 15, velocity);
    break;

  case 4:
    midiSend((0x80 | MIDIchannel), 16, velocity);
    break;

  case 12:
    midiSend((0x80 | MIDIchannel), 17, velocity);
    break;

  case 20:
    midiSend((0x80 | MIDIchannel), 18, velocity);
    break;

  case 30:
    midiSend((0x80 | MIDIchannel), 19, velocity);
    break;

  case 18:
    midiSend((0x80 | MIDIchannel), 20, velocity);
    break;

  case 6:
    midiSend((0x80 | MIDIchannel), 21, velocity);
    break;

  case 14:
    midiSend((0x80 | MIDIchannel), 22, velocity);
    break;

  case 22:
    midiSend((0x80 | MIDIchannel), 23, velocity);
    break;

  default:
    break;  

  }

}



//---------------------------------------------------------------------------------------------------