×

使用MPU 9250的磁力计来定位小型3轮汽车

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

刘军

分享资料个

描述

对于这个项目,我开始使用 MPU-9250 中包含的磁力计来定位一辆小型 3 轮汽车,以便让它沿着 12 英尺乘 12 英尺见方的设定路径行驶,并使用 IR距离传感器,以防止汽车撞墙。完成此任务所需的技能包括:

  • 用 C 编写代码、调试、了解德州仪器的 Code Composer Studio、使用中断服务例程和 SPI 通信。
  • 阅读数据表,寄存器映射
  • 焊锡丝、表面贴装元件、排针

简介和硬件连接

我解释了汽车的设置和使项目工作的组件。

项目车使用德州仪器 F28379D Launchpad XL 来处理处理。还使用了 MPU-9250、直流电机和几个IR 距离传感器下面显示了它们如何连接的进一步说明。附在绿板上的蜂鸣器也在项目期间使用。

poYBAGNy7_WAE5YFAAqq7oDzrps581.jpg
 

上面看到的绿线将来自 IR 距离传感器的信号带到 ADC。红线和黄线允许与 TI Launchpad 进行通信。IR 传感器使用 ADCD 中断程序运行,设置为每 4 毫秒采样一次。

pYYBAGNy8AKANxUTAA0szqCli18094.jpg
 

绿线来自连接在绿板另一侧的 1x3 插头引脚。每个接头上的中间引脚是电源,底部引脚是接地。电源和接地连接焊接在威廉希尔官方网站 板的背面,如下所示。

pYYBAGNy8AmAZTPQAA4KlK6i8Fw899.jpg
 

短的黑线是红外距离传感器的地线,穿过威廉希尔官方网站 板的红线是红外传感器的电源,焊接在威廉希尔官方网站 板边缘 2x5 孔区域的三个大孔上方.

MPU-9250 使用 GPIO 引脚 63、64、65 和 66 连接到 Launchpad。GPIO 63 连接到 SPI 串行数据输入(MPYU-9250 上的 SDA),GPIO 64 连接到 SPI 串行数据输出( AD0),GPIO 65 连接到串行时钟(SCL),GPIO 66 连接到片选(NCS)。MPU-9250 还可以使用 I2C 进行通信,其中 GPIO63/SDA 为 I2C 串行数据端口,GPIO64/AD0 为 I2C 从地址最低有效位,GPIO65/SCL 为 I2C 串行时钟。就本项目而言,SPI 将是 MPU-9250 唯一感兴趣的通信方法,但如果需要也可以使用 I2C。

电机从 QEP A 和 B 接头连接到 Launchpad,其中 QEP A 对应于左侧电机,QEP B 对应于右侧。左侧电机的 PWM 或占空比连接到 GPIO 3,右侧电机连接到 GPIO 2。蜂鸣器连接到 GPIO16。

下图显示了磁力计的轴。为了了解磁力计的工作原理,我不得不在通过 SPI 与芯片通信的程序运行时用手小心地转动整辆汽车。我将汽车在​​ 3 个轴上分别旋转至少 360 度,以查看不同的 X、Y 和 Z 值如何随汽车的位置而变化。感谢 Evan Hall 创建的代码,我在下面和这个项目的团队部分承认了他,我能够将磁力计的 X 和 Y 测量值转换为 0 到 360 度之间的方位角。这部分代码在第 727 到 738 行。

poYBAGNy8AyAcfVRAAAYfBvA3oM161.jpg
 

本项目磁力计与SPI通信,SPI的传输命令位于ADCD中断函数中,设置为每4ms超时一次。因此,在 SPIB 中断功能中,磁力计每 4ms 以及通过 SPI 采样一次。

MPU-9250 磁力计的问题是,当靠近金属或电气设备时,会有很多噪音可以甩掉罗盘角的方位。即使是静止不动,角度也有10度左右的急速波动。在地图上应该是北方的地方和磁力计确定的北方之间似乎也有大约 20 度的偏移。为了解决这个问题,我为罗盘角度创建了一个 20 点的平均值。它显着减少了角度的波动,但由于磁力计的灵敏度,干扰仍然存在。

平均滤波器的结果使汽车的定位更加准确,但由于干扰仍然存在误差。过滤器的 0/360 度点也会导致问题,因为对接近 360 度以下和接近 0 度以上的角度进行平均也会导致平均角度被抛出。因此,我尽量避免在汽车旋转过程中靠近这个点。

项目说明

