////////////////////////////////////////////////////////////////////////////////
// Name:       HarbitronMega-01                                               //
// Platform:   Arduino Mega 2560                                              //
// Created by: HARB rboek2@gmail.com januari 2019 GPL copyrights              //
// Based on:   http://www.arduino.cc/en/Tutorial/Midi                         //
// Robot:      http://robotigs.com/robotigs/includes/bots_header.php?idbot=21 //
//             Midi sending device. Supposed to be a simple instrument.       //
//             In this case to extend the Korg Triton Extreme, but you can    //
//             send any Midi code you like.                                   //
//             Every sequence starts with the number of bytes in the sequence.//
//             Next byte contains the song number                             //
//             Byte 3 contains the sequence in the song = which button.       //
//             Verschillende sequences voor press and release                 //
//             De schakelaar kiest tussen SONG of SYS modus                   //
////////////////////////////////////////////////////////////////////////////////

// SET PRECOMPILER OPTIONS *****************************************************
  // Define precompiler variables, runs faster & doesn`t use RAM ---------------
  // Define PINS ---------------------------------------------------------------
  #define key1            12                        //Red keyboard key HARBITRON
  #define key2            11                      //White keyboard key HARBITRON
  #define key3            10                     //Yellow keyboard key HARBITRON
  #define key4             9                       //Blue keyboard key HARBITRON
  #define key5             8                      //Green keyboard key HARBITRON
  #define key6             7                       //Grey keyboard key HARBITRON
  #define switch1          6                          //Dubbelpolig om HARBITRON

  // Include the needed header files for the precompiler, no charge if not used-
  //Define VARIABLES -----------------------------------------------------------
  bool ledOnBoardVal =  LOW;     //You choose HIGH-on or LOW-off for LED_BUILTIN
  bool key1val       = HIGH;         //HIGH-not-pressed or LOW-pressed HARBITRON
  bool key2val       = HIGH;         //HIGH-not-pressed or LOW-pressed HARBITRON
  bool key3val       = HIGH;         //HIGH-not-pressed or LOW-pressed HARBITRON
  bool key4val       = HIGH;         //HIGH-not-pressed or LOW-pressed HARBITRON
  bool key5val       = HIGH;         //HIGH-not-pressed or LOW-pressed HARBITRON
  bool key6val       = HIGH;         //HIGH-not-pressed or LOW-pressed HARBITRON
  bool switch1val    = HIGH;                         //HIGH=ON LOW=OFF HARBITRON
  int incomingByte   =    0;                    //For incoming serial data RS232
  int counter        =    0;          //Number of bytes to play in sequence MIDI
  int N              =    0;                    //Counter in for/next loops MIDI

  int seq1press[]   = {8, 0x43, 0x45, 0x48, 0x45, 0x4C, 0x45, 0x30, 0x45};
  int seq1release[] = {9, 0x80, 0x43, 0x00, 0x48, 0x00, 0x4C, 0x00, 0x30, 0x0};
  int seq2press[]   = {9, 0x90, 0x44, 0x45, 0x47, 0x45, 0x4C, 0x45, 0x34, 0x45};
  int seq2release[] = {9, 0x80, 0x44, 0x00, 0x47, 0x00, 0x4C, 0x00, 0x34, 0x00};
  int seq3press[]   = {9, 0x90, 0x45, 0x45, 0x48, 0x45, 0x4C, 0x45, 0x2D, 0x45};
  int seq3release[] = {9, 0x80, 0x45, 0x00, 0x48, 0x00, 0x4C, 0x00, 0x2D, 0x00};
  int seq4press[]   = {9, 0x90, 0x45, 0x45, 0x48, 0x45, 0x4D, 0x45, 0x29, 0x45};
  int seq4release[] = {9, 0x80, 0x45, 0x00, 0x48, 0x00, 0x4D, 0x00, 0x29, 0x00};
  int seq5press[]   = {9, 0x90, 0x45, 0x45, 0x48, 0x45, 0x4C, 0x45, 0x2D, 0x45};
  int seq5release[] = {9, 0x80, 0x45, 0x00, 0x48, 0x00, 0x4C, 0x00, 0x2D, 0x00};
  int seq6press[]   = {2, 0xC0, 120};
  int seq6release[] = {2, 0xC0, 3};

  int sys1press[]   = {7, 0xF0, 0x42, 0x30, 0x50, 0x4E, 0x00, 0xF7};  //Sys ex Triton - Change Mode to Combi
  int sys1release[] = {0};
  int sys2press[]   = {3, 0xB0, 0x00, 0x00};    //Plays an entire event message to MIDI - selecteer combi bank D, LUKT NIET!!!!!!!!!!!!!!!!!!!!!!!!!
  int sys2release[] = {0};
  int sys3press[]   = {3, 0xB0, 0x20, 0x03};    //Plays an entire event message to MIDI - selecteer combi bank D, LUKT NIET !!!!!!!!!!!!!!!!!!!!!!!!
  int sys3release[] = {0};   
  int sys4press[]   = {2, 0xC0, 110};           //Verander de combi naar 3 - Selecteer Combination (0-127)
  int sys4release[] = {0};
  int sys5press[]   = {3, 0xB0, 80, 00};        //Set SW1: 0=OFF 80=ON MIDI
  int sys5release[] = {0};
  int sys6press[]   = {3, 0xB0, 81, 80};        //Set SW2: 0=OFF 80=ON MIDI
  int sys6release[] = {0};
  //Initialize OBJECTS ---------------------------------------------------------
