By Harry Schneider
Description:
The MINI controller is a compact and portable MIDI controller which allows you to produce music more efficiently.
Discussion:
Overall, I am very happy with how this project turned out. I am very pleased with the build quality despite it being my first time 3D printing. Also I think the size and overall durability is great. My goal was to make something that, if manufactured, I would personally purchase and use. Maybe I am just overly critical but I would have liked to go smaller if possible. The current size is 3 x 3 inches but I would love if it could fit comfortably in my pocket. The current size was already a challenge for me. It was very hard to fit all of the electronics inside especially with the usb input attachment. This attachment came with a large cable that took up a lot of space on the inside. In the future I would like to make another version which would have a USB type C input instead of type B. Type C is much smaller and more compatible with current technology. Also I would make it around 2 inches by 2 inches instead of 3 inches. In addition I would also make it slimmer. I found the 3D printing process to be really fun. It was very difficult designing everything in cad but with the help of my teacher I was able to actualize the case for the midi controller.
I was very happy with the feedback from my critique. However I was told to consider labeling the functions of the potentiometers. I understand how this makes sense but in reality, the assignments of the knobs change depending on how I intend to use them. Also it was suggested that I could use a micro Arduino if I wanted to go smaller. I will definitely use a smaller Arduino in the future. I think this was really great feedback.
Photos and Videos
Process
3D Modeling
Schematic
Block Diagram
/* Harry Schneider: MINI Controller Adapted from code for midi potentiometers from Gustavo Silviera Aka "Nerd musician" on youtube (http://www.youtube.com/musiconerd) */ #define ATMEGA32U4 1 #ifdef ATMEGA328 #include <MIDI.h> #elif ATMEGA32U4 #include "MIDIUSB.h" #endif const int N_POTS = 4; // total numbers of pots const int POT_ARDUINO_PIN[N_POTS] = {A0, A1, A2, A3}; int potCState[N_POTS] = {0}; // Current state of the pot int potPState[N_POTS] = {0}; // Previous state of the pot int potVar = 0; // Difference between the current and previous state of the pot int midiCState[N_POTS] = {0}; // Current state of the midi value int midiPState[N_POTS] = {0}; // Previous state of the midi value const int TIMEOUT = 300; // Amount of time the potentiometer will be read after it exceeds the varThreshold const int varThreshold = 10; // Threshold for the potentiometer signal variation boolean potMoving = true; // If the potentiometer is moving unsigned long PTime[N_POTS] = {0}; // Previously stored time unsigned long timer[N_POTS] = {0}; // Stores the time that has elapsed since the timer was reset // MIDI byte midiCh = 0; // MIDI channel to be used byte note = 36; // Lowest note to be used byte cc = 1; // Lowest MIDI CC to be used // SETUP void setup() { Serial.begin(115200); #ifdef DEBUG Serial.println("Debug mode"); Serial.println(); #endif } #ifdef pin13 if (i == pin13index) { buttonCState[i] = !buttonCState[i]; // inverts the pin 13 because it has a pull down resistor instead of a pull up } #endif // Sends the MIDI note ON accordingly to the chosen board #ifdef ATMEGA328 // use if using with ATmega328 (uno, mega, nano...) MIDI.sendNoteOn(note + i, 127, midiCh); // note, velocity, channel #elif ATMEGA32U4 // use if using with ATmega32U4 (micro, pro micro, leonardo...) #elif TEENSY //do usbMIDI.sendNoteOn if using with Teensy usbMIDI.sendNoteOn(note + i, 127, midiCh); // note, velocity, channel #elif DEBUG Serial.print(i); Serial.println(": button on"); #endif // Sends the MIDI note OFF accordingly to the chosen board #ifdef ATMEGA328 // use if using with ATmega328 (uno, mega, nano...) MIDI.sendNoteOn(note + i, 0, midiCh); // note, velocity, channel #elif ATMEGA32U4 // use if using with ATmega32U4 (micro, pro micro, leonardo...) #elif TEENSY //do usbMIDI.sendNoteOn if using with Teensy usbMIDI.sendNoteOn(note + i, 0, midiCh); // note, velocity, channel #elif DEBUG Serial.print(i); Serial.println(": button off"); #endif ///////////////////////////////////////////// // POTENTIOMETERS void potentiometers() { for (int i = 0; i < N_POTS; i++) { // Loops through all the potentiometers potCState[i] = analogRead(POT_ARDUINO_PIN[i]); // reads the pins from arduino midiCState[i] = map(potCState[i], 0, 1023, 0, 127); // Maps the reading of the potCState to a value usable in midi potVar = abs(potCState[i] - potPState[i]); // Calculates the absolute value between the difference between the current and previous state of the pot if (potVar > varThreshold) { // Opens the gate if the potentiometer variation is greater than the threshold PTime[i] = millis(); // Stores the previous time } timer[i] = millis() - PTime[i]; // Resets the timer 11000 - 11000 = 0ms if (timer[i] < TIMEOUT) { potMoving = true; } else { potMoving = false; } if (potMoving == true) { // If the potentiometer is still moving, send the change control if (midiPState[i] != midiCState[i]) { // Sends the MIDI CC accordingly to the chosen board #ifdef ATMEGA328 MIDI.sendControlChange(cc + i, midiCState[i], midiCh); // cc number, cc value, midi channel #elif ATMEGA32U4 controlChange(midiCh, cc + i, midiCState[i]); // MidiUSB.flush(); #elif TEENSY usbMIDI.sendControlChange(cc + i, midiCState[i], midiCh); // cc number, cc value, midi channel #elif DEBUG Serial.print("Pot: "); Serial.print(i); Serial.print(" "); Serial.println(midiCState[i]); //Serial.print(" "); #endif potPState[i] = potCState[i]; // Stores the current reading of the potentiometer to compare with the next midiPState[i] = midiCState[i]; } } } } #ifdef ATMEGA32U4 // Arduino (pro)micro midi functions MIDIUSB Library void noteOn(byte channel, byte pitch, byte velocity) { midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity}; MidiUSB.sendMIDI(noteOn); } void noteOff(byte channel, byte pitch, byte velocity) { midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity}; MidiUSB.sendMIDI(noteOff); } void controlChange(byte channel, byte control, byte value) { midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value}; MidiUSB.sendMIDI(event); } #endif