err4o4 / spotify-car-thing-reverse-engineering

394 stars 5 forks source link

Key Codes from buttons #26

Open Borillion opened 1 year ago

Borillion commented 1 year ago

You can use the command showkey to dump the key codes.

Back Button = ESC ( 0x1 KEY_ESC ) Rotary Button -RETRUN (0x1c KEY_ENTER)

Starting from Top left, the preset buttons 1 - Number key 1 - (0x2 KEY_1) 2 - Number key 2 - (0x3 KEY_2) 3 - Number key 3 - (0x4 KEY_3) 4 - Number key 4 - (0x5 KEY_4) 5 - Power Button - Letter Key M - (0x32 KEY_M)

williamtcastro commented 1 year ago

The rotary button is the se value independent of the side you turn ? Or how you're able to know which side you've turned?

Borillion commented 1 year ago

The encoder itself, when you rotate, it has output on /dev/input/event1 through the kernel.

libinput list-device Device: rotary@0 Kernel: /dev/input/event1 Group: 2 Seat: seat0, default Capabilities: keyboard pointer Tap-to-click: n/a Tap-and-drag: n/a Tap drag lock: n/a Left-handed: disabled Nat.scrolling: disabled Middle emulation: n/a Calibration: n/a Scroll methods: none Click methods: none Disable-w-typing: n/a Accel profiles: n/a Rotation: n/a

So far what I see output when I use hexdump isn't super clear to me but this is the capture I have for two turns to the right, and then two turns to the left, going to look at it in a few different ways and see if I can find a pattern. Looks like the last 8 bytes or so encode the direction and rotation distance, but I am not 100% certain.

cat /dev/input/event1 | hexdump -d //two turns right with a few ms pause between each 0000000 37343 21668 09023 00002 00002 00006 00001 00000 0000010 37343 21668 09023 00002 00000 00000 00000 00000 0000020 37345 21668 39180 00006 00002 00006 00001 00000 0000030 37345 21668 39180 00006 00000 00000 00000 00000 // Two turns left 0000040 37348 21668 55672 00001 00002 00006 65535 65535 0000050 37348 21668 55672 00001 00000 00000 00000 00000 0000060 37349 21668 57897 00001 00002 00006 65535 65535 0000070 37349 21668 57897 00001 00000 00000 00000 00000

//Another capture few min later two to the left, pause and then two to the right. / # cat /dev/input/event1 | hexdump -d 0000000 37515 21668 02517 00010 00002 00006 65535 65535 0000010 37515 21668 02517 00010 00000 00000 00000 00000 0000020 37517 21668 23020 00010 00002 00006 65535 65535 0000030 37517 21668 23020 00010 00000 00000 00000 00000 0000040 37520 21668 64519 00013 00002 00006 00001 00000 0000050 37520 21668 64519 00013 00000 00000 00000 00000 0000060 37522 21668 01568 00002 00002 00006 00001 00000 0000070 37522 21668 01568 00002 00000 00000 00000 00000

Borillion commented 1 year ago

37343 21668 09023 screams time stamp to me, also since this is an input event, a few web searches later and we have

https://github.com/torvalds/linux/blob/v4.9/include/uapi/linux/input.h#L25 and the kernel docs. https://www.kernel.org/doc/Documentation/input/input.txt

Also 5. Event interface


......

struct input_event {
    struct timeval time;
    unsigned short type;
    unsigned short code;
    unsigned int value;
};

  'time' is the timestamp, it returns the time at which the event happened.
Type is for example EV_REL for relative moment, EV_KEY for a keypress or
release. More types are defined in include/uapi/linux/input-event-codes.h.

  'code' is event code, for example REL_X or KEY_BACKSPACE, again a complete
list is in include/uapi/linux/input-event-codes.h.

  'value' is the value the event carries. Either a relative change for
EV_REL, absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for
release, 1 for keypress and 2 for autorepeat.
Borillion commented 1 year ago

So out of being lazy, a search of stack overflow yields https://stackoverflow.com/a/16682549

/tmp # ./decode.py 1
// two turns to the right
Event type 2, code 6, value 1 at 1420075338.879530
===========================================
Event type 2, code 6, value 1 at 1420075340.345312
===========================================
//two turns to the left
Event type 2, code 6, value 4294967295 at 1420075342.222124
===========================================
Event type 2, code 6, value 4294967295 at 1420075343.115525
===========================================
Borillion commented 1 year ago

Event type 2, code 6, value 1 at 1420075338.879530 Event type 2 => EV_REL - Used to describe relative axis value changes, e.g. moving the mouse 5 units to the left. Code 6 => REL_WHEEL - used for vertical and horizontal scroll wheels, The value is the number of detents moved. Value - the value the event carries.

Soo this is kind of weird behavior on the wheel here, the value for the number of detents moved here is either 1 for a right turn or 4294967295 for a left turn. Its the same on the setup screen or Settings screen so its not view dependent or anything. Interestingly 4294967295 is the largest unsigned 32 bit number.

lmore377 commented 1 year ago

Not sure what's up with the wacky values that the python script is giving you but it seems like Chrome interprets the wheel as horizonal mouse scroll wheel movement

Borillion commented 1 year ago

Not sure what's up with the wacky values that the python script is giving you but it seems like Chrome interprets the wheel as horizonal mouse scroll wheel movement

Not 100% sure either, my guess is that chromium interprets and keeps count of the inputs it gets from the event device. Pretty sure its coming from the kernel modules this way.

All I can go with is what what I see as output, a left turn has the value on mine as 65535 65535 <=> 0b11111111111111111111111111111111 <=> 0xFFFFFFFF

b'\xae\x94\xa4T\xd0\xc0\x0e\x00\x02\x00\x06\x00\xff\xff\xff\xff'

ckosmic commented 1 year ago

Here's a C implementation of reading car thing input: ckosmic/sm64ex-thing/src/pc/controller/controller_carthing.c.

GPIO (/dev/input/event0) (all values are 0 or 1): Face button: code: 1 Preset button 1: code: 2 Preset button 2: code: 3 Preset button 3: code: 4 Preset button 4: code: 5 Settings button: code: 50 Rotary button: code: 28

Rotary (/dev/input/event1): Rotary wheel: code: 6, values: -1 (left) or 1 (right)

The -1 from the rotary wheel explains why the value shows up as 4294967295 because it's just underflowing

bishopdynamics commented 6 months ago

FWIW, I wrote an python script for listening to button and knob input, to control lighting and presets via Home Assistant API: https://github.com/bishopdynamics/superbird-debian-kiosk/blob/main/files/data/scripts/buttons_app.py