//END OF PRECOMPILER OPTIONS ---------------------------------------------------

void setup() { //Setup runs once ***********************************************
  disable_jtag();         //Disable jtag to free port C, enabled by default JTAG
  Serial.begin(9600);                                 //Set MIDI baud rate RS232
  Serial1.begin(31250);                                //Set MIDI baud rate MIDI
  pinMode(LED_BUILTIN, OUTPUT);  //Arduino boards contain an onboard BUILTIN LED

  pinMode(key1, INPUT_PULLUP);                                  //Blue HARBITRON
  pinMode(key2, INPUT_PULLUP);                                 //Green HARBITRON
  pinMode(key3, INPUT_PULLUP);                                 //White HARBITRON
  pinMode(key4, INPUT_PULLUP);                                //Orange HARBITRON
  pinMode(key5, INPUT_PULLUP);                                //Purple HARBITRON
  pinMode(key6, INPUT_PULLUP);                                //Yellow HARBITRON
  pinMode(switch1, INPUT_PULLUP);                               //Rose HARBITRON
  //Start objects --------------------------------------------------------------
  //Test hardware and software -------------------------------------------------

  Serial.println("Setup completed");     //Show the user the setup is done RS232
} //End of setup ---------------------------------------------------------------




void loop() { //KEEP ON RUNNING THIS LOOP FOREVER ******************************
  speelLadder();        //Plays a ladder of keys music to any instrument by MIDI

  if (Serial.available() > 0) {           //Send data only when you receive data
    incomingByte = Serial.read();                       //Read the incoming byte
    Serial.print("I received: ");                             //Say what you got
    Serial.println(incomingByte, DEC);
    toggle_ledOnBoard();         //Toggles the LED_BUILTIN  ON or OFF onboardLED
  } 
  //delay(1000);                                             //Wait milliseconds

  /*
  key1val = digitalRead(key1);
  key2val = digitalRead(key2);
  key3val = digitalRead(key3);
  key4val = digitalRead(key4);
  key5val = digitalRead(key5);
  key6val = digitalRead(key6);
  switch1val = digitalRead(switch1);

  Serial.print(key1val);
  Serial.print(key2val);
  Serial.print(key3val);
  Serial.print(key4val);
  Serial.print(key5val);
  Serial.print(key6val);

  Serial.print(" ");
  Serial.println(switch1val);
*/
  readKeyboard();             //Check the status of all switches on the KEYBOARD
} //End of void loop() ----------------------- KEEP ON RUNNING THIS LOOP FOREVER





