HAL Pin Names for an Arduino Leonardo Knockoff

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.

Arduino Leonardo knockoff - LinuxCNC box
Arduino Leonardo knockoff – LinuxCNC box

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':
    ATTR{bNumInterfaces}==" 3"
    ATTR{version}==" 2.00"
    ATTR{manufacturer}=="Arduino LLC"
    ATTR{product}=="Arduino Leonardo"

Then we know enough to discover what it can do:

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.