[分享] ›SensorTile实现无线触摸屏 蓝牙HID

kangear   2018-7-20 00:10 楼主
基于@littleshrimp 的HID帖子实现的,最近一直查看相关资料,总算整明白了。基于SensorTile实现了无线触摸屏,目前自动从左上角点击滑动到右下角。 1. 目前实现的是单点触摸,后续会实现多点触摸; 2. 参考文档比较多,@littleshrimp 版主的 空中飞鼠 帖子,微软的描述符文章,Android文章https://source.android.com/devices/input/touch-devices 最终实现了,不容易,真不容易。先发一个图得瑟一下,后续再整理详细的文章,我对Android底层开发熟悉一些,有相关问题可以咨询的。 个人技术博客:https://blog.csdn.net/kangear TIM图片20180720000201.gif 补充: HID => linux kernel input子系统 => Android input子系统 就单点触控而言,倒着看Android里对触摸屏的要求,如下图所示:上报键ABS_X 和 ABS_Y以及BTN_TOUCH,另外还需要一个配置文件指定该设备类型为触摸屏。 (一个设备上传了哪些键值可以通过adb shell getevent -i查看) Selection_316.png 对应到Linux内核(以3.4内核为准)里,HID的描述符就需要包含User Page为DIGITIZER,包含TIPSWITCH Selection_317.png 这里的这个描述符稍微精简一下就可以了。最终如下:
  1. 0x05, 0x0d, // USAGE_PAGE (Digitizers)
  2. 0x09, 0x04, // USAGE (Touch Screen)
  3. 0xa1, 0x01, // COLLECTION (Application)
  4. 0x85, 0x01, // REPORT_ID (Touch) (REPORTID_TOUCH is 1)
  5. 0x09, 0x20, // USAGE (Stylus)
  6. 0xa1, 0x00, // COLLECTION (Physical)
  7. 0x09, 0x42, // USAGE (Tip Switch)
  8. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  9. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  10. 0x75, 0x01, // REPORT_SIZE (1)
  11. 0x95, 0x01, // REPORT_COUNT (1)
  12. 0x81, 0x02, // INPUT (Data,Var,Abs)
  13. 0x95, 0x03, // REPORT_COUNT (3)
  14. 0x81, 0x03, // INPUT (Cnst,Ary,Abs)
  15. /*
  16. 0x09, 0x32, // USAGE (In Range)
  17. 0x09, 0x47, // USAGE (Confidence)
  18. 0x95, 0x02, // REPORT_COUNT (2)
  19. 0x81, 0x02, // INPUT (Data,Var,Abs)
  20. 0x95, 0x0a, // REPORT_COUNT (10)
  21. 0x81, 0x03, // INPUT (Cnst,Ary,Abs)
  22. */
  23. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  24. 0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767)
  25. 0x75, 0x10, // REPORT_SIZE (16)
  26. 0x95, 0x01, // REPORT_COUNT (1)
  27. 0xa4, // PUSH
  28. 0x55, 0x0d, // UNIT_EXPONENT (-3)
  29. 0x65, 0x00, // UNIT (None)
  30. 0x09, 0x30, // USAGE (X)
  31. 0x35, 0x00, // PHYSICAL_MINIMUM (0)
  32. 0x46, 0x00, 0x00, // PHYSICAL_MAXIMUM (0)
  33. 0x81, 0x02, // INPUT (Data,Var,Abs)
  34. 0x09, 0x31, // USAGE (Y)
  35. 0x46, 0x00, 0x00, // PHYSICAL_MAXIMUM (0)
  36. 0x81, 0x02, // INPUT (Data,Var,Abs)
  37. 0xb4, // POP
  38. /*
  39. 0x05, 0x0d, // USAGE PAGE (Digitizers)
  40. 0x09, 0x48, // USAGE (Width)
  41. 0x09, 0x49, // USAGE (Height)
  42. 0x95, 0x02, // REPORT_COUNT (2)
  43. 0x81, 0x02, // INPUT (Data,Var,Abs)
  44. 0x95, 0x01, // REPORT_COUNT (1)
  45. 0x81, 0x03, // INPUT (Cnst,Ary,Abs)
  46. */
  47. 0xc0, // END_COLLECTION
  48. 0xc0, // END_COLLECTION