void readKeyboard(void){ //Check the status of all switches on the KEYBOARD ****

  switch1val = digitalRead(switch1);
  if (switch1val == LOW){               //Meaning the switch is at SONG position

    if (key1val != digitalRead(key1)) {  //Check if red key1 is pressed KEYBOARD
      key1val = !key1val;                                         //Toggle value
      if (key1val == LOW){                          //Meaning the key is pressed
        Play (seq1press);                              //Play the press sequence
            Serial.println("Toets 1 press");
      }else{                                      //Meaning the key was released
        Play (seq1release);                          //Play the release sequence
            Serial.println("Toets 1 release");
      } //End of if (key1val == LOW)                  Meaning the key is pressed
    } //End of if (key1val != digitalRead(key1))    Check if red key1 is pressed

    if (key2val != digitalRead(key2)){ //Check if white key2 is pressed KEYBOARD
      key2val = !key2val;                                         //Toggle value
      if (key2val == LOW){                          //Meaning the key is pressed
        Play (seq2press);                              //Play the press sequence
      }else{                                      //Meaning the key was released
        Play (seq2release);                          //Play the release sequence
      } //End of if (key2val == LOW)                  Meaning the key is pressed
    } //End of if (key2val != digitalRead(key2))  Check if white key2 is pressed

    if (key3val != digitalRead(key3)){//Check if yellow key3 is pressed KEYBOARD
      key3val = !key3val;                                         //Toggle value
       if (key3val == LOW){                         //Meaning the key is pressed
        Play (seq3press);                              //Play the press sequence
      }else{                                      //Meaning the key was released
        Play (seq3release);                          //Play the release sequence
      } //End of if (key3val == LOW)                  Meaning the key is pressed
    } //End of if (key3val != digitalRead(key3)) Check if yellow key3 is pressed

    if (key4val != digitalRead(key4)) { //Check if blue key4 is pressed KEYBOARD
      key4val = !key4val;                                         //Toggle value
      if (key4val == LOW){                          //Meaning the key is pressed
        Play (seq4press);                              //Play the press sequence
      }else{                                      //Meaning the key was released
        Play (seq4release);                          //Play the release sequence
      } //End of if (key4val == LOW)                  Meaning the key is pressed
    } //End of if (key4val != digitalRead(key4))   Check if blue key4 is pressed

    if (key5val != digitalRead(key5)){ //Check if green key5 is pressed KEYBOARD
      key5val = !key5val;                                         //Toggle value
      if (key5val == LOW){                          //Meaning the key is pressed
        Play (seq5press);                              //Play the press sequence
      }else{                                      //Meaning the key was released
        Play (seq5release);                          //Play the release sequence
      } //End of if (key5val == LOW)                  Meaning the key is pressed
    } //End of if (key5val != digitalRead(key5))  Check if green key5 is pressed

    if (key6val != digitalRead(key6)) { //Check if grey key6 is pressed KEYBOARD
      key6val = !key6val;                                         //Toggle value
      if (key6val == LOW){                          //Meaning the key is pressed
        Play (seq6press);                              //Play the press sequence
      }else{                                      //Meaning the key was released
        Play (seq6release);                          //Play the release sequence
      } //End of if (key6val == LOW)                  Meaning the key is pressed
    } //End of if (key6val != digitalRead(key6))   Check if grey key6 is pressed

  }else{                                 //Meaning the switch is at SYS position

    if (key1val != digitalRead(key1)) {  //Check if red key1 is pressed KEYBOARD
      key1val = !key1val;                                         //Toggle value
      if (key1val == LOW){                          //Meaning the key is pressed
        Play (sys1press);                              //Play the press sequence
            Serial.println("Toets 1 press");
      }else{                                      //Meaning the key was released
        Play (sys1release);                          //Play the release sequence
            Serial.println("Toets 1 release");
      } //End of if (key1val == LOW)                  Meaning the key is pressed
    } //End of if (key1val != digitalRead(key1))    Check if red key1 is pressed

    if (key2val != digitalRead(key2)){ //Check if white key2 is pressed KEYBOARD
      key2val = !key2val;                                         //Toggle value
      if (key2val == LOW){                          //Meaning the key is pressed
        Play (sys2press);                              //Play the press sequence
      }else{                                      //Meaning the key was released
        Play (sys2release);                          //Play the release sequence
      } //End of if (key2val == LOW)                  Meaning the key is pressed
    } //End of if (key2val != digitalRead(key2))  Check if white key2 is pressed

    if (key3val != digitalRead(key3)){//Check if yellow key3 is pressed KEYBOARD
      key3val = !key3val;                                         //Toggle value
       if (key3val == LOW){                         //Meaning the key is pressed
        Play (sys3press);                              //Play the press sequence
      }else{                                      //Meaning the key was released
        Play (sys3release);                          //Play the release sequence
      } //End of if (key3val == LOW)                  Meaning the key is pressed
    } //End of if (key3val != digitalRead(key3)) Check if yellow key3 is pressed

    if (key4val != digitalRead(key4)) { //Check if blue key4 is pressed KEYBOARD
      key4val = !key4val;                                         //Toggle value
      if (key4val == LOW){                          //Meaning the key is pressed
        Play (sys4press);                              //Play the press sequence
      }else{                                      //Meaning the key was released
        Play (sys4release);                          //Play the release sequence
      } //End of if (key4val == LOW)                  Meaning the key is pressed
    } //End of if (key4val != digitalRead(key4))   Check if blue key4 is pressed

    if (key5val != digitalRead(key5)){ //Check if green key5 is pressed KEYBOARD
      key5val = !key5val;                                         //Toggle value
      if (key5val == LOW){                          //Meaning the key is pressed
        Play (sys5press);                              //Play the press sequence
      }else{                                      //Meaning the key was released
        Play (sys5release);                          //Play the release sequence
      } //End of if (key5val == LOW)                  Meaning the key is pressed
    } //End of if (key5val != digitalRead(key5))  Check if green key5 is pressed

    if (key6val != digitalRead(key6)) { //Check if grey key6 is pressed KEYBOARD
      key6val = !key6val;                                         //Toggle value
      if (key6val == LOW){                          //Meaning the key is pressed
        Play (sys6press);                              //Play the press sequence
      }else{                                      //Meaning the key was released
        Play (sys6release);                          //Play the release sequence
      } //End of if (key6val == LOW)                  Meaning the key is pressed
    } //End of if (key6val != digitalRead(key6))   Check if grey key6 is pressed
  } //End of if                                        Switch is in SYS position
} //Exit readKeyboard ----------------------------------------------------------



void speelLadder(void){ //Plays settings to Triton by MIDI ********************
  for (int note = 0x1E; note < 0x5A; note ++) {  // play notes from F#-0 (0x1E) to F#-5 (0x5A):
    int ladderAan[]  = {3, 0x90, note, 0x45}; //Note on channel 1 (0x80), some note value (note), silent velocity (0x00):
    Play (ladderAan);
    delay(100);
    int ladderUit[]  = {3, 0x80, note, 0x00};
    Play (ladderUit);
    delay(100);
  } //Next note
} //Exit speelLadder -----------------------------------------------------------



void Play (int playlist[]){ //Plays a sequence array message to MIDI ***********
  counter = playlist[0] + 1;    //Select the number of bytes for this array MIDI
  for (N=1 ; N<counter ; N++) {                             //Play all data MIDI
    Serial1.write(playlist[N]);                //Transmit the selected byte MIDI
  }                           //Check if there are more bytes to be sent by MIDI
} //Exit Play ------------------------------------------------------------------



void toggle_ledOnBoard(void){ //Toggles the LED_BUILTIN on-board LED on or off *
  ledOnBoardVal = !ledOnBoardVal;                                 //Toggle value
  digitalWrite(LED_BUILTIN, ledOnBoardVal);     //Set Arduino boards onboard LED
} //Exit toggle_ledBin ---------------------------------------------------------




void disable_jtag(void) { //Disable jtag to free port C, enabled by default ****
#if defined(JTD)                           //Not all AVR controller include jtag
  MCUCR |= ( 1 << JTD );                                //Write twice to disable
  MCUCR |= ( 1 << JTD );                                       //So stutter once
#endif                                            //End of conditional compiling
} //Exit jtag_disable ----------------------------------------------------------




