Giter Site home page Giter Site logo

hid-remapper's Introduction

HID Remapper

This is a configurable USB dongle that allows you to remap inputs from mice, keyboards and other devices. It works completely in hardware and requires no software running on the computer during normal use.

It can do things like reassign buttons, change keyboard layouts, map mouse buttons to keyboard inputs, map keystrokes to mouse inputs, change mouse sensitivity (permanently or when a button is held), rotate mouse axes by arbitrary (non-90 degree) angles, drag-lock for mouse buttons, scroll by moving the mouse, and much more.

It is configurable through a web browser using WebHID (Chrome or Chrome-based browser required).

Wireless receivers are supported and multiple devices can be connected at the same time using a USB hub (with different mappings for each device if desired).

In addition to the remapping functionality, it can do polling rate overclocking up to 1000 Hz.

A separate serial version of the remapper takes inputs from a serial (RS-232) mouse and translates them to USB.

There's also a Bluetooth version that runs on nRF52840-based boards, which translates Bluetooth inputs to USB.

HID Remapper

How to make the device

There are three main ways of making the HID Remapper. You can either buy this board from Adafruit, make it yourself using a Raspberry Pi Pico (or two), or you can use the provided files to manufacture a custom board at JLCPCB or a similar service. The functionality is the same in all cases.

If you get the Feather RP2040 USB Host board from Adafruit, the device is ready to use, you just need to flash it with the right firmware (remapper_feather.uf2). Hold the "Boot" button on the board, then press the "Reset" button. A USB drive should show up on your computer. Copy the UF2 file to that drive. That's it.

See here for details on how to make the Pico variants of the device and here for details on the custom board option.

How to use the configuration tool

A live version of the web configuration tool can be found here. It only works in Chrome and Chrome-based browsers (including ChromeOS). On Linux you might need to give yourself permissions to the appropriate /dev/hidraw* device.

The input remapping mechanism is based on a list of mappings. Every mapping has an input and an output. Inputs and outputs are things like mouse buttons, mouse axes, keyboard keys etc. For example if you want the right mouse button to act as the left mouse button, add a mapping with input set to "Right button" and output set to "Left button".

By default all inputs that aren't explicitly mapped to anything are passed through unchanged. If you don't want that, you can uncheck the "Unmapped inputs passthrough" checkbox (for each layer separately, see below).

There can be more than one mapping with the same input and the same output. It is useful when you want to map a mouse button to, say, Ctrl-C. You can achieve that by adding two mappings, both with that button as input, one with "Control" as output and one with "C" as output.

Similarly to remapping buttons, you can also remap axes. For example if you want horizontal mouse movements to be mapped to vertical cursor movements on the computer, add a mapping with the input set to "Cursor X" and the output set to "Cursor Y".

