这是一套连载文章,用以记录大眼睛连接蓝牙手柄的全过程。谨以此文献给那一周我缺失的睡眠。
此文的性质相当于(公开的)个人日记,未经本人允许,请勿转载。
上文说到,linmctool编译后连接手柄成功,各按键都有了反应。我可以展开对SixAxis各个按键的探索了。
在测试的过程中,有一次突然连不上了。我很郁闷,无论怎么调都不行。最后终于发现,第一次能够成功连接,完全是归功于我在研究hidd时无意输入的命令: hciconfig hci1 up 和 hciconfig hci1 piscan。由于我有2个蓝牙适配器,在大眼睛启动后,第一个插入的蓝牙适配器被分配到了hci0,在hci0有效的情况下如果再插入一个蓝牙适配器,新插入的就会分配为hci1。大眼睛似乎占用了hci0,导致hci0一直无法up起来。我第一次连成功,正好是因为先插入了一个无用的适配器hci0,然后插入了与SixAxis配对好的适配器hci1。hci0很惨,被大眼睛中的某个进程强抢而去,而hci1没有被抢,正好被linmctool用上了。但是一旦重启大眼睛,或者改变适配器的顺序,或者只插入一个蓝牙适配器,都会导致连不成功。经反复试验,要想正常连接,需要2个条件,1.相应的hci可以成功up;2.相应的hci必须开启pscan。如此说来,瞎蒙能蒙对的机率实在是不大,我真的很幸运。
经过多次试验,我发现了占用hci0的罪魁祸首是/system/bin/bluetoothd。它让我学会了使用ps命令和kill命令,但kill也仍然是kill不掉它,杀了之后就会自动再启动。真是岂有此理,我只好rename了,让系统找不到它。以后再也不怕hci0无法up了。
言归正传。接下来该研究SixAxis的按键和传感器了。
改了改linmctool中的代码,我让它把从手柄中传来的所有数据都显示出来了。
经过反复测试,我不禁惊呆了。
我没有玩过PS3,当初买这个手柄纯粹是一时兴起,看它没有线的束缚才买的。我真的没有想到它居然这么强大!除了SELECT,START,L3,R3和PS键之外,其它所有的按键都能测出按的力度!这也太下本儿了。后来和游戏控同事交流才知道,在PS3中玩游戏时,方向键按轻和按重跑的速度是不同的。我去!
下面是一组示例数据,从hcidump命令获取到的:
> ACL data: handle 42 flags 0x02 dlen 54
L2CAP(d): cid 0x0041 len 50 [psm 19]
HIDP: Data: Input report
0000: 01 00 00 00 00 00 7f 80 81 80 00 00 00 00 00 00 ................
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 03 03 16 ................
0020: ff b7 00 0e 33 a0 77 01 c0 01 fc 01 e7 01 8d 01 ?.3爓.???..
0030: f0 ?
可以看出,每次手柄向主机发送49字节。经过测试、对比,可发现其中的规律:
这49字节中,
第3字节为8个按键,从低到高位,依次是:SELECT,L3,R3,START,上方向,右方向,下方向,左方向。前4个按键的压力值位于第11~第14字节,读数一直是0;后4个按键的压力值分别位于第15~第18字节。
第4字节为8个按键,从低到高位,依次是:L2,R2,L1,R1,三角,圆,叉,方块。这8个按键的压力值分别位于第19~第26字节。
第5字节的最低位是PS键,此键的压力值位于第27字节,读数一直是0。
第42,43字节为X轴(左摇杆水平方向)的值,高字节在前。
第44,45字节为Y轴(左摇杆垂直方向)的值,高字节在前。
第46,47字节为Z轴(右摇杆水平方向)的值,高字节在前。
第48,49字节为gZ轴(右摇杆垂直方向)的值,高字节在前。
其它字节有一些用来测量加速度的,测量摇杆倾斜度的,还有一些不知道干啥的,不容易测,就没有仔细测试。
以上这些足够目前用了。
OK,有了这些,可以初步开始我们的规划了。
我一直在用 Xperia Play,这是一款非常不错的手机,推开手柄后,可以利用手柄进行各种控制,不只是玩游戏,还包括系统的各项功能。
初步设计,我打算用SixAxis实现Play中手柄的各种功能。也就是说,上下左右方向键用来控制光标(不是鼠标指针),叉键确定,圆圈键返回,L3键作为菜单键,R3键作为主页键,L2和R2键作为音量键,
另外,三角键用来搜索,左摇杆控制鼠标指针,方框键模拟鼠标左键,右摇杆用来模拟手划动屏幕。
要实现这些功能,我们的软件就要起到桥梁的作用,一头连接SixAxis,另一头在系统中模拟键盘或鼠标的动作。
下篇继续。