[joysticker]使用Ubuntu读取USB手柄/方向盘的输出控制

您所在的位置:网站首页 测试ps4手柄按键 [joysticker]使用Ubuntu读取USB手柄/方向盘的输出控制

[joysticker]使用Ubuntu读取USB手柄/方向盘的输出控制

2024-07-14 09:23| 来源: 网络整理| 查看: 265

摘要:在淘宝上买到的游戏手柄/USB卖家只给了Windows下的驱动,本来以为Ubuntu下没有驱动,没想到网上早已经有人用cpp开发出了USB手柄的驱动,搜索很多博客的方法终于从手柄拿到数据。 Linux真给力!!

目录

目录1.cat命令2.hexdump命令3.获取游戏手柄的端口输出 (1)获取端口(2)读取游戏手柄端口数据 4.代码实现 warning:deprecated conversion from string constant to ‘char *’ 主要参考

1.cat命令

cat 是一个文本文件查看和连接工具。查看一个文件的内容,用cat比较简单,就是cat 后面直接接文件名,如cat linuxyw.txt

cat –help可以查看cat帮助信息,如各种参数使用方法,当然也可以用man cat来查看,建议大家养成遇到命令不懂用法时,用–help或man来查看帮助信息,养成好习惯。filename为文件名,即系统中需要查看的文件名字。 与这个命令相似功能的命令有:tac,less,tail,more

options: -b:--number-nonblank 对非空输出行编号,即在每行前显示所在行号 -n:--number 对输出的所有行编号,即在每行前显示所在行号

注:cat命令

2.hexdump命令

hexdump命令一般用来查看“二进制”文件的十六进制编码,但实际上它能查看任何文件,而不只限于二进制文件。

hexdump [选项] [文件]... options: -n length 只格式化输入文件的前length个字节。 -C 输出规范的十六进制和ASCII码。 -b 单字节八进制显示。 -c 单字节字符显示。 -d 双字节十进制显示。 -o 双字节八进制显示。 -x 双字节十六进制显示。 -s 从偏移量开始输出。 -e 指定格式字符串,格式字符串包含在一对单引号中,格式字符串形如:'a/b "format1" "format2"'。

注:hexdump命令

3.获取游戏手柄的端口输出 (1)获取端口

在插入设备时,linux系统会使用input子系统,操作系统会为每一个设备分配event号,先插上的为event0,后插上的为event1,首先获取linux系统为游戏手柄分配的event号。 当游戏手柄插入电脑时,需要找到手柄的even号:

cat /proc/bus/input/devices

注:或者可以使用>将输出写入一个txt文档

cat /proc/bus/input/devices >log1.txt

获得如下输出

I: Bus=0003 Vendor=11ff Product=001c Version=0111 N: Name="PXN-V3II" P: Phys=usb-0000:00:14.0-11/input0 S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb1/1-11/1-11:1.0/0003:11FF:001C.0009/input/input29 U: Uniq= H: Handlers=event21 js0 B: PROP=0 B: EV=1b B: KEY=1fff000000000000 0 0 0 0 B: ABS=30027 B: MSC=10

在端口处找到设备名字“PXN-V3II”,event21/js0我们的手柄的接口。

开始的时候有时候找不到,是手柄中的版本不对,根据产品说明书需要由X-input转换到D-input模式。(长按home键3秒) X -input适用于XBOX360移植到PC上的即插即玩的游戏,D-input适用于早期单机游戏如极品飞车1-12等。——要不是要在unbuntu下开发哪来这么多幺蛾子。。。

(2)读取游戏手柄端口数据

查看输入

ls /dev/input

这里写图片描述

可以看见js0和event21,使用以下代码查看端口输出:

cat /dev/input/js0 | hexdump

cat /dev/input/event21 | hexdump

得到一堆16进制的数,当手柄按下时,数字便会变化。 这里写图片描述

测试手柄命令

jstest /dev/input/js0

可以读取Axes和Button的变化。 这里写图片描述

4.代码实现

参照参考3,新建文件夹与cpp文件,实现jstest功能: cpp文件建立执行参照

gedit first.cpp g++ first.cpp -o test ./test

代码如下:

