Going through the usual dance to reveal the HAL pin names for an Arduino Leonardo knockoff shows that it is, indeed, both a mouse and a keyboard.

Pawing through less /proc/bus/input/devices
reveals:
I: Bus=0003 Vendor=2341 Product=8036 Version=0101 N: Name="Arduino LLC Arduino Leonardo" P: Phys=usb-0000:00:1d.0-1/input2 S: Sysfs=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.2/input/input3 U: Uniq= H: Handlers=kbd mouse1 event3 B: EV=100017 B: KEY=70000 0 0 0 0 e080ffdf 1cfffff ffffffff fffffffe B: REL=103 B: MSC=10
Tweaking the permissions:
sudo chgrp users /dev/input/event3 sudo chgrp users /dev/input/mouse1 sudo chmod g+w /dev/input/event3 sudo chmod g+w /dev/input/mouse1
The output of lsusb
shows something interesting:
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 006: ID 06f2:0011 Emine Technology Co. KVM Switch Keyboard Bus 004 Device 005: ID 046d:c401 Logitech, Inc. TrackMan Marble Wheel Bus 004 Device 004: ID 04d9:1203 Holtek Semiconductor, Inc. MC Industries Keyboard Bus 004 Device 003: ID 046d:c216 Logitech, Inc. Dual Action Gamepad Bus 004 Device 002: ID 0451:2046 Texas Instruments, Inc. TUSB2046 Hub Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 002 Device 002: ID 2341:8036 Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
For whatever reason, this board doesn’t report a device name. It’s plugged into the same USB port as that mouse, so it gets the same Bus and Device numbers, which helps confirm that’s the board.
Querying the attributes with udevadm
produces the all-important product string:
udevadm info --query=all --attribute-walk --name=/dev/bus/usb/002/002 ... snippage ... looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1': KERNEL=="2-1" SUBSYSTEM=="usb" DRIVER=="usb" ATTR{configuration}=="" ATTR{bNumInterfaces}==" 3" ATTR{bConfigurationValue}=="1" ATTR{bmAttributes}=="80" ATTR{bMaxPower}=="500mA" ATTR{urbnum}=="17" ATTR{idVendor}=="2341" ATTR{idProduct}=="8036" ATTR{bcdDevice}=="0100" ATTR{bDeviceClass}=="02" ATTR{bDeviceSubClass}=="00" ATTR{bDeviceProtocol}=="00" ATTR{bNumConfigurations}=="1" ATTR{bMaxPacketSize0}=="64" ATTR{speed}=="12" ATTR{busnum}=="2" ATTR{devnum}=="2" ATTR{version}==" 2.00" ATTR{maxchild}=="0" ATTR{quirks}=="0x0" ATTR{authorized}=="1" ATTR{manufacturer}=="Arduino LLC" ATTR{product}=="Arduino Leonardo"
Then we know enough to discover what it can do:
halrun halcmd: loadusr -W hal_input -KRAL Leo halcmd: show all Loaded HAL Components: ID Type Name PID State 5 User hal_input 11265 ready 3 User halcmd11264 11264 ready Component Pins: Owner Type Dir Value Name 5 bit OUT FALSE input.0.btn-middle 5 bit OUT TRUE input.0.btn-middle-not 5 bit OUT FALSE input.0.btn-mouse 5 bit OUT TRUE input.0.btn-mouse-not 5 bit OUT FALSE input.0.btn-right 5 bit OUT TRUE input.0.btn-right-not 5 bit OUT FALSE input.0.key-0 5 bit OUT TRUE input.0.key-0-not 5 bit OUT FALSE input.0.key-1 5 bit OUT TRUE input.0.key-1-not 5 bit OUT FALSE input.0.key-102nd 5 bit OUT TRUE input.0.key-102nd-not 5 bit OUT FALSE input.0.key-2 5 bit OUT TRUE input.0.key-2-not 5 bit OUT FALSE input.0.key-3 5 bit OUT TRUE input.0.key-3-not 5 bit OUT FALSE input.0.key-4 5 bit OUT TRUE input.0.key-4-not 5 bit OUT FALSE input.0.key-5 5 bit OUT TRUE input.0.key-5-not 5 bit OUT FALSE input.0.key-6 5 bit OUT TRUE input.0.key-6-not 5 bit OUT FALSE input.0.key-7 5 bit OUT TRUE input.0.key-7-not 5 bit OUT FALSE input.0.key-8 5 bit OUT TRUE input.0.key-8-not 5 bit OUT FALSE input.0.key-9 5 bit OUT TRUE input.0.key-9-not 5 bit OUT FALSE input.0.key-a 5 bit OUT TRUE input.0.key-a-not 5 bit OUT FALSE input.0.key-apostrophe 5 bit OUT TRUE input.0.key-apostrophe-not 5 bit OUT FALSE input.0.key-b 5 bit OUT TRUE input.0.key-b-not 5 bit OUT FALSE input.0.key-backslash 5 bit OUT TRUE input.0.key-backslash-not 5 bit OUT FALSE input.0.key-backspace 5 bit OUT TRUE input.0.key-backspace-not 5 bit OUT FALSE input.0.key-c 5 bit OUT TRUE input.0.key-c-not 5 bit OUT FALSE input.0.key-capslock 5 bit OUT TRUE input.0.key-capslock-not 5 bit OUT FALSE input.0.key-comma 5 bit OUT TRUE input.0.key-comma-not 5 bit OUT FALSE input.0.key-compose 5 bit OUT TRUE input.0.key-compose-not 5 bit OUT FALSE input.0.key-d 5 bit OUT TRUE input.0.key-d-not 5 bit OUT FALSE input.0.key-delete 5 bit OUT TRUE input.0.key-delete-not 5 bit OUT FALSE input.0.key-dot 5 bit OUT TRUE input.0.key-dot-not 5 bit OUT FALSE input.0.key-down 5 bit OUT TRUE input.0.key-down-not 5 bit OUT FALSE input.0.key-e 5 bit OUT TRUE input.0.key-e-not 5 bit OUT FALSE input.0.key-end 5 bit OUT TRUE input.0.key-end-not 5 bit OUT FALSE input.0.key-enter 5 bit OUT TRUE input.0.key-enter-not 5 bit OUT FALSE input.0.key-equal 5 bit OUT TRUE input.0.key-equal-not 5 bit OUT FALSE input.0.key-esc 5 bit OUT TRUE input.0.key-esc-not 5 bit OUT FALSE input.0.key-f 5 bit OUT TRUE input.0.key-f-not 5 bit OUT FALSE input.0.key-f1 5 bit OUT TRUE input.0.key-f1-not 5 bit OUT FALSE input.0.key-f10 5 bit OUT TRUE input.0.key-f10-not 5 bit OUT FALSE input.0.key-f11 5 bit OUT TRUE input.0.key-f11-not 5 bit OUT FALSE input.0.key-f12 5 bit OUT TRUE input.0.key-f12-not 5 bit OUT FALSE input.0.key-f2 5 bit OUT TRUE input.0.key-f2-not 5 bit OUT FALSE input.0.key-f3 5 bit OUT TRUE input.0.key-f3-not 5 bit OUT FALSE input.0.key-f4 5 bit OUT TRUE input.0.key-f4-not 5 bit OUT FALSE input.0.key-f5 5 bit OUT TRUE input.0.key-f5-not 5 bit OUT FALSE input.0.key-f6 5 bit OUT TRUE input.0.key-f6-not 5 bit OUT FALSE input.0.key-f7 5 bit OUT TRUE input.0.key-f7-not 5 bit OUT FALSE input.0.key-f8 5 bit OUT TRUE input.0.key-f8-not 5 bit OUT FALSE input.0.key-f9 5 bit OUT TRUE input.0.key-f9-not 5 bit OUT FALSE input.0.key-g 5 bit OUT TRUE input.0.key-g-not 5 bit OUT FALSE input.0.key-grave 5 bit OUT TRUE input.0.key-grave-not 5 bit OUT FALSE input.0.key-h 5 bit OUT TRUE input.0.key-h-not 5 bit OUT FALSE input.0.key-home 5 bit OUT TRUE input.0.key-home-not 5 bit OUT FALSE input.0.key-i 5 bit OUT TRUE input.0.key-i-not 5 bit OUT FALSE input.0.key-insert 5 bit OUT TRUE input.0.key-insert-not 5 bit OUT FALSE input.0.key-j 5 bit OUT TRUE input.0.key-j-not 5 bit OUT FALSE input.0.key-k 5 bit OUT TRUE input.0.key-k-not 5 bit OUT FALSE input.0.key-kp0 5 bit OUT TRUE input.0.key-kp0-not 5 bit OUT FALSE input.0.key-kp1 5 bit OUT TRUE input.0.key-kp1-not 5 bit OUT FALSE input.0.key-kp2 5 bit OUT TRUE input.0.key-kp2-not 5 bit OUT FALSE input.0.key-kp3 5 bit OUT TRUE input.0.key-kp3-not 5 bit OUT FALSE input.0.key-kp4 5 bit OUT TRUE input.0.key-kp4-not 5 bit OUT FALSE input.0.key-kp5 5 bit OUT TRUE input.0.key-kp5-not 5 bit OUT FALSE input.0.key-kp6 5 bit OUT TRUE input.0.key-kp6-not 5 bit OUT FALSE input.0.key-kp7 5 bit OUT TRUE input.0.key-kp7-not 5 bit OUT FALSE input.0.key-kp8 5 bit OUT TRUE input.0.key-kp8-not 5 bit OUT FALSE input.0.key-kp9 5 bit OUT TRUE input.0.key-kp9-not 5 bit OUT FALSE input.0.key-kpasterisk 5 bit OUT TRUE input.0.key-kpasterisk-not 5 bit OUT FALSE input.0.key-kpdot 5 bit OUT TRUE input.0.key-kpdot-not 5 bit OUT FALSE input.0.key-kpenter 5 bit OUT TRUE input.0.key-kpenter-not 5 bit OUT FALSE input.0.key-kpminus 5 bit OUT TRUE input.0.key-kpminus-not 5 bit OUT FALSE input.0.key-kpplus 5 bit OUT TRUE input.0.key-kpplus-not 5 bit OUT FALSE input.0.key-kpslash 5 bit OUT TRUE input.0.key-kpslash-not 5 bit OUT FALSE input.0.key-l 5 bit OUT TRUE input.0.key-l-not 5 bit OUT FALSE input.0.key-left 5 bit OUT TRUE input.0.key-left-not 5 bit OUT FALSE input.0.key-leftalt 5 bit OUT TRUE input.0.key-leftalt-not 5 bit OUT FALSE input.0.key-leftbrace 5 bit OUT TRUE input.0.key-leftbrace-not 5 bit OUT FALSE input.0.key-leftctrl 5 bit OUT TRUE input.0.key-leftctrl-not 5 bit OUT FALSE input.0.key-leftmeta 5 bit OUT TRUE input.0.key-leftmeta-not 5 bit OUT FALSE input.0.key-leftshift 5 bit OUT TRUE input.0.key-leftshift-not 5 bit OUT FALSE input.0.key-m 5 bit OUT TRUE input.0.key-m-not 5 bit OUT FALSE input.0.key-minus 5 bit OUT TRUE input.0.key-minus-not 5 bit OUT FALSE input.0.key-n 5 bit OUT TRUE input.0.key-n-not 5 bit OUT FALSE input.0.key-numlock 5 bit OUT TRUE input.0.key-numlock-not 5 bit OUT FALSE input.0.key-o 5 bit OUT TRUE input.0.key-o-not 5 bit OUT FALSE input.0.key-p 5 bit OUT TRUE input.0.key-p-not 5 bit OUT FALSE input.0.key-pagedown 5 bit OUT TRUE input.0.key-pagedown-not 5 bit OUT FALSE input.0.key-pageup 5 bit OUT TRUE input.0.key-pageup-not 5 bit OUT FALSE input.0.key-pause 5 bit OUT TRUE input.0.key-pause-not 5 bit OUT FALSE input.0.key-q 5 bit OUT TRUE input.0.key-q-not 5 bit OUT FALSE input.0.key-r 5 bit OUT TRUE input.0.key-r-not 5 bit OUT FALSE input.0.key-right 5 bit OUT TRUE input.0.key-right-not 5 bit OUT FALSE input.0.key-rightalt 5 bit OUT TRUE input.0.key-rightalt-not 5 bit OUT FALSE input.0.key-rightbrace 5 bit OUT TRUE input.0.key-rightbrace-not 5 bit OUT FALSE input.0.key-rightctrl 5 bit OUT TRUE input.0.key-rightctrl-not 5 bit OUT FALSE input.0.key-rightmeta 5 bit OUT TRUE input.0.key-rightmeta-not 5 bit OUT FALSE input.0.key-rightshift 5 bit OUT TRUE input.0.key-rightshift-not 5 bit OUT FALSE input.0.key-s 5 bit OUT TRUE input.0.key-s-not 5 bit OUT FALSE input.0.key-scrolllock 5 bit OUT TRUE input.0.key-scrolllock-not 5 bit OUT FALSE input.0.key-semicolon 5 bit OUT TRUE input.0.key-semicolon-not 5 bit OUT FALSE input.0.key-slash 5 bit OUT TRUE input.0.key-slash-not 5 bit OUT FALSE input.0.key-space 5 bit OUT TRUE input.0.key-space-not 5 bit OUT FALSE input.0.key-sysrq 5 bit OUT TRUE input.0.key-sysrq-not 5 bit OUT FALSE input.0.key-t 5 bit OUT TRUE input.0.key-t-not 5 bit OUT FALSE input.0.key-tab 5 bit OUT TRUE input.0.key-tab-not 5 bit OUT FALSE input.0.key-u 5 bit OUT TRUE input.0.key-u-not 5 bit OUT FALSE input.0.key-up 5 bit OUT TRUE input.0.key-up-not 5 bit OUT FALSE input.0.key-v 5 bit OUT TRUE input.0.key-v-not 5 bit OUT FALSE input.0.key-w 5 bit OUT TRUE input.0.key-w-not 5 bit OUT FALSE input.0.key-x 5 bit OUT TRUE input.0.key-x-not 5 bit OUT FALSE input.0.key-y 5 bit OUT TRUE input.0.key-y-not 5 bit OUT FALSE input.0.key-z 5 bit OUT TRUE input.0.key-z-not 5 s32 OUT 0 input.0.rel-wheel-counts 5 float OUT 0 input.0.rel-wheel-position 5 bit IN FALSE input.0.rel-wheel-reset 5 float IN 1 input.0.rel-wheel-scale 5 s32 OUT 0 input.0.rel-x-counts 5 float OUT 0 input.0.rel-x-position 5 bit IN FALSE input.0.rel-x-reset 5 float IN 1 input.0.rel-x-scale 5 s32 OUT 0 input.0.rel-y-counts 5 float OUT 0 input.0.rel-y-position 5 bit IN FALSE input.0.rel-y-reset 5 float IN 1 input.0.rel-y-scale
That’s a pretty decent assortment of directly usable names and features, even without keyboard LEDs. The mouse pins could be repurposed for general sensor values:
- counts = integer = accumulated encoder wheel ticks
- position = float = count / scale (why divided? I don’t know)
- scale = float = turns counts into position
- reset = bit = resets position or maybe count (not sure)
I think you could use count to transfer a bare ADC reading from the Leonardo, then use scale
to get the actual voltage in “position”. In that situation, reset wouldn’t be at all useful.
The keyboard pins could transfer Boolean sensors.
You’d want to give HAL exclusive control of the Leonardo-is-not-a-mouse, because the incoming data would make hash of the, ah, LinuxCNC UI experience in short order. I’m not sure how to control that; the Leonardo advice boils down to “be careful” and “use a physical switch”.
I have *no* idea where the names come from, but apparently the OS / kernel / something has a HID layer that translates bare USB capability bits into strings. How that relates to a particular device, what the choices might be, how one could add / replace the names for a given device, and all that, I don’t know yet.