Raspberry Pie uses Xbox360 handle

Start

The Raspberry Pi can control a lot of hardware, the most common is to build a car or something. I have seen many points on the web to control it. It feels a bit cumbersome. It would be nice if I could use the handle.

I thought of the Beitong Asura handle I bought when I was playing “The Witcher 3” lying in the box. I never used it again after clearing the level. If it can be controlled with a Raspberry Pi, I think it’s too much. cooooool!

Since I thought about it, I naturally started on the small pi immediately.

Preparations

1. Raspberry Pi 3B, the system is Raspbian. The performance is strong, and the built-in wireless network card is very cool, eliminating all kinds of connections.

2. Beitong Asura TE wireless handle. Support xbox360 mode, powerful function.

Dependent software

sudo apt-get install joysticksudo apt- get isntall xboxdrv

Connect the handle

On my Raspbian, it looks like The relevant modules are already loaded, so there is no need to configure the kernel.

Check the handle USB head on the small pi, and you can directly drive it. Check that the px light of the handle is on at the same time, indicating that it has been connected. The default is xbox360 mode.

Test the handle

After connecting the handle, you can use it in the system Check some information to confirm whether the handle can work normally.

Enter lsusb under the shell, you can see that the handle has been identified.

lsusb

Bus 001 Device 009: ID 045e:028e Microsoft Corp . Xbox360 Controller
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Enter the /dev/input directory and check that there are two more device files, event0 and js0, which are the handle devices , Indicating that it is ready to start reading data.

ls /dev/input/

by-id by-path event0 js0 mice

Enter jstest under the shell, and then operate the handle, you can see At this point, the data has been successfully read. Check it a little, and the key mapping should be correct.

jstest /dev/input/js0

Axes: 0:- 2194 1: 644 2:-32767 3: -3226 4:-32767 6: 0 Buttons: 0:off 1:off 2:off 3:off 4:off 5:off 7:off off 8:off

You can also use the following command to view several key values.

jstest --event /dev/input/js0 

Event: type 2, time 45840650, number 4, value -2711

Verified here, the handle can be Using it on our small pi, the output of the handle can also be read normally. The rest is how to use the handle for us in the code! ! Victory is on the other side!

Code section

The header file of joystick is in the location /usr/include/linux/joystick.h, and there is only one header file that can be used, which defines some macros and structures, and we only need to use this header file.

The most important structure is the following. The important data output by the handle is these values. During the jstest test, you can see the detailed value output by the handle.

struct js_event {__u32 time; /* event timestamp in milliseconds */ __s16 value; /* value */ __u8 type; / * event type */ __u8 number; /* axis/button number */};

type: 1 is button, 2 is axis

number : Button name

value: Actual value.

time: A time value.

The following is the code: A function similar to jstest is implemented. I additionally mapped the keys of xbox360 to the number value for direct use in the future.

#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 / * left stick button * /#define XBOX_BUTTON_RO 0x0a /* Right stick button*/#define XBOX_BUTTON_ON 0x01#define XBOX_BUTTON_OFF 0x00#define XBOX_AXIS_LX 0x00 /* Left stick X axis*/#define XBOX_AXIS_LY 0x01 XBOX_*/Left stick 0x03 /* Right joystick X axis*/#define XBOX_AXIS_RY 0x04 /* Right joystick Y axis*/#define XBOX_AXIS_LT 0x02#define XBOX_AXIS_RT 0x05#define XB OX_AXIS_XX 0x06 /* Arrow key X axis*/#define XBOX_AXIS_YY 0x07 /* Arrow key Y axis*/#define XBOX_AXIS_VAL_UP -32767#define XBOX_AXIS_VAL_DOWN 32767#define XBOX_AXIS_VAL_LEFT -32767#define XBOX_AXIS_RIGHT 32767 #define XBOX_AXIS_VAL-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(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, siz eof(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 = val ue; 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("
Time:%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;}

实现的功能如下:用手柄测试一下,一切OK,到这我的小pi就可以用手柄控制了!

A:1 B:0 X:1 Y:0 LB:0 RB:0 start:1 back:1 home:0 LO:0 RO:0 XX:0 YY:0 LX :-388 LY:386 RX:-130 RY:1418 LT:0 RT:32767

Summary

span>

The function of the xbox360 handle is very powerful, the wifi control distance is long, the signal is strong, and the control is stable. You can use the handle to control anything in the future, and it is wireless control. Thinking about it, I feel that it is full of various possibilities sex!

In the process, I consulted a lot of information and took many detours. The final implementation is indeed very simple. The things that Baidu found were not very reliable, but they still had to be checked by Baidu. Finally, we summarized a lot of forum information and found a solution.

The Raspberry Pi can be implemented, and other linux systems should be the same. I will keep a record here for my future research and study.

Leave a Comment

Your email address will not be published.