我希望这辆车完成的目标是从某个 12x12 平方英尺的正方形开始,并开始面向东方。汽车将播放一首包含单个音符的歌曲,然后使用磁力计控制其方向向西旋转,然后沿负 X 方向向最西面的墙壁行驶。从那里,使用面向汽车前部的电机编码器或红外传感器,它会停下来然后转向南方,并沿着墙壁沿负 Y 方向行驶,转向避开它并试图保持前进。电机编码器跟踪车轮的旋转,以根据提供的初始条件识别汽车的位置。

到达广场的左下角,它会在一个音阶上演奏一个单音的第二首歌曲,然后转向东方,沿着底墙,然后到达广场的右下角,在那里它会播放第三首歌曲/音符,然后转向广场的中间。一旦它靠近,它会在前进和后退时自行转动,以到达正方形中的点 (6,6),如果左下角是 (0,0)。比例控制将用于控制转弯的速度,以在行驶状态下到达每个方向并保持在目标上。

为了让汽车执行所需的操作,我在 SPI 中断函数中创建了一个状态机。在计算罗盘角度并对其进行平均后,状态机确定汽车正在行驶的路径的哪一部分。在第一个状态,用变量“state”标识,变量设置为 10,汽车将播放一个音符的第一首歌,表明它正在启动,并旋转到对应于向西行驶的角度朝向墙壁。一旦正确定向,汽车就会进入状态 20 并向墙壁移动。

一旦它检测到墙壁或电机编码器确定它已经接近墙壁,它将进入状态 30 并转向南方。转向南后,车子进入40状态,向广场的南墙方向行驶。朝向汽车右侧的红外传感器将防止汽车撞到墙上。前 IR 传感器将确定汽车是否足够靠近南墙,或者一直在计算汽车在正方形中的位置的编码器将确定是否已达到指定的 Y 坐标,状态将变为 50。

在状态 50 时,将播放另一个音符的第二首​​歌曲,根据磁力计的测量结果,汽车将转向东方。然后它将进入状态 60 并沿着南墙行驶,使用右侧的 IR 传感器防止它再次撞到墙上。到达第三个拐角时,由前面的红外传感器达到足够高的电压或编码器确定 X 坐标,汽车将进入状态 70。在这里,它播放第三个音符/歌曲,并使用磁力计将自己指向广场的中心。

状态 80 是汽车向广场中心行驶的地方,一旦接近,将左右转向并向后移动,使汽车前部朝北并定位在坐标 (6,6) 处。到达这一点后,汽车进入状态 90,播放第四首也是最后一首歌曲的最高音,表示程序结束。

项目最终结果

项目运行视频。

上面的视频显示了使用下面的代码运行的项目。它能够根据 MPU-9250 磁力计的读数转动,但由于它旋转得如此之快,车轮打滑,编码器无法准确判断汽车转动了多远。因此,汽车跟踪的 X 和 Y 坐标也不准确,这会干扰状态机从旋转状态到行驶状态的正确进程。在转弯状态下对转弯速度的比例控制似乎确实提高了转弯的准确性,但尝试使用类似的方法使汽车在行驶状态下保持在轨道上,使得汽车在状态 70 之后无法运行。

下一步

尝试使用 MPU-9250 磁力计作为控制汽车方向的一种手段,这表明它可能不是最好的方向控制形式,因为我进行了测试的机电一体化实验室中金属和电子设备的干扰量很大虽然我确实使用比例控制来控制转动速度,但可以实施 PID 控制器的更多方面,以进一步提高每次转动的精度,并防止在电机编码器跟踪全局坐标的方式中产生错误的打滑。状态机在确定行驶状态在哪里结束时也可能是幼稚的,并且改进如何确定部分路径的终点也将提高汽车行驶的准确性。

我欢迎任何人尝试改进这个项目的状态机部分,如果你有代码可以告诉我,我可以尝试看看它是如何工作的!

致谢

我要感谢伊利诺伊大学厄巴纳-香槟分校的 Dan Block 教授在整个学期中的所有帮助,尽管大流行持续存在困难,但他制作了这门 SE 423 - 机电一体化课程,这对每个人来说都是一次很棒的经历。尽管我的最终项目没有像我希望的那样工作,但尝试朝着我的项目目标努力并解决出现的问题仍然很有趣。他提供了用于该项目的大部分代码,包括初始化和几个函数。他为该项目开发了绿板,并提供了该项目中使用的许多传感器和设备。

我还要感谢 Evan Hall 根据磁力计读数计算和角度的代码。他的代码对于理解如何有效地使用磁力计非常有帮助。


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

评论(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.obk20.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:'使用MPU 9250的磁力计来定位小型3轮汽车',//标题 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.obk20.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);