Monday, October 2, 2023

DIY "StreamDeck"

 OK, so it's far from being an ACTUAL StreamDeck, but here's what I did to make a old external 10-key Numpad with PS/2 plug into a keypad that can do macro's over USB HID.

It started when I found a very unique 10key in a recycle pile. It had mechanical keys, and they were VERY clicky. Only issue was, it was PS/2. Ya know, the 5 pin barrel thing from back in the day? Yeah there's adapters for it, but really I didn't need a external numpad. In all honesty, I was just gonna make it a fidget thing cause I liked the clicky nature of it.

That is, until I started learning how some Arduino boards can be setup to be recognized as a HID device. Basically, when you plug it into a computer, it will recognize it as an interface device, and not an arduino board.

So that got me thinking. Yeah, I could make it USB instead of PS/2. But would it be possible for a computer to recognize it as a seperate input? So I can maybe setup hotkeys in OBS?

Well, no...not exactly

But what about translating the keypresses to something else?... Maybe?

I dug into the device to see what I could find. A bunch of pcb and a chip that has no datasheet filed anywhere online.

Welp, there went that idea of maybe tapping some pins to use the standard matrix style key project that can be found in many arduino starter packs. 

I went on to a couple Discord servers to chat/prod for help on this crazy lil idea I had, and someone suggested "Why not just have it use some extended keys?"

Yeah... Why not?

I already knew that keyboard standards accepted things like media hot keys and what have you, as well as function keys beyond the F12 of the standard keyboard. Why not have this do F13-F24? That's plenty of keys for using as macro hotkeys. I broke out my Arduino Leoardo, which I found can do HID nativly, and started looking up coding examples.

With the help of 'chaosfool' from Syd Heresy's crew on discord, I was able to put together a Arduino sketch that was able to take the scan code of the key press, then add a set number of however many keys above that was to make it equal to the scancode of the higher function keys. Wired up the PS/2 wires VC to 5V, GND to GND, Clock to SCL, and DATA to an open data pin on a Arduino Leonardo breakout board, then pushed the sketch over.

Viola! I have data! And the scan codes are pushing the right key presses! 0-9 with period and enter are showing up as F13-F24

Of course, there are still some issues.

The code worked TOO well. As you can see in the video, when I press a key and release it, it sends 2 signals. This is how PS/2 is supposed to work! But, when the Leo translated it to USB via my sketch, it would send the signal twice. Which would cause the keypress to happen twice. And even then, it was sending the signal so fast, applications out of focus of the main window would not see the keypresses. After beating my head over it, I decided to shove it asside and see if I could make this even work independently without it in pieces.

In comes the DFRobot Beetle!

This lil thing is a bit bigger than a quarter and is basically a stripped down Leonardo. Perfect for what I am needing it for! 

The numpad thankfully used a header to connect to the PS/2 cable, so I was able to unplug the cable, snip the end with the header connection, and then strip some wires back to solder to the Beetle. PS/2 Vcc and GND went to 5V out and GND pads respectivly. Clock wire went to the SCL pad (ie, IRQ pin 3) and DATA wire went to Digital Data pin/pad 11.

Electrical taped it sealed, folded the wires over that and it fits perectly in the space above the PCB of the numpad! Had a super long MicroUSB so that fit in the wire hole and under the board of the keypad to the Beetle
Then I pushed the code again, and now I am back at where I was before. Double pressing of keys when I push it once, unable to use it with out of focus applications. At least it looked nice?
Was able to make key lables using a DYMO LabelManager 280 with the durable white on black lables. Being that the printer can connect via USB, I could make nice lil emote style covers.

The project sat for months while I hem and hawed over what to do about the code. I am a complete n00b when it came to C++, but then I decided I need to finish it. Otherwise, it was just getting in the way.

Long story short, fought with it a few days, then came across some information from some help on Reddit. The library I was using had some variables I didn't think of. Once those were in place, it worked like a charm! The sketch is below:

//NUMPAD to extended function keys (f13-f24)
//Converts PS/2 numpad to function as extended function keys over USB HID
#include <PS2KeyAdvanced.h> //required for higher function keys
#include <Keyboard.h>

PS2KeyAdvanced ps2kb;

#define DATAPIN 11 
#define IRQPIN 3 //SCL pin on Beetle

uint16_t c;

void setup( ) { 
   ps2kb.begin( DATAPIN, IRQPIN );
   if ( ps2kb.available ( ) ) {
     c =;

void loop( ) {
  if ( ps2kb.available( ) ) {
    c = );
    if ( c > 0 ) {
      uint16_t fkey = c + (PS2_KEY_F13 - PS2_KEY_KP0); // translate number key to function key
      char hidkey = KEY_F13 + (fkey - PS2_KEY_F13); // convert to hid key code
      if((c>>8)!=80);{ // send to computer;
(big up to for its awesome html maker for code blocks!)

It basically now sends the keypress for 50 ms and then releases it. Super fast and instant. Once I got this running, all I needed to do was set the hotkeys in OBS. Now I am able to switch scenes and even mute input/outputs without needing to switch focus of applications! I'm sure it could be used for anything elses outside of OBS, but for now, I am happy with the result! Hope someone out there will find this and be able to do the same.

Total cost of this was $11 for the Beetle and some time. Well worth it seeing how stream decks are around $100. 

No comments:

Post a Comment

Don't be a dingus

StreamElements Overlay Chat - Top Down display!

 Okay, this seems silly to make a post like this, but I wish I had found a page that told me this before wasting a few hours trying to figur...