Components and supplies
Analog joystick (Generic)
Breadboard (generic)
USB-A to Mini-USB Cable
Arduino Nano R3
Switch Actuator, Head for spring return push-button
MIDI Socket
Rotary Encoder with Push-Button
Rotary potentiometer (generic)
Jumper wires (generic)
Graphic OLED, 128 x 64
Tools and machines
Soldering iron (generic)
CNC Machine
Apps and platforms
Hairless MIDI
Arduino IDE
loopMIDI
Project description
Code
Arduino IDE Codes
arduino
Improved encoder Improved settings menu Added notes equation for midi messages on buttons Screen improvement Added 31250 and 115200 baud rate menu
1#include <SPI.h> 2#include <Wire.h> 3#include <Adafruit_GFX.h> 4#include <Adafruit_SSD1306.h> 5#include <EEPROM.h> 6#define SCREEN_WIDTH 128 // OLED display width, in pixels 7#define SCREEN_HEIGHT 64 // OLED display height, in pixels 8 9#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin) 10Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); 11 12 13#define encoder0PinA 9 14#define encoder0PinB 2 15 16byte selectedVal = 0; 17float inc = 0; 18 19const byte rxPin = 12; // not used for the moment 20const byte txPin = 11; 21 22byte clk = 4; 23long buttonTimer = 0; 24long longPressTime = 500; 25boolean buttonActive = false; 26boolean longPressActive = false; 27 28byte val1; 29byte val1Last; 30byte val2; 31byte val2Last; 32byte val3; 33byte val3Last; 34byte val4; 35byte val4Last; 36byte val5; 37byte val5Last; 38 39int xVal; 40byte xValLast; 41int yVal; 42byte yValLast; 43int aVal; 44byte aValLast; 45int bVal; 46byte bValLast; 47int cVal; 48byte cValLast; 49int dVal; 50byte dValLast; 51 52byte b1Val; //button series 53byte b1ValLast; 54 55byte b2Val; 56byte b2ValLast; 57 58byte b3Val; 59byte b3ValLast; 60 61byte b4Val; 62byte b4ValLast; 63 64byte b5Val; 65byte b5ValLast; 66 67//values for screen 68byte xVals; 69byte yVals; 70byte aVals; 71byte bVals; 72byte cVals; 73byte dVals; 74 75byte yValsOld; 76byte xValsOld; 77 78byte ch = 1; 79int oldVal; 80 81bool enabled = false; 82 83byte noteON = 144;//144 = 10010000 in binary, note on command 84byte noteOFF = 128;//128 = 10000000 in binary, note off command 85 86byte note1 = 47; 87byte note1Old; 88byte note2 = 48; 89byte note2Old; 90byte note3 = 50; 91byte note3Old; 92byte note4 = 52; 93byte note4Old; 94byte note5 = 53; 95byte note5Old; 96byte velocity; 97byte velocityOld; 98 99byte octave = 0; 100char octaveBank = 'A'; 101 102byte countLimit = 10; 103int changeVal = 1; 104 105bool flag1 = false; 106bool flag2 = false; 107 108byte baudSet; 109byte baudNum = 1; 110byte baudSetOld; 111 112const char noteNames[12] = {'C', 'C', 'D', 'D', 'E', 'F', 'F', 'G', 'G', 'A', 'A', 'B'}; 113const char noteNames2[12] = {' ', '#', ' ', '#', ' ', ' ', '#', ' ', '#', ' ', '#', ' '}; 114 115void setup() { 116 note1 = EEPROM.read(1); 117 note2 = EEPROM.read(2); 118 note3 = EEPROM.read(3); 119 note4 = EEPROM.read(4); 120 note5 = EEPROM.read(5); 121 velocity = EEPROM.read(6); 122 baudSet = EEPROM.read(7); 123 124 note1Old = note1; 125 note2Old = note2; 126 note3Old = note3; 127 note4Old = note4; 128 note5Old = note5; 129 velocityOld = velocity; 130 baudSetOld = baudSet; 131 132 pinMode(encoder0PinA, INPUT_PULLUP); 133 pinMode(encoder0PinB, INPUT_PULLUP); 134 pinMode(clk, INPUT_PULLUP); 135 136 pinMode(5, INPUT_PULLUP); 137 pinMode(6, INPUT_PULLUP); 138 pinMode(7, INPUT_PULLUP); 139 pinMode(8, INPUT_PULLUP); 140 pinMode(10, INPUT_PULLUP); 141 142 attachInterrupt(0, doEncoder, CHANGE); // encoder pin on interrupt 0 - pin 2 143 if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 144 Serial.println(F("SSD1306 allocation failed")); 145 for (;;); // Don't proceed, loop forever 146 } 147 display.clearDisplay(); 148 display.setRotation(2); 149 display.setTextSize(2); 150 display.setCursor(0, 0); 151 152 pinMode( rxPin, INPUT_PULLUP ); 153 pinMode( txPin, OUTPUT); 154 155 if (baudSet == 1) { 156 Serial.begin(115200); 157 } 158 if (baudSet == 2) { 159 Serial.begin(31250); 160 } 161 162} 163 164void loop() { 165 if (selectedVal != oldVal || yVals != yValsOld || xVals != yValsOld) { 166 display.clearDisplay(); 167 oldVal = selectedVal; 168 yValsOld = yVals; 169 xValsOld = xVals; 170 valKeep(); 171 } 172 173 buttonCheck(); 174 175 if (digitalRead(10) == LOW) { 176 b5Val = noteON; 177 } else { 178 b5Val = noteOFF; 179 } 180 if (digitalRead(8) == LOW) { 181 b1Val = noteON; 182 } else { 183 b1Val = noteOFF; 184 } 185 if (digitalRead(7) == LOW) { 186 b2Val = noteON; 187 } else { 188 b2Val = noteOFF; 189 } 190 if (digitalRead(6) == LOW) { 191 b3Val = noteON; 192 } else { 193 b3Val = noteOFF; 194 } 195 if (digitalRead(5) == LOW) { 196 b4Val = noteON; 197 } else { 198 b4Val = noteOFF; 199 } 200 201 //Joystick starts here------------------------ 202 xVal = analogRead(A6); 203 xVal = map(xVal, 0, 1023, 0, 127); 204 xVals = map(xVal, 127, 0, 121, 80); 205 206 yVal = analogRead(A7); 207 yVal = map(yVal, 0, 1023, 0, 127); 208 yVals = map(yVal, 127, 0, 0, 40); 209 //Joystick ends here-------------------------- 210 211 aVal = analogRead(A3); 212 aVal = map(aVal, 0, 1022, 0, 127); 213 aVals = map(aVal, 0, 127, 0, 70); 214 215 bVal = analogRead(A2); 216 bVal = map(bVal, 0, 1022, 0, 127); 217 bVals = map(bVal, 0, 127, 0, 70); 218 219 cVal = analogRead(A1); 220 cVal = map(cVal, 0, 1022, 0, 127); 221 cVals = map(cVal, 0, 127, 0, 70); 222 223 dVal = analogRead(A0); 224 dVal = map(dVal, 0, 1022, 0, 127); 225 dVals = map(dVal, 0, 127, 0, 70); 226 227 //-XY Plotter--------------------------- 228 display.drawRect(80, 0, 48, 48, WHITE); 229 display.setCursor(xVals, yVals); 230 display.println("."); 231 //-XY plotter ends---------------------- 232 //-Val Control-------------------------- 233 display.setTextSize(2); 234 display.setTextColor(WHITE); 235 if (ch < 6) { 236 237 //- Pot Val---------------------------- 238 display.drawRect(0, 16, 70, 6, WHITE); 239 display.fillRect(0, 16, aVals, 6, INVERSE); 240 //- Pot Val---------------------------- 241 display.drawRect(0, 24, 70, 6, WHITE); 242 display.fillRect(0, 24, bVals, 6, INVERSE); 243 //- Pot Val---------------------. 244 display.drawRect(0, 32, 70, 6, WHITE); 245 display.fillRect(0, 32, cVals, 6, INVERSE); 246 //- Pot Val---------------------. 247 display.drawRect(0, 40, 70, 6, WHITE); 248 display.fillRect(0, 40, dVals, 6, INVERSE); 249 250 display.setTextSize(2); 251 display.setCursor(0, 0); 252 display.println(ch); 253 display.setCursor(20, 0); 254 display.println(":"); 255 256 display.setCursor(40, 0); 257 display.println(selectedVal); 258 //-Val Control----------------------- 259 } else if (ch == 6) { 260 display.setTextSize(1); 261 display.setCursor(0, 0); 262 display.println("Velocity"); 263 264 display.setTextSize(2); 265 display.setCursor(0, 20); 266 display.println(velocity); 267 268 if (velocityOld == velocity) { 269 display.setTextSize(1); 270 display.setCursor(35, 30); 271 display.println("Saved"); 272 } else { 273 display.setTextSize(1); 274 display.setCursor(35, 30); 275 display.println("Unsaved"); 276 if (digitalRead(6) == LOW && digitalRead(5) == LOW) { 277 EEPROM.write(6, velocity); 278 delay(20); 279 velocityOld = velocity; 280 } 281 } 282 } else if (ch == 7) { 283 display.setTextSize(1); 284 display.setCursor(0, 0); 285 display.println("Button 1"); 286 display.setTextSize(2); 287 display.setCursor(0, 20); 288 display.println(note1); 289 290 display.setTextSize(1); 291 display.setCursor(35, 20); 292 display.println(noteNames[note1 % 12]); 293 display.setCursor(45, 20); 294 display.println(noteNames2[note1 % 12]); 295 //------------------------------------------------------------------------------- 296 if (note1Old == note1) { 297 display.setTextSize(1); 298 display.setCursor(35, 30); 299 display.println("Saved"); 300 } else { 301 display.setTextSize(1); 302 display.setCursor(35, 30); 303 display.println("Unsaved"); 304 if (digitalRead(6) == LOW && digitalRead(5) == LOW) { 305 EEPROM.write(1, note1); 306 delay(20); 307 note1Old = note1; 308 } 309 } 310 //------------------------------------------------------------------------------ 311 } else if (ch == 8) { 312 display.setTextSize(1); 313 display.setCursor(0, 0); 314 display.println("Button 2"); 315 display.setTextSize(2); 316 display.setCursor(0, 20); 317 display.println(note2); 318 319 display.setTextSize(1); 320 display.setCursor(35, 20); 321 display.println(noteNames[note2 % 12]); 322 display.setCursor(45, 20); 323 display.println(noteNames2[note2 % 12]); 324 325 if (note2Old == note2) { 326 display.setTextSize(1); 327 display.setCursor(35, 30); 328 display.println("Saved"); 329 } else { 330 display.setTextSize(1); 331 display.setCursor(35, 30); 332 display.println("Unsaved"); 333 if (digitalRead(6) == LOW && digitalRead(5) == LOW) { 334 EEPROM.write(2, note2); 335 delay(20); 336 note2Old = note2; 337 } 338 } 339 } else if (ch == 9) { 340 display.setTextSize(1); 341 display.setCursor(0, 0); 342 display.println("Button 3"); 343 display.setTextSize(2); 344 display.setCursor(0, 20); 345 display.println(note3); 346 347 display.setTextSize(1); 348 display.setCursor(35, 20); 349 display.println(noteNames[note3 % 12]); 350 display.setCursor(45, 20); 351 display.println(noteNames2[note3 % 12]); 352 353 if (note3Old == note3) { 354 display.setTextSize(1); 355 display.setCursor(35, 30); 356 display.println("Saved"); 357 } else { 358 display.setTextSize(1); 359 display.setCursor(35, 30); 360 display.println("Unsaved"); 361 if (digitalRead(6) == LOW && digitalRead(5) == LOW) { 362 EEPROM.write(3, note3); 363 delay(20); 364 note3Old = note3; 365 } 366 } 367 } else if (ch == 10) { 368 display.setTextSize(1); 369 display.setCursor(0, 0); 370 display.println("Button 4"); 371 display.setTextSize(2); 372 display.setCursor(0, 20); 373 display.println(note4); 374 375 display.setTextSize(1); 376 display.setCursor(35, 20); 377 display.println(noteNames[note4 % 12]); 378 display.setCursor(45, 20); 379 display.println(noteNames2[note4 % 12]); 380 381 if (note4Old == note4) { 382 display.setTextSize(1); 383 display.setCursor(35, 30); 384 display.println("Saved"); 385 } else { 386 display.setTextSize(1); 387 display.setCursor(35, 30); 388 display.println("Unsaved"); 389 if (digitalRead(6) == LOW && digitalRead(5) == LOW) { 390 EEPROM.write(4, note4); 391 delay(20); 392 note4Old = note4; 393 } 394 } 395 } else if (ch == 11) { 396 display.setTextSize(1); 397 display.setCursor(0, 0); 398 display.println("Button 5"); 399 display.setTextSize(2); 400 display.setCursor(0, 20); 401 display.println(note5); 402 403 display.setTextSize(1); 404 display.setCursor(35, 20); 405 display.println(noteNames[note5 % 12]); 406 display.setCursor(45, 20); 407 display.println(noteNames2[note5 % 12]); 408 409 if (note5Old == note5) { 410 display.setTextSize(1); 411 display.setCursor(35, 30); 412 display.println("Saved"); 413 } else { 414 display.setTextSize(1); 415 display.setCursor(35, 30); 416 display.println("Unsaved"); 417 if (digitalRead(6) == LOW && digitalRead(5) == LOW) { 418 EEPROM.write(5, note5); 419 delay(20); 420 note5Old = note5; 421 } 422 } 423 } else if (ch == 12) { 424 display.setTextSize(1); 425 display.setCursor(0, 0); 426 display.println("Output"); 427 display.setTextSize(2); 428 429 display.setCursor(0, 20); 430 431 if (baudNum > 10) { 432 display.println("USB"); 433 baudSet = 1; 434 } else { 435 display.println("MIDI"); 436 baudSet = 2; 437 } 438 439 if (baudSet == baudSetOld) { 440 display.setTextSize(1); 441 display.setCursor(35, 30); 442 display.println("Saved"); 443 } else { 444 display.setTextSize(1); 445 display.setCursor(35, 30); 446 display.println("Unsaved"); 447 if (digitalRead(6) == LOW && digitalRead(5) == LOW) { 448 EEPROM.write(7, baudSet); 449 delay(20); 450 baudSetOld = baudSet; 451 } 452 } 453 } 454 //Velocity Value View 455 display.setTextSize(1); 456 display.setCursor(70, 50); 457 display.println("V:"); 458 display.setCursor(80, 50); 459 display.println(velocity); 460 //Output view 461 display.setCursor(102, 50); 462 if (baudSet == 1) { 463 display.println("USB"); 464 } else { 465 display.println("MIDI"); 466 } 467 468 //-Enable Disable Control------- 469 display.setCursor(0, 50); 470 471 if (enabled == false) { 472 flag1 = false; 473 474 if (flag2 == false) 475 { 476 tone(3, 440, 100); 477 flag2 = true; 478 } 479 480 display.println("Edit"); 481 countLimit = 12; 482 flag1 = false; 483 484 //Octave Control ------------------------ 485 if (digitalRead(8) == LOW) { 486 octave = 0; 487 octaveBank = 'A'; 488 } 489 if (digitalRead(7) == LOW) { 490 octave = 12; 491 octaveBank = 'B'; 492 } 493 if (digitalRead(6) == LOW) { 494 octave = 24; 495 octaveBank = 'C'; 496 } 497 if (digitalRead(5) == LOW) { 498 octave = 36; 499 octaveBank = 'D'; 500 } 501 //Octave Control-------------------------- 502 503 //Enabled Section ------------- 504 } else if (enabled == true) { 505 countLimit = 5; 506 flag2 = false; 507 508 if (flag1 == false) 509 { 510 ch = 1; 511 tone(3, 880, 100); 512 flag1 = true; 513 } 514 //Enable Section End----------- 515 516 display.println("Run!"); 517 midiMsg(); 518 } 519 520 display.setCursor(30, 50); 521 display.println("Bank:"); 522 display.setCursor(60, 50); 523 display.println(octaveBank); 524 display.display(); 525} 526 527void MIDImessage(byte command, byte data1, byte data2) 528{ 529 Serial.write(command); 530 Serial.write(data1); 531 Serial.write(data2); 532 533} 534 535void midiMsg() { 536 if (val1 != val1Last) // If the value does not = the last value the following command is made. This is because the pot has been turned. Otherwise the pot remains the same and no midi message is output. 537 { 538 MIDImessage(176, 1, val1); 539 } // 176 = CC command (channel 1 control change), 1 = Which Control, val = value read from Potentionmeter 1 NOTE THIS SAYS VAL not VA1 (lowercase of course) 540 val1Last = val1; 541 //--- 542 if (val2 != val2Last) 543 { 544 MIDImessage(176, 2, val2); 545 } 546 val2Last = val2; 547 //--- 548 if (val3 != val3Last) 549 { 550 MIDImessage(176, 3, val3); 551 } 552 val3Last = val3; 553 //--- 554 if (val4 != val4Last) 555 { 556 MIDImessage(176, 4, val4); 557 } 558 val4Last = val4; 559 //--- 560 if (val5 != val5Last) 561 { 562 MIDImessage(176, 5, val5); 563 } 564 val5Last = val5; 565 //--- 566 567 //--X Y Value to MIDI------------------------------ 568 if (xVal != xValLast) 569 { 570 MIDImessage(176, 11, xVal); 571 } 572 xValLast = xVal; 573 //------------------ 574 if (yVal != yValLast) 575 { 576 MIDImessage(176, 12, yVal); 577 } 578 yValLast = yVal; 579 580 //------------------ 581 if (aVal != aValLast) 582 { 583 MIDImessage(176, 13, aVal); 584 } 585 aValLast = aVal; 586 //------------------ 587 if (bVal != bValLast) 588 { 589 MIDImessage(176, 14, bVal); 590 } 591 bValLast = bVal; 592 //------------------ 593 if (cVal != cValLast) 594 { 595 MIDImessage(176, 15, cVal); 596 } 597 cValLast = cVal; 598 //------------------ 599 if (dVal != dValLast) 600 { 601 MIDImessage(176, 16, dVal); 602 } 603 dValLast = dVal; 604 //Button Section ------------------------------------- 605 if (b1Val != b1ValLast) 606 { 607 MIDImessage(b1Val, note1 + octave, velocity); 608 } 609 b1ValLast = b1Val; 610 611 if (b2Val != b2ValLast) 612 { 613 MIDImessage(b2Val, note2 + octave, velocity); 614 } 615 b2ValLast = b2Val; 616 617 if (b3Val != b3ValLast) 618 { 619 MIDImessage(b3Val, note3 + octave, velocity); 620 } 621 b3ValLast = b3Val; 622 623 if (b4Val != b4ValLast) 624 { 625 MIDImessage(b4Val, note4 + octave, velocity); 626 } 627 b4ValLast = b4Val; 628 629 if (b5Val != b5ValLast) 630 { 631 MIDImessage(b5Val, note5 + octave, velocity); 632 } 633 b5ValLast = b5Val; 634} 635 636void buttonCheck() { 637 if (digitalRead(clk) == LOW) { 638 if (buttonActive == false) { 639 buttonActive = true; 640 buttonTimer = millis(); 641 } 642 if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) { 643 longPressActive = true; 644 enabled = !enabled; 645 } 646 } else { 647 if (buttonActive == true) { 648 if (longPressActive == true) { 649 longPressActive = false; 650 } else { 651 652 if (ch < countLimit) { 653 ch++; 654 display.clearDisplay(); 655 } else { 656 ch = 1; 657 display.clearDisplay(); 658 } 659 valGet(); 660 inc = selectedVal; 661 } 662 buttonActive = false; 663 } 664 } 665} 666 667void valGet() { 668 switch (ch) { 669 case 1: 670 selectedVal = val1; 671 break; 672 case 2: 673 selectedVal = val2; 674 break; 675 case 3: 676 selectedVal = val3; 677 break; 678 case 4: 679 selectedVal = val4; 680 break; 681 case 5: 682 selectedVal = val5; 683 break; 684 case 6: 685 selectedVal = velocity; 686 break; 687 case 7: 688 selectedVal = note1; 689 break; 690 case 8: 691 selectedVal = note2; 692 break; 693 case 9: 694 selectedVal = note3; 695 break; 696 case 10: 697 selectedVal = note4; 698 break; 699 case 11: 700 selectedVal = note5; 701 break; 702 case 12: 703 selectedVal = baudNum; 704 break; 705 } 706} 707 708void valKeep() { 709 switch (ch) { 710 case 1: 711 val1 = selectedVal; 712 break; 713 case 2: 714 val2 = selectedVal; 715 break; 716 case 3: 717 val3 = selectedVal; 718 break; 719 case 4: 720 val4 = selectedVal; 721 break; 722 case 5: 723 val5 = selectedVal; 724 break; 725 case 6: 726 velocity = selectedVal; 727 break; 728 case 7: 729 note1 = selectedVal; 730 break; 731 case 8: 732 note2 = selectedVal; 733 break; 734 case 9: 735 note3 = selectedVal; 736 break; 737 case 10: 738 note4 = selectedVal; 739 break; 740 case 11: 741 note5 = selectedVal; 742 break; 743 case 12: 744 baudNum = selectedVal; 745 break; 746 } 747} 748void doEncoder() 749{ 750 if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) 751 { 752 if (selectedVal < 127) { 753 inc = inc + 0.5; 754 } 755 } 756 else 757 { 758 if (selectedVal > 0) { 759 inc = inc - 0.5; 760 } 761 } 762 selectedVal = inc; 763}
Comments
Only logged in users can leave comments
yilmazyurdakul
0 Followers
•0 Projects
Table of contents
Intro
31
0