////////////////////////////////////////////////////////////////////////////////
// PIN ALLOCATIONS TABLE ARDUINO MEGA 2560                                    //
// Board  -Atmel- PIN - Function          - External Connection          FUNC //
//                                                                            //
// CONNECTIONS RAILS RIGHT TOP: DIGITAL PWM<~> ****************************** //
// SCL    -  43 - PD0 - SCL/INT0          -                               TWI //
// SDA    -  44 - PD1 - SDA/INT1          -                               TWI //
// AREF   -  98 - REF - AREF              -                               REF //
// 13 PWM -  26 - PB7 - OC0A/OC1C/PCINT17 - LED Arduino LED_BUILTIN       PWM //
// 12 PWM -  25 - PB6 - OC1B/PCINT16      -                               PWM //
// 11 PWM -  24 - PB5 - OC1A/PCINT5       -                               PWM //
// 10 PWM -  23 - PB4 - OC2A/PCINT4       -                               PWM //
//  9 PWM -  18 - PH6 - OC2B              -                               PWM //
//  8 PWM -  17 - PH5 - OC4C              -                               PWM //
//                                                                            //
// CONNECTIONS RAILS RIGHT MIDDLE: DIGITAL PWM<~> *************************** //
//  7 PWM -  16 - PH4 - OC4B              -                               PWM //
//  6 PWM -  15 - PH3 - OC4A              -                               PWM //
//  5 PWM -   5 - PE3 - OC3A/AIN1         -                               PWM //
//  4 PWM -   1 - PG5 - OC0B              -                               PWM //
//  3 PWM -   7 - PE5 - OC3C/INT5         -                               INT //
//  2 PWM -   6 - PE4 - OC3B/INT4         -                               INT //
//  1 TX0 -   3 - PE1 - TXD0              - Serial monitor                TX0 //
//  0 RX0 -   2 - PE0 - RXD0/PCINT8       - Serial Monitor                RX0 //
//                                                                            //
// CONNECTIONS RAILS RIGHT BOTTOM: DIGITAL PWM<~> *************************** //
// 14 TX3 -  64 - PJ1 - TXD3/PCINT10      -                               TX3 //
// 15 RX3 -  63 - PJ0 - RXD3/PCINT9       -                               RX3 //
// 16 TX2 -  13 - PH1 - TXD2              -                               TX2 //
// 17 RX2 -  12 - PH0 - RXD2              -                               RX2 //
// 18 TX1 -  46 - PD3 - TXD1/INT3         - MIDI out                      INT //
// 19 RX1 -  45 - PD2 - RXD1/INT2         -                               INT //
// 20 SDA -  44 - PD1 - SDA/INT1          -                               TWI //
// 21 SCL -  43 - PD0 - SCL/INT0          -                               TWI //
//                                                                            //
// CONNECTIONS RAILS LEFT TOP: POWER **************************************** //
// NC     -     -     -                   - Not Connected                     //
// IOREF  -     -     - 3.3/5Vdc          - Outputs controller voltage        //
// 5V     -   7 - VCC - VCC               -                         VCC       //
// RES    -   1 - RES - PCINT14/RESET     -                         RES       //
// 3.3V   -     -     -                   -                                   //
// 5V     -     -     -                   -                                   //
// GND    -     -     -                   -                                   //
// GND    -     -     -                   -                                   //
// Vin    -     -     -                   - 7 - 9Vdc power in                 //
//                                                                            //
// CONNECTIONS RAILS LEFT MIDDLE : ANALOG IN ******************************** //
// A0     -  97 - PF0 - ADC0              -                               ADC //
// A1     -  96 - PF1 - ADC1              -                               ADC //
// A2     -  95 - PF2 - ADC2              -                               ADC //
// A3     -  94 - PF3 - ADC3              -                               ADC //
// A4     -  93 - PF4 - ADC4/TCK          -                               ADC //
// A5     -  92 - PF5 - ADC5/TMS          -                               ADC //
// A6     -  91 - PF6 - ADC6/TDO          -                               ADC //
// A7     -  90 - PF7 - ADC7/TDI          -                               ADC //
//                                                                            //
// CONNECTIONS RAILS LEFT BOTTOM: ANALOG IN ********************************* //
// A8     -  89 - PK0 - ADC8/PCINT16      -                               ADC //
// A9     -  88 - PK1 - ADC9/PCINT17      -                               ADC //
// A10    -  87 - PK2 - ADC10/PCINT18     -                               ADC //
// A11    -  86 - PK3 - ADC11/PCINT19     -                               ADC //
// A12    -  85 - PK4 - ADC12/PCINT20     -                               ADC //
// A13    -  84 - PK5 - ADC13/PCINT21     -                               ADC //
// A14    -  83 - PK6 - ADC14/PCINT22     -                               ADC //
// A15    -  82 - PK7 - ADC15/PCINT23     -                               ADC //
//                                                                            //
// CONNECTIONS DOUBLE RAILS BOTTOM ****************************************** //
// Board  -Atmel- PIN - Function          - External Connection          FUNC //
// 5V     -     - 5Vdc- 5Vdc              -                               VCC //
// 5V     -     - 5Vdc- 5Vdc              -                               VCC //
// 22     -  78 - PA0 - AD0               -                               DIO //
// 23     -  77 - PA1 - AD1               -                               DIO //
// 24     -  76 - PA2 - AD2               -                               DIO //
// 25     -  75 - PA3 - AD3               -                               DIO //
// 26     -  74 - PA4 - AD4               -                               DIO //
// 27     -  73 - PA5 - AD5               -                               DIO //
// 28     -  72 - PA6 - AD6               -                               DIO //
// 29     -  71 - PA7 - AD7               -                               DIO //
// 30     -  60 - PC7 - A14               -                               DIO //
// 31     -  59 - PC6 - A15               -                               DIO //
// 32     -  58 - PC5 - A13               -                               DIO //
// 33     -  57 - PC4 - A12               -                               DIO //
// 34     -  56 - PC3 - A11               -                               DIO //
// 35     -  55 - PC2 - A10               -                               DIO //
// 36     -  54 - PC1 - A9                -                               DIO //
// 37     -  53 - PC0 - A8                -                               DIO //
// 38     -  50 - PD7 - T0                -                               DIO //
// 39     -  70 - PG2 - ALE               -                               DIO //
// 40     -  52 - PG1 - RD                -                               DIO //
// 41     -  51 - PG0 - WR                -                               DIO //
// 42     -  42 - PL7 -                   -                               DIO //
// 43     -  41 - PL6 -                   -                               DIO //
// 44     -  40 - PL5 - OC5C              - 3 Color led Red               PWM //
// 45     -  39 - PL4 - OC5B              - 3 Color led Green             PWM //
// 46     -  38 - PL3 - OC5A              - 3 Color led Blue              PWM //
// 47     -  37 - PL2 - T5                -                               DIO //
// 48     -  36 - PL1 - ICP5              -                               DIO //
// 49     -  35 - PL0 - ICP4              -                               DIO //
// 50     -  22 - PB3 - MISO/PCINT3       - Lan ENC28J60                  SPI //
// 51     -  21 - PB2 - MOSI/PCINT2       - Lan ENC28J60                  SPI //
// 52     -  20 - PB1 - SCK/PCINT1        - Lan ENC28J60                  SPI //
// 53     -  19 - PB1 - SS/PCINT0         - Lan ENC28J60                  SPI //
// GND    -     - GND - GND               -                               GND //
// GND    -     - GND - GND               -                               GND //
////////////////////////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////////////////////
//3456789112345678921234567893123456789412345678951234567896123456789712345678//
// EEPROM MEMORY MAP:                                          Max 4096 bytes //
// Start End  Number Description                                              //
// 0000  0000      1 Never use this memory location to be AVR compatible      //
////////////////////////////////////////////////////////////////////////////////




//345678911234567892123456789312345678941234567895123456789612345678971234567898
////////////////////////////////////////////////////////////////////////////////
// FUSES (can always be altered by using the STK500)                          //
// On-Chip Debug Enabled: off                            (OCDEN=0)            //
// JTAG Interface Enabled: off                           (JTAGEN=0)           //
// Preserve EEPROM mem through the Chip Erase cycle: On  (EESAVE = 0)         //
// Boot Flash section = 2048 words, Boot startaddr=$3800 (BOOTSZ=00)          //
// Boot Reset vector Enabled, default address=$0000      (BOOTSTR=0)          //
// CKOPT fuse (operation dependent of CKSEL fuses        (CKOPT=0)            //
// Brown-out detection level at VCC=2,7V;                (BODLEVEL=0)         //
// Ext. Cr/Res High Freq.; Start-up time: 16K CK + 64 ms (CKSEL=1111 SUT=11)  //
//                                                                            //
// LOCKBITS (are dangerous to change, since they cannot be reset)             //
// Mode 1: No memory lock features enabled                                    //
// Application Protect Mode 1: No lock on SPM and LPM in Application Section  //
// Boot Loader Protect Mode 1: No lock on SPM and LPM in Boot Loader Section  //
////////////////////////////////////////////////////////////////////////////////