/* * @NAME: MIDI-Controller Arduino Nano Software * @AUTHOR: Gurkengewuerz * @REVIEW: 08.06.2017 * @VCS: https://git.ita15b.de/schuetrumpf/midi_controller */ // http://computermusicresource.com/MIDI.Commands.html boolean debug = false; byte midi_cmd_key_on = 144; byte midi_cmd_key_off = 128; byte midi_cmd_controll = 176; byte potis[] = { 16, 17, 18, 19 }; // http://www.wavosaur.com/download/midi-note-hex.php byte midiNote[] = { 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 }; // 8 notes byte lastPotiStates[] = { 0, 0, 0, 0 }; byte channel_count = 5; byte channel_leds[] = { 8, 9, 10, 11, 12 }; byte channel_current = 1; // Keypad const byte ROWS = 3; const byte COLS = 3; int col[] = { 3, 15, 2 }; // Input int row[] = { 6, 4, 5 }; // Output int last_row = -1; int last_cols = -1; unsigned long last = millis(); void setup() { pinMode(LED_BUILTIN, OUTPUT); // LEDS for (byte i = 0; i < channel_count; ++i) { pinMode(channel_leds[i], OUTPUT); } for (int i = 0; i < ROWS; i++) { pinMode(row[i], OUTPUT); } for (int i = 0; i < COLS; i++) { pinMode(col[i], INPUT_PULLUP); } // If Debug Mode: enter USB Mode if (debug) { Serial.begin(9600); } else { // MIDI baud rate 31250 Serial.begin(31250); } } void loop() { for (int i = 0; i < channel_count; ++i) { if (i == (channel_current - 1)) { digitalWrite(channel_leds[i], HIGH); } else { digitalWrite(channel_leds[i], LOW); } } // Potis abfragen // TODO: Potis Testen for (byte i = 0; i < (sizeof(potis) / sizeof(byte)); ++i) { int val = getDebouncedAnalog(potis[i]); int perc = map(val, 0, 1023, 0, 127); // debugMsg("Poti (" + String(i) + "): " + String(potis[i])); if (!(lastPotiStates[i] > perc - 3 && lastPotiStates[i] < perc + 3)) { debugMsg("Poti => " + String(perc)); sendMIDI(midi_cmd_controll + channel_current, midiNote[i], perc); lastPotiStates[i] = perc; } } for (int i = 0; i < ROWS; i++) { digitalWrite(row[0], HIGH); digitalWrite(row[1], HIGH); digitalWrite(row[2], HIGH); digitalWrite(row[i], LOW); for (int j = 0; j < COLS; j++) { int col_scan = digitalRead(col[j]); if (col_scan == LOW) { keypress(i, j); delay(100); } } } } void keypress(int i, int j) { String val = "x"; debugMsg(String(i) + " => " + String(j)); if (last_row == i && last_cols == j && millis() - last < 150) { val = "r"; debugMsg("MILLIS: " + String(last) + " / " + String(millis()) + " = " + String(millis() - last) + "ms"); last = millis(); } else if (i == 0 && j == 0) { val = "1"; channel_current = 1; } else if (i == 0 && j == 1) { val = "2"; channel_current = 2; } else if (i == 0 && j == 2) { val = "3"; channel_current = 3; } else if (i == 1 && j == 0) { val = "4"; channel_current = 4; } else if (i == 1 && j == 1) { val = "5"; channel_current = 5; } else if (i == 1 && j == 2) { val = "6"; sendMIDI(midi_cmd_key_on + channel_current, midiNote[4], 0x45); } else if (i == 2 && j == 0) { val = "7"; sendMIDI(midi_cmd_key_on + channel_current, midiNote[5], 0x45); } else if (i == 2 && j == 1) { val = "8"; sendMIDI(midi_cmd_key_on + channel_current, midiNote[6], 0x45); } else if (i == 2 && j == 2) { val = "9"; sendMIDI(midi_cmd_key_on + channel_current, midiNote[7], 0x45); } debugMsg(val); last = millis(); last_row = i; last_cols = j; } // http://forum.arduino.cc/index.php?topic=190305.msg1408310#msg1408310 int getDebouncedAnalog(const byte pin) { static int previousReading = 0; // static is better than a global int newReading = analogRead(pin); if ((newReading - 1 > previousReading) || (newReading + 1 < previousReading)) { previousReading = newReading; } return previousReading; } // https://www.arduino.cc/en/Tutorial/Midi // cmd - pitch - velocity void sendMIDI(byte statusByte, byte dataByte1, byte dataByte2) { Serial.write(statusByte); Serial.write(dataByte1); Serial.write(dataByte2); } void debugMsg(String msg) { if (debug) { Serial.println(msg); } }