Emulate a 3 button Foot pedal using keyboard or mouse button

I have a three button footpedal (VEC-USB-3-Infinity-Digital-Control) that is used for dictation software. I don’t like having to use the footpedal and would like to use button presses on a mouse or keypresses on a generic keyboard to act like each of the three buttons on the footpedal.

So far, I have used wireshark to obtain the report descriptor from the footpedal and I have been able to fully emulate the 3 buttons of the footpedal using a macropad (keybow 2040) that is running circuitpython on a rp2040 with the below collection of snippets.

It seems like hid-remapper will let me use a generic keyboard to emulate the footpedal, but may not be set up to identify this type of device (consumer page, programmable button). Can it capture this device, perhaps using the “custom usages” option in the configuration webpage, or will it need some modification to the source code? I would welcome some pointers on how to proceed (Monitor tab didn’t find anything when I pushed the buttons on the footpedal when it was connected to the 2040 feather board and the configuration page able to find and connect to the board).

Thank you.

FOOTPAD_REPORT_DESCRIPTOR = bytes((  
    0x05, 0x0C,  #   Usage Page (Consumer)    
    0x09, 0x03,  #   Usage (Programmable Buttons)
    0xA1, 0x01,  #   Collection (Application)    
    0x05, 0x09,  #   Usage Page (Button)
    0x19, 0x01,  #   Usage Minimum (0x01)
    0x29, 0x03,  #   Usage Maximum (0x03)
    0x15, 0x00,  #   Logical Minimum (0)
    0x25, 0x01,  #   Logical Maximum (1)
    0x95, 0x03,  #   Report Count (3)  Button? (1 bit per each of 3 buttons)
    0x75, 0x01,  #   Report Size (1)
    0x81, 0x02,  #   Input
    0x95, 0x01,  #   Report Count (1)
    0x75, 0x05,  #   Report Size (5)  5 bits of padding?
    0x81, 0x01,  #   Input
    0x95, 0x01,  #   Report Count (1)
    0x75, 0x08,  #   Report Size (8)  8 bits of padding?
    0x81, 0x01,  #   Input
    0xC0,        #   End Collection
)) # 67 bytes

footpad = usb_hid.Device(
    report_descriptor=FOOTPAD_REPORT_DESCRIPTOR,
    usage_page=0x0C,           #
    usage=0x03,                #
    report_ids=(0,),           #
    in_report_lengths=(2,),    # This footpad sends 3 bits of data + 5 bits of padding + 8 bits of padding in its report.
    out_report_lengths=(0,),   # It does not receive any reports.
)
supervisor.set_usb_identification(
                                  manufacturer='VEC',
                                  product='VEC USB Footpedal',
                                  vid=0x05F3, 
                                  pid=0x00FF 
)

You’d have to compile a custom build of the firmware to change the VID/PID and report descriptor.

You could probably do it entirely on GitHub without having to set up a local dev environment. We have a video:

1 Like

I have this working with 2 different macropads (not using remapper though) that use a rp2040 as the microcontroller (NOT USING AUTOHOTKEY AT ALL… no F4… no TAB… The firmware on the macropads completely emulates the deadman switch for dictation as well as the prev/next field buttons) using that code from my original post.

Also, it appears that keyboards that use the QMK firmware already have this functionality built-in, just not enabled. Once I’m finished with the code for the macropads, my next step will be to figure out how to recompile QMK for my keyboard (it appears that “programable buttons”[I think it’s the same one] is already apart of QMK so I’m hopeful that it will work and that all I have to do is change the VID and PID, and enable the programmable button…..).

Once I have the macropads code at the point I’m happy with, get QMK to work, then I’ll work on adapting remapper. It should work with the trackball once remapper has been adapted (and yes, from what I can tell, the trackball should function like a trackball should, just with buttons remapped to act like powermike buttons).

From the link...

#ifdef PROGRAMMABLE_BUTTON_ENABLE
    HID_RI_USAGE_PAGE(8, 0x0C),            // Consumer
    HID_RI_USAGE(8, 0x01),                 // Consumer Control
    HID_RI_COLLECTION(8, 0x01),            // Application
        HID_RI_REPORT_ID(8, REPORT_ID_PROGRAMMABLE_BUTTON),
        HID_RI_USAGE(8, 0x03),             // Programmable Buttons
        HID_RI_COLLECTION(8, 0x04),        // Named Array
            HID_RI_USAGE_PAGE(8, 0x09),    // Button
            HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
            HID_RI_USAGE_MAXIMUM(8, 0x20), // Button 32
            HID_RI_LOGICAL_MINIMUM(8, 0x00),
            HID_RI_LOGICAL_MAXIMUM(8, 0x01),
            HID_RI_REPORT_COUNT(8, 32),
            HID_RI_REPORT_SIZE(8, 1),
            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
        HID_RI_END_COLLECTION(0),
    HID_RI_END_COLLECTION(0),
#endif

Hey @greg did you figure this out? rads resident who would also love this!

1 Like

did you ever get an answer on this?

1 Like

Would love more info on this. We just upgrade to a new PACS, and I’m desperate to ditch the dictaphone and AHK once and for all.

-yet another radiologist

Hey everyone, I’ve stumbled across this post while working on the same sort of thing. Wanted to give an update on my success so far, from a rads resident.

Here’s basically the solution I’m working on. As you all may know, the dictation software like PowerScribe must be the active window in order for a simple keyboard shortcut such as F4 to activate it. The dictaphone and the pedal both circumvent this because they are specific hardware devices that PS recognizes regardless of if the PS window is active or not. Therefore, whatever solution we come up with needs to mimic the actual hardware rather than just sending a custom key command.

So the steps of the solution I’m working on are:

  1. Buy a macropad that uses a compatible board as its microcontroller and can have its firmware re-flashed (modified). So far I’m only trying the RP2040-Zero, but conceivably there could be others. I’ll be buying a 4x4 macropad.
  2. Modify the RP2040-Zero’s firmware so that it tells the computer that it’s actually 2 different USB devices - the first being the original keypad, and the second being a custom device that very closely mimics the foot pedal.
  3. Modify that 1st component further so that 13 of the 16 keys behave like the original keypad, with the remaining 3 being essentially disabled.
  4. Modify that 2nd component further so that the other 3 keys send the pedal commands to the computer (previous field, dictate, next field). This needs to send the commands with very specific information so that the computer and PowerScribe believe the commands are being sent from the foot pedal and not from this custom device.
  5. Install the software to program macros for the remaining 13 keys, so that you can actually use the whole device.

So far what I’ve done is run a basic test to make sure all these things can theoretically happen. I purchased my own RP2040-Zero and made a simple test script that sends both normal keyboard input and the custom foot pedal input to the computer, so make sure that the one board can do both simultaneously. So basically, I’ve put this little script on a tiny microcontroller and plugged it into my work computer by USB, and PowerScribe recognized that this little USB was sending BOTH keyboard and foot pedal commands to it. I even opened up a test accession and it indeed typed letters while also navigating between fields and turning dictation on and off.

The only real step I have left then is to purchase a keypad and attempt to modify it. Going on vacation soon but once I’m back I’ll be purchasing the Keebio Chocopad since it definitely uses the RP2040-Zero and uses existing firmware that I believe is compatible. If I’m able to get it fully functional, I’ll update here.

Hey everyone I’ve been following this thread and have great interest too as a rads resident. I have a working remapper with the single Pico build, and had a spare Pico to test the circuit python snippets above. My main finding was that if you had a composite device (i.e report id 4 for the footpedal) and a simultaneous keyboard/mouse in the report descriptor, the computer would not recognize the footpedal packet (0100 for L, 0200 for M, 0400 for R). So, after banging my head for a few days I realized you could just hook up the GPIO from the normal remapper to the separate pico that is only sending footpedal reports and voila! Now with a simple gpio loop I can send the separate buttons (no rollover, each button can only be sent one at a time) through remapper as a GPIO output. Craziest thing is that I have to host remapper web config on my laptop since the website itself is blocked…

1 Like

Another update. I’ve been working on this custom macropad which runs QMK firmware. It’s a Keebio Chocopad Rev 2 which runs on an RP2040 microcontroller. Currently I have working custom firmware where 3 of the 16 buttons are dedicated to foot pedal controls (previous field, dictate, next field). The remaining 13 buttons are custom macros I’ve decided to use. One is a modification/FN button, so basically I have 12 x 2 for a total of 24 custom whatever-I-want macros. I also set the RGBs to change based on which layer is active, and that works as well. This is all works perfectly with PowerScribe by the way, including on workstations at my work where we can’t install software and basically have 0 computer privileges (like, even right clicking on the desktop isn’t an allowed function).

Right now those macros are custom programmed, which I understand would probably be a pain for most people, so I’m working on trying to re-add in VIA integration (software that let’s you program macros in a web app). I had to remove it for PowerScribe to accept the pedal input, so somehow VIA was messing with the build.

The only HUGE caveat is that I had to custom code this thing to perfectly mimic a certain manufacturer’s device. I’m talking, using the exact same vendor ID and product ID. Windows/PowerScribe thus thinks this device is actually 2 separately connected devices - a keypad, and a [manufacturer] foot pedal. It would be very problematic if I shared this, and I would highly suggest not replicating. Therefore I am continuing to work on a more generalizable model which doesn’t contain any manufacturer-specific info or potentially proprietary info.

If I can’t get that to work, the last resort would be asking Microsoft/PowerScribe if they will let me develop my own device with my own unique custom VID/PID that they will allow PowerScribe to recognize. There’s a way to get a sublicense of Raspberry Pi’s info, but I’m not sure how Microsoft/PowerScribe would feel about it. If I truly need my own identifiers, that’s multiple thousands of dollars to register the VID/PID. So all that to say, I’m still working on a shareable version to the best of my ability.

Who knows, maybe if there’s enough interest for this then a kickstarter or some kind of grant could garner the funds.

I wouldn’t worry about spoofing the VID/PID of an existing device.