×

带有磁性鼠标垫的基于ESP32的BLE鼠标

消耗积分:0 | 格式:zip | 大小:0.16 MB | 2022-11-04

分享资料个

描述

本教程是关于构建基于 esp32 的 BLE 鼠标,与使用传统方法使用光学传感器构建鼠标不同,此鼠标基于嵌入在定制 3D 打印鼠标垫中的磁铁工作。

请务必阅读到本文末尾,以了解这款鼠标是如何从头开始构建的,并了解如何仅使用单个磁极和一堆霍尔效应传感器来导航磁性表面!

补给品

这是可以帮助您轻松完成此项目的产品列表

(会员链接)

3d 打印机:

打印机升级:

橙色灯丝

Esp32:

霍尔效应传感器:

磁铁:

性能板:

18650 电池座:

18650 单元:

按钮:

贴片电容和电阻套件:

按钮:

cp2102:

Tp4056:

第 1 步:光学鼠标如何工作?

首先,我们来谈谈传统鼠标的工作原理。

如果您看一下底部,您可能已经注意到鼠标发出华丽的红光。这是鼠标内部的光学传感器使用的光来确定运动。但它是如何工作的?

最初,当我想到它时,我认为它类似于线路跟随器机器人中使用的 IR 传感器,或者可能更复杂一些,例如 IC 中的 LED 和阵列以及光传感器,最后可能是一些奇特的算法检测运动。

但是当我第一次听到这项工作时,我被所使用的技术所震撼。所以,如果你还没有听说过,让我破坏它。

更多信息

第 2 步:在光学鼠标内部

 
 
 
 
pYYBAGNkXHSAOzdRAAIEC2icTqM301.png
 
1 / 3
 

如果你打开鼠标,你会看到一个底部有一个小凹口的 IC,这是相机的外壳,当你将它与实际的相机进行比较时,这种捕捉方式太少了细节。因为这不是为了拍摄人和猫的照片,所以它是用来拍摄鼠标使用表面上的图案和微小凹槽的照片。一旦拍照,它就会应用一种称为光流的算法,该算法通过比较它在连续运动中拍摄的图像帧来确定鼠标的方向。

这真的让我很吃惊,因为光流算法要检测相机移动的方向,两个连续的帧必须非常接近。如果它们离得很远,那么算法就不能很好地工作。由于这个原因,鼠标光学传感器必须每秒捕获近 2000 到 6000 帧。这比智能手机相机快得多。所以,从现在开始,当你是一只鼠标的时候,你可以认为自己是一个高速摄像机操作员。

第 3 步:更换光学传感器 - 故障

 
 
 
 
pYYBAGNkXHiAdXEPAANWiNrUEUc942.png
 
1 / 2
 

所以,从项目开始。我最初的想法是永远不要使用磁铁。

本来只想做一个BLE蓝牙鼠标,但是在设计鼠标的时候,很快就遇到了找不到光学传感器的问题。它并不便宜,而且 Arduino 社区最熟悉的那个现在已经过时了。

所以我的天才大脑认为我可以使用 ESP32 CAM 构建光学传感器。即使我至少可以获得一些不错的帧速率,我也会非常高兴,因此我可以更换 ESP32 CAM 的镜头并制作一款速度非常慢/响应速度较慢的鼠标。但是在玩了一段时间的 ESP32 CAM 之后,我认为从 ESP32 CAM 开始是一个非常糟糕的主意。

放弃 ESP32 CAM 的主要原因:

  • ESP32 CAM 在捕捉高帧率照片时不可靠,我可以推的最大值是 24,分辨率非常低。
  • 第二个原因是光流算法不能很好地工作并且多次使 esp32 崩溃。
  • 最后,大多数 esp32 cam 的镜头都用强力胶固定在传感器上。

第4步:磁铁!!!

 
 
 
 
poYBAGNkXHuAHklRAADIkt3I0jQ322.png
 
1 / 2
 

由于我没有光学传感器的选择,这让我陷入绝望的境地,无法找到检测鼠标运动的方法,因为电子设备的重置和编码非常简单。这只是添加一些按钮和集成 BLE。

我绝对可以使用任何一种旧方法来构建鼠标。但无论如何,该项目不会像我一开始想要的那样高度可用。所以我决定制作一个鼠标,它使用一些独特的方式来检测运动。