If you want to change cursor speed (mouse sensitivity), you can use the scaling part of the mapping. By default it is set to 1, but you could add mappings with the same axes for inputs and outputs and for example set scaling to 2 to make the cursor move twice as fast, or set it to -1 to invert the direction of the movement. (Usually it's best to first increase the CPI on the device if possible as that will give you better precision.)

You can have a mapping that has a button or a key as input and an axis as output. For example if you add a mapping with "Right arrow" as input and "Cursor X" as output, it will make the cursor move right when right arrow is held on the keyboard.

Having an axis as input and a button as output currently doesn't make a lot of sense.

The sticky flag on a mapping can be used to implement drag-lock functionality. When the flag is enabled on a mapping, pressing (and releasing) the input button will cause the output button to be held until the input button is pressed again.

The layers mechanism might sound familiar if you ever used a custom ergo keyboard. It works as follows. A special mapping can be added with some button as input and "Layer X" as output. This means that when that button is pressed, layer X is active and therefore mappings from layer X are applied. Every mapping has a set of layers on which it is present. If no layer is explicitly activated, layer 0 is active. More than one layer can be active at the same time. This mechanism has many useful applications, from completely separate keyboard layouts to things like "sniper button" on a mouse - increasing precision when a certain button is held.

Layer activating mappings can be sticky.

Tap-hold is another mechanism adopted from the custom ergo keyboard world. It lets you map the same button to different things depending on whether it's tapped (pressed and released quickly) or held (longer than 200ms or whatever you set the threshold to). This allows configurations where a button keeps its primary function when it's clicked, but activates a layer (or a modifier key like Shift) when it's held. Together with the sticky flag, it can also be used to make a button activate a layer permanently when clicked and also temporarily when held. For the last configuration to work properly, create two separate mappings, one with "sticky"+"tap" enabled, and another with "hold" enabled.

Sometimes you want a certain button to send multiple outputs, but not at the same time, but one after another, for example to input a special character by typing something like Alt-0165 or to emulate a double click. You can do that with the macros feature. Each macro is defined as a list of inputs that will be sent one after another. Every input can consist of multiple keys, for example you can have a macro that looks like this: Left Shift+H, E, L, Nothing, L, O that will type the string "Hello" or you can have a macro that looks like this: Left Alt+Numpad 0, Left Alt+Numpad 1, Left Alt+Numpad 6, Left Alt+Numpad 5 that will enter the yen symbol (on some systems). Or, to emulate a double-click, you could define a macro that looks like this: Left button, Nothing, Left button. The "Nothing" part is necessary for the computer to register a "button-up" event, otherwise the first macro would type "Helo" and the last one would just work as a single click.

To make a button send a certain macro, add a mapping with that button as input and with "Macro X" as output.

The expressions mechanism is an advanced and experimental feature that can be used for more complex mappings. Among other things it lets you map things like analog sticks, triggers and D-pads on game controllers, applying dead zones and other non-linear transformations to them. See here for more info on how to use them.

The configuration tool comes with a list of standard inputs like mouse buttons and axes, keyboard keys and media keys like play/pause, mute, etc. Some devices will use inputs from outside that list. Good news is they can still be mapped. To make the device-specific inputs appear on the list, just connect your device to the remapper, and the remapper to your computer, and click the "Open device" button before you define the mappings. The configuration tool will fetch the list of inputs declared by your device and they will show up at the bottom of the input list. Unfortunately they will only appear as hex codes and will not have human friendly names. Therefore it might require some trial and error to find the input you want (and some devices will have a lot of them!).

The remapper supports high-resolution mouse scrolling on the output side, which should work on Windows and modern Linux desktops. To experience it, add a mapping with "Cursor Y" as input and "V scroll" as output (perhaps on a layer). The "Partial scroll timeout" setting is related to this and you can safely ignore it if you're not mapping anything to mouse scroll. It applies when high-resolution scrolling is not in use and is the time after which a "half-tick" of the scroll is forgotten.

If you set the "Polling rate override" to anything else than "don't override", it will use the selected polling rate instead of the polling rate requested by the connected device. Keep in mind this doesn't work for all devices.

If you're getting an "Incompatible version" error, try upgrading to the newest firmware.

If this description wasn't particularly clear for you, perhaps looking at some of the examples that come with the configuration tool will help.

If you can't use the browser-based configuration tool, there's also a command-line tool that takes JSON in the same format as the web tool on standard input. I only tested it on Linux, but in theory it should also run on Windows and Mac.

How to compile the firmware

The easiest way to compile the firmware is to let GitHub do it for you. This repository has GitHub Actions that build the firmware, so you can just fork, make your changes, wait for the job to complete, and look for the binaries in the artifacts produced.

To compile the RP2040 firmware on your machine, use the following steps (details may vary depending on your Linux distribution):

sudo apt install gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib srecord
git clone https://github.com/jfedor2/hid-remapper.git
cd hid-remapper
git submodule update --init
cd firmware
mkdir build
cd build
cmake ..
# or, to build for the custom boards:
# PICO_BOARD=remapper cmake ..
make

To compile the nRF52 firmware, you can either follow Nordic's setup instructions and then west build -b seeed_xiao_nrf52840 to compile the firmware, or you can use Docker with a command like this (start from the top level of the repository or adjust the path accordingly):

docker run --rm -v $(pwd):/workdir/project -w /workdir/project/firmware-bluetooth nordicplayground/nrfconnect-sdk:v2.2-branch west build -b seeed_xiao_nrf52840

License

The software in this repository is licensed under the MIT License, unless stated otherwise.

The hardware designs in this repository are licensed under the Creative Commons Attribution 4.0 International license (CC BY 4.0), unless stated otherwise.

hid-remapper's People

Contributors

jfedor2 avatar shiiba-cba avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hid-remapper's Issues

feature request: toggle lights in configurator

Having the lights on is very useful for testing and pairing, but they are not necessary habitually. Would it be possible to toggle them off in the configurator (I am using a Seeed Xiao nrf). Perhaps there could simply be a no-light firmware variant.

Thanks for all of your work!

Question: How are you maintaining DPI / mouse speed?

Hi there!

First off, thankyou for this awesome project, it's been extremely useful to use as a reference and check my logic against.
Some background, I'm building a tool similar to this but with a completely different application.

I've built a complete HID parser that will hopefully be open sourced soon and have confirmed data being returned from it and it's translation layer is 100% correct in line with the HID spec, though when sending a report back to the pc the mouse speed is almost 5x over the same physical distance.
This behaviour is not seen with this project on the exact same hardware, and I can't see how you've managed it.

In my fruitless efforts to debug this, I've gone as far as copying your mouse descriptor entirely (with the removal of AC Pan) to confirm that's not the issue, and with that in place using WireShark, I can observe the following report from this project 01000200feff00000000

ID BB XXXX YYYY WWWW AAAA
01 00 0200 feff 0000 0000

And from my own code observe the following report fa000700feff0000

ID BB XXXX YYYY WWWW
fa 00 0700 feff 0000

I am triggering a report to be sent to the pc on every report received to the Pico, and as such the Pico is basically a transparent layer with no modification to the data.

The only thing I could see remotely close to speed would be the Report ID (REPORT_ID_MULTIPLIER) field you define in the report, but this not only doesn't affect the X, Y Usage Locals, but is only used throughout your code to change the scroll wheel.

Any tips or pointers where to look to solve this would be immensely appreciated, the past week trying to get my head around the HID Descriptor format has been painful!

Thankyou for your time, I appreciate this is slightly off topic for the repo, you're the only person I can see who has successfully tackled this!

Jack


Some additional notes:

  • Mouse for testing is an Intellimouse Pro NGX-00012 with it's DPI set in windows to 1400
  • Only one Pico in use
  • TinyUSB also has a CDC interface on the device end
  • Attached are 2 pcap files in a zip, one showing this project, the other my implementation and a copy of my descriptor.

Enable upper buttons on the Kensington Slimblade

First of all, thanks for starting this! It looks like a very promising tool for remapping trackball functions with a hardware solution. My application is a Windows laptop where I'd like to avoid installing the Kensington driver and the KensingtonWorks software.

I have tested it with the Slimblade trackball, and the upper two buttons don't work at the moment. Unfortunately Kensington seems to use some non-standard implementation here. Do you think these buttons can be added? On Reddit you mentioned hid-recorder. Below is the log from pressing the bottom left, bottom right, top left, and top right buttons, in this order (recorded on Linux Mint 20.3). Let me know how else I can help.

# Kensington Slimblade Trackball
# 0x05, 0x01,                    // Usage Page (Generic Desktop)        0
# 0x09, 0x02,                    // Usage (Mouse)                       2
# 0xa1, 0x01,                    // Collection (Application)            4
# 0x09, 0x01,                    //  Usage (Pointer)                    6
# 0xa1, 0x00,                    //  Collection (Physical)              8
# 0x05, 0x09,                    //   Usage Page (Button)               10
# 0x19, 0x01,                    //   Usage Minimum (1)                 12
# 0x29, 0x02,                    //   Usage Maximum (2)                 14
# 0x15, 0x00,                    //   Logical Minimum (0)               16
# 0x25, 0x01,                    //   Logical Maximum (1)               18
# 0x95, 0x02,                    //   Report Count (2)                  20
# 0x75, 0x01,                    //   Report Size (1)                   22
# 0x81, 0x02,                    //   Input (Data,Var,Abs)              24
# 0x95, 0x01,                    //   Report Count (1)                  26
# 0x75, 0x06,                    //   Report Size (6)                   28
# 0x81, 0x03,                    //   Input (Cnst,Var,Abs)              30
# 0x05, 0x01,                    //   Usage Page (Generic Desktop)      32
# 0x09, 0x30,                    //   Usage (X)                         34
# 0x09, 0x31,                    //   Usage (Y)                         36
# 0x09, 0x38,                    //   Usage (Wheel)                     38
# 0x15, 0x81,                    //   Logical Minimum (-127)            40
# 0x25, 0x7f,                    //   Logical Maximum (127)             42
# 0x75, 0x08,                    //   Report Size (8)                   44
# 0x95, 0x03,                    //   Report Count (3)                  46
# 0x81, 0x06,                    //   Input (Data,Var,Rel)              48
# 0x06, 0x00, 0xff,              //   Usage Page (Vendor Defined Page 1) 50
# 0x19, 0x01,                    //   Usage Minimum (1)                 53
# 0x29, 0x02,                    //   Usage Maximum (2)                 55
# 0x15, 0x00,                    //   Logical Minimum (0)               57
# 0x25, 0x01,                    //   Logical Maximum (1)               59
# 0x95, 0x02,                    //   Report Count (2)                  61
# 0x75, 0x01,                    //   Report Size (1)                   63
# 0x81, 0x02,                    //   Input (Data,Var,Abs)              65
# 0x95, 0x01,                    //   Report Count (1)                  67
# 0x75, 0x06,                    //   Report Size (6)                   69
# 0x81, 0x03,                    //   Input (Cnst,Var,Abs)              71
# 0xc0,                          //  End Collection                     73
# 0xc0,                          // End Collection                      74
# 
R: 75 05 01 09 02 a1 01 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 95 02 75 01 81 02 95 01 75 06 81 03 05 01 09 30 09 31 09 38 15 81 25 7f 75 08 95 03 81 06 06 00 ff 19 01 29 02 15 00 25 01 95 02 75 01 81 02 95 01 75 06 81 03 c0 c0
N: Kensington Slimblade Trackball
I: 3 047d 2041
#  Button: 1  0 | # | X:    0 | Y:    0 | Wheel:    0 | Vendor Usage 1: 0 | Vendor Usage 2: 0 | # 
E: 000000.000000 5 01 00 00 00 00
#  Button: 0  0 | # | X:    0 | Y:    0 | Wheel:    0 | Vendor Usage 1: 0 | Vendor Usage 2: 0 | # 
E: 000000.192059 5 00 00 00 00 00

#  Button: 0  1 | # | X:    0 | Y:    0 | Wheel:    0 | Vendor Usage 1: 0 | Vendor Usage 2: 0 | # 
E: 000001.439958 5 02 00 00 00 00
#  Button: 0  0 | # | X:    0 | Y:    0 | Wheel:    0 | Vendor Usage 1: 0 | Vendor Usage 2: 0 | # 
E: 000001.727981 5 00 00 00 00 00

#  Button: 0  0 | # | X:    0 | Y:    0 | Wheel:    0 | Vendor Usage 1: 1 | Vendor Usage 2: 0 | # 
E: 000005.543959 5 00 00 00 00 01
#  Button: 0  0 | # | X:    0 | Y:    0 | Wheel:    0 | Vendor Usage 1: 0 | Vendor Usage 2: 0 | # 
E: 000005.815943 5 00 00 00 00 00

#  Button: 0  0 | # | X:    0 | Y:    0 | Wheel:    0 | Vendor Usage 1: 0 | Vendor Usage 2: 1 | # 
E: 000007.088063 5 00 00 00 00 02
#  Button: 0  0 | # | X:    0 | Y:    0 | Wheel:    0 | Vendor Usage 1: 0 | Vendor Usage 2: 0 | # 
E: 000007.407931 5 00 00 00 00 00

bug report: macro called from other macro does not execute

Hi Jacek -

Macros are great, and work really well thus far!

One bug I've noticed is that macros called from other macros does not execute on any of my remapper devices, despite that those macros are available as key mappings. Tested on v1 hardware (4x) and pico.

Example follows. Note that Macro 1 is large, and unrelated as far as I can tell, so I've removed it here. In my setup, macro 1 is not blank.

"macros": [
        [removed],
        [
            [
                "0x000700e2",
                "0x000700e1",
                "0x00070050"
            ]
        ],
        [
            [
                "0xfff20002"
            ],
            [
                "0xfff20002"
            ],
            [
                "0xfff20002"
            ]
        ],
        [],
        [],
        [],
        [],
        []

Scroll Acceleration / Momentum

I really want to use a trackball in each hand - one dedicated to mousing and one dedicated to scrolling. I want the ball movement from the "scrolling hand" to act like scrolling on a touch screen with precise control for small and slow movements and with the ability to "flick" the ball and let the physical momentum transfer to momentum in the on screen scroll event. KensingtonWorks's TrackScroll in combination with a very tweaked SmoothScroll configuration gets really close but TrackScroll emulates a regular scroll wheel and so lacks the precise scrolling and I really like the idea of a hardware solution anyway.

With this project, although I'm sure I read that you have implemented precise scrolling it does not seem to act that way for me - it seems like normal scroll wheel emulation - and as it currently does not have scroll momentum I loose the momentum provided by TrackScroll.

In any case, I see the potential in hid-remapper. Do you think this dream can eventually be realized through this project? If so, please let me know if there is anything I can do to help it along.

Can't pair on NRF52840. No Bluetooth device visible

Flashed the appropriate firmware on Seeed nRF52840.
Solid blue light when plugged in.
Successfully connected through web tool and clicked pair.
No bluetooth signal visible to laptop or cell phone (S22 Ultra).
I tried nRF Connect app and still don't see it.
Flashed SEEED "HID Keyboard Demo" and that works correctly. [Wrote down MAC address]
Reflashed hid-remapper, but still can't find it.

Can you help?
Thanks!!

Elecom Huge Wired does not function with 2 Pico variant

It seems that the Elecom Huge wired version is not working with the device. I had only tested it with the 2 Pico variant. Upon connection, the LED on the mouse would sometimes blink (when connected directly to a device it would blink twice) and no input could be read. The status LED on neither Pico would blink.

I would like to assist in debugging the device, but since I only have limited hardware knowledge I would need instructions on where and what information I can provide to help.

I tried using win-hid-dump to get the HID descriptors but it seems to always crash. But I did see 4 entries created by this mouse so it could still be related to #18

Honor Scaling magnitude for mouse cursor to keystroke action

Fantastic project!

I have a small feature request that occurred to me as I enjoyed experimenting with it this weekend.

Scaling for mouse movement to keystroke action

I want to make the following mapping: in a certain layer, hold Alt, and convert Mouse Y movement into Tab/Shift-Tab. (This will let me quickly scrub across all my open windows.) This mapping works, but it seems like any amount of mouse movement generates a keystroke: i.e. the magnitude of the "Scaling" field is ignored (thankfully, its sign is respected). So it absolutely blazes across all my windows at a rate faster than I can see.

It would be cool to honor the magnitude of the Scaling field for these mappings. Then, I would have to move my cursor, say 10 "pixels" for another Tab keystroke to be generated.

I might take a look at implementing this myself - the code looks approachable. It would probably be something like how scaling works for scroll actions. However, filing this here upfront for opinions and suggestions. 😄

Mapping one key + modifier to multiple keys possible

This project is a very elegant solution to remap keyboards at an affordable cost, and I am eager to buy a pi board and test it.

I would like to attach it to a BÉPO keyboard so that it looks like an AZERTY one.

The problem I foresee is that upper case accented letters such as É would require to input the dead accent ´ followed by the uppercase E: É = ´ + E.
Would it be possible to implement this easily (one key + modifier maps to 2 keys) ? Do you think it would require a lot of changes and affect many files?

Other combinations will also be needed, for example to map Ç. On windows, this requires to input ALT+0199, mapping therefore one key + shift modifier to 4 keys + alt modifier.

I could devote some time to make this work, but I would appreciate if you can tell me how hard this looks to you and where to start.

Layer-switch buttons do not map correctly on alternate layers

Hi,

My specific issue is involving my Kensington SlimBlade. If on layer 0 I map the "back" button to activate L1, and the "forward" button to activate L2, then on L1 I map the "forward" button to send a "forward" HID event, and on L2 I map the "back" button to send a "back" HID event, neither works reliably.

In other words, what I expect (and am aiming for) is that if I hold the top right quadrant button and click the top left quadrant button, to go back, and vice versa -- if I hold the top left and click the top right button, I want to go forwards.

I think I've learned most of what I know about HID between this and QMK in the past few weeks so I have no idea how to debug it, but my guess would be that there's some sort of weird conflict where it's interpreting the layer shift commands even though they should be superseded by higher layer commands mapped to those buttons.

getting invalid syntax when trying to run the config tool

the message i get is:
File "remapper-config.py", line 175
f"{d['manufacturer_string']} {d['product_string']}",
^
SyntaxError: invalid syntax

i am running it on ubuntu python 3.7, it is also a problem in the config tool for the two balls trackball

Overclocking MLT04 mice (IMO 1.1a specifically), mouse won't respond?

Hello, these are the steps I've done:
-Got microUSB to USB cable from my motorola charger
-Held the BOOTSEL button (while having microUSB put in) and inserted the USB part in my PC
-Linux/Windows found the RPI Pico, opened the folder up and inserted the remapper.uf2 file inside
-Folder closed, all things are still plugged in
-Opened up the website and connected the mouse to the soldered USB hub
-Mouse has LED's turned on but it doesn't recognize any input?
I've tried mapping cursor X and Y, etc. to the same outputs but to no avail. I feel like I'm either connecting the mouse early/late or not using the website right, any help?

https://youtu.be/nxhV84Gcb0g

https://cdn.discordapp.com/attachments/263456086001057804/966016984535928892/20220419_184516.jpg

Config tool: allow keypress to select Input

I was hoping for a possible enhancement with the web config tool- I have some non standard keys (euro, yen, $) on my keypad and the selection list for input choices has hundreds of hex options. Without going through all of them through trial and error, my thought is to allow the input box to accept a keypress from the keypad then move to the next Output selector for remapping. I'm able to capture the scan codes with the linux tools showkey and xev but their output does not correlate with the options I see available in the input box.

This is the keypad I'm using: https://www.amazon.com/dp/B09TYQ2TKZ

Thank you!

Add momentary/tap layer/action aka QMK LT()

The best way to explain what I'm looking for is to quote QMK documentation for its equivalent LT() feature:

LT(layer, kc) - momentarily activates layer when held, and sends kc when tapped.

So the idea is I would set, e.g., the back button as an input, and the output would be switching to another layer while I hold it down, but if I release it within e.g., 250ms the remapper will issue a back button press.

Support report descriptors longer than 256 bytes

Due to hardcoded buffer sizes, the dual Pico version doesn't support report descriptors that are longer than 256 bytes. This is an issue for the Microsoft Nano Transceiver v2.0 for example (media keys don't work).

Taito Egret II Trackball / Spinner (suggestion for examples)

Taito produces a neat Trackball / Spinner controller for their miniature Arcade System that unfortunately has mapped inputs in a weird way. The following JSON, tested on a single board PICO setup:

  • Scales the trackball x5 to make it better usable in Windows
  • Maps the spinner from V-Scroll to X-Input for instant compatibility with many games / emulations
  • Maps the buttons that are invisible to Windows: White Mouse 3, Violet Mouse 4 / Forward, Blue Mouse 5 / Backward
    This enables configuration of the device in all emulation setups (Windows and Linux) I tested

A BIG THANK YOU FOR BUILDING THIS AMAZING PIECE OF CODE. THIS IS JUST AWESOME!

Feel free to include this in the Examples section!

{ "version": 6, "partial_scroll_timeout": 1000000, "interval_override": 0, "mappings": [ { "target_usage": "0x00090004", "source_usage": "0x00090017", "scaling": 1000, "layers": [ 0 ], "sticky": false, "tap": false, "hold": false }, { "target_usage": "0x00090005", "source_usage": "0x00090018", "scaling": 1000, "layers": [ 0 ], "sticky": false, "tap": false, "hold": false }, { "target_usage": "0x00090003", "source_usage": "0x0009001a", "scaling": 1000, "layers": [ 0 ], "sticky": false, "tap": false, "hold": false }, { "target_usage": "0x00090001", "source_usage": "0x0009001d", "scaling": 1000, "layers": [ 0 ], "sticky": false, "tap": false, "hold": false }, { "target_usage": "0x00090002", "source_usage": "0x0009001e", "scaling": 1000, "layers": [ 0 ], "sticky": false, "tap": false, "hold": false }, { "target_usage": "0x00010030", "source_usage": "0x00010038", "scaling": -1000, "layers": [ 0 ], "sticky": false, "tap": false, "hold": false }, { "source_usage": "0x00010030", "target_usage": "0x00010030", "layers": [ 0 ], "sticky": false, "tap": false, "hold": false, "scaling": 5000 }, { "source_usage": "0x00010031", "target_usage": "0x00010031", "layers": [ 0 ], "sticky": false, "tap": false, "hold": false, "scaling": 5000 } ], "unmapped_passthrough_layers": [ 0, 1, 2, 3 ], "macros": [ [], [], [], [], [], [], [], [] ], "tap_hold_threshold": 200000, "expressions": [ "", "", "", "", "", "", "", "" ] }

Add support for DT225 trackball

CH Products DT225 trackball (VID=0x068e, PID=0xf700) seems to have a slightly broken HID report descriptor. Usage Maximum for the buttons is 1 when it should be 4. Because of that, only the first button works. We should be able to apply quirks to make all 4 buttons work.

Multiple devices with same usage

Let's consider the following example:

We connect two mice to the remapper. We press and hold the left button on mouse 1 and then, while holding it, move mouse 2. Because the report from mouse 2 is the last one received and because the left button is not pressed on mouse 2, the remapper now considers the button to be released. Obviously the user's expectation is for it to stay pressed for as long as it's pressed on mouse 1.

We should probably address this even before we get into per-device mappings.

ELECOM EX-G PRO / DEFT PRO (wired) does not work

ELECOM EX-G PRO / DEFT PRO (wireless) works with Single Version, but EX-G PRO / DEFT PRO (wired) does not work with both Single Version and Dual Version. Both ball and buttons are not responding.

In common with these models, they return multiple USB HID Descriptors.

M-DPT1MR (Wired), M-XPT1MR (Wired)

  • 05 01 09 02 a1 01 85 01 09 01 a1 00 05 09 19 01 29 08 15 00 25 01 75 01 95 08 81 02 05 01 09 30 09 31 16 00 80 26 ff 7f 75 10 95 02 81 06 09 38 15 81 25 7f 75 08 95 01 81 06 05 0c 0a 38 02 95 01 81 06 c0 c0 05 01 09 80 a1 01 85 02 19 81 29 83 15 00 25 01 75 01 95 03 81 02 95 05 81 01 c0 05 0c 09 01 a1 01 85 03 19 00 2a ff 07 15 00 26 ff 07 75 10 95 01 81 00 c0

  • 05 01 09 06 a1 01 05 07 19 e0 29 e7 15 00 25 01 75 01 95 08 81 02 75 08 95 01 81 03 05 07 19 00 2a ff 00 15 00 26 ff 00 95 06 81 00 c0

  • 06 01 ff 09 01 a1 01 09 20 15 00 26 ff 00 75 08 95 20 81 02 09 21 91 02 09 22 95 08 b1 02 c0

M-DPT1MR (Wireless), M-XPT1MR (Wireless)

  • 05 01 09 06 a1 01 05 07 19 e0 29 e7 15 00 25 01 75 01 95 08 81 02 95 01 75 08 81 01 95 05 75 01 05 08 19 01 29 05 91 02 95 01 75 03 91 01 95 06 75 08 15 00 26 ff 00 05 07 19 00 2a ff 00 81 00 09 05 15 00 26 ff 00 75 08 95 02 b1 02 c0

  • 05 01 09 02 a1 01 85 01 09 01 a1 00 05 09 19 01 29 08 15 00 25 01 75 01 95 08 81 02 05 01 09 30 09 31 16 00 80 26 ff 7f 75 10 95 02 81 06 09 38 15 81 25 7f 75 08 95 01 81 06 05 0c 0a 38 02 95 01 81 06 c0 c0

  • 05 0c 09 01 a1 01 85 01 15 00 25 01 75 01 95 18 0a 23 02 0a 21 02 0a 8a 01 0a ae 01 0a 96 01 0a 92 01 0a 21 02 0a 24 02 0a 26 02 0a 27 02 0a 2a 02 0a 83 01 0a 94 01 09 40 09 30 09 b7 09 70 09 6f 09 b6 09 cd 09 b5 09 e2 09 ea 09 e9 81 02 c0 05 01 09 80 a1 01 85 02 15 00 25 01 75 01 95 01 09 82 81 02 95 01 75 07 81 03 c0

  • 06 0a ff 09 01 a1 01 09 02 a1 00 06 00 ff 09 03 09 04 15 80 25 7f 35 00 46 ff 00 75 08 95 05 81 02 09 05 09 06 15 80 25 7f 35 00 46 ff 00 75 08 95 05 91 02 c0 c0

Suggestion: Double-tap input mappings

Hi, thanks for this great software.

I'd like to make a feature suggestion: double-tap inputs.

My use case is a trackball mouse where I'd like to do a double-middle-click to enter Layer 1 where the ball becomes a scroll wheel. That way I could still do single middle-click normally and not have to assign a whole separate button to Layer 1.

Also, I think it would be nice if:

Layer activating mappings work on all layers, regardless of which layer they are defined on.

was optional. I'm imagining double-middle-click while on L0 enters L1, and then a single middle-click while on L1 goes back to L0. I can also imagine defining a single button that rotates through several layers one at a time with a different layer activate command on each layer, but that's a whole other idea!

Board v1 - Side A flashing Side B required each power cycle

This is a bit unusual, but for the custom board v1 flashing Side B via Side A seems to work just fine. Copy remapper_board.uf2 over to Side A in boot select mode (via button or config UI), load config page, press "load side B" in the config UI.

Thereafter, the config page updates to say "Flash succeeded, please unplug and plug in." Unplug and plug back in, device works great.

Until the next power cycle. Board v1 is unplugged sometime later, and a re-flash of Side B is required before remapping works again.

Repeatable on my end across four different v1 boards.

Idea for Pico W

I don´t know if this is the place to put this... but I got an idea for PICOW. Why don't expose a sensor over MQTT that will send the key pressed (either only the unmapped or all of them) so that the "stream" deck could also interface with HomeAssistant for light control?

It will require the tool to have wifi config section, and mqtt config section....

Question: Support for wired Apple Magic Keyboard?

I'm currently considering to use your guide to use an Apple Magic Keyboard on Windows. I could mostly solve mapping problems with autohotkey so far, but for RDP sessions or virtual machines these autohotkey scripts won't work for obvious reasons.

My plan would be to buy the v1 board from JLCPCB and then use it on a Windows based OS.

I'm somewhat worried because the Magic Keyboard is custom tailored for Mac computers, although it works on Windows just fine with some swapped buttons like Alt and Win.

Are your boards are compatible with the Magic Keyboard? Or is there something I should take into consideration before ordering the boards?

Firmware "lost" after disconnect on rp2040-zero clone

Hi

I have a couple of clones (from ali) of the rp2040-zero.
When I load the uf2 it works fine. But if I pull the connection to the pc and reconnect it's not found by the pc (windows) and I have to reset with the boot button held and get an empty drive (there's just the html/txt file with board info)..
When I load the firmware it works again and have the settings made earlier.
It's the same on both boards.

I have some bigger board (with all the pins and 16mb flash, also from ali) and they work fine after power cycle.

Does anybody know how to make it work?

/martin

why did hid-remapper not report some key when use japanese keyboard?

I trying hid-remapper with Japanese keyboard https://archisite.co.jp/products/archiss/progres-touch/retro-tkl-jp/.
But, some below key does not working.

  • [¥|] key at left-side on [BS].
  • [henkan], [muhenkan] key at side on [SPACE].
  • [kana] key at left-side on [Right ALT].
  • [_] key at left-side on [Right SHIFT].

I marked circle not working key in this image.
image

[Unmapped inputs passthrough] configration is true.
image

OS-keyboard setting is JIS type ( when press shift-2 appeared ["] )
When I pressed above keys, green LED is flashing on rpi-pico, but does not appear key_code. I am checking key-event by Karabiner-EventViewer.

Is there anything I can do?

Support for standalone Linux app on (Raspbian)?

Hey, not sure if this is the right place to ask questions but here it goes.. Will the hid-remapper work as a standalone app on Raspbian or any other Linux OS?

I would like to use a full OS so pico is not cutting it for me.

If the answer is no, would you be able to recommend a similar software that allows keys to be re-mapped in software? I've been digging into xmodmap but still unsure if I can remap 1 key to multiple I.e. key number 1 for example to ALT+SHIFT+F18 etc.

Output Key order

Hello,
I think this project is amazing. It solves a problem that many have trouble with and go to great lengths to fix. @jfedor2 did a great job.

I created a dual-Pico running the latest r2023-02-17 as of today.

My question is about the order of output with certain keys. I am having trouble getting key combinations to output in the correct order. I am using F17 & C as an example below.

In the documentation, using two mappings, the example for LCtrl + C yields as follows:

HID-remapper Configuration:
Input Output
B Left Control
B C

Output (Recorded by Autohotkey)
Up/Down time Key
down 1.73 LControl
down 0.00 c
up 0.11 LControl
up 0.00 c

The above functions exactly as it was entered. However, if you use F17 (or any fn key), it outputs differently. Whatever the second key is, it is always pressed down first. This seems to happen with all fn keys, and most non-letter keys.

HID-remapper Configuration:
Input Output
B F17
B C

Output (Recorded by Autohotkey)
Up/Down time Key
down 3.77 c
down 0.00 F17
up 0.13 c
up 0.00 F17

I have tried inverting the mappings in the configuration tool. I have also tried adding the 'nothing' value in different combinations.

I also tried different combinations in the Macros. The macros output F17Down F17Up CDown Cup

I cannot get the Fn key to output first.

Can anyone help me get my configuration such that the keys fire in the desired order? Thanks!

Add Japanese Key Keybindings

Please add the following Japanese keys to your config/web-config.

The 4 Japanese Keys are:

  • 0x1C: Convert
  • 0x1D: No Conversion
  • 0x19: Half-width/Full-width
  • 0x15: Katakana/Hiragana

Background:

One trick I would use often with my Elecom mice was to bind the Japanese keys to the buttons, and then use AutoHotkey to trigger off these buttons. Since I had a US keyboard, I never had any conflict.

You can find my old post here...

https://www.reddit.com/r/Trackballs/comments/3zrl8h/elecom_driver_autohotkey_trick/

pairing with zmk keyboard

I am able to pair with several devices without problems (Logitech MX keys, MX anywhere 3). I am using a XIAO-ble board. I can also pair with a BT60v1 board running zmk. This board connects, and the lights show that it is receiving input, but there is nothing that gets sent to the host (Windows).

Hold instantly activates when using macros

I have 2 mappings setup for one input key, one is for a tap and the other for holding the key down. However when the held is set to a macro, the macro instantly activates instead of waiting for the held delay. I’ve tested the held key as another action which doesn’t instantly activate but when setback to a macro the held delay is ignored. Am I doing something wrong or is this a bug

Is it possible to attach a usb male to the hid-remapper?

Is it possible to attach a usb male to the hid-remapper?

I cut the usb extension cable to make the hid-remapper, so the usb male cable is still there.
Is it possible to make effective use of this usb male cable by soldering it to an open gpio pin?

The other day I raised an issue where hid-remapper would not report some keys on the Japanese keyboard.
At that time, I thought that if I could read the console log on the micro usb port of the raspberry pico, I might be able to provide detailed debugging information.

Would it be difficult to handle two usb-io's with raspberry-pico?

Intermittent issues with scrolling

Hi. I absolutely love this project as it has enabled a lot of functionality into my ergonomic vertical mice buttons. However, I seem to be having an intermittent problem that I cannot solve.

I have two thumb buttons that are back and forward buttons. I mapped them to page down and up, respectively, on tap, and vertical scroll on hold. For the hold, I applied around a 0.15 multiplier (positive and negative where appropriate). These buttons work as expected on my web browser but every now and then my web page continuously scrolls down or up after using the buttons, as if the down or up arrow was held down or something. I don't know if it really is an up or down arrow but I noticed that during this behavior if I right-clicked to open the usual web browser context menu I can see the items being highlighted rapidly in the down or up directions as if the arrow down or up keys were held. I can break this behavior usually if I just tap the buttons a few times. I cannot consistently replicate this issue but since I use these buttons so often to help me browse the web I run into the issue every 10 minutes or so. Sometimes the issue shows up on the first click and sometimes during a sequence of clicks while browsing.

For full disclosure I use this mouse in a 2 output KVM setup. The above was for my personal PC. When I KVM over to my work computer, I mostly use word and adobe acrobat. The behavior seems slightly different there. In those programs, the buttons would just stop working when this happens, and windows would beep every second or so until I try to break the mouse out of the behavior by tapping the buttons a few times. I tried another mouse and it was the same problem.

Please let me know if anyone has any clues on how to fix this issue. I have wrist problems and having additional functionality mapped to my vertical mouse has been game changing for me. Thanks.

BOOTSEL as reset button

Hello, Just a minor request... I see myself needing to re-plug the Pico every now and then, as my Mac doesn't recognized upon restart. I saw this and it is posible to read the BOOTSEL status. Can it be used to reset the pico (so that I dont need to re-plug it every now and then)?

Output non valid/unused keys - custom output keyId

Hey there,

Im thinking of using this in combination of AHK (autohotkey) to automate some stuff.
Why? I got an wireless numpad and want to use it as a macro pad - not just for key-combos/shortcuts also for interacting with webrequests/home assistant/dlls etc.

From my understanding the remapper can technically send anything to the pc (in terms of "keys"), so my idea would be to remap lets say Num1 to an unused keyid. AHK can read raw hid/input data and handles then the rest. (no other program will do anything since it doesn't understand the key or doesn't even listen to them)

That said, would it be possible to configure "custom" keyid's in general (output)?
Does it already work with editing the json? (i've seen code changes for adding track balls, but that was for input not output)
Furthermore, if all that works, for ease of use add that "use custom keyid" in the webtool for others / ppl that arent comfortable directly editing jsons.

PS: awesome project :D

Add Layer Cycling

The current setup binds layer shifts to a button. That button can be sticky. This allows for a sniper-assist mode, which is good. However, it only allows for one set of scaling (tied to the layer you are on).

It would be nice if layers could be cycled rather than toggled.

Press Middle Mouse Button -> Activate Layer 1 with 0.5 X/Y scaling
Press Middle Mouse Button Again -> Deactivate Layer 1, Activate Layer 2 with 0.25 X/Y scaling

More macros

I'm looking to start this project. When I open the HID-remapper on Chrome there are only 8 macro slots. Is there a way to have more than 8 macros?

support game controller / other HID devices

i am looking for a possibility to remap USB game controller as HID keyboard.
my used controller (xbox) was not recognized and I couldn't find any hints for gamepad compatibility in this repo.

I know, that the used tiny USB and PICO-PIO_USB libs are capable of this, but it seems not implemented (yet). my coding skills are just too bad to figure it out myself.

Axis -> button mapping

  1. separate mouse move left and mouse move right as different inputs. Same for vertical mouse movements.
    • this can be helpful to remap mouse movement to keyboard arrow key behavior.

PS: Thank you very much for this project. It is very handy.
It saved my life moving from my home Mac to the company issued PC,
which does not allow the installation of AHK or SharpKeys.
Wish you all the best and looking forward to seeing improvement in the future.

Bug With the Layer X, turn to Layer Y ?

I set the middle button as set the Layer 2.

and I wanna set

With the Layer 2,
Press the Middle button to set the Layer3 sticky.

But the result is actually,

With any Layer,
Press the Middle button to set the Layer3 sticky.

Could you please test that?

I use the Slim blade.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.