Advertisement
Guest User

SimpleSeq

a guest
Feb 21st, 2012
539
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 37.87 KB | None | 0 0
  1. //////////////////////////////////////////////
  2. //
  3. //  SimpleSeq v.1.0 (2011-11-09)
  4. //   - by Trey Norman
  5. //   - based on design and firmware of Michael Roebbeling's "SimplenZAR"
  6. //
  7. //////////////////////////////////////////////
  8. //
  9. //  Small manual:
  10. //
  11. //  pushbutton 1 moves right <SELECT-R>, pushbutton 2 is enter <ENTER>, pushbutton 3 moves left <SELECT-L>
  12. //
  13. //  scroll trough the steps with <SELECT-L>||<SELECT-R>
  14. //
  15. //  pressing <ENTER> in sequence view (initial view) will take you to Mode Selection
  16. //    - select note on/off, pitch, velocity for each voice by pressing <SELECT-L>||<SELECT-R>
  17. //    - 7 modes total; the mode LEDs will show you the mode
  18. //      * LED1 = (voice 1) note on/off
  19. //      * LED2 = (voice 1) pitch
  20. //      * LED3 = (voice 1) velocity
  21. //      * LEDs inverted for voice 2
  22. //      * No LED = exit mode selection, back to step scolling
  23. //    - choose mode with <ENTER>
  24. //    - adjust mode parameters with potentiometer
  25. //
  26. //  pressing <SELECT-L>&&<SELECT-R> simultaneously will take you to the Menu
  27. //    - 4 menu options, indicated by the first 4 step LEDs
  28. //    - 3 submenu items for each menu option, indicated by the last 3 step LEDs
  29. //    - Menu/submenu breakdown
  30. //      * 1st = change BPM
  31. //        - <ENTER> to select
  32. //        - all submenu items are the same
  33. //        - <ENTER> again to change BPM with potentiometer
  34. //      * 2nd = change play mode
  35. //        - <ENTER> to select
  36. //        - submenu items
  37. //          * 1 = 8-Step sequence
  38. //          * 2 = 16-Step sequence (step LEDs inverted for second 8 steps)
  39. //          * 3 = Shift 8 (8-Step sequence repeated 8 times with ability to shift all notes up or down each time)
  40. //            - edit shiftings with second 8 steps
  41. //        - <ENTER> to choose submenu item
  42. //      * 3rd = read preset from memory
  43. //        - <ENTER> to select
  44. //        - submenu items: presets 1, 2, 3
  45. //        - <ENTER> to load preset
  46. //      * 4th = write preset to memory
  47. //        - <ENTER> to select
  48. //        - submenu items: presets 1, 2, 3
  49. //        - <ENTER> twice to write preset to memory
  50. //  
  51. //  pressing <SELECT-L>&&<ENTER> simultaneously will mute all notes (velocity=0)
  52. //
  53. //  pressing <ENTER>&&<SELECT-R> simultaneously will enter MIDI Control Mode (MIDI CC)
  54. //  - used to control arbitrary functions (eg. delay, filter cutoff frequency, resonance, portamento, etc.)
  55. //  - 8 MIDI CC values available, 0x01 to 0x08 (on most synthesizers 0x01 = modulation wheel)
  56. //  - <ENTER> to write MIDI CC data
  57. //    * value determined by potentiometer
  58. //  - <ENTER> again to stop
  59. //  - NOTE: when setting up MIDI CC on a device listening for a MIDI event (eg. Ableton Live),
  60. //          it is helpful to mute all notes prior to writing MIDI CC data
  61. //
  62. //////////////////////////////////////////////
  63.  
  64. #include <EEPROM.h>        // Include EEPROM library for saving presets (memory addresses 0-422); 512 memory slots total; (memory addresses 423-511 left over)
  65.  
  66. const int stepLed1 = 6;
  67. const int stepLed2 = 7;
  68. const int stepLed3 = 8;
  69. const int stepLed4 = 9;
  70. const int stepLed5 = 10;
  71. const int stepLed6 = 11;
  72. const int stepLed7 = 12;
  73. const int stepLed8 = 13;
  74.  
  75. const int modeLed1 = 3;
  76. const int modeLed2 = 4;
  77. const int modeLed3 = 5;
  78.  
  79.  
  80.   int pos1 = 1;
  81.   int pos2 = 1;
  82.   int pos3 = 1;
  83.  
  84.   int stepPosi = 1;
  85.   int workPosi = 1;
  86.   int stepLength = 8;
  87.  
  88.   int beat = 120;                     // BPM
  89.   int delayMS = (60000 / (beat*4));   // milliseconds of delay = # miliseconds in a minute divided by (BPM x 4); assumes (1 beat = 4 steps)
  90.  
  91.   int note[17];  //0 off / 1 on
  92.   int note2[17];  //0 off / 1 on
  93.   int pitch[17]; //starting at C3 -> Hex 30
  94.   int pitch2[17]; //starting at C3 -> Hex 30
  95.   int velo[17];  // 0 - 127
  96.   int velo2[17]; // 0 - 127
  97.   int prevPitch; //used to start the next enabled note at the last pitch selected
  98.  
  99.   int oldnote[17];  //To stop old note
  100.   int oldnote2[17];  //To stop old note
  101.  
  102.   int shift[9];  //amount of shift from the basenote
  103.  
  104.   int mode = 7; //mode 1 = voice1 note on/off
  105.                 //mode 2 = voice1 pitch
  106.                 //mode 3 = velocity
  107.                 //mode 4 = voice2 note on/off
  108.                 //mode 5 = voice2 pitch
  109.                 //mode 6 = voice2 velocity
  110.                 //mdoe 7 = back
  111.                
  112.   int button1 = A1; //<SELECT-R> Analogpin 1
  113.   boolean button1Pressed = false; //Shows if Button 1 was pressed
  114.   boolean button1State = false;  //Was there a state change?
  115.   int button2 = A2; //<ENTER> Analogpin 2
  116.   boolean button2Pressed = false; //Shows if Button 2 was pressed
  117.   boolean button2State = false;  //Was there a state change?
  118.   int button3 = A3; //<SELECT-L> Analogpin 3
  119.   boolean button3Pressed = false; //Shows if Button 3 was pressed
  120.   boolean button3State = false;  //Was there a state change?
  121.   boolean oneThreePressed = false;  //Shows if Buttons 1&3 were pressed simultateously
  122.   boolean oneThreeState = false;   //Was there a state change?
  123.   boolean oneTwoPressed = false;  //Shows if Buttons 1&2 were pressed simultateously
  124.   boolean oneTwoState = false;   //Was there a state change?
  125.   boolean twoThreePressed = false;  //Shows if Buttons 2&3 were pressed simultateously
  126.   boolean twoThreeState = false;   //Was there a state change?
  127.   int pot1 = A0; // Analogpin 0
  128.   int potposition;
  129.   int programpos = 1;
  130.   int presetCount = 0;   // How many times has enter been pressed when storing preset (2x to store in EEPROM)
  131.   boolean edit = false;  // LED will blink in Edit mode
  132.  
  133.   int menupos = 0;     // menu  0=normal play&edit
  134.                        // 1=change tempo
  135.                        // 2=change steps (8-16-shift)
  136.                        // 3=memory read
  137.                        // 4=memory write
  138.                        
  139.   int submenupos = 1; // used in menupos2 to select play mode, and in menupos3&4 to select memory preset
  140.                      
  141.   //int stepdirection = 1;  // 1 = forward, 2 reverse, 3 bounce MAYBE IN THE FUTURE
  142.  
  143.   int shiftpos = 1;            // position incremented after each step
  144.  
  145.   boolean mute = false;           // Used to mute note playback when setting MIDI control parameters (e.g. in Ableton Live)
  146.   boolean menuactive = false;     // If Menu Active, allow selection of menu items
  147.   boolean menuon = false;         // Menumodus
  148.   boolean shifting = false;       // shift modus on/off
  149.   boolean memWriteArmed = false;     // can only write to memory if true (<ENTER> must be pressed twice)
  150.   boolean midiCCon = false;       // for using pot1 to send MIDI CC (control) messages
  151.   boolean midiCCactive = false;   // If MIDI CC active, send MIDI CC messages
  152.   int midiCC = 0x01;              // Which MIDI control value to use?
  153.  
  154.   int basenote;
  155.  
  156.   int shift816 = 1;            // indicator for 8/16 steps or Shifting, default 8 steps
  157.  
  158.   int ledSetCount = 0;         // used for flashing LEDs on/off; found in main loop under "Final - Set LEDs" section
  159.  
  160.   long prevCheckMS = 0;        // keeps track of last time buttons were checked
  161.   long prevLedMS = 0;          // keeps track of last time LEDs were set
  162.   long prevPlayMS = 0;         // keeps track of last time notes were played
  163.  
  164. void setup()
  165. {
  166.   // set the digital pin for the 8 step leds
  167.   pinMode(stepLed1, OUTPUT);
  168.   pinMode(stepLed2, OUTPUT);
  169.   pinMode(stepLed3, OUTPUT);
  170.   pinMode(stepLed4, OUTPUT);
  171.   pinMode(stepLed5, OUTPUT);
  172.   pinMode(stepLed6, OUTPUT);    
  173.   pinMode(stepLed7, OUTPUT);
  174.   pinMode(stepLed8, OUTPUT);  
  175.  
  176.   pinMode(modeLed1, OUTPUT);
  177.   pinMode(modeLed2, OUTPUT);
  178.   pinMode(modeLed3, OUTPUT);
  179.  
  180.   pinMode(button1, INPUT);
  181.   pinMode(button2, INPUT);  
  182.   pinMode(pot1, INPUT);
  183.  
  184.   // cool looking boot sequence
  185.   digitalWrite(modeLed1, HIGH);
  186.   digitalWrite(modeLed2, HIGH);
  187.   digitalWrite(modeLed3, HIGH);
  188.  
  189.   for(int i = 0; i <= 3; i++)
  190.   {
  191.     digitalWrite(10+i, HIGH);
  192.     digitalWrite(9-i, HIGH);
  193.     delay(250);
  194.   }
  195.  
  196.   for(int led = 13; led >= 6; led--)
  197.   {
  198.     digitalWrite(led, LOW);
  199.     delay(100);
  200.   }
  201.  
  202.   digitalWrite(5, LOW);
  203.   digitalWrite(4, LOW);
  204.   digitalWrite(3, LOW);
  205.  
  206.  
  207.   // initialization of step parameter
  208.   for (int a = 1; a <= 16; a++)
  209.   {
  210.     note[a]=0;
  211.     note2[a]=0;
  212.     pitch[a]=0;
  213.     pitch2[a]=0;
  214.     velo[a]=60;
  215.     velo2[a]=60;
  216.   }
  217.  
  218.   for (int a = 1; a <= 8; a++)
  219.    shift[a]=0;
  220.  
  221.   // 1st Note as index
  222.   note[1]=1;
  223.   pitch[1]=0;
  224.   velo[1]=55;
  225.  
  226.  Serial.begin(31250); //Baudrate for Midi
  227. // Serial.begin(9600); //Baudrate for Serial communication = Debugging
  228.  
  229.  
  230. }
  231.  
  232.  
  233.  
  234.  
  235. void memRead(int preset)
  236. {
  237.   noteOn(0x80, oldnote[stepPosi], 0);        //Turn note off
  238.   noteOn(0x80, oldnote2[stepPosi], 0);       //Turn note off
  239.  
  240.   int addr;    //Incremented to keep track of EEPROM address
  241.   switch (preset)
  242.   {
  243.     case 1:
  244.     addr = 0;              //For Preset 1, first memory address used is address 0
  245.     break;
  246.    
  247.     case 2:
  248.     addr = 141;            //For Preset 2, first memory address used is address 141
  249.     break;
  250.        
  251.     case 3:
  252.     addr = 282;            //For Preset 3, first memory address used is address 282
  253.     break;
  254.        
  255.   }
  256.  
  257.   //The following comments are for the Preset 1 case; add 141 for Preset 2, 282 for Preset 3
  258.  
  259.   beat = EEPROM.read(addr);         //BPM stored at address 0
  260.   delayMS = (60000 / (beat*4));     // delayMS = # miliseconds in a minute divided by (BPM x 4); assumes (1 beat = 4 steps)
  261.   addr++;
  262.  
  263.   for (int x = 1; x <= 16; x++)     //All values for notes, pitches, and velocities are interlaced in addresses 1-8 for step1, 9-16 for step2, ... , 113-128 for step16
  264.   {
  265.     note[x] = EEPROM.read(addr);
  266.     addr++;
  267.     note2[x] = EEPROM.read(addr);
  268.     addr++;
  269.     pitch[x] = EEPROM.read(addr);
  270.     addr++;
  271.     pitch2[x] = EEPROM.read(addr);
  272.     addr++;
  273.     velo[x] = EEPROM.read(addr);
  274.     addr++;
  275.     velo[x] = EEPROM.read(addr);
  276.     addr++;
  277.     oldnote[x] = EEPROM.read(addr);
  278.     addr++;
  279.     oldnote2[x] = EEPROM.read(addr);
  280.     addr++;
  281.   }
  282.    
  283.   for (int x = 1; x <= 8; x++)
  284.   {
  285.     shift[x] = EEPROM.read(addr);      //Amount of shift stored at addresses 129-136
  286.     addr++;
  287.   }
  288.  
  289.   prevPitch = EEPROM.read(addr);       //prevPitch stored at address 137
  290.   addr++;
  291.   stepLength = EEPROM.read(addr);      //stepLength stored at address 138
  292.   addr++;
  293.   shift816 = EEPROM.read(addr);        //shift816 stored at address 139
  294.   addr++;
  295.  
  296.   if (EEPROM.read(addr) == 1)          //shifting stored at address 140 (0 for "false" 1 for "true")
  297.     shifting = true;
  298.   else
  299.     shifting = false;
  300. }
  301.  
  302.  
  303.  
  304.  
  305. void memWrite(int preset)
  306. {
  307.   int addr;                       //Incremented to keep track of EEPROM address
  308.   switch (preset)
  309.   {
  310.     case 1:
  311.     addr = 0;              //For Preset 1, first memory address used is address 0
  312.     break;
  313.    
  314.     case 2:
  315.     addr = 141;            //For Preset 2, first memory address used is address 141
  316.     break;
  317.        
  318.     case 3:
  319.     addr = 282;            //For Preset 3, first memory address used is address 282
  320.     break;
  321.        
  322.   }
  323.  
  324.   //The following comments are for the Preset 1 case; add 141 for Preset 2, 282 for Preset 3
  325.  
  326.   EEPROM.write(addr, beat);       //BPM stored at address 0
  327.   addr++;
  328.  
  329.   for (int x = 1; x <= 16; x++)   //All values for notes, pitches, and velocities are interlaced in addresses 1-8 for step1, 8-16 for step2, ... , 113-128 for step16
  330.   {
  331.     EEPROM.write(addr, note[x]);
  332.     addr++;
  333.     EEPROM.write(addr, note2[x]);
  334.     addr++;
  335.     EEPROM.write(addr, pitch[x]);
  336.     addr++;
  337.     EEPROM.write(addr, pitch2[x]);
  338.     addr++;
  339.     EEPROM.write(addr, velo[x]);
  340.     addr++;
  341.     EEPROM.write(addr, velo2[x]);
  342.     addr++;
  343.     EEPROM.write(addr, oldnote[x]);
  344.     addr++;
  345.     EEPROM.write(addr, oldnote2[x]);
  346.     addr++;
  347.   }
  348.  
  349.   for (int x = 1; x <= 8; x++)
  350.   {
  351.     EEPROM.write(addr, shift[x]);      //Amount of shift stored at addresses 129-136
  352.     addr++;
  353.   }
  354.  
  355.   EEPROM.write(addr, prevPitch);       //prevPitch stored at address 137
  356.   addr++;
  357.   EEPROM.write(addr, stepLength);      //stepLength stored at address 138
  358.   addr++;
  359.   EEPROM.write(addr, shift816);        //shift816 stored at address 139
  360.   addr++;
  361.  
  362.   if (shifting == true)                 //shifting stored at address 140 (0 for "false" 1 for "true")
  363.     EEPROM.write(addr, 1);
  364.   else
  365.     EEPROM.write(addr, 0);
  366. }
  367.  
  368.  
  369.  
  370.  
  371. void ledSet(int steppos, int workpos, int mode, int meunpos, int shiftpos, boolean shifting)
  372. {
  373.   int workpos2, steppos2;
  374.   int invert = 0;                           // if workpos >8 invert modes
  375.    // All LEDs OFF
  376.   for(int x = 3; x < 14; x++)               //digital outputs 6 - 14 for step leds, 3-5 mode leds
  377.     digitalWrite(x, LOW);
  378.  
  379.   if (menupos > 0)                          //Menu is turned on
  380.   {
  381.                                             //Menuindication  
  382.      digitalWrite(2+mode, HIGH);            //Sets Mode runlight
  383.      digitalWrite(5+menupos, HIGH);         //Sets Menuposition
  384.      
  385.      switch(submenupos)
  386.      {
  387.        case 1:
  388.        digitalWrite(11, HIGH);              //6th LED for 8 Steps
  389.        break;
  390.        
  391.        case 2:
  392.        digitalWrite(12, HIGH);              //7th LED for 16 setps
  393.        break;
  394.        
  395.        case 3:
  396.        digitalWrite(13, HIGH);              //8th LED for Shifting
  397.        break;
  398.        
  399.      }
  400.   }
  401.   else //Normal work -> no Menu active
  402.   {
  403.  
  404.     //set Step LED
  405.     if (((steppos > 8) && (workpos > 8))||((steppos < 9)&&(workpos < 9))) // if Step and work are in the same 8 steps
  406.     {
  407.       if(steppos > 8)
  408.         steppos = steppos-8;
  409.        
  410.       digitalWrite(5+steppos, HIGH);  
  411.     }
  412.    
  413.     // Shift LED on
  414.     if (workpos > 8 && shifting == true)
  415.        digitalWrite(5+shiftpos, HIGH);
  416.    
  417.     // workpos set
  418.     if(workpos > 8)
  419.     {
  420.         workpos = workpos-8;
  421.         invert = 1;
  422.     }
  423.    
  424.     digitalWrite(5+workpos, HIGH);
  425.    
  426.    
  427.        
  428.      
  429.      
  430.    
  431.     // mode set
  432.     if(programpos>2)
  433.     {
  434.        if(edit == true)
  435.        {
  436.           if (((invert == 0) && ((mode == 1) || (mode == 4) || (mode == 6))) || ((invert == 1) && ((mode == 2) || (mode == 3) || (mode == 5))))            // note on-off
  437.             digitalWrite(5, HIGH);   // pin 5
  438.           if (((invert == 0) && ((mode == 2) || (mode == 4) || (mode == 5))) || ((invert == 1) && ((mode == 1) || (mode == 3) || (mode == 6))))            // pitch
  439.             digitalWrite(4, HIGH);   // pin 4
  440.           if (((invert == 0) && ((mode == 3) || (mode == 5) || (mode == 6))) || ((invert == 1) && ((mode == 1) || (mode == 2) || (mode == 4))))            // velocity
  441.             digitalWrite(3, HIGH);   // pin 3
  442.           edit = false;
  443.        }
  444.        else
  445.          edit = true;
  446.     }
  447.     else
  448.     {
  449.       if (((invert == 0) && ((mode == 1) || (mode == 4) || (mode == 6))) || ((invert == 1) && ((mode == 2) || (mode == 3) || (mode == 5))))            // note on-off
  450.         digitalWrite(5, HIGH);   // pin 5
  451.       if (((invert == 0) && ((mode == 2) || (mode == 4) || (mode == 5))) || ((invert == 1) && ((mode == 1) || (mode == 3) || (mode == 6))))            // pitch
  452.         digitalWrite(4, HIGH);   // pin 4
  453.       if (((invert == 0) && ((mode == 3) || (mode == 5) || (mode == 6))) || ((invert == 1) && ((mode == 1) || (mode == 2) || (mode == 4))))            // velocity
  454.         digitalWrite(3, HIGH);   // pin 3
  455.       if ((mode==7)&&(invert ==1)) //if no mode choosen and workpos >8, invert
  456.       {
  457.         digitalWrite(5, HIGH);   // pin 5
  458.         digitalWrite(4, HIGH);   // pin 4
  459.         digitalWrite(3, HIGH);   // pin 3
  460.       }
  461.     }
  462.   }
  463. }
  464.  
  465.  
  466.  
  467.  
  468.  
  469. void noteOn(int cmd, int pitch, int velocity)
  470. {
  471.   if (mute)                      // all note velocities set to 0 when muted
  472.   {
  473.     Serial.print(cmd, BYTE);
  474.     Serial.print(pitch, BYTE);
  475.     Serial.print(0, BYTE);
  476.   }
  477.   else
  478.   {
  479.     Serial.print(cmd, BYTE);
  480.     Serial.print(pitch, BYTE);
  481.     Serial.print(velocity, BYTE);
  482.   }
  483. }
  484.  
  485.  
  486.  
  487.  
  488. void checkbuttons()
  489. {
  490.  
  491.   //Button 1 <SELECT-R>
  492.   if(digitalRead(button1)&&button1Pressed==false)
  493.   {
  494.     button1Pressed = true;
  495.     button1State = true;
  496.   }
  497.   else if (button1Pressed == true&&digitalRead(button1)==false)
  498.     button1Pressed = false;  
  499.    
  500.   //Button2 <ENTER>
  501.   if(digitalRead(button2)&&button2Pressed==false)
  502.   {
  503.     button2Pressed = true;
  504.     button2State = true;
  505.   }
  506.   else if (button2Pressed == true&&digitalRead(button2)==false)
  507.     button2Pressed = false;
  508.    
  509.   //Button 3 <SELECT-L>
  510.   if(digitalRead(button3)&&button3Pressed==false)
  511.   {
  512.     button3Pressed = true;
  513.     button3State = true;
  514.   }
  515.   else if (button3Pressed == true&&digitalRead(button3)==false)
  516.     button3Pressed = false;
  517.    
  518.   //Buttons 1&3 <MENU>
  519.   if(digitalRead(button1)&&digitalRead(button3)&&oneThreePressed==false)
  520.   {
  521.     oneThreePressed = true;
  522.     oneThreeState = true;    
  523.   }
  524.   else if (oneThreePressed == true&&digitalRead(button1)==false&&digitalRead(button3)==false)
  525.     oneThreePressed = false;
  526.    
  527.   //Buttons 1&2 <MIDI-CC>
  528.   if(digitalRead(button1)&&digitalRead(button2)&&oneTwoPressed==false)
  529.   {
  530.     oneTwoPressed = true;
  531.     oneTwoState = true;    
  532.   }
  533.   else if (oneTwoPressed == true&&digitalRead(button1)==false&&digitalRead(button2)==false)
  534.     oneTwoPressed = false;
  535.    
  536.   //Buttons 2&3 <MUTE>
  537.   if(digitalRead(button2)&&digitalRead(button3)&&twoThreePressed==false)
  538.   {
  539.     twoThreePressed = true;
  540.     twoThreeState = true;    
  541.   }
  542.   else if (twoThreePressed == true&&digitalRead(button2)==false&&digitalRead(button3)==false)
  543.     twoThreePressed = false;
  544.    
  545.  
  546. }
  547.  
  548. void loop()
  549. {
  550.  
  551. //---------------------------------------------
  552. //---------- Play the next note ---------------
  553. //---------------------------------------------
  554.  
  555.   if (millis() - prevPlayMS > delayMS)
  556.   {
  557.    
  558.     noteOn(0x80, oldnote[stepPosi], 0);        //Turn note off
  559.     noteOn(0x80, oldnote2[stepPosi], 0);        //Turn note off
  560.                                                 //Next step calculation
  561.     stepPosi++;
  562.    
  563.     if (stepPosi > stepLength)
  564.     {
  565.       stepPosi = 1;
  566.       shiftpos++;                               //after 8 Steps shiftposition +1
  567.       if (shiftpos > 8)                         // There are 8 shift positions
  568.         shiftpos=1;
  569.     }
  570.      
  571.                                                 //Check if shift is on
  572.     if(shifting)
  573.        basenote = 0x30+shift[shiftpos];         //Basenote incremented by Shift value
  574.     else
  575.       basenote = 0x30;                          //Basenote stays at hex30
  576.      
  577.      
  578.                                                 // Now we Play the note of the step
  579.  
  580.     if (note[stepPosi])                         // If Note is on, we play the note
  581.     {
  582.  
  583.       noteOn(0x90, basenote+pitch[stepPosi], velo[stepPosi]);
  584.       oldnote[stepPosi]=basenote+pitch[stepPosi];  // Save the note, to turn it off for the next step
  585.     }
  586.    
  587.     if (note2[stepPosi])                         // If Note is on, we play the note
  588.     {
  589.  
  590.       noteOn(0x90, basenote+pitch2[stepPosi], velo2[stepPosi]);
  591.       oldnote2[stepPosi]=basenote+pitch2[stepPosi];  // Save the note, to turn it off for the next step
  592.     }
  593.    
  594.     prevPlayMS = millis();
  595.    
  596.   }    
  597.    
  598.       //----------------------------------------------------
  599.       //----------------- Set LEDs -------------------------
  600.       //----------------------------------------------------
  601.      
  602.       if (millis() - prevLedMS > 25)             // Only allow LEDs to change every 25ms
  603.       {
  604.         if(menuon && menuactive==false)          // running mode LEDs inside menu level
  605.         {
  606.           ledSetCount++;
  607.          
  608.           if(ledSetCount%4 == 0)
  609.             mode++;
  610.          
  611.           if(mode>3)
  612.           {
  613.             mode=1;
  614.             ledSetCount=0;
  615.           }
  616.              
  617.           ledSet(stepPosi, workPosi, mode, menupos, shiftpos, shifting);
  618.         }
  619.        
  620.         if(menuon && menuactive)                // flashing step LEDs when menu item selected
  621.         {
  622.           ledSetCount++;
  623.          
  624.           if(ledSetCount%4 == 0)                // running mode LEDs inside menu
  625.             mode++;
  626.          
  627.           if(mode>3)
  628.             mode=1;
  629.          
  630.           if(ledSetCount<8)
  631.           {
  632.             ledSet(stepPosi, workPosi, mode, menupos, shiftpos, shifting);
  633.             digitalWrite(5+menupos, LOW);
  634.             digitalWrite(10+submenupos, LOW);
  635.           }
  636.           else if(ledSetCount>=8 && ledSetCount<16)
  637.             ledSet(stepPosi, workPosi, mode, menupos, shiftpos, shifting);
  638.           else
  639.           {
  640.             ledSetCount=0;
  641.             ledSet(stepPosi, workPosi, mode, menupos, shiftpos, shifting);
  642.           }
  643.          
  644.           if(memWriteArmed)                    // all step LEDs illuminated when memWriteArmed = true; warns user that preset is about to be overwritten
  645.           {
  646.             for(int x=6; x<14; x++)
  647.               digitalWrite(x, HIGH);
  648.           }
  649.          
  650.         }
  651.        
  652.         if(midiCCon && midiCCactive==false)
  653.           ledSet(midiCC+8, midiCC+8, 7, menupos, shiftpos, false);  // step & work positions the same with all menu LEDs illuminated in MIDI CC mode
  654.        
  655.         if(midiCCon && midiCCactive)                                   // flash step LEDs illuminated when MIDI CC active
  656.         {
  657.           ledSetCount++;
  658.          
  659.           if(ledSetCount<8)
  660.           {
  661.             ledSet(midiCC+8, midiCC+8, 7, menupos, shiftpos, false);
  662.           }
  663.           else if(ledSetCount>=8 & ledSetCount<16)
  664.           {
  665.             for(int x=6; x<14; x++)
  666.               digitalWrite(x, HIGH);
  667.           }
  668.           else
  669.             ledSetCount=0;
  670.         }
  671.        
  672.         if(midiCCon==false && menuon==false)
  673.           ledSet(stepPosi, workPosi, mode, menupos, shiftpos, shifting);
  674.          
  675.         prevLedMS = millis();
  676.       }
  677.      
  678.       //------------------------------------------------
  679.       //--- Check the buttons and process them ---------
  680.       //------------------------------------------------
  681.    
  682.       if (millis() - prevCheckMS > 50)
  683.       {
  684.         checkbuttons();  
  685.        
  686.         //--------------------------------------------Buttons 1&3 <MODE> is pressed, toggle menu
  687.         if (oneThreePressed == true && oneThreeState == true)
  688.         {
  689.           if (menuon==false)                        // toggle menu
  690.           {
  691.             midiCCon=false;                         // Disable MIDI CC
  692.             midiCCactive=false;
  693.             mode=7;                                 // Mode to 7 (no LED)
  694.             programpos=1;                           // Programmpos to 1
  695.            
  696.             memWriteArmed=false;                      // Deactivate ability to write to memory
  697.            
  698.             menuon=true;
  699.             menupos = 1;                            // Menu position to 1
  700.           }
  701.           else                                      // was already on, will be off now
  702.           {
  703.             menuon=false;
  704.             menupos = 0;                            // Menupos to 0
  705.             mode=7;                                 // Mode to 7 (no LED)
  706.             programpos=1;                           // Programmpos to 1
  707.             menuactive=false;                       // There is no Menu
  708.           }
  709.          button1State=false;                        // both buttons are processed
  710.          button3State=false;
  711.          oneThreeState=false;
  712.         }
  713.        
  714.         //--------------------------------------------Buttons 1&2 <MIDI-CC> is pressed, toggle MIDI CC
  715.         if (oneTwoPressed == true && oneTwoState == true)
  716.         {
  717.           if (midiCCon==false)                        // toggle MIDI CC on
  718.           {
  719.             menuon=false;                           // Disable menu
  720.             menuactive=false;                       // There is no Menu
  721.             menupos = 0;                            // Menupos to 0
  722.             mode=7;                                 // Mode to 7 (no LED)
  723.             programpos=1;                           // Programmpos to 1
  724.            
  725.             memWriteArmed=false;                      // Deactivate ability to write to memory
  726.            
  727.             midiCCon=true;
  728.             midiCCactive=false;
  729.           }
  730.           else                                      // was already on , will be off now
  731.           {
  732.             midiCCon=false;
  733.             midiCCactive=false;
  734.             mode=7;                                 // Mode to 7 (no LED)
  735.             programpos=1;                           // Programmpos to 1
  736.           }
  737.          button1State=false;                        // both buttons are processed
  738.          button2State=false;
  739.          oneTwoState=false;
  740.         }
  741.        
  742.         //--------------------------------------------Buttons 2&3 <MUTE> is pressed, toggle note playing on/off
  743.         if (twoThreePressed == true && twoThreeState == true)
  744.         {
  745.           if (mute)                                 // toggle mute
  746.             mute=false;
  747.           else                                      // was already on, will be off now
  748.           {
  749.             mute=true;
  750.           }
  751.          button2State=false;                        // both buttons are processed
  752.          button3State=false;
  753.          twoThreeState=false;
  754.         }
  755.        
  756.         //----------------------------------------------Button 1 - <SELECT-R>
  757.         if (button1Pressed==true && button1State==true)
  758.         {
  759.           if (memWriteArmed==true)
  760.           {
  761.             memWriteArmed=false;                      // Disable ability to write to memory
  762.             menuactive=false;                         // Deactivate Menu
  763.             submenupos=1;
  764.           }
  765.          
  766.           if (menuon == true && menuactive == false)  // If in menumode and no menu is active
  767.           {
  768.              menupos++;                             // <SELECT-R> will scoll trough the menus
  769.              if (menupos > 4)                       // 4 Menupos - Speed, 8/16/Shift, Memory Read, Memory Write
  770.                menupos = 1;
  771.                
  772.              programpos = 0;
  773.           }
  774.          
  775.           if (menuon == true && menuactive == true) //If in menumode and a menu is active
  776.           {
  777.             submenupos++;                           // <SELECT-R> will scoll trough the submenus
  778.             if (submenupos > 3)                     // 3 Submenupos: play mode - step8,step16,shift8; memory read/write - presets 1,2,3
  779.               submenupos = 1;
  780.              
  781.             programpos = 0;
  782.           }
  783.          
  784.           if (midiCCon)                            // Scroll Right through MIDI CC options
  785.           {
  786.             if (midiCC < 0x08)
  787.               midiCC++;
  788.             else
  789.               midiCC = 0x01;
  790.             programpos = 0;
  791.           }
  792.          
  793.                                                     // 1st program level - select moves the cursor
  794.           if (programpos == 1)
  795.           {  
  796.             workPosi++;                             // If Shifing is off and workposi > steplengt back to 1
  797.             if (shifting==false && workPosi > stepLength)
  798.               workPosi = 1;                         // If Shifting is on, there are 8 steps, if workposi > 8, Workposi is for Shifting
  799.             if (shifting == true && workPosi >16)
  800.               workPosi = 1;
  801.           }
  802.          
  803.                                                      // 2nd program level - select changes the mode -1
  804.           if (programpos == 2)
  805.           {
  806.             mode--;
  807.             if (workPosi > stepLength && mode < 1)      // only one mode available for shifting
  808.                 mode = 7;
  809.             if (mode<1)
  810.               mode = 7;
  811.           }
  812.          
  813.                                                        // 3rd,4th,5th,6th,7th,8th Program level - select moves back to 2 level  
  814.           if (programpos > 2)
  815.           {
  816.             programpos = 2;
  817.           }
  818.          
  819.                                                        // Buttonstate to false, button is processed
  820.             button1State=false;
  821.         }
  822.        
  823.        
  824.         //--------------------------------------------------Button 2 - <ENTER>
  825.         if (button2Pressed==true && button2State==true)
  826.         {
  827.           ledSetCount=0;
  828.          
  829.           if (menuon == true)                          // If in menu level
  830.           {                                                
  831.              if (menuactive==false)                     // Menu is turned active
  832.              {                                          
  833.                submenupos=1;                            // Submenu defaults to position 1
  834.                menuactive=true;
  835.              }
  836.              else
  837.              {
  838.                // Note: menupos = 1 case => BPM - controlled by potentiometer
  839.                
  840.                if(menupos==2)          // <SELECT> cycles play modes, <ENTER> sets mode and deactivates menu
  841.                {
  842.                  if(submenupos==1)     // Change play mode to 8-Steps
  843.                  {
  844.                    stepLength=8;
  845.                    shifting=false;
  846.                    shift816=1;
  847.                  }
  848.                  if(submenupos==2)     // Change play mode to 16-Steps
  849.                  {
  850.                    stepLength=16;
  851.                    shifting=false;
  852.                    shift816=2;
  853.                  }              
  854.                  if(submenupos==3)     // Change play mode to Shifting
  855.                  {
  856.                    shifting=true;                                        
  857.                    stepLength=8;
  858.                    shift816=3;
  859.                  }          
  860.                }
  861.                
  862.                if(menupos==3)           // <SELECT> cycles presets, <ENTER> loads preset and deactivates menu
  863.                  memRead(submenupos);
  864.      
  865.                if(menupos==4)           // <SELECT> cycles presets, <ENTER> saves preset and deactivates menu
  866.                {
  867.                  if(memWriteArmed)
  868.                  {
  869.                    memWrite(submenupos);
  870.                    memWriteArmed = false;
  871.                    submenupos=1;
  872.                    menuactive=false;
  873.                  }
  874.                  else
  875.                    memWriteArmed = true;
  876.                }          
  877.                else
  878.                {
  879.                  submenupos=1;
  880.                  menuactive=false;
  881.                }
  882.              }
  883.              
  884.              
  885.              button2State=false;
  886.           }
  887.          
  888.           if (midiCCon && button2State)                 // <ENTER> activates MIDI CC
  889.           {
  890.             if (midiCCactive)
  891.               midiCCactive=false;
  892.             else
  893.               midiCCactive=true;
  894.              
  895.             programpos=1;
  896.             button2State=false;
  897.           }
  898.                                                          // 1st program level - ENTER changes to Program level 2
  899.           if (programpos==1 && button2State==true)
  900.           {  
  901.              programpos=2;
  902.              mode=1;
  903.              button2State=false;
  904.           }
  905.          
  906.                                                           // 2nd program level - Enter changes to program level 3,4,5,6,7,8 (Note on/off, Pitch, Velocity, Voice2 Note on/off, Voice2 Pitch, Voice2 Velocity)
  907.           if (programpos==2 && button2State==true)
  908.           {
  909.             if (workPosi > stepLength && mode == 1)
  910.                 programpos = 3;                           // Change amount of shift
  911.             else
  912.             {
  913.               if (mode == 1)
  914.                 programpos = 3;                             // Note on/off
  915.               if (mode == 2)
  916.                 programpos = 4;                             // Pitch
  917.               if (mode == 3)
  918.                 programpos = 5;                             // Velocity
  919.               if (mode == 4)
  920.                 programpos = 6;                             // Voice2 Note on/off
  921.               if (mode == 5)
  922.                 programpos = 7;                             // Voice2 Pitch
  923.               if (mode == 6)
  924.                 programpos = 8;                             // Voice2 Velocity
  925.             }
  926.            
  927.             if (mode == 7)                                // there is no Mode 7, is used to go back
  928.               programpos = 1;                             // back
  929.              
  930.             button2State=false;                           // Button is processed
  931.           }
  932.          
  933.                                                           // 3rd,4th,5th,6th,7th,8th Program level - ENTER will go back to level 2  
  934.           if (programpos>2 && button2State==true)
  935.           {
  936.             programpos=2;
  937.             button2State=false;                          // Button is processed
  938.           }
  939.          
  940.         }
  941.        
  942.        
  943.         //----------------------------------------------Button 3 - <SELECT-L>
  944.         if (button3Pressed==true && button3State==true)
  945.         {
  946.           if (memWriteArmed==true)
  947.           {
  948.             memWriteArmed=false;                      // Disable ability to write to memory
  949.             menuactive=false;                         // Deactivate Menu
  950.             submenupos=1;
  951.           }
  952.          
  953.           if (menuon == true && menuactive == false)  // If in menumode and no menu is active
  954.           {
  955.              menupos--;                             // <SELECT-L> will scoll trough the menus
  956.              if (menupos < 1)                       // 4 Menupos - Speed, 8/16/Shift, Memory Read, Memory Write
  957.                menupos = 4;
  958.                
  959.              programpos = 0;
  960.           }
  961.          
  962.           if (menuon == true && menuactive == true) // If in menumode and a menu is active
  963.           {
  964.             submenupos--;                           // <SELECT-L> will scoll trough the submenus
  965.             if (submenupos < 1)                     // 3 Submenupos: play mode - step8,step16,shift8; memory read/write - presets 1,2,3
  966.               submenupos = 3;
  967.              
  968.             programpos = 0;
  969.           }
  970.          
  971.           if (midiCCon)                            // Scroll Left through MIDI CC options
  972.           {
  973.             if (midiCC > 0x01)
  974.               midiCC--;
  975.             else
  976.               midiCC = 0x08;
  977.             programpos = 0;
  978.           }
  979.          
  980.                                                     // 1st program level - select moves the cursor
  981.           if (programpos == 1)
  982.           {  
  983.             workPosi--;                             // If Shifing is off and workposi < 1, back to stepLength
  984.             if (shifting==false && workPosi < 1)
  985.               workPosi = stepLength;                         // If Shifting is on, there are 8 steps, if workposi < 1, Workposi is for Shifting
  986.             if (shifting == true && workPosi < 1)
  987.               workPosi = 16;
  988.           }
  989.          
  990.                                                      // 2nd program level - select changes the mode +1
  991.           if (programpos == 2)
  992.           {
  993.             mode++;
  994.             if (workPosi > stepLength && mode > 1)      // only one mode available for shifting
  995.                 mode = 7;
  996.             if (mode>7)
  997.               mode = 1;
  998.           }
  999.                                                        // 3rd,4th,5th,6th,7th,8th Program level - select moves back to 2 level  
  1000.           if (programpos > 2)
  1001.           {
  1002.             programpos = 2;
  1003.           }
  1004.          
  1005.                                                        // Buttonstate to false, button is processed
  1006.             button3State=false;
  1007.         }
  1008.      
  1009.      
  1010.         //---------------------------------------------------
  1011.         //--- Potentiometer ---------------------------------
  1012.         //---------------------------------------------------
  1013.         if(programpos==3 && menupos==0 && workPosi <= stepLength)  // Note on/off mode
  1014.         {
  1015.           note[workPosi] = analogRead(pot1)/512;
  1016.           if(oldnote[workPosi] == 0)
  1017.             pitch[workPosi] = prevPitch;                           // Starts new note using previous pitch to keep everything in key
  1018.         }
  1019.        
  1020.         if(programpos==3 && menupos==0 && workPosi > stepLength)   // ATTENTION this is the change for basenote shifting
  1021.           shift[workPosi-8] = analogRead(pot1)/28 - 18;            // can shift up or down 18 half-steps from basenote (C2)
  1022.        
  1023.         if(programpos==4 && menupos==0)                            // Pitch mode
  1024.         {
  1025.           pitch[workPosi] = analogRead(pot1)/28;
  1026.           if(oldnote2[workPosi] == 0)
  1027.             prevPitch = pitch[workPosi];
  1028.         }
  1029.        
  1030.         if(programpos==5 && menupos==0)                            // Velocity mode
  1031.           velo[workPosi] = analogRead(pot1)/8;
  1032.          
  1033.         if(programpos==6 && menupos==0 && workPosi <= stepLength)  // Voice2 Note on/off mode
  1034.         {
  1035.           note2[workPosi] = analogRead(pot1)/512;
  1036.           pitch2[workPosi] = prevPitch;                            // Starts new note using previous pitch to keep everything in key
  1037.         }
  1038.        
  1039.         if(programpos==7 && menupos==0)                            // Voice2 Pitch mode
  1040.         {
  1041.           pitch2[workPosi] = analogRead(pot1)/28;
  1042.           prevPitch = pitch2[workPosi];
  1043.         }
  1044.        
  1045.         if(programpos==8 && menupos==0)                            // Voice2 Velocity mode
  1046.           velo2[workPosi] = analogRead(pot1)/8;
  1047.        
  1048.         if(menupos==1 && menuactive==true)                        // If menuactive and menu 1 chosen
  1049.         {
  1050.           beat = 60 + .2346*(analogRead(pot1));                   // set BPM (60 to 300) | .2346 = 1023/240
  1051.           delayMS = (60000 / (beat*4));                           // delayMS = # miliseconds in a minute divided by (BPM x 4); assumes (1 beat = 4 steps)
  1052.         }
  1053.          
  1054.         if(midiCCactive)                                          // Send pot value (0-127) to slected MIDI CC
  1055.         {
  1056.           Serial.print(0xB0, BYTE);
  1057.           Serial.print(midiCC, BYTE);
  1058.           Serial.print((analogRead(pot1)/8), BYTE);
  1059.         }
  1060.      
  1061.         prevCheckMS = millis();
  1062.       }
  1063. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement