×

使用Simulink和Arduino的红外接近传感器

消耗积分:2 | 格式:zip | 大小:0.13 MB | 2022-12-09

分享资料个

描述

介绍

第一部分中,我们构建了 Sharp IR 传感器的模型并了解了它的工作原理。我们还实施了一个软件模型以在 Arduino 上使用范围测量。在这一部分中,我们将添加一个 Arduino 块,它可以在由 Arduino 数字输入之一触发时调用中断服务例程 (ISR)。

中断在某些情况下很有用,因为它们可以响应特定的硬件事件,而无需不断检查输入状态的代码,从而减少处理器的负载。当处理器必须快速响应事件时,它也很有用。在这里,我们将使用中断来响应当物体离红外传感器太近时发生的事件。在下一节中,我们将在机器人接近某物时将其用作警报信号。例如,机器人可以选择后退、转弯或只是停止。

此处的重点将放在如何使用中断块上,但包含有关其工作原理的注释以更好地理解它,以防有人想要修改它或继续开发。

项目文件

要使用该库,请在下载提交后解压缩文件。使用 MATLAB 转到 blocks 文件夹并键入. 这将为您的 Simulink 安装编译块。如果编译失败,请检查您是否选择了带.mex arduino_interrupt.cmex -setup

先决条件

所需硬件

与第 1 部分相同:

  • Arduino Mega 2506 开发板
  • 带电线的小面包板
  • 1 个夏普红外传感器 GP2Y0A02YK0F
  • 1 个电容 10uF – 100uF
  • 1个电容1uF
  • 1 个电容 200 nF
  • 1 个电阻 10 欧姆

第 2 部分的新组件

  • 1 个 LM311N 比较器
  • 2个10k欧姆电阻
  • 1个10k欧姆电位器

Arduino 中断基础知识

arduino 文档包含关于如何使用中断的很好的概述和建议还有一张表将不同的中断编号映射到连接引脚,适用于不同的板,在您自己的项目中使用中断时需要查阅。

在这部分中,我们将使用中断 0,它连接到 arduino mega 2560 板上的数字引脚 2。当中断被触发时,中断服务程序被调用。当相应引脚上的电压从高电平下降到低电平(下降)或从低电平变为高电平(上升)时,可以触发中断。arduino mega 还有两种触发模式,low 和 change。有关更多详细信息,请参阅文档。

要使用中断,您必须将中断服务程序附加到中断。这就是新区块要做的。由于中断服务例程会中断其他代码,因此通常建议在其中做的事情越少越好。与在服务例程中进行复杂计算相比,仅向主循环发送有关事件的信号并让它处理它通常更好。

Simulink 库和文件

让我们来看看新的区块。下载 zip 文件 [链接] 并将其解压缩到一个文件夹中。在 MATLAB 中,转到文件夹并运行 setup.m 文件,然后键入 MyArduinoLib。这个库应该打开:

 
pYYBAGOSiTiARxK2AABdcAjm4YA344.png
 

库中的块可用于将硬件中断映射到将作为中断服务例程执行的子系统。该块有一个输入端口,称为 simIRQ。该输入端口可用于仿真,以模拟硬件中断。对于在目标上执行,它没有任何功能。输出端口是函数调用信号。它应该连接到一个称为子系统的函数,如下面的任务 2 所示。

如果双击该块以打开遮罩,它包括四个设置。中断号和引脚号是威廉希尔官方网站 板设置,根据文档,它们必须与威廉希尔官方网站 板匹配。模式决定输入引脚上的什么事件将触发中断,上升、下降、变化或低。最终设置启用和禁用输入端口。

对于有兴趣的人,这里有一个简短的描述,它属于包含新块的库的块文件夹中的文件。

  • MyArduinoLib.slx——库文件
  • slblocks.m – 描述库的 MATLAB 文件。如果此文件存在,库将包含在 Simulink 库浏览器中。
  • arduino_interrupt.c – 这是一个 c 文件 s-function,用于实现此块在仿真期间将执行的操作。此文件编译为:mex arduino_interrup.c(之前运行 mex -setup)。这必须在您使用库之前完成。
  • arduino_int_lib.tlc——这个文件告诉代码生成器要为这个块生成什么样的代码。
  • arduino_interrupt.tlc – 由上面的文件取消包含系统头文件。

如果您有兴趣,请研究 arduino_interrupt.c 和 arduino_interrupt.tlc 的实现以了解它们的作用。您也可以根据需要更改行为。

