1 使用Arduino和LM393传感器测量移动机器人-德赢Vwin官网 网
×

使用Arduino和LM393传感器测量移动机器人

消耗积分:0 | 格式:zip | 大小:0.03 MB | 2022-12-15

分享资料个

描述

LM393 速度传感器模块 (H206)

在开始项目的电路图和代码之前,让我们先了解一下LM393速度传感器模块,因为它在项目中起着至关重要的作用。H206速度传感器模块由红外光传感器和LM393电压比较器IC组成,故命名为LM393速度传感器。该模块还包括一个网格板,该网格板必须安装在电机的旋转轴上。所有组件都在下图中标出。

pYYBAGOYD4qAVb-AAABQes7kVYg24.jpeg
 

红外光传感器由红外发光二极管和光电晶体管组成,由一个小间隙隔开。如上图所示,整个传感器设备被放置在一个黑色的外壳中。栅板由凹槽组成,板设置在红外光传感器的间隙之间,使传感器能够感应到栅板中的间隙。栅板中的每个缝隙在通过缝隙时都会触发IR传感器;然后使用比较器将这些触发器转换为电压信号。比较器使用 ON Semiconductor 的 LM393 IC。模块有3个引脚,其中2个用于给模块供电,1个输出引脚用于统计触发次数。

H206 传感器安装

poYBAGOYD42AQ94aAACPT_LYKHk003.jpg
 

安装这些类型的传感器有点棘手。只能安装在轴两侧突出的电机上。轴的一侧连接车轮,而另一侧用于安装网格,如上图所示。

由于车轮和车轮连接在同一轴上,都以相同的速度旋转,因此通过测量车辆速度,我们可以测量车轮的速度。在传感器可以计算通过的间隙数量之前,请确保网格板中的间隙通过红外传感器。只要满足规定条件,也可以自行设置机械装置安装传感器。红外传感器常用于许多机器人项目中,用于引导机器人了解障碍物。

上面显示的网格板有 20 个槽(网格)。这意味着传感器将发现车轮一整圈的 20 个间隙。通过计算传感器检测到的间隙数量,我们可以计算出车轮行进的距离,同样通过测量传感器发现的间隙的速度,我们可以检测出车轮的速度。在我们的机器人中,我们将此传感器安装在两个轮子上,因此我们也可以找到机器人的角度。但是,使用加速度计或陀螺仪可以更明智地计算旋转角度。在这里我们学习使用Arduino将加速度计与陀螺仪连接,并尝试使用它们来测量旋转角度。

示意图

速度和距离传感机器人的完整电路图如下所示。该机器人以Arduino Nano为大脑,两个用于车轮的直流电机由L298N H桥电机驱动模块驱动。操纵杆用于控制机器人的速度和方向,两个速度传感器H206用于测量机器人的速度、距离和角度。然后,测量值显示在 1602 LCD 模块中。连接到 LCD 的电位器可用于调节 LCD 的对比度,电阻器用于限制流向 LCD 背光的电流。

pYYBAGOYD5KAMzymAAB_wJgl0Mo198.jpg
 

整个电路由7.4V锂电池供电。7.4V 电源提供给电机驱动模块的 12V 引脚。然后,电机驱动模块上的稳压器将 7.4V 转换为稳压 + 5V,为 Arduino、LCD、传感器和操纵杆供电。

电机由 Arduino 数字引脚 8、9、10 和 11 控制。由于还必须控制电机的速度,因此我们应该向电机的正极提供 PWM 信号。因此,我们有引脚 9 和 10,它们都是 PWM 引脚。操纵杆的 X 和 Y 值分别使用模拟引脚 A2 和 A3 读取。

我们知道 H206 传感器在检测到网格中的间隙时触发。由于无法始终准确地读取这些触发器来计算正确的速度和距离,因此触发器(输出)引脚连接到 Arduino 板的外部中断引脚 2 和 3。将整个电路组装在底盘上,按照说明安装速度传感器。连接完成后,机器人将如下图所示。

poYBAGOYD5WAM4UEAADu0Shra7U322.jpg
 

硬件部分已经完成。下面让我们深入了解如何测量机器人的速度、距离和角度,然后进入编程部分。

使用 H206 传感器测量速度背后的逻辑

从传感器安装设置中,您应该知道 H206 传感器仅测量网格中存在的间隙。安装时,确保车轮(应测量其速度)和挡板以相同的速度旋转。就像这里一样,由于我们将轮子和轮子安装在同一根轴上,它们都会以相同的速度旋转。

在我们的设置中,我们为每个车轮安装了两个传感器来测量机器人的角度。但如果您的目标只是测量速度和距离,我们可以将传感器安装在任何车轮上。传感器的输出(触发信号)最常连接到微控制器的外部中断引脚。每次检测到网格中的间隙时,都会触发中断并执行 ISR(中断服务程序)中的代码。如果我们可以计算出两个这样的触发器之间的时间间隔,我们就可以计算出车轮的速度。

