网络摄像头转usb接口_Arduino + USB Host Sheild 实现USB鼠标转PS/2接口
制作缘由
公司内网只有PS/2接口,希望可以使用无线鼠标(貌似没有PS/2接口的)。而那种USB转PS/2的转接头只是简单的连线,需要键盘或鼠标本身支持PS/2模式才可以正常工作,现代的USB鼠标接收器显然没有考虑这一点。无意中发现有人用Arduino制作过USB键盘转PS/2的装置,那么鼠标一定也可以。这个装置,从原理上来说,就是一个转发器。对于USB鼠标(非蓝牙无线鼠标对主机来说仍是USB鼠标,和有线的没啥区别),他是一个主机,接收来自鼠标的数据;对于真正的主机,他是一个PS/2鼠标,负责向其发送转换过的数据。
PS/2部分
物理接口
如下图,实际有用的只有4根线,1 - Data:用于传输数据(双向);5 - Clock:用于向主机发送脉冲,控制读写数据;3 - Ground:接地;4 - Vcc (+5V) :电源。其中1和2可以接在Arduino任意的数字引脚上(但要避开USB Host Sheild占用的那些引脚,我实际使用的是2号、3号引脚),而3和4分别接在Arduino的5V和GND引脚上,这样不用额外供电,连到主机的PS/2接口就能正常工作。
数据传输(1位)
设备 > 主机 :由设备控制Clock以产生脉冲,首先,设置Data为要发送的位(高/低电平表示1/0),同时保持Clock为高电平一段时间,然后拉低Clock为低电平,产生一个下降沿,通知主机读取(锁存)Data,继续保持Clock为低电平一段时间后释放Clock(恢复为高电平,为传输下1位数据做准备)。。
主机 > 设备:仍然由设备控制Clock脉冲。当主机拉低Data或Clock时表示想要向设备发送(命令)数据,此时设备应该停止发送数据,优先读取来自主机的数据,待主机释放Clock(变为高电平)时,表示设备可以开始读入数据。首先,设备让Clock保持高电平一段时间,然后拉低Clock,产生一个下降沿,通知主机设置Data,继续保持Clock为低电平一段时间后,释放Clock为高电平(此时设备可以锁存当前Data,并且准备读入下1位数据)
数据传输(1字节)
每传输1字节数据,需要额外附带起始位(0),奇校验位,停止位(1),共11位
代码实现
最初在Arduino官方网站找到了一个叫做ps2dev的示例代码,里面的PS2dev类看上去实现了单个字节的读写,但是版本过于老旧。后来发现这个ps2dev已经是Arduino的一个库了,在库管理器中就可以搜索安装,但还是不够新,存在一些问题。他的最新版本在这里 https://github.com/Harvie/ps2dev,其中简单模拟鼠标的例子在某些时候会死循环出不来,我的修正已经被作者合并进去了。进一步地,为了提高通讯速度,我修改了时钟频率以及发送单个字节的间隔,目前工作正常。:)
鼠标协议
总的来说,主机向鼠标发送各种命令,以设置或询问鼠标的状态或参数;而鼠标呢,除了答复来自主机的命令,就是向主机发送位移数据包(处于Stream模式并且“数据报告”使能状态下,可以主动上报);更具体的可以参考网上的文档。(有中文版哦,搜索“PS2 鼠标 键盘技术参考”)下面列出我抓到的命令序列:
19:44:22.522 -> process_cmd FF 重置命令,进入Reset模式,重置各种状态,回复自检完成、设备ID,进入Steam模式
19:44:22.556 -> process_cmd F2 询问设备ID,首次询问应该回复00(标准鼠标),但我一律回复的03(滚轮鼠标)也没事哦
19:44:22.556 -> process_cmd E8 设置解析度
19:44:22.556 -> set resolution 0 读取解析度,1count/mm
19:44:22.556 -> process_cmd E6 设置缩放比例1:1
19:44:22.556 -> process_cmd E6 设置缩放比例1:1
19:44:22.556 -> process_cmd E6 设置缩放比例1:1,为啥连续发了3次?
19:44:22.556 -> process_cmd E9 询问鼠标状态,此时应该回复3字节的状态包
19:44:22.556 -> process_cmd E8 设置解析度
19:44:22.589 -> set resolution 3 读取解析度,8count/mm
19:44:22.589 -> process_cmd F3 设置采样率
19:44:22.589 -> set sample rate 200 读取采样率 200/sec
19:44:22.589 -> process_cmd F3 设置采样率
19:44:22.589 -> set sample rate 100 读取采样率 100/sec
19:44:22.589 -> process_cmd F3 设置采样率
19:44:22.589 -> set sample rate 80 读取采样率 80/sec,注意,当主机按此顺序设置采样率,表示他支持03鼠标(滚轮鼠标)
19:44:22.589 -> process_cmd F2 询问设备ID,此时应该回复03,如果鼠标支持的话
19:44:27.052 -> process_cmd FF 重置命令
19:44:27.052 -> process_cmd F2 询问设备ID
19:44:27.052 -> process_cmd E8 设置解析度
19:44:27.052 -> set resolution 0 读取解析度,1count/mm
19:44:27.052 -> process_cmd E6 设置缩放比例1:1
19:44:27.052 -> process_cmd E6 设置缩放比例1:1
19:44:27.052 -> process_cmd E6 设置缩放比例1:1,同样的,为啥连续发了3次?我猜可能有含义的。
19:44:27.086 -> process_cmd E9 询问鼠标状态,此时应该回复3字节的状态包
19:44:27.086 -> process_cmd E8 设置解析度
19:44:27.086 -> set resolution 3 读取解析度,8count/mm
19:44:27.086 -> process_cmd F3 设置采样率
19:44:27.086 -> set sample rate 200 读取采样率 200/sec
19:44:27.086 -> process_cmd F3 设置采样率
19:44:27.086 -> set sample rate 100 读取采样率 100/sec
19:44:27.086 -> process_cmd F3 设置采样率
19:44:27.086 -> set sample rate 80 读取采样率 80/sec,为啥又来一遍?囧
19:44:27.086 -> process_cmd F2 询问设备ID,此时应该回复03,如果鼠标支持的话
19:44:27.120 -> process_cmd F3 设置采样率
19:44:27.120 -> set sample rate 200 读取采样率 200/sec
19:44:27.120 -> process_cmd F3 设置采样率
19:44:27.120 -> set sample rate 200 读取采样率 200/sec
19:44:27.120 -> process_cmd F3 设置采样率
19:44:27.120 -> set sample rate 80 读取采样率 80/sec,注意,当主机按此顺序设置采样率,表示他支持04鼠标(5键滚轮)
19:44:27.120 -> process_cmd F2 询问设备ID,此时应该回复04,如果鼠标支持的话,但是我没有。:)
19:44:27.120 -> process_cmd F3 设置采样率
19:44:27.120 -> set sample rate 100 读取采样率 100/sec
19:44:27.120 -> process_cmd E8 设置解析度
19:44:27.154 -> set resolution 3 读取解析度,8count/mm
19:44:27.154 -> process_cmd F4 使能“数据报告”,下面鼠标就可以开始主动上报“位移数据包”了。。
USB部分
使用USB Host Shield扩展板(采用MAX3421E芯片,支持USB2.0),加上USB Host Shield 2.0(它也是Arduino的一个库),最新版本在这里 https://github.com/felis/USB_Host_Shield_2.0,只要继承HIDUniversal类并且覆盖虚函数ParseHIDData就能得到HID设备的数据(数据格式可用USBBlyzer分析)。实际使用中发现,如果本次数据和上次的完全一致,则不会调用ParseHIDData。(比如同方向滚动滚轮,后面的都被忽略了)只需略微修改hiduniversal.cpp,已提合并请求,作者暂时没理我。^_^ (我的修改见 https://github.com/felis/USB_Host_Shield_2.0/pull/522)
USB是一种主从结构,只有当主机向设备发送IN令牌包(见上述库中 USB::InTransfer)时,设备才可以向主机发送数据。在鼠标设备内部,分为USB芯片(用于与USB主机通讯)和MCU(用于执行鼠标固件程序)。当检测到鼠标状态变化(比如按键按下或发生移动),MCU将状态数据写入USB芯片的缓冲区,待收到IN令牌包时由USB芯片将数据发给主机。如果主机请求数据速度过慢会怎样?我猜数据会丢失?从目前能找到的固件程序代码看,都是直接向芯片缓冲区写数据的,并没有额外的处理。或许当缓冲区满了之后,合并后续数据会好一点?
鼠标回报率
也就是上面提到的采样率。
PS/2理论上支持:10、20、40、60、80、100、200。我的主机最终设置的值为100,目前USB部分耗时2ms,PS/2部分耗时6-7ms,已经可以满足。曾经试过把时钟频率调的更快、发送单个字节的间隔改的更短,没成功。:(
USB1.1支持:125
USB2.0支持:250、500、1000
考虑到USB和PS/2收发速率可能不匹配,所以实现了一个循环队列用于存放来自USB鼠标的数据,并尽可能地将新的数据与队尾元素合并。但是,实际测试中,队列长度从未超过1并且合并函数从未被调用,即便在loop()中尝试读取多次USB数据再向PS/2发送也是如此,Why?可能是因为我的USB鼠标只有125的回报率吧。
呼吸灯
为了了解转换器的工作状态(以及更炫酷一点),额外加了一个全彩LED灯在盒子顶部。繁忙时,以红色快速闪烁;而空闲时,则以绿色缓慢呼吸;
最终成品
完整源代码在这里 https://github.com/liumazi/MzMouse
参考资料
https://www.zhihu.com/answer/619886526
https://www.arduino.cn/forum.php?mod=viewthread&tid=22851
http://www.burtonsys.com/ps2_chapweske.htm
http://usb.baiheee.com/usb_projects/easy_usb_51_programer_plus/usb_hid_mouse.html
https://blog.csdn.net/suipingsp/article/details/30238891
网络摄像头转usb接口_Arduino + USB Host Sheild 实现USB鼠标转PS/2接口相关推荐
- 2022年全球市场Type-C USB网络摄像头总体规模、主要生产商、主要地区、产品和应用细分研究报告
本文研究全球市场.主要地区和主要国家Type-C USB网络摄像头的销量.销售收入等,同时也重点分析全球范围内主要厂商(品牌)竞争态势,Type-C USB网络摄像头销量.价格.收入和市场份额等.针对 ...
- 2022年全球与中国USB网络摄像头市场现状及未来发展趋势
2022-2028全球与中国USB网络摄像头市场现状及未来发展趋势 根据QYR(恒州博智)的统计及预测,2021年全球USB网络摄像头市场销售额达到了 亿美元,预计2028年将达到 亿美元,年复合增长 ...
- TX2+GStreamer+OpenCV读取显示网络摄像头
参考:https://jkjung-avt.github.io/tx2-camera-with-python/ 参考:http://blog.iotwrt.com/media/2017/08/23/o ...
- python多个摄像头_python - 使用python和OpenCV与VideoCapture洞察多个网络摄像头捕获 - 堆栈内存溢出...
我正在尝试同时(或几乎同时)从多个网络摄像头捕获图像. 我一直在玩OpenCV ,使用VideoCapture和python编程. 但有一些困惑,希望有人可以帮助解释事情...... 首先,我尝试了V ...
- Win10系统C++调用OpenCV实现网络摄像头录像和抓拍图片
1 前言 前边文章介绍了在WIN10系统上,分别用C++和Python调用OpenCV接口,播放本地和网络摄像头视频.本篇我们来看一下,用C++如何调用OpenCV接口,打开网络摄像头的视频,对其进行 ...
- 电脑主板PS/2接口
主板知识,什么是PS/2接口. PS/2接口是目前最常见的鼠标接口,最初是IBM公司的专利,俗称"小口".这是一种鼠标和键盘的专用接口,是一种6针的圆型接口.但鼠标只使用其中的4针 ...
- 网络摄像头转usb接口_同时读取多个摄像头数据(包括海康网络摄像头和USB摄像头)...
一.功能 1.实现多个摄像头同时获取图像,并保存到个各自目录 2.摄像头类别包括海康RSTP协议网络摄像头和普通USB摄像头 3.可自动和手动保存图片 二.注意事项 1.python可以使用multi ...
- usb网络linux系统安装教程,Linux系统入门学习:如何在树莓派上安装USB网络摄像头...
Question: 我可以在树莓派上使用标准的USB网络摄像头么?我该如何检查USB网络摄像头与树莓派是否兼容?另外我该如何在树莓派上安装它? 如果你想在树莓上拍照或者录影,你可以安装树莓派的摄像头板 ...
- ---WebCam网络摄像头9 usb dirver
Device Drivers ---><*> Multimedia support --->[*] Video capture adapters --->[*] ...
最新文章
- 神经网络与机器学习 笔记—小规模和大规模学习问题
- go mod引用git仓库中的包:拉取存放在gitee中的package
- java学习(123):treeset排序集合
- coreldraw x4如何重叠图片_CorelDRAW复制及镜面反转对象
- 百度编辑器 Ueditor 如何增加模板 ?
- 英文简历 计算机知识,计算机应届生英文简历范文
- series、dataframe转为tensor格式数据
- Effective_STL 学习笔记(二十六) 尽量使用 iterator 代替 const_iterator,reverse_iterator和const_reverse_iterator...
- 定义一个内核panic问题
- android studio 软件使用 详细说明
- SAP 软件PS 模块系统操作之一工作分解结构(WBS)的创建
- 网络可视化工具netron
- 跨境电商亚马逊产品运营模式都有哪些
- 网站变更服务器要重新备案吗,网站更换服务器要重新备案吗
- springcould 微服务 nacos 跨域问题
- Unity中导出apk文件
- java可以编写siri_打造Android的中文Siri语音助手(一)
- 儿童身高体重记录检测表
- uniAPP开发 全教程
- java中使用pdfBox打印pdf;java web打印pdf;静默打印;jar程序打包成exe文件;exe4j的使用
热门文章
- 【clickhouse】Clickhouse 版本号历史
- [Flink] Not a valid protocol version This 1s not an HTTP port
- 【Spring】Spring 解决循环依赖的 3 种方式
- Memcache监控小工具stats命令
- Kudu 使用注意点
- private关键字
- SpringBoot默认日志配置输出级别
- 监控、链路追踪、日志的区别
- Java中的回调机制,这篇给你整的明明白白的
- Redis问的太深入,面试官说:“你先回去等通知吧“!