Skip to content

Instantly share code, notes, and snippets.

@felixroos
Created February 14, 2021 18:08
Show Gist options
  • Select an option

  • Save felixroos/cd7111d1b1a2ba7e381b82faf6abb9e2 to your computer and use it in GitHub Desktop.

Select an option

Save felixroos/cd7111d1b1a2ba7e381b82faf6abb9e2 to your computer and use it in GitHub Desktop.
arduino keyboard scanner
#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);
}
@godbless876
Copy link

Thanks for the reply.. yes I have 8x8x8 matrix for a 61key novation ks4

@godbless876
Copy link

And a I was using a teensy 3.2 but I have 2 megas and some nanos and picos

@felixroos
Copy link
Author

Thanks for the reply.. yes I have 8x8x8 matrix for a 61key novation ks4

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

@godbless876
Copy link

Ok. I will get some of those then

@godbless876
Copy link

I guess 8x 16 is the correct way to say it.. 8 ins 16 outs

@felixroos
Copy link
Author

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

@RandyRyanG
Copy link

How would I change the code to work with 25 keys with out the multiplexers?

@felixroos
Copy link
Author

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.

@RandyRyanG
Copy link

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.

@chauau20
Copy link

Hi. help me! matrix 61key 12x12 with stm32f030r8t6.

@felixroos
Copy link
Author

@chauau20 i guess you need to figure out the details by yourself.. check out my blog post related to this script: https://loophole-letters.vercel.app/diy-midi-keyboard if you have any more specific questions i might be able to help you (no guarantees)

@felixroos
Copy link
Author

Hello! I have a Korg KROME 61-key keyboard, and the same keyboard is used in the Korg PA700 synthesizer. There are two 74HC138 chips installed on the keyboard board. There are a total of 16 wires, including 2 (-) and one (+5) volt power supply, 8 for diode anodes, combined ABC (74HC138), IC1 (74HC138 - E1-4 pin), and another IC2 (74HC138 - E3-6 pin) connected to the same bus, IC1-(74HC138 - E2-5 pin) Please advise on how to connect it to the Arduino Leonardo (Pro Micro) and kindly share the Arduino sketch. Thank you in advance!

i guess you need to figure out the details by yourself.. check out my blog post related to this script: https://loophole-letters.vercel.app/diy-midi-keyboard if you have any more specific questions i might be able to help you (no guarantees)

@jasper192
Copy link

jasper192 commented Feb 16, 2026

Thanks for dissecting your keyboard and sharing your findings with us. I have been wanting to make a midi keybed for some time, 3d printing the keys and designing my own pcbs which I’ll get JLBPCB to make for me. The only things that has kept me back is finding a suitable keyboard scanner circuit. I have drawn out your scanner circuit in Kicad as best as I could following your sketch. I wasn’t sure if there should be a diode from X4 of the first 4051 to X3 on the last 4051, and I wasn’t sure about arduino pins 10,11 and 12 going to keyboard pins 2,3 and 4. If you could advise me here, I’d be most grateful. I won’t dive straight into assembly, I’m going to play around with the Leonardo and the multiplexers for a while to get used to them first. Thanks.

Oh just one observation that I had, I see that you used your ninth input pin, purely for the first key. I am going to use just 8 input pins and make a 48-note keyboard. Obviously I’ll have to find all the key values again but that should be a problem.
scanner

@felixroos
Copy link
Author

felixroos commented Feb 16, 2026

@jasper192
hey glad you got something out of it. i don't remember all the details but this drawing should be what i did, so arduino pins 10 11 12 go to the upper 4051 into the 3 pins on its bottom right. you can also see it on the photo. i don't remember using any diodes. but take all this with caution, as i am not an expert and this was just me tinkering around, finding something that worked

@jasper192
Copy link

jasper192 commented Feb 16, 2026 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment