-
-
Save felixroos/cd7111d1b1a2ba7e381b82faf6abb9e2 to your computer and use it in GitHub Desktop.
arduino keyboard scanner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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); | |
| } |
Author
Yeah thats the one I used. I’m an engineer so might go back to basics and
use an arduino with lots of pins to creat the matrix, cutting out the
multiplexer. That would in turn simplify the software. Cheers mate
…On Mon, 16 Feb 2026 at 13:06, felixroos ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
@jasper192 <https://github.com/jasper192>
hey glad you got something out of it. i don't remember all the details but this
drawing
<https://loophole-letters.vercel.app/img/maudio49/scanner-schematic.png>
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
<https://loophole-letters.vercel.app/img/maudio49/arduino-scanner-pcb.png>.
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
—
Reply to this email directly, view it on GitHub
<https://gist.github.com/felixroos/cd7111d1b1a2ba7e381b82faf6abb9e2#gistcomment-5989280>
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/BKMEZJ6QWDWPME5K3KDTX6T4MGXF7BFHORZGSZ3HMVZKM5LQMRQXIZNMON2WE2TFMN2F65DZOBS2WR3JON2EG33NNVSW45FGORXXA2LDOOIYFJDUPFYGLJDHNFZXJJLWMFWHKZNJGEYDOOJSG42TQMVKMF2HI4TJMJ2XIZLTSOBKK5TBNR2WLKBRGIYDEMZQGMZKI3TBNVS2QYLDORXXEX3JMSBKK5TBNR2WLJDUOJ2WLJDOMFWWLO3UNBZGKYLEL5YGC4TUNFRWS4DBNZ2F6YLDORUXM2LUPGBKK5TBNR2WLJDHNFZXJJDOMFWWLK3UNBZGKYLEL52HS4DF>
.
You are receiving this email because you were mentioned.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@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