1. 安装xboxdrv和joystick
sudo apt install xboxdrv
sudo apt install joystick
2. 将usb无线接收器插入,查看设备信息
cat /proc/bus/input/devices
输出如下信息说明系统已经识别到了xbox的接收器
I: Bus=0003 Vendor=045e Product=0719 Version=0100
N: Name="Xbox 360 Wireless Receiver"
P: Phys=
S: Sysfs=/devices/virtual/input/input28
U: Uniq=
H: Handlers=event28 js3
B: PROP=0
B: EV=b
B: KEY=f 0 0 0 0 0 0 7fdb000000000000 0 0 0 0
B: ABS=1b
登录后复制
3. 编译xow
Xow是一个非官方的Linux版本Xbox one手柄无线适配器驱动,其底层基于libusb进行工作,通过Wifi与游戏手柄进行连接,其使用MT76xx的Wifi chip;
3.1 下载xow源码
git clonet https://github.com/medusalix/xow.git
3.2 安装依赖
audo apt install curl libusb-1.0-0-dev cabextract
3.3 编译
cd xow
make BUILD=RELEASE
sudo make install
3.4 Download the firmware for the wireless dongle:
sudo xow-get-firmware.sh
3.5 运行xow
sudo ./xow
[sudo] password for sar:
2022-05-20 11:18:43 INFO - xow v0.5-36-gd335d60 ©Severin v. W.
2022-05-20 11:18:43 INFO - Waiting for device…
2022-05-20 11:18:43 INFO - Wireless address: 62:45:bd:05:8b:85
2022-05-20 11:18:43 INFO - Dongle initialized
2022-05-20 11:18:49 INFO - Controller ‘1’ connected
2022-05-20 11:18:49 INFO - Device announced, product id: 02d1
2022-05-20 11:18:49 INFO - Battery level: full
2022-05-20 11:28:10 INFO - Controller ‘1’ disconnected
2022-05-20 11:33:12 INFO - Controller ‘1’ connected
2022-05-20 11:33:12 INFO - Device announced, product id: 02d1
3.6 编译错误解决:
执行make BUILD=RELEASE报错:找不到uinput_setup、uinput_abs_setup的定义
报错原因:linux内核版本太低,xow不支持UINPUT_VERSION 5以下版本;
解决方法:从高版本的ubuntu中拷贝/usr/include/linux/uinput.h替换当前系统下的/usr/include/linux/uinput.h
xow驱动分析可以参考这篇博客:https://blog.csdn.net/YingbinLi/article/details/123268015
4. xbox手柄测试
先运行./xow,在按下xbox one手柄最前端的带x标识的圆形按键,按下按键后按键灯点亮,开始慢闪,配对成功后,按键灯常亮;
打开了一个linux终端,运行:
sudo jstest /dev/input/js4
Driver version is 2.1.0.
Joystick (Xbox One Wireless Controller) has 8 axes (X, Y, Z, Rx, Ry, Rz, Hat0X, Hat0Y)
and 11 buttons (BtnA, BtnB, BtnX, BtnY, BtnTL, BtnTR, BtnSelect, BtnStart, BtnMode, BtnThumbL, BtnThumbR).
Testing ... (interrupt to exit)
Axes: 0: 0 1: 0 2:-32767 3: 0 4: 0 5:-32767 6: 0 7: 0 Buttons: 0:off 1:off 2:off 3:off 4:off 5:off 6:off 7:off 8:off 9:off 10:off
登录后复制
注意:在/dev/input下可能会生成js0, js1, js2, js3, js4 5个文件,可以分别使用jstest 测试一下,运行sudo jstest /dev/input/js4 后, *** 作手柄 *** 作杆查看数据是否有变化。
5. xbox手柄 *** 作数据接收与解析
joystick_xbox.h
#include <linux/input.h>
#include <linux/joystick.h>
#include <string>
class JoystickXBox
{
public:
JoystickXBox(const std::string &dev_name)
~JoystickXBox()
bool Open()
void Close()
bool Read(struct js_event &js)
unsigned char GetAxes()
{
return axes_
}
unsigned char GetButtons()
{
return buttons_
}
int GetFd()
{
return fd_
}
void PrintData()
void ProcessData(const struct js_event &js)
private:
bool debug_ = false
int fd_ = -1
std::string dev_name_ = ""
int version_ = 0x000800
char name_[512] = "Unkown"
unsigned char axes_ = 2
unsigned char buttons_ = 2
int *axis_ = nullptr
char *button_ = nullptr
}
登录后复制
joystick_xbox.cpp
#include <errno.h>
#include <fcntl.h>
#include <memory>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "joystick_xbox.h"
JoystickXBox::JoystickXBox(const std::string &dev_name) : fd_(-1),dev_name_(dev_name)
{
}
JoystickXBox::~JoystickXBox()
{
if (axis_)
{
delete axis_
axis_ = nullptr
}
if (button_)
{
delete button_
button_ = nullptr
}
}
bool JoystickXBox::Open()
{
int fd = -1
if (dev_name_.length() == 0)
{
return false
}
// O_NONBLOCK open
fd = open(dev_name_.c_str(), O_RDONLY | O_NONBLOCK)
if (fd <0)
{
fd_ = -1
printf("JoystickXBox open %s error, %d(%s)\n", dev_name_.c_str(), errno, strerror(errno))
return false
}
ioctl(fd, JSIOCGVERSION, &version_)
ioctl(fd, JSIOCGAXES, &axes_)
ioctl(fd, JSIOCGBUTTONS, &buttons_)
ioctl(fd, JSIOCGNAME(512), name_)
printf("JoystickXBox Driver version is %d.%d.%d.\n", version_ >>16, (version_ >>8) &0xff, version_ &0xff)
printf("JoystickXBox (%s) has %d axes and %d buttons\n", name_, axes_, buttons_)
fd_ = fd
axis_ = (int *)calloc(axes_, sizeof(int))
button_ = (char *)calloc(buttons_, sizeof(char))
return true
}
void JoystickXBox::Close()
{
if (fd_ >0)
{
close(fd_)
fd_ = -1
}
}
bool JoystickXBox::Read(struct js_event &js)
{
int len = -1
if (fd_ <0)
{
return false
}
memset(&js, 0, sizeof(js))
len = read(fd_, &js, sizeof(struct js_event))
if (len != sizeof(struct js_event))
{
printf("JoystickXBox: error reading, %d(%s)\n", errno, strerror(errno))
return false
}
return true
}
void JoystickXBox::ProcessData(const struct js_event &js)
{
JoystickFrame frame
int joystick_angular_value = 0
int joystick_linear_value = 0
int button_angular_value = 0
int button_linear_value = 0
switch (js.type &~JS_EVENT_INIT)
{
case JS_EVENT_BUTTON:
button_[js.number] = js.value
break
case JS_EVENT_AXIS:
axis_[js.number] = js.value
break
}
if (debug_)
{
PrintData()
}
}
void JoystickXBox::PrintData()
{
if (axes_ &&axis_)
{
printf("Axes: ")
for (int i = 0i <axes_i++)
{
printf("%2d:%6d ", i, axis_[i])
}
}
if (buttons_ &&button_)
{
printf("Buttons: ")
for (int i = 0i <buttons_i++)
{
printf("%2d:%s ", i, button_[i] ? "on " : "off")
}
}
printf("\n")
fflush(stdout)
}
int main()
{
bool ret = false
int err_cnt = 0
fd_set rfds
timeval timeout
struct js_event js
int fd = -1
std::string dev_name = "/dev/input/js4"
std::unique_ptr<JoystickXBox>joystick_xbox = std::make_unique<JoystickXBox>(dev_name)
ret = joystick_xbox->Open()
if (!ret)
{
return -1
}
fd = joystick_xbox->GetFd()
while (1)
{
usleep(100)
timeout.tv_sec = 1
timeout.tv_usec = 0
FD_ZERO(&rfds)
FD_SET(fd, &rfds)
int ret = select(fd + 1, &rfds, NULL, NULL, &timeout)
if (ret >0 &&FD_ISSET(fd, &rfds))
{
ret = joystick_xbox->Read(js)
if (ret)
{
joystick_xbox->ProcessData(js)
}
}
}
joystick_xbox->Close()
return 0
}
登录后复制
ubuntu
linux
点赞文章给优秀博主打call~
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)