在 Arduino 中,我们可以使用 millis() 函数轻松计算出这个时间间隔。由于设备上电,这个毫秒函数会每毫秒增加1。因此,当第一次中断发生时,我们可以将millis()的值保存在一个哑变量中(比如代码中的pevtime),然后当第二次中断发生时,我们可以计算出从millis()中减去所需要的时间为 pevtime 值。

公式:

所用时间=当前时间-上一次

timetaken = millis()-pevtime; //以毫秒为单位的时间

一旦我们计算了使用的时间,我们可以使用以下公式简单地计算 rpm 的值,其中 (1000 / timetaken) 给出 RPS(每秒转数)并将其乘以 60 以将 RPS 转换为 RPM 每分钟转数)。

公式:

rpm=(1000/timetaken)*60;

计算出速度后,我们可以使用下面的公式来计算车辆的速度,前提是我们知道车轮的半径。

公式:

速度 = 2π × RPS × 车轮半径。

v = radius_of_wheel * rpm * 0.104

请注意,上述公式用于计算速度,单位为 m/s。如果要使用 km / hr,请将 0.0104 替换为 0.376。如果您想知道如何获得 0.104 的值,请尝试简化公式 V = 2π × RPS × 车轮半径。

即使霍尔传感器用于测量旋转物体的速度,也使用相同的技术。但是H206传感器有一个缺陷,网格板有20个插槽,所以用来测量两个插槽间隙的时间会使单片机过载。因此,我们只测量车轮完全旋转时的速度。由于每个间隙都会产生两次中断(一个在间隙开始,另一个在间隙结束),我们将总共获得 40 次中断,以使轮子完成一个完整的旋转。所以我们在实际计算轮速之前等待 40 次中断。代码如下。

代码:

如果(旋转> = 40)

{

timetaken = millis()-pevtime; //以毫秒为单位的时间

rpm=(1000/timetaken)*60;//计算转速的公式

pevtime = 毫秒();

旋转=0;

}

这种方法的另一个缺点是速度值不会降到零,因为中断会一直等待车轮完成一圈来计算转速值。通过添加一个简单的代码来监控两个中断之间的时间间隔,可以轻松克服这个缺点。如果它超过正常值,那么我们可以将 rpm 和速度值强制为零。链接 在下面的代码中,我们使用变量 dtime 来检查时间差。如果超过 500 毫秒,则将速度和 rpm 值强制为零。

代码:

/*如果车辆停止则降为零*/

if(millis()-dtime>500) //500ms 内没有找到 inetrrupt

{

转速= v = 0;// 使 rpm 和速度为零

dtime=毫秒();

}

测量车轮行驶距离背后的逻辑

我们已经知道,当轮子完成一个完整的旋转时,Arduino 会感应到 40 次中断。因此,对于轮子每转一圈,显然轮子行进的距离等于轮子的周长。由于我们已经知道车轮的半径,我们可以使用以下公式轻松计算覆盖距离。

距离 = 2πr * 转数

距离 = (2*3.141*radius_of_wheel) * (left_intr/40)

在使用公式 2πr 计算车轮周长的情况下,然后乘以车轮的转数。

测量机器人角度背后的逻辑

确定机器人角度的方法有很多。加速度计和陀螺仪通常用于确定这些值。但另一种便宜的方法是在两个车轮上都使用 H206 传感器。这样,我们就可以知道每个轮子的转数。下图说明了如何计算角度。

pYYBAGOYD5mAACnjAAA98zlsYP4659.jpg
 

机器人初始化时,其所面对的角度为 0°。从那里开始,当它向左旋转初始化机器人时,它所面对的角度被认为是 0°。从那里它向左旋转,角度负增加,如果它向右旋转,角度增加正。为了便于理解,让我们考虑 -90 到 +90 的范围,如图所示。在这种布置中,由于两个轮子的直径相同,如果任一轮子完全旋转,我们将以 90° 的角度转动。

例如,如果左轮完成一圈(80 次中断),机器人将向左转 90°,如果右轮完成一圈(80 次中断),机器人将向右转 90°。现在我们知道,如果Arduino在一个轮子上检测到80次中断,那么机器人已经转动了90°,我们可以通过正(右)或负(左)来判断机器人是在旋转。所以可以用下面的公式来计算左右角:

公式:

int angle_left = (left_intr % 360) * (90/80) ;

int angle_right = (right_intr % 360) * (90/80) ;

90 是中断 80 时所覆盖的角度。结果值乘以中断次数。我们还使用了 360 的模数,因此得到的值不超过 36。一旦我们计算了左右角,我们可以通过从右角中减去左角来简单地获得机器人所面对的有效角度。

角度 = 角度右 - 角度左;

Arduino编程

我们通过为两个电机定义数字 I/O 引脚来启动程序。请注意,我们还必须控制电机的速度,因此必须使用 Arduino 上的 PWM 引脚来控制电机。此处使用引脚 8、9、10 和 11。

代码:

#define LM_pos 9 // 左电机

#define LM_neg 8 // 左电机

#define RM_pos 10 // 右电机

#define RM_neg 11 // 右电机

#定义joyX A2

#definejoyY A3

要测量行驶的速度和距离,我们需要知道车轮的半径,测量值以米为单位输入,如下所示。对于机器人,半径为 0.033 米,但根据您的机器人,可能会有所不同。