#include #include #include #include #include #include #include #include #include #define XBOX_TYPE_BUTTON 0x01 #define XBOX_TYPE_AXIS 0x02 #define XBOX_BUTTON_A 0x00 #define XBOX_BUTTON_B 0x01 #define XBOX_BUTTON_X 0x02 #define XBOX_BUTTON_Y 0x03 #define XBOX_BUTTON_LB 0x04 #define XBOX_BUTTON_RB 0x05 #define XBOX_BUTTON_START 0x06 #define XBOX_BUTTON_BACK 0x07 #define XBOX_BUTTON_HOME 0x08 #define XBOX_BUTTON_LO 0x09 /* 左摇杆按键 */ #define XBOX_BUTTON_RO 0x0a /* 右摇杆按键 */ #define XBOX_BUTTON_ON 0x01 #define XBOX_BUTTON_OFF 0x00 #define XBOX_AXIS_LX 0x00 /* 左摇杆X轴 */ #define XBOX_AXIS_LY 0x01 /* 左摇杆Y轴 */ #define XBOX_AXIS_RX 0x03 /* 右摇杆X轴 */ #define XBOX_AXIS_RY 0x04 /* 右摇杆Y轴 */ #define XBOX_AXIS_LT 0x02 #define XBOX_AXIS_RT 0x05 #define XBOX_AXIS_XX 0x06 /* 方向键X轴 */ #define XBOX_AXIS_YY 0x07 /* 方向键Y轴 */ #define XBOX_AXIS_VAL_UP -32767 #define XBOX_AXIS_VAL_DOWN 32767 #define XBOX_AXIS_VAL_LEFT -32767 #define XBOX_AXIS_VAL_RIGHT 32767 #define XBOX_AXIS_VAL_MIN -32767 #define XBOX_AXIS_VAL_MAX 32767 #define XBOX_AXIS_VAL_MID 0x00 typedef struct xbox_map { int time; int a; int b; int x; int y; int lb; int rb; int start; int back; int home; int lo; int ro; int lx; int ly; int rx; int ry; int lt; int rt; int xx; int yy; }xbox_map_t; int xbox_open(const char *file_name) { int xbox_fd; xbox_fd = open(file_name, O_RDONLY); if (xbox_fd < 0) { perror("open"); return -1; } return xbox_fd; } int xbox_map_read(int xbox_fd, xbox_map_t *map) { int len, type, number, value; struct js_event js; len = read(xbox_fd, &js, sizeof(struct js_event)); if (len < 0) { perror("read"); return -1; } type = js.type; number = js.number; value = js.value; map->time = js.time; if (type == JS_EVENT_BUTTON) { switch (number) { case XBOX_BUTTON_A: map->a = value; break; case XBOX_BUTTON_B: map->b = value; break; case XBOX_BUTTON_X: map->x = value; break; case XBOX_BUTTON_Y: map->y = value; break; case XBOX_BUTTON_LB: map->lb = value; break; case XBOX_BUTTON_RB: map->rb = value; break; case XBOX_BUTTON_START: map->start = value; break; case XBOX_BUTTON_BACK: map->back = value; break; case XBOX_BUTTON_HOME: map->home = value; break; case XBOX_BUTTON_LO: map->lo = value; break; case XBOX_BUTTON_RO: map->ro = value; break; default: break; } } else if (type == JS_EVENT_AXIS) { switch(number) { case XBOX_AXIS_LX: map->lx = value; break; case XBOX_AXIS_LY: map->ly = value; break; case XBOX_AXIS_RX: map->rx = value; break; case XBOX_AXIS_RY: map->ry = value; break; case XBOX_AXIS_LT: map->lt = value; break; case XBOX_AXIS_RT: map->rt = value; break; case XBOX_AXIS_XX: map->xx = value; break; case XBOX_AXIS_YY: map->yy = value; break; default: break; } } else { /* Init do nothing */ } return len; } void xbox_close(int xbox_fd) { close(xbox_fd); return; } int main(void) { int xbox_fd ; xbox_map_t map; int len, type; int axis_value, button_value; int number_of_axis, number_of_buttons ; memset(&map, 0, sizeof(xbox_map_t)); xbox_fd = xbox_open("/dev/input/js0"); if(xbox_fd < 0) { return -1; } while(1) { len = xbox_map_read(xbox_fd, &map); if (len < 0) { usleep(10*1000); continue; } printf("\rTime:%8d A:%d B:%d X:%d Y:%d LB:%d RB:%d start:%d back:%d home:%d LO:%d RO:%d XX:%-6d YY:%-6d LX:%-6d LY:%-6d RX:%-6d RY:%-6d LT:%-6d RT:%-6d", map.time, map.a, map.b, map.x, map.y, map.lb, map.rb, map.start, map.back, map.home, map.lo, map.ro, map.xx, map.yy, map.lx, map.ly, map.rx, map.ry, map.lt, map.rt); fflush(stdout); } xbox_close(xbox_fd); return 0; }

运行结果如图: 这里写图片描述 可以从代码中获取各个键及方向盘的值~

如果代码报错:

warning:deprecated conversion from string constant to ‘char *’

解决方案:比较合理的办法是把参数类型修改为const char * 参考:https://blog.csdn.net/xyy410874116/article/details/6397549

主要参考

1.ubuntu下使用USB手柄 2.在UBUNTU中使用北通USB游戏手柄 3.Linux获取/dev/input目录下的event对应的设备 4.树莓派 使用xbox360手柄



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3