然后在while循环里,模拟发出一个触摸滑动的事件
  1. static int8_t ipRepVal[REPORT_IP_LEN_0] = {0};
  2. /*
  3. static int8_t cnt = 0;
  4. if(cnt == 0) {
  5. ipRepVal[1] = MOUSE_OFFSET_X;
  6. ipRepVal[2] = MOUSE_OFFSET_Y;
  7. cnt++;
  8. } else {
  9. ipRepVal[1] = -MOUSE_OFFSET_X;
  10. ipRepVal[2] = -MOUSE_OFFSET_Y;
  11. cnt--;
  12. }
  13. */
  14. ipRepVal[1] = 0x01; // down
  15. if (abs_hor < 32760) {
  16. abs_hor += 20;
  17. abs_ver += 20;
  18. } else {
  19. ipRepVal[1] = 0x00; // up
  20. }
  21. ipRepVal[0] = 0x01; // Report ID
  22. ipRepVal[2] = abs_hor%256;
  23. ipRepVal[3] = abs_hor/256;
  24. ipRepVal[4] = abs_ver%256;
  25. ipRepVal[5] = abs_ver/256;
  26. HidDevice_Update_Input_Report(0,0,REPORT_IP_LEN_0,ipRepVal);
  27. if (ipRepVal[1] == 0x00) {
  28. abs_hor = 0;
  29. abs_ver = 0;
  30. }
Android系统中的放一个配置文件,路径:/system/usr/idc/HID.idc
  1. # Copyright (C) 2010 The Android Open Source Project
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # [url=http://www.apache.org/licenses/LICENSE-2.0]http://www.apache.org/licenses/LICENSE-2.0[/url]
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. #
  15. # Input Device Calibration File for the touch screen.
  16. #
  17. # Basic Parameters
  18. touch.deviceType = touchScreen
  19. #touch.orientationAware = 1
  20. # Size
  21. # Based on empirical measurements, we estimate the size of the contact
  22. # using size = sqrt(area) * 43 + 0.
  23. #touch.size.calibration = area
  24. #touch.size.scale = 6
  25. #touch.size.bias = 0
  26. #touch.size.isSummed = 0
  27. # Pressure
  28. # Driver reports signal strength as pressure.
  29. #
  30. # A normal thumb touch typically registers about 80 signal strength
  31. # units although we don't expect these values to be accurate.
  32. #touch.pressure.calibration = amplitude
  33. #touch.pressure.scale = 0.0125
  34. #
  35. # Orientation
  36. #touch.orientation.calibration = none
这样连接到该设备后就可以如下图自动从左上角滑动到右下角了。这里有git diff文件可以详细查看: https://gitee.com/kangear/STM32C ... 59307223735d3658e6d 本帖最后由 kangear 于 2018-7-20 23:04 编辑

回复评论 (21)

