Ubuntu joystick 测试手柄 xbox
测试使用Ubuntu20.04 测试环境在工控机
安装测试
实际测试使用的手柄是北通阿修罗2pro
兼容xbox
Ubuntu20.04主机
连接手柄或者无线接收器后查看是否已经检测到:
ls /dev/input
找到输入中的 js0 即为手柄输入
需要安装joystick安装包:
sudo apt install joystick
测试手柄的数据输入:
jstest /dev/input/js0
测试代码
->>>完整的项目代码:
https://gitee.com/tianxiaohuahua/joystick_code
driver_Xbox_Joystick.cpp
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/joystick.h>
#include "driver_Xbox_Joystick.h"
/* 获得手柄设备输入流 */
int xbox_open(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_SELECT:
map->select = value;
break;
case XBOX_BUTTON_START:
map->start = 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
{
/* 若出错 */
}
return len;
}
/* 关闭手柄设备输入流 */
void xbox_close(int xbox_fd)
{
close(xbox_fd);
return;
}
int test(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((char*)("/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 select:%d start:%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.select, map.start, 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;
}
JoyStickDriver::JoyStickDriver(){
JoyStickInit();
}
JoyStickDriver::~JoyStickDriver(){
JoyStickClose();
}
int JoyStickDriver::JoyStickInit(){
JoystickFd = xbox_open((char*)("/dev/input/js0"));
if(JoystickFd < 0) {
return -1;
}
return 0;
}
int JoyStickDriver::JoyStickRead(xbox_map_t *pMap){
return xbox_map_read(JoystickFd, pMap);
}
int JoyStickDriver::JoyStickRead(void){
return xbox_map_read(JoystickFd, &joystickData);
}
int JoyStickDriver::JoyStickClose(){
xbox_close(JoystickFd);
return 0;
}
driver_Xbox_Joystick.h
#ifndef driver_Xbox_Joystick_H
#define driver_Xbox_Joystick_h
/* 手柄面板上所有可控制按键/轴(包括一个时间量) */
typedef struct xbox_map
{
int time;
int a;
int b;
int x;
int y;
int lb;
int rb;
int select;
int start;
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;
#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_SELECT 0x06
#define XBOX_BUTTON_START 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
int test(void);
class JoyStickDriver {
public:
xbox_map_t joystickData;
JoyStickDriver(void);
~JoyStickDriver(void);
int JoyStickInit(void);
int JoyStickRead(xbox_map_t *pMap);
int JoyStickRead(void);
int JoyStickClose();
private:
int JoystickFd ;
};
#endif
main.cpp
#include <iostream>
#include "main.h"
int main(int argc, char *argv[])
{
std::cout << "123" << std::endl;
JoyStickDriver joystick;
while(1)
{
int len = joystick.JoyStickRead();
if (len < 0)
{
usleep(10*1000);
continue;
}
printf("\rTime:%8d A:%d B:%d X:%d Y:%d LB:%d RB:%d select:%d start:%d lo:%d ro:%d XX:%-6d YY:%-6d LX:%-6d LY:%-6d RX:%-6d RY:%-6d LT:%-6d RT:%-6d",
joystick.joystickData.time,
joystick.joystickData.a, joystick.joystickData.b,
joystick.joystickData.x, joystick.joystickData.y,
joystick.joystickData.lb, joystick.joystickData.rb,
joystick.joystickData.select, joystick.joystickData.start,
joystick.joystickData.lo, joystick.joystickData.ro,
joystick.joystickData.xx, joystick.joystickData.yy,
joystick.joystickData.lx, joystick.joystickData.ly,
joystick.joystickData.rx, joystick.joystickData.ry,
joystick.joystickData.lt, joystick.joystickData.rt);
fflush(stdout);
}
return 0;
}
CMakeList.txt
# VERSION需要和本机安装的Cmake对应
cmake_minimum_required(VERSION 3.10.2)
# 指定了当前的工程名称,最后输出的可执行文件名称,赋值给了{PROJECT_NAME}变量
project(app)
# c++ 11
set(CMAKE_CXX_FLAGS "-std=c++11")
# 添加头文件
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_SOURCE_DIR}/include/driver)
# 查找指定目录下的所有.cpp与.h文件 并存放到指定变量名{SC_FILES}中
FILE(GLOB
SC_FILES
${PROJECT_SOURCE_DIR}/src/driver/driver_Xbox_Joystick.cpp
)
#####生成可执行文件
# 使用指定的源文件创建出一个可执行文件,第一个变量必须是可执行文件的名字,后面默认是其他源文件
add_executable(${PROJECT_NAME} ${SC_FILES} ${PROJECT_SOURCE_DIR}/src/main.cpp)
# 指定链接给定目标和/或其依赖项时要使用的库或标志,链接动态库静态库等