当前位置: 首页 > news >正文

DIY蓝牙键盘(1) - 理解 键盘报文(免费)

DIY蓝牙键盘(1) - 理解键盘报文

1. 键盘报文体验

一个键盘对于用户的体验是,用户按按键A他能看到字母A会在主机上显示出来。那这是如何实现的?

其实很简单,只要键盘发送下面的两个报文给主机,字母A就能在主机上显示出来。

(1)表1:字母A按下的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x040x000x000x00

(2)表2:字母A松开的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x000x000x000x00

报文的原则很简单,就是它把字母A所以对应的usage发给主机,主机就能显示出字母A. 以上表1按下报文Byte 1的值就是字母A的usage, 这个在USB官网的HID usage table(https://usb.org/sites/default/files/hut1_22.pdf)里面有定义。因为这个是USB标准所定义的,现在所有的操作系统都会认识这个usage, 于是主机会把0x04翻译成字母A.

有人要问了,那看起来只要发一个报文就可以输出A了,为什么还要再发一个松开的报文?

大家在用键盘的时候应该有这个体验,我们要输入一个字母A, 会按下A键然后松开。如果你一直按着字母A, 那么在主机上会看到一直会有字母A输出,下到你松开按键A.

当键盘只给主机发送一个A键盘按下的报文(表1),那么主机会一直输出字母A,这自然不是我们想到的。因此我们在发送完按下的报文后,还要发送松开的报文告诉主机说按键已经松开了。表2中把Byte 1的值改为0x00就是告诉主机按键已松开。

2. 按键实验

我们有了之上的知识后,那么比如我现在想要输入其他的字母要怎么做?

第一步我们要找到HID usage table(https://usb.org/sites/default/files/hut1_22.pdf),然后找到其他字母对应的usage并发出去。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UoLjMqi3-1631431089485)(C:\Users\86180\AppData\Roaming\Typora\typora-user-images\image-20210912112932516.png)]

上面我截取了一段键盘按键的usage, N的usage为0x11, i的usage为0x0C, c的usage为0x06, e的usage为0x08. 所以如果我要让主机输出单词Nice, 键盘必须要发出下面4组报文(report).

(1)发送N的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x110x000x000x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x000x000x000x00

(2)发送i的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x0C0x000x000x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x000x000x000x00

(3)发送c的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x060x000x000x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x000x000x000x00

(4)发送e的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x080x000x000x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x000x000x000x00

以此类推,我们查找到26个字母对应的usage, 并让键盘发出去,就可以让主机输出26个字母出来。

3. 报文格式解析

细心的同学可能会有个疑问:我用一个字节就可以完成26个字母的发送,还要其他4个字节来做什么?

第一个字节Byte 0下面会讲到,这里先跳过。 第2到第5个字母的地位是等同的。也就是说发送按键A,下面的4种方式的效果是一样的。

Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x040x000x000x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x000x040x000x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x000x000x040x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x000x000x000x04

可能大家还是蒙的,你说这么多还是没有解释原因呀。现在解释正式开始。

上面说的所有情况都是用户一个按键一个按键按住松开的情况,那如果我4个按键一起按住一起松开,那键盘该怎么发送报文?

还是以Nice这个单词为例,假如我同时按住Nice然后松开,键盘应该发送如下的报文。

(1) 4个按键按住的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x110x0C0x060x08

(2) 4个按键松开的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x000x000x000x000x00

可能有人要说了,如果我有同时按键10个按键的情况,那这4个字节不够用看呀,怎么办呢?其实也很简单,你只要把报文扩展为11个字节就可以了,下面两个报文就是同时输出: ABCDEFGHIJ的例子.

Byte 0Byte 1Byte 2Byte 3Byte 4Byte 5Byte 6Byte 7Byte 8Byte 9Byte 10
0x000x040x050x060x070x080x090x0A0x0B0x0C0x0D
Byte 0Byte 1Byte 2Byte 3Byte 4Byte 5Byte 6Byte 7Byte 8Byte 9Byte 10
0x000x000x000x000x000x000x000x000x000x000x00

更多详细信息,请查看下面的文章。
在这里插入图片描述

相关文章:

  • JAX深度学习库入门
  • JS实现双向数据绑定的三种方式
  • 面试题:RabbitMQ 消息队列中间件
  • 基于ssm的轻型卡车零部件销售平台(java项目+文档+源码)
  • 站群服务器如何提高搜索引擎排名
  • Linux中部署Java jar 包 shell 脚本
  • Excel中文显示问号
  • 多媒体编解码
  • Axure案例分享—垂直手风琴(附下载地址)
  • 如何使用 Python 本地客户端操作读写云服务器 Redis 缓存数据库详细教程(更新中)
  • Ubuntu20.04使用Neo4j导入CSV数据可视化知识图谱
  • 【C语言】预处理详解
  • 【C++】编程规范之表达式原则
  • 第四篇:3.3 无效流量(Invalid traffic) - IAB/MRC及《增强现实广告效果测量指南1.0》
  • Spring Boot 学习(2)——HelloWorld
  • 【mysql】环境安装、服务启动、密码设置
  • 10个最佳ES6特性 ES7与ES8的特性
  • Akka系列(七):Actor持久化之Akka persistence
  • es6--symbol
  • Java的Interrupt与线程中断
  • nodejs调试方法
  • SAP云平台里Global Account和Sub Account的关系
  • V4L2视频输入框架概述
  • Vue.js源码(2):初探List Rendering
  • 阿里云Kubernetes容器服务上体验Knative
  • 安卓应用性能调试和优化经验分享
  • 编写高质量JavaScript代码之并发
  • 树莓派 - 使用须知
  • 王永庆:技术创新改变教育未来
  • 责任链模式的两种实现
  • HanLP分词命名实体提取详解
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • ​比特币大跌的 2 个原因
  • ###C语言程序设计-----C语言学习(3)#
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (力扣)循环队列的实现与详解(C语言)
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (一)Thymeleaf用法——Thymeleaf简介
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • ***测试-HTTP方法
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .NET 设计一套高性能的弱事件机制
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)
  • .net6Api后台+uniapp导出Excel
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • .net生成的类,跨工程调用显示注释
  • [20170705]lsnrctl status LISTENER_SCAN1