Categorieën bekijken

Input/Button device via Bluetooth (linux)

In this example we are connecting a input button device via bluetooth.

Connect via Bluetooth #

Please NOTE: Bluetooth manual basics

To create a connection with the built-in utils, you can follow this slightly more manual process using bluetoothctl.

hcitool scan  # to get the MAC address of your device
bluetoothctl
power on  # in case the bluez controller power is off 
agent on
scan on  # wait for your device's address to show up here
scan off
trust MAC_ADDRESS
pair MAC_ADDRRESS
connect MAC_ADDRESS

So let’s connect

To connect via bluetooth enter the bluetooth commandline:

bluetoothctl

Start the scan:

[bluetooth]# power on
[bluetooth]# agent on
[bluetooth]# scan on
Discovery started

Power on the MIDI Pad, eventuelly it will be discovered and you will see something like:

[NEW] Device 58:71:33:33:71:58 58-71-33-33-71-58
[CHG] Device 58:71:33:33:71:58 LegacyPairing: no
[CHG] Device 58:71:33:33:71:58 Name: AB Shutter 3
[CHG] Device 58:71:33:33:71:58 Alias: AB Shutter 3

Turn scan off:

[bluetooth]# scan off

Pair the device by entering it’s MAC address:

[bluetooth]# pair 58:71:33:33:71:58

Output:

Attempting to pair with 58:71:33:33:71:58
[CHG] Device 58:71:33:33:71:58 Connected: yes
[CHG] Device 58:71:33:33:71:58 Bonded: yes
[CHG] Device 58:71:33:33:71:58 Modalias: bluetooth:v04E8p7021d0100
[CHG] Device 58:71:33:33:71:58 UUIDs: 00001124-0000-1000-8000-00805f9b34fb
[CHG] Device 58:71:33:33:71:58 UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device 58:71:33:33:71:58 ServicesResolved: yes
[CHG] Device 58:71:33:33:71:58 Paired: yes
Pairing successful
[CHG] Device 58:71:33:33:71:58 ServicesResolved: no
[CHG] Device 58:71:33:33:71:58 Connected: no

Connect the device by entering it’s MAC address:

[bluetooth]# connect 58:71:33:33:71:58

Output:

Attempting to connect to 58:71:33:33:71:58
[CHG] Device 58:71:33:33:71:58 Connected: yes
Connection successful
[CHG] Device 58:71:33:33:71:58 ServicesResolved: yes

The device is now paired with the system, you can exit the bluetooth terminal.

dmesg

[39477.691212] hid-generic 0005:04E8:7021.0003: unknown main item tag 0x0
[39477.691507] input: AB Shutter 3 Keyboard as /devices/virtual/tty/ttyBT0/hci0/hci0:50/0005:04E8:7021.0003/input/input5
[39477.692088] hid-generic 0005:04E8:7021.0003: input,hidraw0: BLUETOOTH HID v1.00 Keyboard [AB Shutter 3] on e3:e8:5a:8c:7e:1b

You can see the port number: 142

Test event input #

evtest

sudo evtest

No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:      sunxi-ir
/dev/input/event1:      AB Shutter 3 Keyboard
Select the device event number [0-1]:

Output:

