🌓

How to set up a Macropad from AliExpress on Linux Linux makes everything possible, with just a couple minutes you can get a cheap Macropad keyboard to run scripts and anything you can think of.

by
on April 26, 2024
(6 minute read)

I’ve been using a Griffin Powermate for many years and I find it’s an extremely useful little device. It’s just a knob that you can also click it, nothing more, but the fact that it is so ergonomic and you can have it anywhere on your desk makes it super useful.

Things I’m buying on Amazon this week

Wandering around AliExpress I found these macropads or macro keyboards which you could buy for super cheap (7€ each) so I decided to get a couple for home and work. The model I bought is a 3×1 keys + 1 knob keyboard, it has no brand but through some Linux commands I found the HID is 1189:8890 (vendorId:productId), sometimes detected as an Acer keyboard (I believe due to this HID being officially used by Acer). It is also sometimes identified as vendor 0x1189 and product 0x8890 (Trisat Industrial Co., Ltd.).

The product page only showed drivers for Windows (which some people are mentioning it contains malware), but myself running Linux I was pretty sure I could set it up as a keyboard and intercept the device signals to then run scripts with it, after all, with Linux you have full control of your computer and anything you connect to it. Thank you Linux!

So I got the package delivered and after connecting it to the USB-C, I saw that whenever you typed any key, scroll the knob or even click the knob, it always typed a lowercase C. After some searching and troubleshooting, trying a few different workarounds and being a bit daunted that this device would end up in a drawer collecting dust since key capturing tools couldn’t differentiate the Cs, I saw the light thanks to a french guy’s blog and other folks that had built libraries and tinkered with it. The idea was to reprogram the ROM of the macro keyboard to do whatever you wanted.

It’s actually really easy, I’ve created this article so you only need to copy and paste the following commands to get you set up. Please read the instructions and understand what each command is doing, this guide will get you up to running a custom script with each key/roll/click.

Reprogramming the keyboard

First thing we need to do is to reprogram the ROM of the device so that it doesn’t output C letters all the time but some key combinations we can later remap.

Download the ch57x tool which will allow you to reprogram several models of macro keyboards. We will be using version 1.2.4 since it worked for me, as of writing this the latest version is the 1.4.x but I couldn’t make it work and the 1.2.4 works great:

cd ~/Downloads
mkdir ch57x-keyboard-tool
cd ch57x-keyboard-tool
wget https://github.com/kriomant/ch57x-keyboard-tool/releases/download/v1.2.4/ch57x-keyboard-tool-x86_64-unknown-linux-gnu.tar.gz
tar zxvf ch57x-keyboard-tool-x86_64-unknown-linux-gnu.tar.gz
nano mapping.yaml

Now, type this into your YAML file (if you have the 3×1 + 1 knob macro keyboard):

orientation: normal
rows: 1
columns: 3
knobs: 1
layers:
  - buttons:
      - ["alt-ctrl-shift-q", "alt-ctrl-shift-w", "alt-ctrl-shift-e"]
    knobs:
      - ccw: "alt-ctrl-shift-r"
        press: "alt-ctrl-shift-t"
        cw: "alt-ctrl-shift-y"

The configuration above will set the events like this:

Action Hotkey
Key 1 Control+Alt+Shift + Q
Key 2 Control+Alt+Shift + W
Key 3 Control+Alt+Shift + E
Knob counter-clockwise Control+Alt+Shift + R
Knob click Control+Alt+Shift + T
Knob clockwise Control+Alt+Shift + Y

Validate it:

sudo ./ch57x-keyboard-tool validate < mapping.yaml
-- config is valid 👌

If all works, then upload it (note that the keyboard has a guaranteed 200 write limit so try and minimize writes as much as possible to extend your device’s EEPROM life):

sudo ./ch57x-keyboard-tool upload < mapping.yaml

You may also turn on the LEDs (change from 1 to 3 for different modes, 0 to disable):

sudo ./ch57x-keyboard-tool led 1

Mapping keys to commands

We can now use xBindKeys to map key presses to console commands:

sudo apt install xbindkeys
xbindkeys --defaults > ~/.xbindkeysrc

