mixxx_controller.ino 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include "Controllers.h"
  2. /* This is a sketch that it transforms your Arduino Leonardo or Leonardo like (i.e. boards with atmega32u4) in a MIDI console for interfacing
  3. * with Mixxx (https://mixxx.org). Perhaps you can also use an UNO but you have to sacrifice some pins in order to add a MIDI interface to your Arduino.
  4. * Once you have flashed the board, you have to train Mixxx in Preferences/Controllers menu.
  5. * Remember to plug the Arduino before launching Mixxx, otherwise it won't be detected.
  6. *
  7. * This software is released under the Unlicense (see LICENSE for more info).
  8. *
  9. * Last revision 27-dec-2023
  10. */
  11. // Pin definition
  12. /* Connect linear potentiometers (sliders and knobs) to Analog Inputs on your board.
  13. * On Leonardo, from A0 to A5 are on the left (with USB on top)
  14. * A6, A7, A8, A9, A10 and A11 are digital pins:
  15. * 4, 6, 8, 9, 10, 12.
  16. *
  17. * Change the first value accordingly, the last one is the MIDI effect that is sent to
  18. * Mixxx, every control needs to have a unique number.
  19. */
  20. //Analog controls pins and effects (effects have to be unique among all controls)
  21. int analog_controls_pins[] = {A0,A1,A2,A3,A4,A5,A7,A10,A11};
  22. int analog_controls_effects[] = {7,8,9,1,2,3,4,5,6};
  23. /* Rotary Encorders need two pins.
  24. * clk should be an interrupt. On Leonardo interrupts are on pin 0, 1, 2, 3 and 7.
  25. * dt are digital pins
  26. * rot_effect must be unique and also rot_effect+1 has to be
  27. * it's reserved for anticlockwise
  28. */
  29. const int rot_clk_pins[] = {2,3,0};
  30. const int rot_dt_pins[] = {4,5,1};
  31. const int rot_effect[] = {10,12,18};
  32. /* Digital buttons are connected to a digital pin. If you use toggle, long press or long press toggle rembember that the MIDI message byte has to be unique.
  33. * long_inteval is the interval of long clicks, toggle and long_toggle (for long presses) send two different messages for odd and even strokes.
  34. * If effect is 0 the toggle, long press or long press toggle is disabled.
  35. */
  36. const int button_pins[] = {9,11,8,7,13};
  37. const int button_effect[] = {14,15,16,17,20};
  38. const int button_effect_toggle[] = {0,0,0,0,0};
  39. const int button_effect_long[] {0,23,0,24,25};
  40. const int button_effect_toggle_long[] {0,0,0,26,0};
  41. AnalogControl analog_controls[] = {
  42. AnalogControl(analog_controls_pins[0],analog_controls_effects[0],520),
  43. AnalogControl(analog_controls_pins[1],analog_controls_effects[1],520),
  44. AnalogControl(analog_controls_pins[2],analog_controls_effects[2],520),
  45. AnalogControl(analog_controls_pins[3],analog_controls_effects[3],520),
  46. AnalogControl(analog_controls_pins[4],analog_controls_effects[4],520),
  47. AnalogControl(analog_controls_pins[5],analog_controls_effects[5],520),
  48. AnalogControl(analog_controls_pins[6],analog_controls_effects[6],520),
  49. AnalogControl(analog_controls_pins[7],analog_controls_effects[7],520),
  50. AnalogControl(analog_controls_pins[8],analog_controls_effects[8],520),
  51. };
  52. int active_analog_controls = sizeof(analog_controls)/sizeof(analog_controls[0]);
  53. EncoderButton rotary_encoders[] = {
  54. EncoderButton(rot_clk_pins[0],rot_dt_pins[0]),
  55. EncoderButton(rot_clk_pins[1],rot_dt_pins[1]),
  56. EncoderButton(rot_clk_pins[2],rot_dt_pins[2]),
  57. };
  58. const int active_encoders = sizeof(rotary_encoders)/sizeof(rotary_encoders[1]);
  59. void eb_Encoder(EncoderButton& eb) {
  60. int inc = eb.increment();
  61. if (inc > 0) {
  62. controlChange(1,eb.userId()+1,1);
  63. } else {
  64. controlChange(1,eb.userId(),1);
  65. }
  66. MidiUSB.flush();
  67. }
  68. DigitalButton switches[] = {
  69. DigitalButton(button_pins[0],button_effect[0],button_effect_toggle[0],button_effect_long[0],button_effect_toggle_long[0]),
  70. DigitalButton(button_pins[1],button_effect[1],button_effect_toggle[1],button_effect_long[1],button_effect_toggle_long[1]),
  71. DigitalButton(button_pins[2],button_effect[2],button_effect_toggle[2],button_effect_long[2],button_effect_toggle_long[2]),
  72. DigitalButton(button_pins[3],button_effect[3],button_effect_toggle[3],button_effect_long[3],button_effect_toggle_long[3]),
  73. DigitalButton(button_pins[4],button_effect[4],button_effect_toggle[4],button_effect_long[4],button_effect_toggle_long[4]),
  74. };
  75. const int active_switches = sizeof(switches)/sizeof(switches[0]);
  76. void setup() {
  77. #ifdef DEBUG
  78. while(!Serial);
  79. Serial.begin(115200);
  80. Serial.println("RDY");
  81. #endif
  82. for (int i = 0; i < active_encoders; i++) {
  83. //pinMode(rot_clk_pins[i],INPUT);
  84. //pinMode(rot_dt_pins[i],INPUT);
  85. rotary_encoders[i].setUserId(rot_effect[i]);
  86. rotary_encoders[i].setEncoderHandler(eb_Encoder);
  87. }
  88. }
  89. void loop() {
  90. // Analog controls check.
  91. for (int i = 0; i < active_analog_controls; i++) {
  92. analog_controls[i].checkStatus();
  93. }
  94. // Switches check.
  95. for (int i = 0; i < active_switches; i++) {
  96. switches[i].checkStatus();
  97. }
  98. // Rotary encoders check.
  99. for (int i = 0; i < active_encoders; i++) {
  100. rotary_encoders[i].update();
  101. }
  102. }