就个人而言,我最喜欢用磁铁做实验,而且非常令人满意。此外,我在以前的项目中使用过带有电子设备的磁铁。

第 5 步:使磁铁有用

 
 
 
 
pYYBAGNkXICADRftAAJNs7PiYAo186.png
 
1 / 4
 

为了使这个磁铁有用,我必须将磁场转换为电信号,为此我们需要使用霍尔效应传感器。确切地说,我将使用 49E 线性霍尔效应传感器。

该传感器会将磁场强度转换为模拟电压,稍后我们可以使用微控制器读取该电压。

经过几次实验并使用磁铁和霍尔效应传感器后,我发现 2 个磁铁之间的距离合适,当我穿过它们时,霍尔效应传感器的值会不断变化。这非常重要,因为如果没有这种值的变化,检测运动是完全不可能的。

在我的例子中,距离是 3 毫米,对您来说可能会有所不同,因为霍尔效应传感器的值取决于磁铁的直径、厚度和材料。

第 6 步:构建磁性鼠标垫

 
 
 
 
poYBAGNkXIKAHAEhAAE5VYp1edg678.png
 
1 / 5
 

我在 Fusion 360 中设计了一个可以嵌入 49 个磁铁的垫子,这给了我们 7 行和 7 列,每个磁铁之间的距离是 3mm。49只是一个任意数字,可以增加磁铁的数量来增加鼠标垫的尺寸。

下一步是 3d 打印。并将磁铁放置到位。只需确保将磁铁放置在所有北极或南极都面向 u 的位置,这将确保我们有一个单极表面,这将使我们更容易检测运动。

注意:对我来说,将磁铁放置在正确的位置是一项艰巨的任务,因为强磁场会使磁铁相互坍塌。所以为了让它不那么乏味,我不得不用一些胶带把它们暂时固定在适当的位置。

 

第 7 步:编码器类比

 
 
 
 
pYYBAGNkXIWAJZ9rAAFhLKE9XIU809.png
 
1 / 4
 

通过这种当前设置,我们可以看到在磁单极子表面上导航的逻辑

这个想法受到旋转编码器机制的极大启发。如果您以前使用过旋转编码器机构,您就会知道它们是根据相位差原理工作的。来自编码器的任一信号将滞后或超前,通过使用此相位差,我们可以确定我们是顺时针还是逆时针方向转动编码器。我在描述中放置了一个链接,您可以在其中了解有关旋转编码器的更多信息。

现在,类似地,我们将使用 4 个具有不同相位的单个,其中两个用于检测左、右,另外两个用于检测上、下。

注意:编码器如何工作

第 8 步:找出霍尔效应传感器的运动和方向

 
 
 
 
pYYBAGNkXIiAG6JoAAC-eqw5q30578.png
 
1 / 4
 

起初,很难注意到或有点难以想象我们如何使用磁铁实现编码器类比。但是看看它们是如何工作的还是很有趣的。

首先,绘制出焊盘上所有磁铁的磁场。当我们将传感器扫过网格时,这应该会给我们一个近似正弦波,其中正弦波的顶峰是霍尔效应传感器读取的最大磁场,底部波谷是霍尔读取的最小磁场效应传感器。

现在有了这个霍尔效应传感器值,我们可以通过比较过去和现在的读数来找到霍尔效应传感器的运动和方向。

第 9 步:使用单个传感器的问题

 
 
 
 
pYYBAGNkXI2AYMCYAAbN_NXxIBY658.png
 
1 / 3
 

我刚才说我们可以通过一个传感器找到霍尔效应传感器的方向和运动。因此,很容易假设我们只需使用 2 个传感器就可以找到所有四个方向,以及为什么兄弟使用编码器机制。

但这就是事情变得棘手的地方。

如果我将两个传感器固定在同一平面上并开始移动平面,您可以看到霍尔效应传感器的值都发生了变化,无论是从左到右还是从上到下。这使得确定鼠标确切移动的方向变得非常复杂。

为了解决这个问题,我将添加另一组霍尔效应传感器。我们将使用其中两个来检测左右运动,其余两个用于检测上下运动。

第 10 步:添加更多对霍尔效应传感器

 
 
 
 
poYBAGNkXJCAB8eCAACde1kWoRs797.png
 
1 / 6
 

