midi-controller/sketch.ino

198 lines
4.2 KiB
C++

/*
* @NAME: MIDI-Controller Arduino Nano Software
* @AUTHOR: <admin@gurkengewuerz.de> 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);
}
}