Now you can set any terminal command you want, edit the file nano ~/.xbindkeysrc and type something like:

"gnome-terminal"
  control + alt + shift + q

"gnome-calculator"
  control + alt + shift + w

"gnome-system-monitor"
  control + alt + shift + e

"amixer -D pulse sset Master 10%-"
  control + alt + shift + r

"~/audio-output-switch.sh"
  control + alt + shift + t

"amixer -D pulse sset Master 10%+"
  control + alt + shift + y

FYI the audio output script can be found here.

You will need to run xbindkeys if you haven’t already:

xbindkeys

That’s it, everything should be working now.

If xBindKeys is not reloading the changes, type this:

killall -HUP xbindkeys; xbindkeys

Customizing your actions

That’s all! You now just need to think what to use those keys for, a few ideas:

  • Keys:
    • Empty recycling bin
    • Clear RAM
    • Suspend / Power off / Log out
    • Switch to full screen terminal
    • Set window full screen
    • Play video or move one frame
    • Run a webhook to toggle a home light switch
    • Change screen brightness
      xrandr --output DisplayPort-1 --brightness 0.5
  • Knob:
    • Volume up/down
      amixer -D pulse sset Master 10%-
    • Screen brightness up/down
    • Switch to next/previous window/tab
  • Knob click:
    • Mute/Unmute volume
    • Switch sound output source
    • Switch screens arrangement
    • Toggle notifications/DND

Other useful commands

Here’s some useful commands regarding key presses and their terminal output:

xbindkeys --key

"(Scheme function)"
    m:0x9 + c:50
    Shift+Alt + Shift_L

xev

KeyRelease event, serial 39, synthetic NO, window 0x3000001,
    root 0x6c0, subw 0x0, time 2547135, (162,-22), root:(572,46),
    state 0x8, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 39, synthetic NO, window 0x3000001,
    root 0x6c0, subw 0x0, time 2547135, (162,-22), root:(572,46),
    state 0x0, keycode 25 (keysym 0x77, w), same_screen YES,
    XLookupString gives 1 bytes: (77) "w"
    XFilterEvent returns: False

xinput

⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ HID 1189:8890 Keyboard                  	id=12	[slave  pointer  (2)]
⎜   ↳ HID 1189:8890                           	id=13	[slave  pointer  (2)]
⎜   ↳ SINOWEALTH Wired Gaming Mouse           	id=14	[slave  pointer  (2)]
⎣ Virtual core keyboard                   	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
    ↳ Power Button                            	id=6	[slave  keyboard (3)]
    ↳ Power Button                            	id=7	[slave  keyboard (3)]
    ↳ HOLTEK USB Keyboard                     	id=8	[slave  keyboard (3)]
    ↳ HOLTEK USB Keyboard System Control      	id=9	[slave  keyboard (3)]
    ↳ HOLTEK USB Keyboard Consumer Control    	id=10	[slave  keyboard (3)]
    ↳ HID 1189:8890                           	id=11	[slave  keyboard (3)]
    ↳ SINOWEALTH Wired Gaming Mouse Keyboard  	id=15	[slave  keyboard (3)]
    ↳ HID 1189:8890 Keyboard                  	id=16	[slave  keyboard (3)]

showkey -a

^[E 	 27 0033 0x1b
 	 69 0105 0x45
^[W 	 27 0033 0x1b
 	 87 0127 0x57
^[Q 	 27 0033 0x1b
 	 81 0121 0x51

Please donate to keep this server up

 

References:

 

Free 100% online banking account

💳 Get your free debit Mastercard

No comments yet

Treasure Chest

Get notified of new projects I make
Usually one email every 3 months

Follow me for cool new products and interesting findings on graphic design, web development, marketing, startups, life and humor.


/*Twitter*/ !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs"); /*Facebook (function(d, s, id) {var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = "//connect.facebook.net/en_GB/all.js#xfbml=1&appId=28624667607";fjs.parentNode.insertBefore(js, fjs);}(document, 'script', 'facebook-jssdk'));*/ /*Google+*/ window.___gcfg = {lang: 'en-GB'};(function() {var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;po.src = 'https://apis.google.com/js/plusone.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);})();