给力啊,楼主全能。
点赞  2018-7-20 09:56
无线触摸屏实现之后,我觉得还是有很多想像空间的,可以实现物理外挂、把手游改装成体感游戏(比如吃鸡可以改装成一个物理的玩具枪,扣扳机时就向手机发按射击键)想想好有意思
点赞  2018-7-20 10:09
引用: kangear 发表于 2018-7-20 10:09
无线触摸屏实现之后,我觉得还是有很多想像空间的,可以实现物理外挂、把手游改装成体感游戏(比如吃鸡可以 ...

体感吃鸡这个想法不错
点赞  2018-7-20 10:16
引用: littleshrimp 发表于 2018-7-20 10:16
体感吃鸡这个想法不错

多点触摸ok了
点赞  2018-7-23 19:19
引用: littleshrimp 发表于 2018-7-20 10:16
体感吃鸡这个想法不错

TIM图片20180723191727.gif
点赞  2018-7-23 19:22
引用: kangear 发表于 2018-7-23 19:22

多点触摸试过在普通手机上什么效果没?我上弄的会显示鼠标指针,多点应该不会显示多个指针
点赞  2018-7-24 08:13
引用: littleshrimp 发表于 2018-7-24 08:13 多点触摸试过在普通手机上什么效果没?我上弄的会显示鼠标指针,多点应该不会显示多个指针
普通手机上会有一点问题,因为Android内核里的多点触摸驱动给触摸设备设置了类似USB中的VID PID白名单,只有这名单里的才是多点触摸屏,而系统从SensorTile里获取到的始终是0x00 0x00。所以暂时没有办法适配普通手机,这个Android平板的内核我简单的改了一下才能用。我正在找SensorTile中如何设置VendorId 和 ProductId。这里记录的有文章:蓝牙设备也有VendorId ProductId ? 本帖最后由 kangear 于 2018-7-24 10:56 编辑
点赞  2018-7-24 10:51
引用: littleshrimp 发表于 2018-7-24 08:13
多点触摸试过在普通手机上什么效果没?我上弄的会显示鼠标指针,多点应该不会显示多个指针

发的帖子或者回复,老是会被审核,效率好低呢
点赞  2018-7-24 11:05
引用: kangear 发表于 2018-7-24 10:51
普通手机上会有一点问题,因为Android内核里的多点触摸驱动给触摸设备设置了类似USB中的VID PID白名单, ...

如果PID和VID设置成白名单中的数值普通手机就不会显示鼠标指针了吧?
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2018-7-24 12:55
引用: kangear 发表于 2018-7-24 11:05
发的帖子或者回复,老是会被审核,效率好低呢

回复里有链接,没办法的
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2018-7-24 12:55
引用: littleshrimp 发表于 2018-7-24 12:55
如果PID和VID设置成白名单中的数值普通手机就不会显示鼠标指针了吧?

嗯,那样就不会显示指针了。你做那个也可以让其不显示指针,放一个配置文件到/system/usr/idc/HID.idc,内容为:touch.deviceType = touchScreen,还要chmod 777 /system/usr/idc/HID.idc,这样就不显示指针了。Android里对输入设备有指针类型 和 触摸屏,默认是指针类型,你实现的那个因为没有配置文件,系统默认当成指针类型了,就给你显示 鼠标的指针了。
点赞  2018-7-24 15:34
引用: kangear 发表于 2018-7-24 15:34
嗯,那样就不会显示指针了。你做那个也可以让其不显示指针,放一个配置文件到/system/usr/idc/HID.idc, ...

看看你配置VID和PID后的结果吧
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2018-7-24 20:21
引用: littleshrimp 发表于 2018-7-24 20:21
看看你配置VID和PID后的结果吧

目前在iOS上就能用,iOS不区别vid pid。 这个算是惊喜。
点赞  2018-7-25 17:40
引用: kangear 发表于 2018-7-25 17:40
目前在iOS上就能用,iOS不区别vid pid。 这个算是惊喜。

我的在ios下为什么触摸没有反应呢
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2018-7-25 18:44
引用: littleshrimp 发表于 2018-7-25 18:44
我的在ios下为什么触摸没有反应呢

iOS哪有单点触摸过?都是多点的,能且只能多点。
点赞  2018-7-25 20:03
引用: littleshrimp 发表于 2018-7-25 18:44
我的在ios下为什么触摸没有反应呢

VID PID的问题也不用再追踪了,Linux内核3.5以上的都和iOS一样,根据描述符来识别是否为多点触摸设备(依据是描述符中是否包含了HID_DG_CONTACTID,包含则是,否则不是,我开发板和Nexus 5手机上刚好用的只是3.4版本的内核,新手机一般都是大于3.5内核了),寻找VID PID的线路暂停了。
点赞  2018-7-26 15:43
我发帖子一般会加上自己的查找到的理论依据, 但是如果贴链接会导致帖子进入审核,这里就暂时不贴链接了。下一步我的计划是:能使用SensorTile上的按键触发其发送按下某个坐标,俗话讲替我吃鸡里按开枪键。 本帖最后由 kangear 于 2018-7-26 15:53 编辑
点赞  2018-7-26 15:46
引用: kangear 发表于 2018-7-26 15:43
VID PID的问题也不用再追踪了,Linux内核3.5以上的都和iOS一样,根据描述符来识别是否为多点触摸设备(依 ...

HID_DG_CONTACTID的问题能解决吗?
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2018-7-26 16:14
引用: kangear 发表于 2018-7-26 15:46
我发帖子一般会加上自己的查找到的理论依据, 但是如果贴链接会导致帖子进入审核,这里就暂时不贴链接了。 ...

只要链接不违规迟早能通过
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2018-7-26 16:16
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复