这组额外的传感器将在读数中产生偏移,如果您看到左右传感器一起读数,当我左右移动鼠标时,它们中的任何一个都会领先或落后。确切地说,这也适用于 up 和 down 。我们也可以使用单个传感器来做到这一点。

有趣的是,相移仅发生在一组传感器上,当平面沿单个方向(上/下或左/右)移动时,读数具有相移,而对于剩余的一组传感器, [理想情况下]不会发生相移。

因此,通过以这种方式布置传感器,我们可以检测到用于在屏幕上向各个方向移动鼠标的所有 4 个方向。

如果您觉得难以理解,我建议您下载 CAD 模型并自己尝试。

第 11 步:BLE 鼠标的电子设备

 
 
 
 
poYBAGNkXJKASXVlAAFpxvYix88950.png
 
1 / 3
 

不管怎样,既然鼠标的运动已经弄清楚了,剩下的电路就很容易了!

只需为 esp32 添加一些按钮、电池和充电电路。您可以查看电路图以更好地理解(这些电路大部分用于我之前的项目中)。

 

第 12 步:使用 PCBway 制造 PCB

 
 
 
 
poYBAGNkXJWAHMH5AAKWdVTwjQY434.png
 
1 / 4
 

一旦电路和PCB布局准备就绪。我发送了用于制造的 Gerber 文件,PCBway慷慨地赞助了这个项目。

因此,如果您的项目需要定制 PCB,他们提供 10 个定制 PCB,价格低至 5 美元,并且您可以为您的 PCB 选择各种定制,例如阻焊层、丝层和表面光洁度的颜色。在您的第一个订单中,您将获得 5 美元的优惠券!因此,基本上,您只需在第一个订单期间支付运费。因此,请查看描述中的链接以访问他们的网站。

一周后,我收到了我的多氯联苯。除了 PCB,我还收到了一个闪亮的铝模板,便于焊接。

第 13 步:组装和焊接

 
 
 
 
poYBAGNkXJqARgyDAASH5ZyG4Uk644.png
 
1 / 6
 

现在,是采购组件的时候了,由于某种原因,这个项目在获取组件方面遇到了很多问题,有一些在运输过程中丢失了,还有一些在定制中停留了太久。无论如何,我想尽快完成这个项目,所以我将不使用那些剩余的组件。

注意:出于同样的原因,我没有包含该项目的 Gerber 文件。但无论如何,我用更容易/更容易获得的组件更新了电路图。所以,我很快也会尝试重建 PCB。

第 14 步:对 ESP32 BLE 鼠标进行编程

 
 
 
 
pYYBAGNkXJ-AaHRiAAQrxwaLJXM862.png
 
1 / 3
 

对于代码,第一步是清理信号。

在这里,您可以使用不同类型的滤波器和数字信号处理方法来清除噪声。但为了保持简单和快速,我将通过平均信号来平滑信号。然后我使用了旋转编码器示例代码并对其进行了一些修改,以使用所有四个传感器来检测运动。老实说,这是我一段时间以来写的最糟糕的代码之一,因为在拖了这个项目太久之后我失去了耐心。

无论如何,在为按钮添加一些 esp32 BLE 库和附加代码之后,我们就完成了!

只需上传代码就可以了。

 

第 15 步:测试 BLE 鼠标

 
 
 
 
pYYBAGNkXKGALeOPAADgLvh3fpg017.png
 
1 / 5
 

好吧,我绝对认为运动检测会更好。但至少它有效!和其他功能,如左键单击、右键单击滚动单击效果很好。[我会尽快更新视频]

第 16 步:最后的想法

 
 
pYYBAGNkXKiAAyulAAee4JDghhw655.jpg
 

这个项目无论如何都不完美。我会说它也只有 50% 的工作/准确度,我不确定是否可以像实际鼠标一样进行平滑移动,但我可以做几件事。首先我可以回过头来复习一下我对滤波器和数字信号处理的了解,让来自传感器的信号更好,使鼠标移动更流畅。或者其次,我可以尝试其他类型的传感器,我目前正在寻找替代品,如 IR 传感器、激光等。

在评论部分让我知道您对此的看法。

我希望至少这篇文章能给你一些新的想法和不同的方法来构建鼠标。请务必阅读更多即将发布的教程,并确保查看我的Youtube 频道以获取更多类似内容。

 


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

评论(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:'带有磁性鼠标垫的基于ESP32的BLE鼠标',//标题 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);