×

适用于现有键盘的通用免触摸键盘适配器

消耗积分:0 | 格式:zip | 大小:0.05 MB | 2023-06-30

王婷

分享资料个

描述

主意

如今,我们都面临着 Covid-19 大流行;我们知道有多种感染方式,其中之一是触摸被感染者或触摸被感染者触摸过的东西。事实上,病毒在某些表面上可以抵抗几个小时。

在我们的日常生活中,我们触摸了许多以前被别人触摸过的物体。例如,当我们进入电梯时,我们必须按一个按钮来选择所需的楼层。

该项目针对所有在传统键盘上中继的机器(电梯自助加油站、公共饮水机)进行教学,在这些机器中,用户必须物理触摸键盘的按钮,从而使自己和他人面临被感染的风险。该适配器可以针对每种键盘布局进行配置,并且必须安装在传统键盘的顶部。它提供了一个免触摸界面(红外传感器矩阵),用户无需触摸设备,因为当距离 2-3 厘米时检测到手指的存在;然后适配器将负责按下物理按钮。另一种交互是通过蓝牙:在这种情况下,用户必须通过扫描相关的二维码将手机连接到适配器,然后他才能通过应用程序与键盘交互,它在显示器上再现了原始键盘的数字副本。如果您按下应用程序中的按钮,适配器将按下机器键盘上的该按钮。

这个项目可以帮助防止病毒传播的方式是它消除了机器和用户之间的联系。

这个项目也可以被看作是从今天我们仍然需要与机器进行物理交互的世界到未来可能的世界的“桥梁”,在这个世界中,每次交互都是非接触式的,甚至可能是由我们的思想控制的机器。

框图

pYYBAGN-33eAdTdtAACD-SefJI8765.png
 

主控制器是一个 Arduino MKR 1010 WiFi,它负责通过 BLE 与手机上的应用程序通信并读取 IR 矩阵(免触摸界面)。它还通过 I2C 与 Arduino Pro Micro 通信。

辅助控制器是 Arduino Pro Micro。这个小控制器处理电机和编码器。它的工作是从主控制器接收目标位置数据,然后移动轴以到达这些目标位置。

该应用程序是使用 Flutter 开发的,该框架允许在 Dart 中编写应用程序,然后为许多不同的操作系统(IOS、OSX、Android 等)生成应用程序文件。

硬件

硬件是使用 Fusion 360 开发的。它由一个 3 轴系统组成:X 轴和 Y 轴由两个直流有刷电机移动,Z 轴 I 由步进电机移动。伺服电机上连接着物理按下键盘上按钮的尖端。

除不锈钢棒、螺钉和螺栓、电机等外,所有硬件均使用 PLA 进行了 3D 打印。

通过查看 Fusion360 设计,可以轻松组装硬件。https://a360.co/2YJQkPy这是在浏览器中查看设计和下载的链接

pYYBAGN-33mAcTcxAABtt8jGHgU859.png
 
poYBAGN-33-ASvYYAABeYVmco4I925.png
这张图片显示了按下物理按钮的尖端在哪里。
 

轴编码器

X轴和Y轴的编码器集成在结构中。特别是在每个齿轮支架上都有 2 个红外发射器和 2 个接收器,并且齿轮具有间隙,当它旋转时,从一个 IR 接收器产生输出,该输出相对于另一个 90 度异相。

Z 轴不需要编码器,因为它已经集成在伺服电机中。

pYYBAGN-34SAGz1LAAB4Hx4WDE0049.png
Y轴一体式编码器
 
poYBAGN-34eARS-vAABA9RX3m7k799.png
X轴一体式编码器
 

蓝牙连接

要将应用程序与键盘适配器连接,用户只需扫描相关的二维码。标签充当整个系统的参考点。

pYYBAGN-35SAL5AmAAqTJ4URM4E764.png
 

给键盘拍照:一旦用户给键盘拍照,图像处理过程就开始了。特别是应用了高斯模糊滤波器,然后是边缘检测算法,最后是闭合路径搜索算法。结果是包含键盘按钮边界的图像。

poYBAGN-35eAKGK-AADsgzULlZ0282.png
处理后的键盘图像。以红色突出显示按钮边界
 

用户必须选择检测到的闭合路径边界中的哪些是真正的按钮。事实上,图像中可能还有其他接近的路径几何形状。选择路径后,必须提供按钮的标签。

poYBAGOYHkOAKC8LAADzitw9a_E595.png
配置按钮时,其边界变为浅蓝色
 

选择所有按钮后,需要按右上角的“下一步”按钮保存配置,并在“保存”按钮上仔细检查布局后应用更改。

poYBAGOYHkqAb-8RAAC8AoiDz7A646.png
配置检查页面
 

红外传感器矩阵

pYYBAGOYHkyADE7JAABh8jjeNhQ092.png
墙壁顶部的孔用于插入红外发射器和接收器
 

红外传感器矩阵是无触摸交互方式。事实上,这项技术可以在手指(或更一般地说是一个物体)触摸按钮之前检测到它。红外发射器和接收器安装在结构墙壁顶部的孔中。在矩阵结构的两个相邻侧有红外发射器,在另外两侧有红外接收器。

矩阵不是由主控制器(Arduino MKR 1010)直接控制的,因为有 10 个发射器和 10 个接收器需要控制,并且需要大量的 GPIO。取而代之的是两个电路:一个用于控制 IR 发射器,另一个用于控制接收器。第一个由两个 3-8 通道解码器组成,第二个由两个 8-3 通道解复用器组成。这大大减少了控制矩阵所需的 GPIO 数量至仅 5 个(4 个输出用于选择激活哪对 IR,1 个用于读取所选对接收器的值)。

poYBAGOYHlWAcPdWAADPHaj_bok186.png
矩阵红外发射器选择器
 
poYBAGOYHleAUr4VAADAng1Yvjk366.png
矩阵红外接收器选择器
 

存储键盘布局配置

键盘配置需要永久存储在内存中,以便在启动时加载。不幸的是,Arduino MKR 1010 的微控制器没有集成的 EEPROM 存储器,所以我决定使用一个外部的,它通过 I2C 总线与主控制器通信。EEPROM IC 是 STMicroelectronics 24C04WP。它有 4kbit(512 字节)的可用内存,足以存储多达 45 个按钮。

为什么是两个微控制器而不是一个?

划分BLE控制和通过电机和编码器的运动的选择来自第一次测试。事实上,原始设置全部由 Arduino MKR 1010 管理。该配置的问题在于,与两个连续编码器中断例程之间的时间相比,某些 BLE 中断例程太慢;因此缺少一些编码器 ISR,导致轴未对准。相反,单独的控制器只负责处理电机和编码器,因此更加准确

电路实现

该电路已在原型板上实现。

pYYBAGOYHo2AOGleAAjRmMtKh5w463.png
电路板正面(使用 Arduino MKR 1010)
 

等等但是 Arduino Micro 在哪里?好吧,对于一些空间限制,Arduino Micro 就在 Arduino MKR 的下方!

poYBAGOYHtKADNIxAA2bJ6S1QxI802.png
电路板正面(不带 Arduino MKR 1010)
 
pYYBAGOYHt2ABNcIAAMwTggSwCE327.jpg
 

我真的希望您喜欢我的项目,并且觉得它有趣或有用。我也希望将来这个项目可以帮助对抗病毒的传播。

感谢您的阅读!


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.lene-v.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'适用于现有键盘的通用免触摸键盘适配器',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.lene-v.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);