任务 1 – 修改对象模型并添加施密特触发器

为了使模拟比文章 1 运行得更快,我们将在此处使用比上一篇文章中更小的对象模型。但请返回更详细的工厂并对其进行测试,以确保简化模型足够。在构建任何硬件之前制作系统模型是一种很好的基于模型的设计实践。这意味着在将时间和金钱花费在硬件上之前,想法或概念会通过模拟进行测试。

新的完整系统模型名为 system_model.slx,如下所示。

 
poYBAGOSiTyAVJ7TAABaR5t2918121.png
 

正如您在上面的模型中看到的,有传感器模型、一个 arduino 板子系统和一个名为 SchmittTrigger 的块。在第一篇文章中,我们看到传感器会针对不同的距离提供不同的电压。这意味着我们需要一个能够在特定距离(电压)触发的威廉希尔官方网站 。当障碍物位于触发距离附近时,为了使其稳健并避免多次中断,我们实施了施密特触发器。这里它是在 MATLAB 函数块中用 MATLAB 代码实现的。

Arduino 子系统有两个输入,A0 用于模拟输入,D2 用于触发中断的数字输入。

 
pYYBAGOSiU2AfxLnAABImpbSjjs272.png
 

有一个采样子系统将电压转换为可以在软件中读取的数字,还有一个时间表子系统。调度子系统将调用软件中的函数。阶跃函数定期调用,中断在施密特触发器触发时调用。需要这种调度才能通过中断模拟该系统的异步行为。

任务 2 – 构建软件模型

好的,系统已经建模,是时候实现稍后应该作为软件在目标上运行的部分了。模拟输入只是与步进函数中的距离进行比较,如果障碍物太近,我们会在数字输出引脚上发出一个信号。输出引脚可以连接到外部 LED(作为练习实现)。如果没有检测到障碍物,则发送零。中断服务例程在每次被施密特触发器调用时切换数字输出。

 
poYBAGOSiVCAYrj5AABBNkuXotA031.png
 

请注意,软件模型是作为库块实现的。这是因为我们稍后将在线束模型中使用相同的块在目标上运行。

运行模拟给出以下结果。

 
poYBAGOSiWiAeT8JAACBh0gPCdk689.png
 

青色线是实际距离,并且在不断减小。品红色线是中断输出的结果,黄线是与恒定距离比较的阶跃函数。如果检查模型的阶跃函数,您会发现它将在 250 mm 处触发。放大绘图显示,由于实施和采样,它实际上是在输入为 245 mm 时触发的。您可以更改此值并查看洋红色线将在不同位置触发。

有趣的是,当障碍物离得更近时,它会再次触发。这是因为我们在上一篇文章中了解到传感器的工作原理。它的非线性行为意味着当障碍物太近时,传感器输出电压会降低,而在我们的实施中,它似乎比实际更远。

任务 3 – 构建施密特触发器威廉希尔官方网站

如下图所示,在上一篇文章中构建的过滤器旁边构建施密特触发器。您可能需要稍后调整电位器以确保施密特触发器正确触发。

任务 4 – 软件线束模型并在目标上运行

用于在目标上运行软件的软件线束模型如下所示。

 
poYBAGOSiXGAWR-tAABIG92Tvzk526.png
 

模拟输入块读取引脚 0,A0,这是我们的传感器值。左下方是我们新的中断块。右边的块写入数字引脚 12 和 13。此模型中有两个额外的块可能需要一些解释。第一个是函数调用生成器。这用于定期触发阶跃函数。需要速率转换块是因为信号源块(中断服务例程)是异步的,而数字输出块与周期性采样时间同步。

现在尝试在目标上运行它!

建议的实验

  • 修改并试验施密特触发器以获得所需的阈值。不要忘记更新模型以匹配行为。
  • 使用第 1 部分中的详细模型进行测试。小模型是否足够?有什么不同吗?

概括

本文展示了一个示例,说明如何在仿真中使用异步块并将其作为中断服务例程在目标上运行。这对于节省目标执行时间和对事件做出反应很有用。

在下一篇文章中,我们将在移动机器人上使用它。首先,我们将为机器人设置一个模拟器来测试实现,然后我们在真实机器人上运行软件部分。

有用的链接


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

评论(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:'使用Simulink和Arduino的红外接近传感器',//标题 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);