Testing ... (interrupt to exit)
Event: time 1745264847.781517, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e9
Event: time 1745264847.781517, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 1
Event: time 1745264847.781517, -------------- SYN_REPORT ------------
Event: time 1745264848.064553, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 2
Event: time 1745264848.064553, -------------- SYN_REPORT ------------
Event: time 1745264848.104548, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 2
Event: time 1745264848.104548, -------------- SYN_REPORT ------------
Event: time 1745264848.144547, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 2
Event: time 1745264848.144547, -------------- SYN_REPORT ------------
Event: time 1745264848.184551, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 2
Event: time 1745264848.184551, -------------- SYN_REPORT ------------
Event: time 1745264848.224550, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 2
Event: time 1745264848.224550, -------------- SYN_REPORT ------------
Event: time 1745264848.264551, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 2
Event: time 1745264848.264551, -------------- SYN_REPORT ------------
Event: time 1745264848.304551, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 2
Event: time 1745264848.304551, -------------- SYN_REPORT ------------
Event: time 1745264848.339072, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e9
Event: time 1745264848.339072, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 0
Event: time 1745264848.339072, -------------- SYN_REPORT ------------
Event: time 1745264849.506453, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70028
Event: time 1745264849.506453, type 1 (EV_KEY), code 28 (KEY_ENTER), value 1
Event: time 1745264849.506453, -------------- SYN_REPORT ------------
Event: time 1745264849.760547, type 1 (EV_KEY), code 28 (KEY_ENTER), value 2
Event: time 1745264849.760547, -------------- SYN_REPORT ------------
Event: time 1745264849.800551, type 1 (EV_KEY), code 28 (KEY_ENTER), value 2
Event: time 1745264849.800551, -------------- SYN_REPORT ------------
Event: time 1745264849.840551, type 1 (EV_KEY), code 28 (KEY_ENTER), value 2
Event: time 1745264849.840551, -------------- SYN_REPORT ------------
Event: time 1745264849.880551, type 1 (EV_KEY), code 28 (KEY_ENTER), value 2
Event: time 1745264850.160547, -------------- SYN_REPORT ------------
Event: time 1745264850.200550, type 1 (EV_KEY), code 28 (KEY_ENTER), value 2
Event: time 1745264850.200550, -------------- SYN_REPORT ------------
Event: time 1745264850.240559, type 1 (EV_KEY), code 28 (KEY_ENTER), value 2
Event: time 1745264850.240559, -------------- SYN_REPORT ------------
Event: time 1745264850.279076, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70028
Event: time 1745264850.279076, type 1 (EV_KEY), code 28 (KEY_ENTER), value 0
Event: time 1745264850.279076, -------------- SYN_REPORT ------------

Node-Red #

In node-red you can also catch the output of evtest and put it trough some functions to get all the gamepad data in JSON format:

FLOW:

[
    {
        "id": "ef101a8bf14c7170",
        "type": "exec",
        "z": "34ba443e.fcb78c",
        "command": "sudo evtest /dev/input/event1",
        "addpay": false,
        "append": "",
        "useSpawn": "true",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 920,
        "y": 1220,
        "wires": [
            [
                "e60ea5fbac6f1d61"
            ],
            [],
            []
        ]
    },
    {
        "id": "b3eea446bd16b143",
        "type": "inject",
        "z": "34ba443e.fcb78c",
        "name": "Start",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "5",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 730,
        "y": 1220,
        "wires": [
            [
                "ef101a8bf14c7170"
            ]
        ]
    },
    {
        "id": "e60ea5fbac6f1d61",
        "type": "function",
        "z": "34ba443e.fcb78c",
        "name": "Decode line",
        "func": "let lines = msg.payload.split(\"\\n\");\nlet results = [];\n\nlet regex = /^Event: time ([\\d\\.]+), type (\\d+) \\(([^)]+)\\), code (\\d+) \\(([^)]+)\\), value (.+)$/;\n\nfor (let line of lines) {\n    line = line.trim();\n    if (line.length === 0) continue;\n\n    let match = line.match(regex);\n\n    if (match) {\n        let result = {\n            time: parseFloat(match[1]),\n            type: {\n                code: parseInt(match[2]),\n                name: match[3]\n            },\n            code: {\n                code: parseInt(match[4]),\n                name: match[5]\n            },\n            value: isNaN(match[6]) ? match[6] : parseInt(match[6])\n        };\n        results.push({ payload: result });\n    }\n    // SYN_REPORT kun je ook nog apart verwerken als je wilt\n    else if (line.includes(\"SYN_REPORT\")) {\n        // results.push({ payload: { type: \"SYN_REPORT\" } }); // optioneel\n    }\n}\n\nreturn [results];\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1150,
        "y": 1220,
        "wires": [
            [
                "9a16335bdbe14406"
            ]
        ]
    },
    {
        "id": "9a16335bdbe14406",
        "type": "debug",
        "z": "34ba443e.fcb78c",
        "name": "Debug OUTPUT",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 1320,
        "y": 1220,
        "wires": []
    }
]