-
-
Save felixroos/cd7111d1b1a2ba7e381b82faf6abb9e2 to your computer and use it in GitHub Desktop.
#include "MIDIUSB.h" | |
bool debug = 0; | |
int maxPressTime = 250; | |
int minVelocity = 10; | |
int maxVelocity = 90; | |
int midiChannel = 0; | |
int keys[98] = { | |
31, 29, | |
56, 59, | |
80, 83, | |
104, 107, | |
92, 95, | |
68, 71, | |
44, 47, | |
8, 11, | |
20, 23, | |
58, 57, | |
82, 81, | |
106, 105, | |
94, 93, | |
70, 69, | |
46, 45, | |
10, 9, | |
22, 21, | |
48, 51, | |
72, 75, | |
96, 99, | |
84, 87, | |
60, 63, | |
36, 39, | |
0, 3, | |
12, 15, | |
50, 49, | |
74, 73, | |
98, 97, | |
86, 85, | |
62, 61, | |
38, 37, | |
2, 1, | |
14, 13, | |
55, 53, | |
79, 77, | |
103, 101, | |
91, 89, | |
67, 65, | |
43, 41, | |
7, 5, | |
19, 17, | |
54, 52, | |
78, 76, | |
102, 100, | |
90, 88, | |
66, 64, | |
42, 40, | |
6, 4, | |
18, 16 | |
}; | |
unsigned long pressStart[49] = {}; | |
bool pressed[49] = {}; | |
void setup() { | |
Serial.begin(9600); | |
//select pins | |
// ABC of INPUT | |
pinMode(10, OUTPUT); | |
pinMode(11, OUTPUT); | |
pinMode(12, OUTPUT); | |
// ABC of OUTPUTs | |
pinMode(2, OUTPUT); | |
pinMode(3, OUTPUT); | |
pinMode(4, OUTPUT); | |
// from keyboard (9 pin) | |
pinMode(5, INPUT); // gray | |
digitalWrite(5, HIGH); // pullup | |
pinMode(6, INPUT); // yellow | |
digitalWrite(6, HIGH); // pullup | |
// to keyboard (12 pin) | |
pinMode(7, OUTPUT); // green | |
pinMode(8, OUTPUT); // green | |
} | |
void set4051(int pinA, int pinB, int pinC, int channel) { | |
// A = least significant bit | |
// bitRead also starts from least significant bit | |
digitalWrite(pinA, bitRead(channel, 0)); | |
digitalWrite(pinB, bitRead(channel, 1)); | |
digitalWrite(pinC, bitRead(channel, 2)); | |
} | |
void loop() { | |
for (int n = 0; n < 98; n++) { | |
int k = keys[n]; | |
// for finding out order of keys, comment out above line and rename n to k | |
int i = k / 12; | |
int o = k % 12; | |
int readPin = bitRead(i, 3) == 0 ? 6 : 5; | |
set4051(10, 11, 12, i); | |
set4051(2, 3, 4, o); | |
digitalWrite(7, bitRead(o, 3)); | |
digitalWrite(8, !bitRead(o, 3)); | |
bool isConnected = digitalRead(readPin) == LOW; | |
bool isDown = n % 2 == 1; | |
int keyIndex = n / 2; | |
int midi = keyIndex + 38; | |
bool isPressed = pressed[keyIndex] == 1; | |
// keypress starts | |
if (isConnected && !isPressed && !isDown && !pressStart[keyIndex]) { | |
if (debug) { | |
Serial.print("start pressing "); | |
} | |
pressStart[keyIndex] = millis(); | |
} | |
// key is now fully pressed | |
if (isConnected && !isPressed && isDown) { | |
unsigned long pressTime = millis() - pressStart[keyIndex]; | |
float f = (1 - (float)pressTime / (float)maxPressTime); | |
int velocity = f * (maxVelocity - minVelocity) + minVelocity; | |
if (debug) { | |
Serial.print("done pressing "); | |
Serial.println(f); | |
} | |
pressed[keyIndex] = 1; | |
if (pressTime <= maxPressTime) { // min velocity? | |
noteOn(midiChannel, midi, velocity); | |
MidiUSB.flush(); | |
if (debug) { | |
Serial.print("on "); | |
Serial.print(midi); | |
Serial.println(" "); | |
} | |
} | |
} | |
// key is now fully unpressed | |
if (!isConnected && isPressed && !isDown) { | |
pressed[keyIndex] = 0; | |
noteOff(midiChannel, midi, 0); | |
MidiUSB.flush(); | |
if (debug) { | |
Serial.print("off "); | |
Serial.print(midi); | |
Serial.print(" "); | |
Serial.println(" "); | |
} | |
} | |
// key is unpressed => may include keypresses that have started but did not go down | |
if (!isConnected && !isDown) { | |
pressStart[keyIndex] = 0; // reset time when key is released completely | |
} | |
} | |
} | |
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); | |
} |
Ok. I will get some of those then
I guess 8x 16 is the correct way to say it.. 8 ins 16 outs
I guess 8x 16 is the correct way to say it.. 8 ins 16 outs
okay then you'd probably need 3 multiplexers (cd4051) + 9 digital i/o pins:
3 outputs to set the input channel of the mux1
3 outputs to set the output channels of mux2 + mux3 (can be connected together)
1 output to write the input of mux1
1 input to read the output of mux2
1 input to read the output mux3
maybe I am slightly off, but I guess you could double check yourself
How would I change the code to work with 25 keys with out the multiplexers?
How would I change the code to work with 25 keys with out the multiplexers?
that depends on your microcontroller pins and the exact arrangement of your keyboard pcb.. I cannot write the code for you, but I could give you some hints if you get stuck with a more specific problem.
I have an 8x8 fatar keybed, using a teensy 4.1. Rows are wired to pins 40-33, cols are wired to pins 25-32. Each key has 2 switches to calculate velocity.
for 8x8 without multiplexer, you'd need 8 digital outputs and 8 digital inputs. if you have 2 multuplexers (1 to select input and 1 to select output), you'd only need 6 outputs and 2 inputs on your microcontroller.. btw arduino micro is good because it's already a compliant usb device