代码:

浮动radius_of_wheel = 0.033;//测量你的轮子的半径并在这里输入厘米

在 setup 函数中,我们将所有值初始化为零,然后在 LCD 上显示一个简短的文本。我们还初始化了串行监视器以进行调试。然后我们提到速度传感器 H206 连接到引脚 2 和 3 作为外部中断。这是检测到中断的地方,ISR 函数 Left_ISR 和 Right_ISR 将相应地执行。

代码:

无效设置()

{

旋转 = rpm = pevtime = 0;//将所有变量初始化为零

序列号.开始(9600);

lcd.begin(16, 2); //初始化16*2 LCD

lcd.print("机器人监视器"); //介绍消息第 1 行

lcd.setCursor(0, 1);

lcd.print("-CircuitDigest"); //介绍消息第 2 行

延迟(2000);

lcd.clear();

lcd.print("Lt: Rt:");

lcd.setCursor(0, 1);

lcd.print("S:D:A:");

pinMode(LM_pos,输出);

pinMode(LM_neg,输出);

pinMode(RM_pos,输出);

pinMode(RM_neg,输出);

数字写入(LM_neg,低);

数字写入(RM_neg,低);

attachInterrupt(digitalPinToInterrupt(2), Left_ISR, CHANGE); //Left_ISR在左轮传感器被触发时调用

attachInterrupt(digitalPinToInterrupt(3), Right_ISR, CHANGE);//右轮传感器触发时调用Right_ISR

}

在 Left_ISR 函数代码中,我们简单地添加了一个名为 left_intr 的变量,稍后将使用该变量来测量机器人的角度。在 Right_ISR 内部,我们做同样的事情,但除此之外,我们还在此处计算速度。每次中断都会增加变量旋转,然后使用上面的逻辑来计算速度。

代码:

无效 Left_ISR()

{

left_intr++;延迟(10);

}

无效 Right_ISR()

{

right_intr++; 延迟(10);

旋转++;

dtime=毫秒();

如果(旋转> = 40)

{

timetaken = millis()-pevtime; //以毫秒为单位的时间

rpm=(1000/timetaken)*60;//计算转速的公式

pevtime = 毫秒();

旋转=0;

}

}

在主循环函数中,我们监控操纵杆中 X 和 Y 的值。根据移动操纵杆的值,我们相应地控制机器人。机器人的速度取决于操纵杆的推动距离。

代码:

int xValue = 模拟读取(joyX);

int yValue = 模拟读取(joyY);

int 加速度 = 地图 (xValue, 500, 0, 0, 200);

如果 (xValue<500)

{

类比写入(LM_pos,加速度);

模拟写入(RM_pos,加速度);

}

别的

{

类比写入(LM_pos,0);

模拟写入(RM_pos,0);

}

如果(y值>550)

类比写入(RM_pos,80);

如果(y值<500)

类比写入(LM_pos,100);

以下函数将帮助用户移动机器人并检查获得的值是否符合预期。最后,我们可以用上面的逻辑计算出机器人的速度、距离和角度,并用下面的代码在LCD上显示出来。

代码:

v = radius_of_wheel * rpm * 0.104;//0.033 是车轮的半径,以米为单位

距离 = (2*3.141*radius_of_wheel) * (left_intr/40);

int angle_left = (left_intr % 360) * (90/80) ;

int angle_right = (right_intr % 360) * (90/80) ;

角度 = 角度右 - 角度左;

lcd.setCursor(3, 0); lcd.print(""); lcd.setCursor(3, 0); lcd.print(left_intr);

lcd.setCursor(11, 0); lcd.print(""); lcd.setCursor(11, 0);lcd.print(right_intr);

lcd.setCursor(2, 1); lcd.print(""); lcd.setCursor(2, 1);lcd.print(v);

lcd.setCursor(9, 1); lcd.print(""); lcd.setCursor(9, 1);lcd.print(距离);

lcd.setCursor(13, 1); lcd.print(""); lcd.setCursor(13, 1);lcd.print(角度);

测试 Arduino 机器人以测量距离、速度和角度

硬件准备好后,将代码上传到 Arduino 并使用操纵杆移动机器人。机器人的速度、距离和角度将显示在液晶屏上,如下图所示。

pYYBAGOYD6mAT5e_AADA4Z7PHVk482.jpg
 

在 LCD 上,术语 Lt 和 Rt 分别表示左中断计数和右中断计数。您会发现传感器检测到的每个间隙都会增加这些值。时间 S 表示机器人的速度,单位为米/秒,项 D 表示距离,单位为米。机器人的角度以0°显示为直线的终点,逆时针旋转为负,顺时针旋转为正。

希望大家喜欢这个项目,如果喜欢,还可以查看这篇关于轮速传感器的相关帖子享受阅读!

 


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

评论(0)
发评论

下载排行榜

全部0条评论

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

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"//www.hzfubeitong.com/m/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="https://m.elecfans.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:'使用Arduino和LM393传感器测量移动机器人',//标题 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.hzfubeitong.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);