Linux操作USB手柄
Linux控制原理
Linux C控制JoyStick的比较简单,首先在JoyStick在Linux 安装好驱动后会在/dev/input生成js0.对其设备控制,就是读取相应的结构来判断用户输入哪一些指令.
当用户操作手柄时,驱动发送js_event的结构给应用程序以通知用户作了哪一些操作。js_event有如下定义
struct js_event {
unsigned int time; /* event timestamp in milliseconds */
short value; /* value */
unsigned char type; /* event type */
unsigned char number; /* axis/button number */
};
手柄按钮分布
当按下1-4号键会发送type = 1 (Button),number = 0- 3的值
按下 select 返回 type = 1,number = 8,
按下 start 返回 type = 1,number = 9
当按下左侧四个键.有两种情况,当按ANALOG键时(即红灯亮起)。它返回如下四个值
js_event 的type 为2.(AXIS).
上键/下键:number = 6,两者的区别在于value,上键按下value = -32767,松开等于 = 0.
下健按下value = 32767,松开等于 0
,
左/右键:number = 5两者的区别在于value,左键按下value = -32767,松开等于 = 0.
右健按下value = 32767,松开等于 0
当ANALOG键关闭时(即红灯灭时).
上键/下键:number =1, 左/右键:number =0.
下面的转动控制杆相对比较复杂。
左侧旋转杆,向上拨 type = 2,number = 1,value = -32767
向下拨 type = 2,number = 1,value = 32767
向左 type = 2,number = 2,value = -32767
向右 type = 2,number = 2,value = 32767
如果是偏于某个方向,即于返回最接近的键的值type/number,但是value有介于0到最大值之间。
当选旋转时,相当于向系统传送一系列的value渐变的jse_event。
右侧转动控制杆是
向上type = 2,number = 2 ,value =-32767
向下拨 type = 2,number = 2,value = 32767
向左 type = 2,number = 3,value = -32767
向右 type = 2,number = 3,value = 32767
完整的控制代码
这是从网上下载的演示代码,这是调整过后正确误的
JoyStick.h
/*
(C) Copyright 2007,2008, Stephen M. Cameron.
This file is part of wordwarvi.
wordwarvi is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
wordwarvi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with wordwarvi; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#ifndef __JOYSTICK_H__
#define __JOYSTICK_H__
#define JOYSTICK_DEVNAME "/dev/input/js0"
#define JS_EVENT_BUTTON 0x01 /* button pressed/released */
#define JS_EVENT_AXIS 0x02 /* joystick moved */
#define JS_EVENT_INIT 0x80 /* initial state of device */
struct js_event {
unsigned int time; /* event timestamp in milliseconds */
short value; /* value */
unsigned char type; /* event type */
unsigned char number; /* axis/button number */
};
struct wwvi_js_event {
int button[11];
int stick1_x;
int stick1_y;
int stick2_x;
int stick2_y;
};
extern int open_joystick(char *joystick_device);
extern int read_joystick_event(struct js_event *jse);
extern void set_joystick_y_axis(int axis);
extern void set_joystick_x_axis(int axis);
extern void close_joystick();
extern int get_joystick_status(struct wwvi_js_event *wjse);
#endif
JoyStick.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "joystick.h"
static int joystick_fd = -1;
int open_joystick(char *joystick_device)
{
joystick_fd = open(joystick_device, O_RDONLY | O_NONBLOCK); /* read write for force feedback? */
if (joystick_fd < 0)
return joystick_fd;
/* maybe ioctls to interrogate features here? */
return joystick_fd;
}
int read_joystick_event(struct js_event *jse)
{
int bytes;
bytes = read(joystick_fd, jse, sizeof(*jse));
if (bytes == -1)
return 0;
if (bytes == sizeof(*jse))
return 1;
printf("Unexpected bytes from joystick:%d\n", bytes);
return -1;
}
void close_joystick()
{
close(joystick_fd);
}
int get_joystick_status(struct wwvi_js_event *wjse)
{
int rc;
struct js_event jse;
if (joystick_fd < 0)
return -1;
// memset(wjse, 0, sizeof(*wjse));
while ((rc = read_joystick_event(&jse) == 1)) {
jse.type &= ~JS_EVENT_INIT; /* ignore synthetic events */
if (jse.type == JS_EVENT_AXIS) {
switch (jse.number) {
case 0: wjse->stick1_x = jse.value;
break;
case 1: wjse->stick1_y = jse.value;
break;
case 2: wjse->stick2_x = jse.value;
break;
case 3: wjse->stick2_y = jse.value;
break;
default:
break;
}
} else if (jse.type == JS_EVENT_BUTTON) {
if (jse.number < 10) {
switch (jse.value) {
case 0:
case 1: wjse->button[jse.number] = jse.value;
break;
default:
break;
}
}
}
}
// printf("%d\n", wjse->stick1_y);
return 0;
}
#if 1
/* a little test program */
int main(int argc, char *argv[])
{
int fd, rc;
int done = 0;
struct js_event jse;
fd = open_joystick("/dev/js0");
if (fd < 0) {
printf("open failed.\n");
exit(1);
}
while (!done) {
rc = read_joystick_event(&jse);
usleep(1000);
if (rc == 1) {
printf("Event: time %8u, value %8hd, type: %3u, axis/button: %u\n",
jse.time, jse.value, jse.type, jse.number);
}
}
}
#endif
转载链接:http://blog.chinaunix.net/uid-20587912-id-405148.html
Linux操作USB手柄的更多相关文章
- Kali Linux Live USB初始化+使用日记
1.Live USB制作官方guide:Making a Kali Bootable USB Drive:https://docs.kali.org/downloading/kali-linux-li ...
- Linux下 USB设备驱动分析(原创)
之前做过STM32的usb HID复合设备,闲来看看linux下USB设备驱动是怎么一回事, 参考资料基于韦东山JZ2440开发板,以下,有错误欢迎指出. 1.准备知识 1.1USB相关概念: USB ...
- Linux中USB协议栈的框架简介
文本旨在简单介绍一下Linux中USB协议栈的代码框架: 下图是USB协议栈相关数据结构的关系图: 下面结合上图看一下系统初始化的流程: 1.USB子系统初始化:\drivers\usb\core\u ...
- 基于Linux的USB 主/从设备之间通讯的三种方式
转载:http://archive.eet-china.com/www.eet-china.com/ART_8800323770_617693_TA_eda530e7.HTM 随着简单易用的USB接口 ...
- linux控制USB的绑定/解绑
linux控制USB的绑定/解绑 http://www.jianshu.com/p/57293f9be558 今天工作中遇到一个问题, 要用代码实现USB的enable和disable. 谷歌了一番, ...
- Linux操作系统内核编译之NTFS文件系统模块支持案例
Linux操作系统内核编译之NTFS文件系统模块支持案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.内核编译概述 单内核体系设计.但充分借鉴了微内核设计体系的优点,为内核引 ...
- Linux操作基础
摘要 一.Linux操作系统概述 二.Linux操作系统安装 三.Linux文件系统及文件基础 四.Linux操作系统命令使用基础 五.Linux应用程序的安装与卸载基础 五.用户及进程 六.相关信息 ...
- Linux云计算-01_介绍以及Linux操作系统安装
1 学习目的 兴趣爱好 技能提升 找到满意的工作 2 什么是云计算 云计算(cloud computing)是分布式计算的一种,指的是通过网络"云"将巨大的数据计算处理程序分解成无 ...
- Linux操作系统主机名(hostname)简介
http://www.jb51.net/LINUXjishu/10938.html 摘要:本文是关于Linux操作系统主机名(hostname)的文档,对主要配置文件/etc/hosts进行简要的说明 ...
随机推荐
- web前端-框架jquery
1.jquery库 就是js的库 ,可以通过jquery语法简化js操作 ,如文档遍历 ,文档操作 ,事件处理 ,动画js定时器等等 2.引用 下载:https://www.bootcdn.cn/jq ...
- 关于Qt 静态成员函数调用信号
class globalCalcThread; extern globalCalcThread *g_calcThread; class globalCalcThread : public QThre ...
- 微信小程序自定义tabbar的实现
微信小程序自定义tabbar的实现 目的:当采用微信的自定义tabbar组件的时候,切换的时候会出现闪屏的效果:当使用微信默认的tabbar的时候,限制了tabbar的数量以及灵活配置. 方案:自己动 ...
- Java foreach循环
foreach循环:增强性的for循环应用: 在for语句中,需要使用索引来进行操作具体的数组或集合内容操作:而foreach可以取消索引的操作细节: for ( 类型 变量 : 数组 | 集合 ) ...
- sparkstreaming 黑名单过滤
要用到transform and rdd.leftOuterJoin transform: 使 DStream 和 RDD 之间的类型进行了转换,然后可以进行调用 leftOuterJoin(左外连接 ...
- Java代码实现定时器
一 import java.util.Timer; import java.util.TimerTask; public class time { public static void main(St ...
- 01-MySQL 大纲介绍
MySQL 大纲介绍 1.官方定义的MySQL DBA工作内容 (1)运维DBA 初级:各版本.各平台安装搭建.升级 中级:体系结构原理.基础管理(启动关闭.初始化配置文件管理.多实例管理.用户权限管 ...
- Java后端面经总结:拿下蚂蚁金服美团头条 offer 秘诀
笔者在面过 猿辅导,去哪儿,旷视, 陌陌,头条, 阿里, 快手, 美团, 腾讯之后,除了收获一大堆面试问题,还思考到如何成为面试官眼中的”爱技术,爱思考,靠谱,有潜力候选人的”一些”套路”. 面试问题 ...
- 解决IIS7、IIS7.5 应用程序池回收假死的方法
最近iis网站一直假死状态,都懵了,查看程序有没有关闭数据库,反复捣鼓,还一直测试是否是程序应用池自动回收问题依然没有效果.经过老师提醒,找到了解决办法,在此做个笔记! 原因在于:应用程序池超时配置被 ...
- SQL-on-Hadoop 技术
SQL-on-Hadoop 技术 备注 Apache Hive Cloudera Impala Facebook Presto Apache Drill Spark SQL Apache Phoeni ...