Analog numpad with Hall effect sensors
-
- Location: France
- Main keyboard: KBT Pure Pro
- Main mouse: G500
- Favorite switch: MX Red, MX Blue
- DT Pro Member: -
Hi everyone! First post here, so I guess a quick introduction is in order. I'm Matt, a relative newcomer the the mechanical keyboard craze, having bought my first one (a Pure Pro) a little more than a year ago. Since then I have been considering other purchases and planning to build a custom 65% board but despite the shortcomings of the Pure Pro (nonstandard layout, OEM profile thin ABS keycaps) it seems so well-rounded to me that I feel no urge to own another keyboard.
On to the subject: a few weeks ago, after playing a bit of GTA V and noticing that the lack of analog control with a keyboard can be limiting, I started searching for info on analog keyboards — I was not even sure such a thing existed but I came across an experiment you might already know: Ben Heck's addition of an analog WASD cluster to a mechanical keyboard thanks to Hall effect sensors (details here).
What he did was mod MX switches with magnets and sensors, wire the sensors to a microcontroller which sends the signal to a digital pot and then to the logic board of a 360 gamepad, which is connected to a USB hub inside the keyboard case. As a result, the modded switches are seen as gamepad axes in Windows.
Concept: I don't want to deal with such a convoluted setup, so I'm aiming at a simpler approach: a discrete keypad that I can keep on my desk with four analog keys, other keys acting as joystick buttons, and a dedicated switch to turn it into a numpad or a macro pad when I'm not gaming (and possibly cycle through several layers). Something I would use as a Belkin Nostromo when playing, but with a smaller footprint, and which will remain useful in a working environment.
Layout: I'd like to keep things simple and avoid the need to source special keycaps, so I've settled with the traditional numpad arrangement, except that it is mirrored since it is meant to be used with the left hand and I find larger keys to be easier to use with the pinky when the left hand is in resting position (fingers on 4856). Also it should be possible to replace 2u keys with 1u keys.
Controller: A Teensy 2.0 has enough inputs to accomodate either a 5x4 switch matrix or 20 switches wired directly, four analog inputs for the sensors, one pin for a status LED, and have a few pins left for an optional extension if using a matrix. I considered trying the newer Teensy LC, but it is not 5 V tolerant (the Hall sensors operate between 0 and 5 V), does not have significantly more pins, and I am not sure there is any advantage in using an ARM mcu for this project.
Firmware: This is going to be the hardest part for me. Using a Teensy allows me to use one of the popular keyboard firmwares (Soarer's, Hasu's or Metalliqaz') but I have no clue about how to add the hall sensor logic to their code. On the other hand, the teensyduino environment makes coding this feature much easier, but the whole matrix implementation will have to be done from scratch, the thought of which I find befuddling. This will be my biggest hurdle.
Assembly: I'd love to try a CNC alu case but the first unit will use cheaper acrylic layers instead. This crude foamcore mockup shows what it should look like : a low profile case with narrow edges, a thicker front edge, and most likely small-radius corners (not seen here). I may use something different for the first prototype and make sure that I have a working concept before ordering laser-cut acrylic layers (for which the .svg files are already drawn).
The first unit will be hand-wired. I have already laid out a PCB that can accomodate up to 20 switches (5x4 matrix) in a mirrored numpad layout with PCB-mounted stabs :
This was done before I realized that the matrix programming was a brick wall for my poor coding skills and that direct wiring switches to the Teensy would probably be easier for me. It will be simple to lay out a different board if needed, but to avoid unneeded costs and superfluous delays I'll hand-wire the first unit.
That's it for the overview of the project, let's start making stuff! Before I can build the first unit, I need to experiment with components and code, so I'll use a testbed with six switches connected directly to the Teensy, six more wired as a 3x2 matrix (with diodes), and a few other things (an RGB status LED, Hall sensors and so on).
On to the subject: a few weeks ago, after playing a bit of GTA V and noticing that the lack of analog control with a keyboard can be limiting, I started searching for info on analog keyboards — I was not even sure such a thing existed but I came across an experiment you might already know: Ben Heck's addition of an analog WASD cluster to a mechanical keyboard thanks to Hall effect sensors (details here).
What he did was mod MX switches with magnets and sensors, wire the sensors to a microcontroller which sends the signal to a digital pot and then to the logic board of a 360 gamepad, which is connected to a USB hub inside the keyboard case. As a result, the modded switches are seen as gamepad axes in Windows.
Concept: I don't want to deal with such a convoluted setup, so I'm aiming at a simpler approach: a discrete keypad that I can keep on my desk with four analog keys, other keys acting as joystick buttons, and a dedicated switch to turn it into a numpad or a macro pad when I'm not gaming (and possibly cycle through several layers). Something I would use as a Belkin Nostromo when playing, but with a smaller footprint, and which will remain useful in a working environment.
Layout: I'd like to keep things simple and avoid the need to source special keycaps, so I've settled with the traditional numpad arrangement, except that it is mirrored since it is meant to be used with the left hand and I find larger keys to be easier to use with the pinky when the left hand is in resting position (fingers on 4856). Also it should be possible to replace 2u keys with 1u keys.
Controller: A Teensy 2.0 has enough inputs to accomodate either a 5x4 switch matrix or 20 switches wired directly, four analog inputs for the sensors, one pin for a status LED, and have a few pins left for an optional extension if using a matrix. I considered trying the newer Teensy LC, but it is not 5 V tolerant (the Hall sensors operate between 0 and 5 V), does not have significantly more pins, and I am not sure there is any advantage in using an ARM mcu for this project.
Firmware: This is going to be the hardest part for me. Using a Teensy allows me to use one of the popular keyboard firmwares (Soarer's, Hasu's or Metalliqaz') but I have no clue about how to add the hall sensor logic to their code. On the other hand, the teensyduino environment makes coding this feature much easier, but the whole matrix implementation will have to be done from scratch, the thought of which I find befuddling. This will be my biggest hurdle.
Assembly: I'd love to try a CNC alu case but the first unit will use cheaper acrylic layers instead. This crude foamcore mockup shows what it should look like : a low profile case with narrow edges, a thicker front edge, and most likely small-radius corners (not seen here). I may use something different for the first prototype and make sure that I have a working concept before ordering laser-cut acrylic layers (for which the .svg files are already drawn).
The first unit will be hand-wired. I have already laid out a PCB that can accomodate up to 20 switches (5x4 matrix) in a mirrored numpad layout with PCB-mounted stabs :
This was done before I realized that the matrix programming was a brick wall for my poor coding skills and that direct wiring switches to the Teensy would probably be easier for me. It will be simple to lay out a different board if needed, but to avoid unneeded costs and superfluous delays I'll hand-wire the first unit.
That's it for the overview of the project, let's start making stuff! Before I can build the first unit, I need to experiment with components and code, so I'll use a testbed with six switches connected directly to the Teensy, six more wired as a 3x2 matrix (with diodes), and a few other things (an RGB status LED, Hall sensors and so on).
- vvp
- Main keyboard: Katy/K84CS
- Main mouse: symetric 5-buttons + wheel
- Favorite switch: Cherry MX
- DT Pro Member: -
You will need to find firmware which supports also joystick USB endpoint. You want at least 2 endpoints: keyboard and joystick. I plan to add a joystick endpoint to my keyboard eventually but this is at least half a year in the future, maybe a year or even more ... if everMatt_ wrote: ↑ Firmware: This is going to be the hardest part for me. Using a Teensy allows me to use one of the popular keyboard firmwares (Soarer's, Hasu's or Metalliqaz') but I have no clue about how to add the hall sensor logic to their code. On the other hand, the teensyduino environment makes coding this feature much easier, but the whole matrix implementation will have to be done from scratch, the thought of which I find befuddling. This will be my biggest hurdle.
Most free keyboard firmwares contain keyboard and mouse endpoint. I do not know whether any firmware already contains a joystick endpoint too.
-
- Location: France
- Main keyboard: KBT Pure Pro
- Main mouse: G500
- Favorite switch: MX Red, MX Blue
- DT Pro Member: -
Thanks for the tip, I'll keep that in mind! At the moment I'm leaning towards trying tyo write my own code for the switches (unless there is something already available and open source for arduino/teensyduino) because there needs to be some processing in order for the sensors to be seen as joyxtick axes (more on that soon), but it's good to have choices in case I run into a deadlock.
-
- Location: France
- Main keyboard: KBT Pure Pro
- Main mouse: G500
- Favorite switch: MX Red, MX Blue
- DT Pro Member: -
No, fortunately, that would be a painfully difficult mod to do, I found a simpler way to work this out. This is what the next part of the worklog will be about, I just need to take a few explanatory pictures before I post it.
-
- Location: France
- Main keyboard: KBT Pure Pro
- Main mouse: G500
- Favorite switch: MX Red, MX Blue
- DT Pro Member: -
So let's start with the main feature of the project — the analog cluster with Hall sensors!
The Hall effect sensors
There are two sorts of Hall sensors: some integrate extra circuitry to act as on/off (digital) switches, and some are linear; we need the latter to make analog switches. What they do is output a voltage proportional to the magnetic field they sense, their quiescent output (the output they send when they sense nothing) being half their operating voltage.
Here I am using an Allegro A1302 sensor, which operates at 5 V. When no magnetic field is applied, it outputs around 2.5 V:
Here is a 3x10 mm neodymium magnet (the USB receptacle is just here to hold it in place). When it gets closer, the output of the sensor decreases:
Note that if I had moved
- the other end of the magnet towards the same side of the sensor, or
- the same end of the magnet towards the other side of the sensor,
it would have worked in reverse — the output would have increased instead (from 2.5 V to 5 V).
There is no 'best' magnet orientation, but in case I end up using a Teensy 3.1/LC (working at 3.3 V) I'd rather have the sensors output between 0 and 2.5 V than 2.5 - 5 V. Also, the flat side of the sensor is more sensitive than the other, so that's probably the side we'll want to use.
Modding the switches
One thing we need to know about magnets is that their strength depends on several factors, notably their size and material. Bigger means stronger, and a higher grade also means a stronger magnet. The 3x10 mm magnet shown above is made of N35 neodymium, and it performs acceptably with our sensor : its magnetic field can be sensed from around 4mm away, and it brings the output value near 0 when it touches the sensor — well, not quite, but the ouput varies between 2.2 and 0.4 V, which should make for an acceptable range for half an axis.
Now we need to adapt MX switches to accomodate a sensor and a magnet that moves with the plunger. I have seen attempts at modding MX switches with 3mm rod magnets (with no documented result) but fortunately there seems to be a simpler way to achieve our goal:
1. Cut the bottom of the switch open: using a pcb to hold it may be helpful. Cut it flush, drill what remains with a 2 mm bit (you can do that by hand, there is less than 0.5 mm left to remove).
2. This time we'll use a N52 grade (strongest commercially available), 1 mm thick, 2 mm diameter magnet and attach it to the end of the slider. Scratch the magnet with the tip of your knife so that glue adheres to it, use cyano glue to attach it.
I tested each magnet beforehand with the setup shown above to find the proper side (i.e. the one that lowers the sensor's output voltage) and marked it with a white dot which I removed once the magnet was glued.
Check that the magnet is properly aligned with the plunger, reassemble the switch, check that it descends smoothly. If not, the opening of the switch has to be carefully widened with a small round file or a 2.2 mm drill bit.
When the switch is fully depressed, the 1mm-thick magnet comes flush to the opening, which means that it should touch the sensor at the end of the travel as seen above.
The code
For anything code-related, I'll be using the Teensyduino environment (instructions here).
We can test our analog switches with a simple analogRead sketch to find their output range:
Here for instance, when the tested switch is left untouched, the sensors returns a stable value of 502; when I depress it slightly, the output decreases gradually down to around 230 when fully depressed. Each sensor is a bit different so each of them will have to be measured individually. Once we know their working range, it is just a matter of using the map() function to convert them to a standard 0-1023 range than can be interpreted as a joystick position value.
An extra bit of explanation just in case: a joystick is just two potentiometers actuated by a single lever, each potentiometer (working as a voltage divider) corresponding to an axis (usually X and Y); when the joystick is in center position, the pots are in the middle of their rotation, so they both output half the reference voltage, which with the teensy's 10-bit analog to digital converter gives a logic value of 512 (or around half of 1023). If the joystick is moved left, the X-axis value will decrease (down to 0 if pushed to the far left), if it is pushed up the Y-axis value will increase (up to 1023).
Since we have two keys/sensors per axis instead of one, we have to sum up their values into a single one, make sure that the resting value will be 512, that a press on one key ("left" for instance) will decrease the value down to 0 and that a press on the other ("right") key will increase it to 1023. Here is the code for one key and the resulting behavior in the game controler monitor (joy.cpl):
For a complete axis, we just need to add both values:
I had a small pcb made to simplify the wiring but ironically I miserad the sensor's datasheet and inverted the gnd and output leads, so there will be a bit of leg crossing (I might actually use single-switch pcbs instead this time), but ideally it should end up like this:
And now we repeat the sensor calibration process to find the correct values for each key. Once it's done, we have our four-key cluster being seen as a two-axis controller in Windows. To use it in-game, we can emulate an xinput controller with x360ce.
Finally, notice that since the addition of the analog mechanism dit not alter the switches' contacts, we can still use them as regular (on/off) switches. We'll have to work out our code to allow the gamepad to work in different modes, which is where it gets more complicated.
The Hall effect sensors
There are two sorts of Hall sensors: some integrate extra circuitry to act as on/off (digital) switches, and some are linear; we need the latter to make analog switches. What they do is output a voltage proportional to the magnetic field they sense, their quiescent output (the output they send when they sense nothing) being half their operating voltage.
Here I am using an Allegro A1302 sensor, which operates at 5 V. When no magnetic field is applied, it outputs around 2.5 V:
Here is a 3x10 mm neodymium magnet (the USB receptacle is just here to hold it in place). When it gets closer, the output of the sensor decreases:
Note that if I had moved
- the other end of the magnet towards the same side of the sensor, or
- the same end of the magnet towards the other side of the sensor,
it would have worked in reverse — the output would have increased instead (from 2.5 V to 5 V).
There is no 'best' magnet orientation, but in case I end up using a Teensy 3.1/LC (working at 3.3 V) I'd rather have the sensors output between 0 and 2.5 V than 2.5 - 5 V. Also, the flat side of the sensor is more sensitive than the other, so that's probably the side we'll want to use.
Modding the switches
One thing we need to know about magnets is that their strength depends on several factors, notably their size and material. Bigger means stronger, and a higher grade also means a stronger magnet. The 3x10 mm magnet shown above is made of N35 neodymium, and it performs acceptably with our sensor : its magnetic field can be sensed from around 4mm away, and it brings the output value near 0 when it touches the sensor — well, not quite, but the ouput varies between 2.2 and 0.4 V, which should make for an acceptable range for half an axis.
Now we need to adapt MX switches to accomodate a sensor and a magnet that moves with the plunger. I have seen attempts at modding MX switches with 3mm rod magnets (with no documented result) but fortunately there seems to be a simpler way to achieve our goal:
1. Cut the bottom of the switch open: using a pcb to hold it may be helpful. Cut it flush, drill what remains with a 2 mm bit (you can do that by hand, there is less than 0.5 mm left to remove).
2. This time we'll use a N52 grade (strongest commercially available), 1 mm thick, 2 mm diameter magnet and attach it to the end of the slider. Scratch the magnet with the tip of your knife so that glue adheres to it, use cyano glue to attach it.
I tested each magnet beforehand with the setup shown above to find the proper side (i.e. the one that lowers the sensor's output voltage) and marked it with a white dot which I removed once the magnet was glued.
Check that the magnet is properly aligned with the plunger, reassemble the switch, check that it descends smoothly. If not, the opening of the switch has to be carefully widened with a small round file or a 2.2 mm drill bit.
When the switch is fully depressed, the 1mm-thick magnet comes flush to the opening, which means that it should touch the sensor at the end of the travel as seen above.
The code
For anything code-related, I'll be using the Teensyduino environment (instructions here).
We can test our analog switches with a simple analogRead sketch to find their output range:
Code: Select all
//wire the sensor's +5V and GND pins adequately and its output to the teensy's A0 pin
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(analogRead(A0));
delay(500);
}
An extra bit of explanation just in case: a joystick is just two potentiometers actuated by a single lever, each potentiometer (working as a voltage divider) corresponding to an axis (usually X and Y); when the joystick is in center position, the pots are in the middle of their rotation, so they both output half the reference voltage, which with the teensy's 10-bit analog to digital converter gives a logic value of 512 (or around half of 1023). If the joystick is moved left, the X-axis value will decrease (down to 0 if pushed to the far left), if it is pushed up the Y-axis value will increase (up to 1023).
Since we have two keys/sensors per axis instead of one, we have to sum up their values into a single one, make sure that the resting value will be 512, that a press on one key ("left" for instance) will decrease the value down to 0 and that a press on the other ("right") key will increase it to 1023. Here is the code for one key and the resulting behavior in the game controler monitor (joy.cpl):
Code: Select all
int left;
void setup() {
Serial.begin(9600);
}
void loop() {
// map(value, fromLow, fromHigh, toLow, toHigh)
// swap toLow and toHigh to invert the value for the left and down keys
left = map(analogRead(A0), 230, 502, 512, 0);
Joystick.X(left);
}
For a complete axis, we just need to add both values:
Code: Select all
int left;
int right;
void setup() {
Serial.begin(9600);
}
void loop() {
// map(value, fromLow, fromHigh, toLow, toHigh)
// swap toLow and toHigh to invert the value for the left and down keys
left = map(analogRead(A0), 230, 502, 0, 512);
right = map(analogRead(A1), 220, 495, 512, 0);
Joystick.X(left + right);
}
And now we repeat the sensor calibration process to find the correct values for each key. Once it's done, we have our four-key cluster being seen as a two-axis controller in Windows. To use it in-game, we can emulate an xinput controller with x360ce.
Finally, notice that since the addition of the analog mechanism dit not alter the switches' contacts, we can still use them as regular (on/off) switches. We'll have to work out our code to allow the gamepad to work in different modes, which is where it gets more complicated.
Last edited by Matt_ on 21 Jul 2015, 18:32, edited 2 times in total.
-
- Location: France
- Main keyboard: KBT Pure Pro
- Main mouse: G500
- Favorite switch: MX Red, MX Blue
- DT Pro Member: -
I got 10 of these N52 magnets for £2.29 from an ebay seller. The sensors are most costly, usually around $1.8 each from most suppliers, I got five of them for 10€ (incl.shipping).
I made a corrected version of the small pcb and shared it on OSHPark ($2.60 per three pcbs, so you'll need to order six) in case someone is interested in experimenting with sensors but does not care about a bigger pcb: https://oshpark.com/shared_projects/CfWdcQtV
Keep in mind that the setup I described still needs a few tweaks (mainly anchoring properly the sensors so that they don't move and affect the readings), but it is already a functional working basis. Now I just need to add code for the remaining 20 switches
I made a corrected version of the small pcb and shared it on OSHPark ($2.60 per three pcbs, so you'll need to order six) in case someone is interested in experimenting with sensors but does not care about a bigger pcb: https://oshpark.com/shared_projects/CfWdcQtV
Keep in mind that the setup I described still needs a few tweaks (mainly anchoring properly the sensors so that they don't move and affect the readings), but it is already a functional working basis. Now I just need to add code for the remaining 20 switches
Last edited by Matt_ on 21 Jul 2015, 21:40, edited 3 times in total.
- HaaTa
- Master Kiibohd Hunter
- Location: San Jose, California, USA
- Main keyboard: Depends the day
- Main mouse: CST L-TracX
- Favorite switch: Fujitsu Leaf Spring/Topre/BS/Super Alps
- DT Pro Member: 0006
- Contact:
Neat. Thought about doing something similar to this a long time ago (never got around to it).
However, I still want to do analog sense at some point, so I made sure to add it to my KLL spec https://www.overleaf.com/read/zzqbdwqjfwwf
Haven't added full firmware support yet for analog switches (only because I don't have any analog switches on hand).
https://github.com/kiibohd/controller
However, I still want to do analog sense at some point, so I made sure to add it to my KLL spec https://www.overleaf.com/read/zzqbdwqjfwwf
Haven't added full firmware support yet for analog switches (only because I don't have any analog switches on hand).
https://github.com/kiibohd/controller
- rsbseb
- -Horned Rabbit-
- Location: In the heart of the Ozarks
- Main keyboard: Varies
- Main mouse: logitech 570 trackball
- Favorite switch: I dream of a silky smooth Izot
- DT Pro Member: 0112
Neat project, I have also wanted to toy around with a hall effect switch and have about 40 sensors in my parts box along with a number of reed switches. Can't wait to see ho this works out.
-
- Location: France
- Main keyboard: KBT Pure Pro
- Main mouse: G500
- Favorite switch: MX Red, MX Blue
- DT Pro Member: -
Thanks for your interest rsbseb ! Let's keep going with some code. As I said before, I have no background in coding so for now all I'm doing is essentially combining bits and pieces from various examples. As a result the code is not pretty, but hopefully I can get it to do what I need and be able to optimize it later.
So what do I need? As stated before, I want a keypad with the following functions:
- several layers and a way to cycle through them
- status LED as a layer indicator — possibly RGB
- ease of programming
- switch debounce
I am having issues with the matrix programming, so for now the switches will be wired directly to the Teensy, which has 25 available pins; I need four analog pins for the Hall sensors, up to 20 (19 in my case) for the switches, which leaves one or two for the status LED.
An RGB LED needs three pins, so I can either use a one-color LED to indicate the current layer (with different brightness settings or blinking rates for example), or a special kind of RGB LED which needs only one pin — a WS2812b (which is essentially a RGB LED with a LED driver integrated in the same package). The code is easy to implement, it's not hard to mod switches to accomodate them (provided I use a PCB), and I can use any color (or lighting effect) to indicate the current layer:
I am using the Bounce library to manage switches. The base code to create and flick through layers looks like this:
Note that there is only one working switch in this part of the code — the switch I'll use to change layers, and which will always behave the same regardless of how the different layers are programmed.
Then the LED functions. They could be added directly in the main loop but since I'm still switching things around I'm keeping them in a separate part of the code (and a dedicated tab of the arduino IDE):
And finally the functions that hold the layer keymap informations:
I am using a separate keypress() function to avoid dealing with one keyboard.press and one keyboard.release per key and keep the whole thing readable. The code allows me to assign any key from the following list [link], text macros, or key macros (not shown here). Here is the full code for my six-switch test cluster, the RGB LED is connected to pin 19, the six switches to pins 5-10:
So yeah, that's a cumbersome piece of code, but that's the best I have been able to come up with for now. I can probably trim it down (using arrays for instance) but at least it works reliably and does what I need. I'd be more than happy to read what people with coding experience have to say about it and do my best to learn from their suggestions!
So what do I need? As stated before, I want a keypad with the following functions:
- several layers and a way to cycle through them
- status LED as a layer indicator — possibly RGB
- ease of programming
- switch debounce
I am having issues with the matrix programming, so for now the switches will be wired directly to the Teensy, which has 25 available pins; I need four analog pins for the Hall sensors, up to 20 (19 in my case) for the switches, which leaves one or two for the status LED.
An RGB LED needs three pins, so I can either use a one-color LED to indicate the current layer (with different brightness settings or blinking rates for example), or a special kind of RGB LED which needs only one pin — a WS2812b (which is essentially a RGB LED with a LED driver integrated in the same package). The code is easy to implement, it's not hard to mod switches to accomodate them (provided I use a PCB), and I can use any color (or lighting effect) to indicate the current layer:
I am using the Bounce library to manage switches. The base code to create and flick through layers looks like this:
Code: Select all
#include <Bounce.h>
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, 19, NEO_GRB + NEO_KHZ800); // (number of LEDs, teensy pin, )
Bounce button1 = Bounce(5, 10); // switch connected to pin 5, 10 ms debounce
int layer = 1;
void setup() {
pinMode(5, INPUT_PULLUP);
strip.begin();
strip.setBrightness(32); // Adjust brightness from 0 to 255
}
void loop() {
button1.update();
if (button1.fallingEdge()) {
layer++;
if(layer > 4){ // Number of layers
layer = 1;
}
}
if (layer == 1) {
ledWhite();
layer1();
}
if (layer == 2) {
ledTeal();
layer2();
}
if (layer == 3) {
ledLime();
layer3();
}
if (layer == 4) {
ledOrange();
layer4();
}
}
Then the LED functions. They could be added directly in the main loop but since I'm still switching things around I'm keeping them in a separate part of the code (and a dedicated tab of the arduino IDE):
Code: Select all
void ledWhite() {
strip.setPixelColor(1, 255, 255, 255);
strip.show();
}
void ledTeal() {
strip.setPixelColor(1, 0, 255, 200);
strip.show();
}
void ledLime() {
strip.setPixelColor(1, 102, 255, 0);
strip.show();
}
void ledOrange() {
strip.setPixelColor(1, 255, 200, 0);
strip.show();
}
Code: Select all
void keypress(Bounce pin, int key) {
if (pin.fallingEdge()) {
Keyboard.press(key);
}
if (pin.risingEdge()) {
Keyboard.release(key);
}
}
void layer1() {
keypress(button2, KEY_Z);
keypress(button4, KEY_Q);
keypress(button5, KEY_S);
keypress(button6, KEY_D);
if (button3.fallingEdge()) {
Keyboard.print("This is the first layer.");
}
}
void layer2() {
keypress(button2, KEY_E);
keypress(button4, KEY_S);
keypress(button5, KEY_D);
keypress(button6, KEY_F);
if (button3.fallingEdge()) {
Keyboard.print("This is the second layer.");
}
}
void layer3() {
keypress(button2, KEY_F1);
keypress(button4, KEY_F2);
keypress(button5, KEY_F3);
keypress(button6, KEY_F4);
if (button3.fallingEdge()) {
Keyboard.print("This is the third layer.");
}
}
void layer4() {
keypress(button2, KEYPAD_1);
keypress(button4, KEYPAD_2);
keypress(button5, KEYPAD_3);
keypress(button6, KEYPAD_4);
if (button3.fallingEdge()) {
Keyboard.print("This is the fourth layer.");
}
}
Code: Select all
#include <Bounce.h>
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, 19, NEO_GRB + NEO_KHZ800); // number of pixels, teensy pin
Bounce button1 = Bounce(5, 10);
Bounce button2 = Bounce(6, 10);
Bounce button3 = Bounce(7, 10);
Bounce button4 = Bounce(8, 10);
Bounce button5 = Bounce(9, 10);
Bounce button6 = Bounce(10, 10);
int layer = 1;
void setup() {
for (int pin = 5; pin < 11; pin++) {
pinMode(pin, INPUT_PULLUP);
}
strip.begin();
strip.setBrightness(32); // Adjust brightness from 0 to 255
}
void loop() {
button10.update();
button9.update();
button8.update();
button7.update();
button6.update();
button5.update();
if (button5.fallingEdge()) {
layer++;
if(layer > 4){ // Number of layers
layer = 1;
}
}
if (layer == 1) {
ledWhite();
layer1();
}
if (layer == 2) {
ledTeal();
layer2();
}
if (layer == 3) {
ledLime();
layer3();
}
if (layer == 4) {
ledOrange();
layer4();
}
}
void keypress(Bounce pin, int key) {
if (pin.fallingEdge()) {
Keyboard.press(key);
}
if (pin.risingEdge()) {
Keyboard.release(key);
}
}
void layer1() {
keypress(button2, KEY_Z);
keypress(button4, KEY_Q);
keypress(button5, KEY_S);
keypress(button6, KEY_D);
if (button3.fallingEdge()) {
Keyboard.print("This is the first layer.");
}
}
void layer2() {
keypress(button2, KEY_E);
keypress(button4, KEY_S);
keypress(button5, KEY_D);
keypress(button6, KEY_F);
if (button3.fallingEdge()) {
Keyboard.print("This is the second layer.");
}
}
void layer3() {
keypress(button2, KEY_F1);
keypress(button4, KEY_F2);
keypress(button5, KEY_F3);
keypress(button6, KEY_F4);
if (button3.fallingEdge()) {
Keyboard.print("This is the third layer.");
}
}
void layer4() {
keypress(button2, KEY_Z);
keypress(button4, KEY_Q);
keypress(button5, KEY_S);
keypress(button6, KEY_D);
if (button3.fallingEdge()) {
Keyboard.print("This is the fourth layer.");
}
}
void ledWhite() {
strip.setPixelColor(1, 255, 255, 255);
strip.show();
}
void ledTeal() {
strip.setPixelColor(1, 0, 255, 200);
strip.show();
}
void ledLime() {
strip.setPixelColor(1, 102, 255, 0);
strip.show();
}
void ledOrange() {
strip.setPixelColor(1, 255, 200, 0);
strip.show();
}
void ledBlue() {
strip.setPixelColor(1, 50, 0, 255);
strip.show();
}
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Hmm… this reminded me I don't really know how hall effect sensors are driven in a matrix. Are you going to share 4 pins for every sensor on the board? That's really neat if they can do that.Matt_ wrote: ↑for now the switches will be wired directly to the Teensy, which has 25 available pins; I need four analog pins for the Hall sensors, up to 20 (19 in my case) for the switches, which leaves one or two for the status LED.
Oh, wait. Your plan is for 4 analogue switches and just the usual digitals everywhere else. Just one pin per hall effect sensor then! I was getting confused with the fact they do indeed take more lines on a PCB than other switches (they need a power supply) which is one of the standard ways we recognise them in vintage kit!
See, analog gets me thinking of a little custom MIDI piano keyboard… with a lot more than 4 switches!
-
- Location: France
- Main keyboard: KBT Pure Pro
- Main mouse: G500
- Favorite switch: MX Red, MX Blue
- DT Pro Member: -
Yes, each sensor has three pins (and I think some have four) : +5V, GND and a data line, but you only send the latter to the Teensy, so it's one pin (analog input) per sensor.
And yes, the plan is to use only four analog switches (to be used as the wasd/esdf cluster for gaming) and the rest of the switches are behaving normally (but in the current state of the project, they also need one teensy pin (digital input) each). It's quite possible to make all switches analog, provided you find a controller with enough analog inputs (or a way to multiplex them), but if you balance the extra cost ($2 per switch), the work needed to mod so many switches and their usefulness, I am not sure it would be interesting.
Piano keyboards are actually more complicated than analog keyboards: I believe that there are two switches per key, one that detects the start of the travel and another for the end (and then another sensor for aftertouch), and the difference between the start and the end of the travel provides the velocity information. There are many things I'd like to build to make music (either that or buying a Push from Ableton), but I'm struggling enough with a "simple" keypad
Regarding pin availability, I have to say that I am hesitating between switching to another controller with more inputs (Teensy 3.1 ?) and freeing pins with a matrix implementations so that I can add an extension to the keypad:
6 extra keys + one analog stick (that can be used either as a joystick in-game or a trackpoint, depending on how you program your layers). Might be worth some extra work on the code.
And yes, the plan is to use only four analog switches (to be used as the wasd/esdf cluster for gaming) and the rest of the switches are behaving normally (but in the current state of the project, they also need one teensy pin (digital input) each). It's quite possible to make all switches analog, provided you find a controller with enough analog inputs (or a way to multiplex them), but if you balance the extra cost ($2 per switch), the work needed to mod so many switches and their usefulness, I am not sure it would be interesting.
Piano keyboards are actually more complicated than analog keyboards: I believe that there are two switches per key, one that detects the start of the travel and another for the end (and then another sensor for aftertouch), and the difference between the start and the end of the travel provides the velocity information. There are many things I'd like to build to make music (either that or buying a Push from Ableton), but I'm struggling enough with a "simple" keypad
Regarding pin availability, I have to say that I am hesitating between switching to another controller with more inputs (Teensy 3.1 ?) and freeing pins with a matrix implementations so that I can add an extension to the keypad:
6 extra keys + one analog stick (that can be used either as a joystick in-game or a trackpoint, depending on how you program your layers). Might be worth some extra work on the code.
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
A little stick looks sweet on that pad.
Yeah, MIDI keyboards provide a signal named "velocity" to the host. As far as I'm aware, MIDI pianos just use two *digital* switches (one triggered early in the press, and another deeper down) so they can compute the velocity using the time difference between these binary events. I don't know how they do after touch, but I reckon it's either a third digital switch or another simple derived property from the existing two.
Naturally, true analog switches can track the key's position directly instead. But as the controller must supply the MIDI standard velocity signal anyway, things are a bit more complex than simply passing that direct state along. Hosts expect obfuscated velocity input instead of pure key state. Grr!
Yeah, MIDI keyboards provide a signal named "velocity" to the host. As far as I'm aware, MIDI pianos just use two *digital* switches (one triggered early in the press, and another deeper down) so they can compute the velocity using the time difference between these binary events. I don't know how they do after touch, but I reckon it's either a third digital switch or another simple derived property from the existing two.
Naturally, true analog switches can track the key's position directly instead. But as the controller must supply the MIDI standard velocity signal anyway, things are a bit more complex than simply passing that direct state along. Hosts expect obfuscated velocity input instead of pure key state. Grr!
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Having just read up on after touch, it is indeed pretty cheap and limited. What a surprise! Instead, I found this more impressive:
https://en.wikipedia.org/wiki/Keyboard_ ... ensitivity
Organ keyboards have always made more sense than piano ones to me. Want a loud note: press further. Pianos need to swing physical hammers of course. But electronics does not. We could implement this!
Well, if anyone with a clue at coding is interested. I'm terrible at this stuff!
https://en.wikipedia.org/wiki/Keyboard_ ... ensitivity
Organ keyboards have always made more sense than piano ones to me. Want a loud note: press further. Pianos need to swing physical hammers of course. But electronics does not. We could implement this!
Well, if anyone with a clue at coding is interested. I'm terrible at this stuff!
-
- Location: Chicago
- Main keyboard: phantom with clears
- Main mouse: some logitech mx ones
- Favorite switch: consensus is not in yet, maybe jailhoused gateron
- DT Pro Member: -
All this piano and keyboard talk reminds me of a midi "keyboard" that one of my professors in college made and sold. It used multiple rows of hall effect sensors to track finger positions on a neoprene sheet in 3 dimensions that then could be output over midi channels as the note and two additional parameters.
Found the website for it, and here is a page on the internal mechanical structure:
http://www.hakenaudio.com/Continuum/hak ... vervf.html
Found the website for it, and here is a page on the internal mechanical structure:
http://www.hakenaudio.com/Continuum/hak ... vervf.html
-
- Location: France
- Main keyboard: KBT Pure Pro
- Main mouse: G500
- Favorite switch: MX Red, MX Blue
- DT Pro Member: -
I have always thought that it was the other way round: a piano has a dynamic touch (play harder = more powerful sound) while an organ had a static touch, hence the need for different keyboards/registers to produce a variety of sounds. I guess that is true for most pipe organs, but I had no idea that some had that kind of refinement.Muirium wrote: ↑Having just read up on after touch, it is indeed pretty cheap and limited. What a surprise! Instead, I found this more impressive:
https://en.wikipedia.org/wiki/Keyboard_ ... ensitivity
Organ keyboards have always made more sense than piano ones to me. Want a loud note: press further. Pianos need to swing physical hammers of course. But electronics does not. We could implement this!
Well, if anyone with a clue at coding is interested. I'm terrible at this stuff!
You can hear it (or see it live) in some Dream Theater songs (the intro of "Octavarium" for instance), their keyboardist Jordan Rudess is a big fan of that kind of stuff. I had no idea they used Hall sensors like this, I always thought there was an array of pressure sensors under the board instead!unoab wrote: ↑All this piano and keyboard talk reminds me of a midi "keyboard" that one of my professors in college made and sold. It used multiple rows of hall effect sensors to track finger positions on a neoprene sheet in 3 dimensions that then could be output over midi channels as the note and two additional parameters.
Found the website for it, and here is a page on the internal mechanical structure:
http://www.hakenaudio.com/Continuum/hak ... vervf.html
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Admittedly, I hardly know my way around a musical keyboard in truth! Just the idea of measuring velocity using what amounts to a pair of tripwires per key seems so dirty and a hack… but aye, I should go play an organ before I decide they're better as a model for computer instruments.
Real pianos, ah, I've tinkered on a few of those. That weighting… it's what I like best (in a lesser form) in typing keyboards too. The "swing" of beamspring, and Topre.
Real pianos, ah, I've tinkered on a few of those. That weighting… it's what I like best (in a lesser form) in typing keyboards too. The "swing" of beamspring, and Topre.
- DiodeHead
- Location: Spain
- Favorite switch: Gateron white
- DT Pro Member: -
Excelent post , thanks for sharing.
a sot 223 package for the hall effect should solve your anchoring problems.
it´s really tight but i think it could work , the problem now would be finding one with the same carasteristics in that package T_T
good luck with your project.
a sot 223 package for the hall effect should solve your anchoring problems.
it´s really tight but i think it could work , the problem now would be finding one with the same carasteristics in that package T_T
good luck with your project.
- Redmaus
- Gotta start somewhere
- Location: Near Dallas, Texas
- Main keyboard: Unsaver | 3276 | Kingsaver
- Main mouse: Kensington Slimblade
- Favorite switch: Capacitative Buckling Spring
- DT Pro Member: -
- Contact:
Wow this is really cool. Loving this project. I might even get one if the price is sane.
-
- Location: France
- Main keyboard: KBT Pure Pro
- Main mouse: G500
- Favorite switch: MX Red, MX Blue
- DT Pro Member: -
I briefly thought about it at one point but quickly gave up the idea as the A1301/2 are only available in the smaller SOT123 package, but you're right, using SMT parts may be a valid design choice. I'll dig in this direction, thanks for the tip!DiodeHead wrote: ↑Excelent post , thanks for sharing.
a sot 223 package for the hall effect should solve your anchoring problems.
https://dl.dropboxusercontent.com/u/48905360/sot223.JPG
it´s really tight but i think it could work , the problem now would be finding one with the same carasteristics in that package T_T
good luck with your project.
I don't intend to sell these in their completed form, but when it's mature enough I will likely be able to offer PCBs for sale, and maybe we can arrange a group buy for other components (diodes, sensors, maybe switches and keycaps) if there is enough interest. It is not the highest priority for me, but it is certainly something that could be done.Redmaus wrote: ↑Wow this is really cool. Loving this project. I might even get one if the price is sane.
- Anticham
- Location: France
- DT Pro Member: -
Hi Matt,
I'm rally interested by this project, it's for musical purpose...
First I will copy you, you did the work thank you. hall effect, yes, very clever.
Now I need to know where you found the cap with the transparent led strip? Very sexy!
Antichambre
I'm rally interested by this project, it's for musical purpose...
First I will copy you, you did the work thank you. hall effect, yes, very clever.
Now I need to know where you found the cap with the transparent led strip? Very sexy!
Antichambre
- Anticham
- Location: France
- DT Pro Member: -
http://midibox.org/forums/topic/14338-c ... ent-128120
About the two contact to get velocity
About the two contact to get velocity
-
- Location: Montreal, Canada
- DT Pro Member: -
Hi everyone..i am a new user here. As per my knowledge you need to find firmware which supports also joystick USB endpoint. You want at least 2 endpoints: keyboard and joystick. I plan to add a joystick endpoint to my keyboard eventually but this is at least half a year in the future, maybe a year or even more.Most free keyboard firmwares contain keyboard and mouse endpoint. I do not know whether any firmware already contains a joystick endpoint too.
pcb assembly china
pcb assembly china