/ DSP-G1_Trellis_Synth / DSP-G1_Trellis_Synth.ino
DSP-G1_Trellis_Synth.ino
1 // SPDX-FileCopyrightText: 2018 John Edgar Park for Adafruit Industries 2 // 3 // SPDX-License-Identifier: MIT 4 5 #include <MIDI.h> 6 #include "Adafruit_Trellis.h" 7 //use Trellis 0-11 and 16-27 as input for notes. 8 //use Trellis 12-15 and 28-31 for input to modes, sequencer, patches 9 //six potentiometers as CC value input 10 //rotary switch to choose banks of CC numbers for knobs 11 12 //John Park for Adafruit Industries 13 14 MIDI_CREATE_DEFAULT_INSTANCE(); 15 Adafruit_Trellis matrix0 = Adafruit_Trellis(); //left Trellis 16 Adafruit_Trellis matrix1 = Adafruit_Trellis(); //right Trellis 17 Adafruit_TrellisSet trellis = Adafruit_TrellisSet(&matrix0, &matrix1); 18 #define NUMTRELLIS 2 19 #define numKeys (NUMTRELLIS * 16) 20 //#define INTPIN A2 21 #define MOMENTARY 0 22 #define LATCHING 1 23 int holdMode = 0; 24 int lastHoldMode = 0; 25 static const unsigned LED = 13; // LED pin on the Feather 26 27 /*********************/ 28 //pick scale mode here: 29 //0=chromatic, 1=major, 2=minor, 3=dorian, 4=mixolydian, 5=harmonic minor 30 int scaleMode = 0; //Dorian 31 /*********************/ 32 int octave = 1; 33 int transpose[6] = {0, 12, 24, 36, 48, 60}; //multiply notes depending on octave 34 //Trellis assignments 35 /* 36 //First three rows map to MIDI Notes, bottom row is special functions 37 ------------------------------------------------------------------------------- 38 0 1 2 3 16 17 18 19 39 M16 M17 M18 M19 M20 M21 M22 M23 40 41 42 4 5 6 7 20 21 22 23 43 M8 M9 M10 M11 M12 M13 M14 M15 44 45 46 8 9 10 11 24 25 26 27 47 M0 M1 M2 M3 M4 M5 M6 M7 48 ------------------------------------------------------------------------------- 49 50 12 13 14 15 28 29 30 31 51 seq patch pause/play rec I II III hold mode 52 ------------------------------------------------------------------------------- 53 */ 54 55 //Map physical Trellis grids to single logical grid 56 int logicalPads[32] = { 0, 1, 2, 3, 8, 9, 10, 11, 57 16, 17, 18, 19, 24, 25, 26, 27, 58 4, 5, 6, 7, 12, 13, 14, 15, 59 20, 21, 22, 23, 28, 29, 30, 31 } ; 60 61 int padNoteMap[24] = { 16, 17, 18, 19, 20, 21, 22, 23, 62 8, 9, 10, 11, 12, 13, 14, 15, 63 0, 1, 2, 3, 4, 5, 6, 7}; 64 65 int padFuncMap[8] = { //note, only hold mode is implemented currently 66 0, // sequencer 67 1, // patch 68 2, // pause/play / recall 69 3, // record / store 70 4, // sequence I / patch I 71 5, // seq. II / patch II 72 6, // seq. III / patch III 73 7 //hold mode: LATCHING or MOMENTARY 74 }; 75 //Define Scales 76 int scalesMatrix[6][24] = { 77 //Chromatic 78 { 0, 1, 2, 3, 4, 5, 6, 7, 79 8, 9, 10, 11, 12, 13, 14, 15, 80 16, 17, 18, 19, 20, 21, 22, 23 }, 81 82 //Major 83 { 0, 2, 4, 5, 7, 9, 11, 12, 84 12, 14, 16, 17, 19, 21, 23, 24, 85 24, 26, 28, 29, 31, 33, 35, 36 }, 86 87 //Minor 88 { 0, 2, 3, 5, 7, 8, 10, 12, 89 12, 14, 15, 17, 19, 20, 22, 24, 90 24, 26, 27, 29, 31, 32, 34, 36 }, 91 92 //Dorian 93 { 0, 2, 3, 5, 6, 9, 10, 12, 94 12, 14, 15, 17, 18, 21, 22, 24, 95 24, 26, 27, 29, 30, 33, 34, 36 }, 96 97 //Mixolydian 98 { 0, 2, 4, 5, 7, 9, 10, 12, 99 12, 14, 16, 17, 19, 21, 22, 24, 100 24, 26, 28, 29, 31, 33, 34, 36 }, 101 102 //Harmonic Minor 103 { 0, 2, 3, 5, 7, 8, 11, 12, 104 12, 14, 15, 17, 19, 20, 23, 24, 105 24, 26, 27, 29, 31, 32, 35, 36 } 106 }; 107 108 //Set up selector switch pins to read digital input pins that set the CC bank 109 const int CC_bankPin0 = 9; 110 const int CC_bankPin1 = 10; 111 const int CC_bankPin2 = 11; 112 const int CC_bankPin3 = 12; 113 114 int CC_bankState0 = 0; 115 int CC_bankState1 = 0; 116 int CC_bankState2 = 0; 117 int CC_bankState3 = 0; 118 119 //current bank per knob. assume not on 0-3 120 int currentBank[6] = {4, 4, 4, 4, 4, 4}; 121 //last bank per knob. assume not on 0-3 122 int lastBank[6] = {5, 5, 5, 5, 5, 5}; 123 124 //Set up potentiometer pins 125 const int CC0_pin = A0; //potentiometer pin 126 int CC0_value; //store pot value 127 const int CC1_pin = A1; 128 int CC1_value; 129 const int CC2_pin = A2; 130 int CC2_value; 131 const int CC3_pin = A3; 132 int CC3_value; 133 const int CC4_pin = A4; 134 int CC4_value; 135 const int CC5_pin = A5; 136 int CC5_value; 137 138 int CC_read[4] ; 139 140 //Store previous values to enable hysteresis and pick-up mode for knobs 141 int CC_bank0_lastValue[6] = {32, 32, 32, 32, 32, 32}; 142 int CC_bank1_lastValue[6] = {32, 32, 32, 32, 32, 32}; 143 int CC_bank2_lastValue[6] = {32, 32, 32, 32, 32, 32}; 144 int CC_bank3_lastValue[6] = {32, 32, 32, 32, 32, 32}; 145 146 int CC_bank0_value[6] = {0, 0, 0, 0, 0, 0}; 147 int CC_bank1_value[6] = {0, 0, 0, 0, 0, 0}; 148 int CC_bank2_value[6] = {0, 0, 0, 0, 0, 0}; 149 int CC_bank3_value[6] = {0, 0, 0, 0, 0, 0}; 150 151 void setup() { 152 Serial.begin(115200); 153 pinMode(LED, OUTPUT); 154 digitalWrite(LED, HIGH); //turn this on as a system power indicator 155 pinMode(CC_bankPin0, INPUT_PULLUP); //loop this 156 pinMode(CC_bankPin1, INPUT_PULLUP); 157 pinMode(CC_bankPin2, INPUT_PULLUP); 158 pinMode(CC_bankPin3, INPUT_PULLUP); 159 160 // Default Arduino I2C speed is 100 KHz, but the HT16K33 supports 161 // 400 KHz. We can force this for faster read & refresh, but may 162 // break compatibility with other I2C devices...so be prepared to 163 // comment this out, or save & restore value as needed. 164 #ifdef ARDUINO_ARCH_SAMD 165 Wire.setClock(400000L); 166 #endif 167 #ifdef __AVR__ 168 TWBR = 12; // 400 KHz I2C on 16 MHz AVR 169 #endif 170 171 trellis.begin(0x70, 0x71); 172 for (uint8_t i=0; i<numKeys; i++) { 173 trellis.setLED(i); 174 trellis.writeDisplay(); 175 delay(15); 176 } 177 // then turn them off 178 for (uint8_t i=0; i<numKeys; i++) { 179 trellis.clrLED(i); 180 trellis.writeDisplay(); 181 delay(15); 182 } 183 184 MIDI.begin(1); 185 186 //All notes off MIDI panic if reset 187 for(int n=0; n<128; n++){ 188 MIDI.sendNoteOff(n, 127, 1); //DC Filter cutoff 189 } 190 191 /////////////DSP-G1 CC Parameter Settings Defaults (to be changed with knobs) 192 MIDI.sendControlChange( 7, 119, 1); //volume 193 MIDI.sendControlChange( 1, 24, 1); //LFO mod 24 194 MIDI.sendControlChange(16, 6, 1); //LFO rate 12 195 MIDI.sendControlChange(20, 0, 1); //LFO waveform 0-63 sine, 64-127 S/H 196 MIDI.sendControlChange(74, 80, 1); //DC Filter cutoff 197 MIDI.sendControlChange(71, 70, 1); //DC Filter resonance 198 MIDI.sendControlChange(82, 32, 1); //DC Filter envelope Attack 199 MIDI.sendControlChange(83, 38, 1); //DC Filter envelope Decay 200 MIDI.sendControlChange(28, 64, 1); //DC Filter envelope Sustain 201 MIDI.sendControlChange(29, 32, 1); //DC Filter envelope Release 202 MIDI.sendControlChange(81, 57, 1); //DC Filter envelope modulation 203 MIDI.sendControlChange(76, 100, 1); //DC Oscillator waveform* 100 204 MIDI.sendControlChange( 4, 0, 1); //DC Oscillator wrap 205 MIDI.sendControlChange(21, 0, 1); //DC Oscillator range 206 MIDI.sendControlChange(93, 0, 1); //DC Oscillator detune 207 MIDI.sendControlChange(73, 0, 1); //DC Oscillator envelope Attack 208 MIDI.sendControlChange(75, 12, 1); //DC Oscillator envelope Decay 209 MIDI.sendControlChange(31, 60, 1); //DC Oscillator envelope Sustain 210 MIDI.sendControlChange(72, 80, 1); //DC Oscillator envelope Release 211 /*Wavforms: 0 tri, 25 squarish, 50 pulse, 75 other squarish, 100 saw */ 212 } 213 214 void loop(){ 215 //read selector switch pins to find CC knob bank 216 CC_bankState0 = digitalRead(CC_bankPin0);//loop this 217 CC_bankState1 = digitalRead(CC_bankPin1); 218 CC_bankState2 = digitalRead(CC_bankPin2); 219 CC_bankState3 = digitalRead(CC_bankPin3); 220 int b; //to increment through current bank state values 221 if (CC_bankState0 == LOW){ //low means it's the selected bank 222 for (b=0;b<6;b++){currentBank[b] = 0;} 223 read_CC_Knobs(0); 224 } 225 else if (CC_bankState1 == LOW){ 226 for (b=0;b<6;b++){currentBank[b] = 1;} 227 read_CC_Knobs(1); 228 } 229 else if (CC_bankState2 == LOW){ 230 for (b=0;b<6;b++){currentBank[b] = 2;} 231 read_CC_Knobs(2); 232 } 233 else if (CC_bankState3 == LOW){ 234 for (b=0;b<6;b++){currentBank[b] = 3;} 235 read_CC_Knobs(3); 236 } 237 else { //4-7 have been picked, not connected 238 for (b=0;b<6;b++){currentBank[b] = 4;} 239 } 240 241 //Trellis MIDI out Keyboard 242 delay(30); // 30ms delay is required, dont remove me! 243 244 if (holdMode == MOMENTARY) { 245 if (trellis.readSwitches()) { // If a button was just pressed or released... 246 for (uint8_t i=0; i<numKeys; i++) { // go through every button 247 if (trellis.justPressed(i)) { // if it was pressed, map what it actually does 248 //remap the physical button to logical button. 'p' is logical pad, i is physical pad. these names stink. 249 int p = logicalPads[i]; 250 // Serial.print("logical pad: "); Serial.println(p); 251 if(p<24){ //it's a MIDI note pad, play a note 252 int padNote = logicalPads[i]; 253 MIDI.sendNoteOn((scalesMatrix[scaleMode][padNoteMap[padNote]] + transpose[octave]), 127, 1); 254 //uncomment for debugging: 255 /* 256 Serial.print("v"); Serial.println(p); //print which button pressed 257 trellis.setLED(i); //light stuff up 258 Serial.print("OUT: "); //print MIDI out command 259 Serial.print("\tChannel: "); Serial.print(1); 260 Serial.print("\tNote: "); Serial.print(scalesMatrix[scaleMode][padNoteMap[padNote]] + transpose[octave]); 261 Serial.print("\tValue: "); Serial.println("127"); 262 */ 263 } 264 else if (p==31){ // last button on bottom row swaps hold modes 265 holdMode = !holdMode; 266 lastHoldMode = holdMode; 267 //Serial.println("Hold mode switch to Latching."); 268 for (uint8_t n=0; n<24; n++) { //clear note LEDs 269 trellis.clrLED(n); 270 trellis.writeDisplay(); 271 } 272 trellis.setLED(i); //light stuff up 273 trellis.writeDisplay(); 274 delay(30); 275 } 276 else{ 277 Serial.println("not a note"); 278 } 279 } 280 if (trellis.justReleased(i)) { // if it was released, turn it off 281 int p = logicalPads[i]; 282 //Serial.print("logical pad: "); Serial.println(p); 283 if(p<24){ //it's a MIDI note pad, play a note 284 int padNote=logicalPads[i]; 285 MIDI.sendNoteOff((scalesMatrix[scaleMode][padNoteMap[padNote]] + transpose[octave]), 127, 1); 286 //Serial.print("^"); Serial.println(p); 287 for (uint8_t i=0; i<numKeys; i++) { 288 trellis.clrLED(i); 289 trellis.writeDisplay(); 290 } 291 trellis.setLED(i); //keep last one that was pressed turned on 292 //uncomment for debugging 293 /* 294 Serial.print("OUT: "); 295 Serial.print("\tChannel: "); Serial.print(1); 296 Serial.print("\tNote: "); Serial.print(scalesMatrix[scaleMode][padNoteMap[padNote]]+ transpose[octave]); 297 */ 298 299 //Serial.print("\tValue: "); Serial.println("0"); 300 } 301 else if (p==31){ // last button on bottom row swaps hold modes 302 } 303 else{ 304 Serial.println("not a note"); 305 } 306 } 307 } 308 trellis.writeDisplay(); // tell the trellis to set the LEDs we requested 309 } 310 } 311 312 if (holdMode == LATCHING) { 313 if (trellis.readSwitches()) { 314 for (uint8_t i=0; i<numKeys; i++) { 315 if (trellis.justPressed(i)) { 316 int p = logicalPads[i]; 317 //Serial.print("logical pad: "); Serial.println(p); 318 if(p<24){ 319 int padNote = logicalPads[i]; 320 //Serial.print("pad note: "); Serial.println(padNote); 321 //Serial.print("v"); Serial.println(i); 322 if (trellis.isLED(i)){ // Alternate the button 323 MIDI.sendNoteOff((scalesMatrix[scaleMode][padNoteMap[padNote]] + transpose[octave]), 127, 1); 324 trellis.clrLED(i); 325 } 326 else{ 327 MIDI.sendNoteOn((scalesMatrix[scaleMode][padNoteMap[padNote]] + transpose[octave]), 127, 1); 328 trellis.setLED(i); 329 } 330 } 331 else if (i==31){ // last button on bottom row swaps hold modes 332 holdMode = !holdMode; 333 lastHoldMode = holdMode; 334 for(int n=0; n<128; n++){ 335 MIDI.sendNoteOff(n, 127, 1); //DC Filter cutoff 336 } 337 for (uint8_t j=0; j<24; j++) { //clear all note pads 338 trellis.clrLED(j); 339 } 340 trellis.clrLED(i); //clear holdMode pad 341 trellis.writeDisplay(); 342 //Serial.println("holdMode switch to Momentary."); 343 delay(30); 344 } 345 else{ 346 Serial.println("not a note"); 347 } 348 } 349 trellis.writeDisplay(); 350 } 351 } 352 } 353 //clear key LEDs after a hold mode change 354 if(holdMode != lastHoldMode){ 355 //Serial.print("Hold mode: "); Serial.println(holdMode); 356 //Serial.print("Last hold mode: "); Serial.println(lastHoldMode); 357 for (uint8_t j=0; j<24; j++) { //clear all note pads 358 trellis.clrLED(j); 359 } 360 trellis.writeDisplay(); 361 } 362 } 363 364 void read_CC_Knobs(int CC_bank){ 365 int AnalogPin[6] = {A0, A1, A2, A3, A4, A5}; //define the analog pins 366 int CCKnob[6] = {0, 1, 2, 3, 4, 5}; //define knobs 367 // choose which CC numbers are on each knob per bank 368 // definitions are at bottom of code 369 //Note: can set knobs to "never change" by repeating CC numbers per array 370 int CCNumber[6]; //variable array to store the CC numbers 371 if(CC_bank == 0){ //set the CC numbers per knob per bank 372 //OSC 373 int CCNumberChoice[6] = {71, //Filter resonance bottom of left knobs 374 74, //Filter cutoff top of left two knobs 375 21, //DCO range upper row 376 93, //DCO detune 377 4, //DCO wrap 378 76 //DCO waveform 379 380 }; 381 for(int n=0; n<6; n++){ 382 CCNumber[n] = CCNumberChoice[n]; 383 } 384 } 385 else if(CC_bank == 1){ 386 //Envelope (for main oscillators) 387 int CCNumberChoice[6] = {71, //Filter resonance 388 74, //Filter cutoff top of left two knobs 389 82, //VCA Attack 390 83, //VCA Decay 391 28, //VCA Sustain 392 29 //VCA Release 393 }; 394 for(int n=0; n<6; n++){ 395 CCNumber[n] = CCNumberChoice[n]; 396 } 397 } 398 else if(CC_bank == 2){ 399 //LFO low frequency oscillator for main OSC 400 int CCNumberChoice[6] = {71, //Filter resonance 401 74, //Filter cutoff top of left two knobs 402 1, //LFO mod 403 16, //LFO rate 404 20, //LFO waveform shape 405 81 //Filter mod 406 }; 407 for(int n=0; n<6; n++){ 408 CCNumber[n] = CCNumberChoice[n]; 409 } 410 } 411 412 else if(CC_bank == 3){ 413 //Envelope (for filter) 414 int CCNumberChoice[6] = {71, //Filter resonance 415 74, //Filter cutoff top of left two knobs 416 1, //Filter A 417 16, //Filter D 418 20, //Filter S 419 81 //Filter R 420 }; 421 for(int n=0; n<6; n++){ 422 CCNumber[n] = CCNumberChoice[n]; 423 } 424 } 425 //Knob pick-up mode -- to deal with multiple knob banks, 426 //value doesn't get sent until knob reaches pravious ("last") position 427 //NOTE: ugly way to do this, clean it up so a matrix is used instead 428 //per bank loop currently 429 430 //Send CC values only when they change beyond last value to avoid getting stuck between two values 431 //thanks to Groovesizer Foxtrot code for this idea: https://groovesizer.com/foxtrot/ 432 //thanks to Todbot for the delta hysteresis idea 433 434 if(CC_bank == 0){ //first bank is selected 435 for(int k=0; k<6; k++){ //loop through each of six pots 436 if(currentBank[k] != lastBank[k]){ //if the current bank for current knob 437 //digitalWrite(LED, LOW); 438 //is different than the last bank for the current knob: 439 //read CC values from potentiometers 440 CC_read[CC_bank] = analogRead(AnalogPin[k]); 441 CC_bank0_value[k] = map(CC_read[CC_bank], 0, 1023, 0, 127); // remap range to 0-127 442 //check against last read when we were on this bank, only send CC if value 443 //of knob is withing a certain delta of the last value 444 if((abs(CC_bank0_lastValue[k] - CC_bank0_value[k])) < 3){ //hysteresis for spinning knob too fast 445 Serial.println("PICKUP ACHIEVED"); 446 //digitalWrite(LED, HIGH); 447 Serial.print("\nCC_bank0_value for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank0_value[k]); 448 Serial.print("CC_bank0_lastValue for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank0_lastValue[k]); 449 lastBank[k] = 0; 450 } 451 } 452 else if(currentBank[k] == lastBank[k]){ 453 //read CC values from potentiometers 454 CC_read[CC_bank] = analogRead(AnalogPin[k]); 455 CC_bank0_value[k] = map(CC_read[CC_bank], 0, 1023, 0, 127); // remap range to 0-127 456 //check against last read, only send CC if value has changed since last read by a certain delta 457 if((abs(CC_bank0_lastValue[k] - CC_bank0_value[k])) > 3){ //hysteresis for spinning knob too fast 458 Serial.print("\nCC_bank0_value for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank0_value[k]); 459 Serial.print("CC_bank0_lastValue for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank0_lastValue[k]); 460 MIDI.sendControlChange(CCNumber[k], CC_bank0_value[k], 1); 461 //Serial.print("CC number: "); Serial.println(CCNumber[k]); 462 CC_bank0_lastValue[k] = CC_bank0_value[k]; 463 lastBank[k] = 0; 464 } 465 } 466 } 467 } 468 469 if(CC_bank == 1){ //second bank is selected 470 for(int k=0; k<6; k++){ //loop through each of six pots 471 if(currentBank[k] != lastBank[k]){ 472 //read CC values from potentiometers 473 CC_read[CC_bank] = analogRead(AnalogPin[k]); 474 CC_bank1_value[k] = map(CC_read[CC_bank], 0, 1023, 0, 127); // remap range to 0-127 475 //check against last read when we were on this bank, only send CC if value 476 //of knob is withing a certain delta of the last value 477 if((abs(CC_bank1_lastValue[k] - CC_bank1_value[k])) < 3){ //hysteresis for spinning knob too fast 478 Serial.println("Pickup achieved."); 479 Serial.print("\nCC_bank1_value for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank1_value[k]); 480 Serial.print("CC_bank1_lastValue for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank1_lastValue[k]); 481 lastBank[k] = 1; 482 } 483 } 484 else if(currentBank[k] == lastBank[k]){ 485 //read CC values from potentiometers 486 CC_read[CC_bank] = analogRead(AnalogPin[k]); 487 CC_bank1_value[k] = map(CC_read[CC_bank], 0, 1023, 0, 127); // remap range to 0-127 488 //check against last read, only send CC if value has changed since last read by a certain delta 489 if((abs(CC_bank1_lastValue[k] - CC_bank1_value[k])) > 3){ //hysteresis for spinning knob too fast 490 Serial.print("\nCC_bank1_value for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank1_value[k]); 491 Serial.print("CC_bank1_lastValue for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank1_lastValue[k]); 492 MIDI.sendControlChange(CCNumber[k], CC_bank1_value[k], 1); 493 //Serial.print("CC number: "); Serial.println(CCNumber[k]); 494 CC_bank1_lastValue[k] = CC_bank1_value[k]; 495 lastBank[k] = 1; 496 } 497 } 498 } 499 } 500 if(CC_bank == 2){ //third bank is selected 501 for(int k=0; k<6; k++){ //loop through each of six pots 502 if(currentBank[k] != lastBank[k]){ 503 //read CC values from potentiometers 504 CC_read[CC_bank] = analogRead(AnalogPin[k]); 505 CC_bank2_value[k] = map(CC_read[CC_bank], 0, 1023, 0, 127); // remap range to 0-127 506 //check against last read when we were on this bank, only send CC if value 507 //of knob is withing a certain delta of the last value 508 if((abs(CC_bank2_lastValue[k] - CC_bank2_value[k])) < 3){ //hysteresis for spinning knob too fast 509 Serial.println("Pickup achieved."); 510 Serial.print("\nCC_bank2_value for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank2_value[k]); 511 Serial.print("CC_bank2_lastValue for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank2_lastValue[k]); 512 lastBank[k] = 2; 513 } 514 } 515 else if(currentBank[k] == lastBank[k]){ 516 //read CC values from potentiometers 517 CC_read[CC_bank] = analogRead(AnalogPin[k]); 518 CC_bank2_value[k] = map(CC_read[CC_bank], 0, 1023, 0, 127); // remap range to 0-127 519 //check against last read, only send CC if value has changed since last read by a certain delta 520 if((abs(CC_bank2_lastValue[k] - CC_bank2_value[k])) > 3){ //hysteresis for spinning knob too fast 521 Serial.print("\nCC_bank2_value for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank2_value[k]); 522 Serial.print("CC_bank2_lastValue for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank2_lastValue[k]); 523 MIDI.sendControlChange(CCNumber[k], CC_bank2_value[k], 1); 524 //Serial.print("CC number: "); Serial.println(CCNumber[k]); 525 CC_bank2_lastValue[k] = CC_bank2_value[k]; 526 lastBank[k] = 2; 527 } 528 } 529 } 530 } 531 if(CC_bank == 3){ //fourth bank is selected 532 for(int k=0; k<6; k++){ //loop through each of six pots 533 if(currentBank[k] != lastBank[k]){ 534 //read CC values from potentiometers 535 CC_read[CC_bank] = analogRead(AnalogPin[k]); 536 CC_bank3_value[k] = map(CC_read[CC_bank], 0, 1023, 0, 127); // remap range to 0-127 537 //check against last read when we were on this bank, only send CC if value 538 //of knob is withing a certain delta of the last value 539 if((abs(CC_bank3_lastValue[k] - CC_bank3_value[k])) < 3){ //hysteresis for spinning knob too fast 540 Serial.println("Pickup achieved."); 541 Serial.print("\nCC_bank3_value for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank3_value[k]); 542 Serial.print("CC_bank3_lastValue for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank3_lastValue[k]); 543 lastBank[k] = 3; 544 } 545 } 546 else if(currentBank[k] == lastBank[k]){ 547 //read CC values from potentiometers 548 CC_read[CC_bank] = analogRead(AnalogPin[k]); 549 CC_bank3_value[k] = map(CC_read[CC_bank], 0, 1023, 0, 127); // remap range to 0-127 550 //check against last read, only send CC if value has changed since last read by a certain delta 551 if((abs(CC_bank3_lastValue[k] - CC_bank3_value[k])) > 3){ //hysteresis for spinning knob too fast 552 Serial.print("\nCC_bank3_value for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank3_value[k]); 553 Serial.print("CC_bank3_lastValue for knob: "); Serial.print(k); Serial.print("\t"); Serial.println(CC_bank3_lastValue[k]); 554 MIDI.sendControlChange(CCNumber[k], CC_bank3_value[k], 1); 555 //Serial.print("CC number: "); Serial.println(CCNumber[k]); 556 CC_bank3_lastValue[k] = CC_bank3_value[k]; 557 lastBank[k] = 3; 558 } 559 } 560 } 561 } 562 }