原文:https://circuitdigest.com/microcontroller-projects/speed-distance-and-angle-measurement-for-mobile-robots-using-arduino-and-lm393-h206

使用Arduino和LM393速度传感器(H206)的移动机器人的速度,距离和角度测量

ARDUINO项目

经过**阿斯温斯·拉吉(Aswinth Raj)** 2019年1月16日修改
使用Arduino和LM393传感器(H206)的移动机器人的速度,距离和角度测量

机器人已开始慢慢进入我们的社会,以使我们的生活更简单。我们已经在英国的道路上找到了星际飞船(Starship)上的六个轮式送餐机器人,它们在平民之间巧妙地导航以到达目的地。导航到环境中的每个移动机器人都应始终了解其相对于现实世界的位置和方向。通过使用不同的技术(例如GPS,RF三角测量,加速度计,陀螺仪等),可以通过多种方法来实现这一目标。每种技术都有其自身的优势,并且自身是独一无二的。在本Arduino LM393速度传感器教程中,我们将使用简单易用的LM393速度传感器模块使用Arduino测量一些重要参数,例如速度,行进距离和机器人角度。有了这些参数,机器人将能够知道其现实状态并可以使用它进行安全导航。

Arduino是构建机器人的爱好者中最受欢迎的选择,从简单的线路跟随器到更复杂的自平衡或地板清洁机器人。您可以在"机器人技术"部分中检查所有类型的机器人。

我们将建造一个由锂电池供电的小型机器人,并使用操纵杆驱动它。在运行期间,我们可以测量机器人的速度,距离和角度,并将其实时显示在与Arduino连接的LCD显示屏上。该项目仅能帮助您测量这些参数,完成此操作后,您就可以根据需要使用这些参数来自动操作机器人。听起来很有趣吧?因此,让我们开始吧。

LM393速度传感器模块(H206)

在进入该项目的电路图和代码之前,让我们了解LM393速度传感器模块,因为它在项目中起着至关重要的作用。该H206速度传感器模块包括一个红外光传感器与一个LM393电压比较IC故名LM393速度传感器集成在一起。该模块还包括一个栅板,必须将其安装到电动机的旋转轴上。下图标记了所有组件。

所述**红外线传感器**包括一个IR LED和由小GAB分离的光电晶体管的。整个传感器装置如上图所示放置在黑色外壳中。栅格板由狭槽组成,该板以这样的方式设置在红外传感器的间隙之间:传感器可以感应栅格板中的间隙。栅板中的每个缝隙穿过缝隙时都会触发红外传感器。然后使用比较器将这些触发器转换为电压信号。比较器不过是安森美半导体的LM393 IC。该模块具有三个引脚,其中两个用于为模块供电,一个输出引脚用于计算触发次数。

H206传感器的安装


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

由于车轮和板连接到相同的轴,两者均以相同的速度旋转,因此通过测量板的速度,我们可以测量车轮的速度。确保栅格板上的缝隙穿过红外传感器,只有这样,传感器才能够计算已穿过的缝隙的数量。只要满足指定条件,您还可以提出自己的机械布置来安装传感器。红外传感器通常用于许多机器人项目中,以引导机器人注意障碍物。

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

DIY Arduino LM393速度传感器机器人电路图

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

完整的电路由7.4V锂电池为动力的。此7.4V提供给电机驱动器模块的12V引脚。然后,电机驱动器模块上的电压调节器将7.4V转换为可调节的+ 5V,该电压用于为Arduino,LCD,传感器和操纵杆供电。

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

众所周知,当检测到格栅板中的间隙时,H206传感器会产生触发信号。由于不应该总是准确地读取这些触发器来计算正确的速度和距离,因此两个触发器(输出)引脚都连接到Arduino板的外部中断引脚2和3。按照说明将整个电路组装在机箱上并安装速度传感器,连接完成后,我的机器人看起来如下图所示。您也可以在本页末尾观看视频,以了解传感器的安装方式。

现在,硬件部分已经完成,让我们进入如何测量机器人的速度,距离和单个性的逻辑,然后继续进行编程部分。

使用LM393速度传感器模块进行速度测量的逻辑

从传感器安装设置中,您应该了解到LM393速度传感器模块(H206)仅能测量栅板上的间隙。在安装时,应确保车轮(应测量其速度)和格栅板以相同的速度旋转。像这里一样,由于我们将轮子和板都安装在同一根轴上,因此它们显然都将以相同的速度旋转。

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

在Arduino中,我们可以使用millis()函数轻松地计算该时间间隔。自打开设备电源后,此毫秒功能将保持每毫秒增加1的速度。因此,当第一次中断发生时,我们可以将millis()的值保存在一个虚拟变量中(例如此代码中的pevtime),然后当第二次中断发生时,我们可以通过从millis()中减去pevtime值来计算所需的时间。。

Time taken=current time-previous time
timetaken =millis() - pevtime ; // timetaken在毫秒

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

rpm =(1000 /timetaken)* 60;

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

Velocity=2π×RPS×radius of wheel。
v =radius_of_wheel* rpm * 0.104

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

即使使用霍尔传感器测量旋转物体的速度,也使用相同的技术。但是对于H206传感器来说,有一个陷阱,栅板上有20个插槽,因此,测量两个插槽间隙之间的时间会使微控制器过载。因此,我们仅在车轮完全旋转时测量速度。由于每个间隙都会产生两个中断(一个间隙开始,另一个间隙结束),所以轮将总共产生40个中断,以使齿轮旋转一整圈。因此,在实际计算车轮速度之前,我们需要等待40次中断。相同的代码如下所示

  if(rotation> = 40){ timelapsed = millis()-pevtime; //以毫秒为单位的时间rpm =(1000 / timetaken)* 60; //计算转速的公式pevtime = millis(); rotation= 0; }

这种方法的另一个缺点是,速度值不会降为零,因为中断将始终等待车轮完成一轮旋转以计算rpm值。可以通过添加一个简单的代码来监视两个中断之间的时间间隔来轻松克服此缺陷,如果该时间间隔超出正常范围,则可以强制将rpm和speed的值设置为零。在下面的代码中链接,我们使用了变量dtime来检查时间差,如果时间差超过500毫秒,则将速度和rpm的值强制设为零。

/ *要在车辆停止时降至零* /
if(millis()-dtime> 500)//在500毫秒内未发现无扰动
{ rpm = v = 0; //将rpm和 speed设置为零dtime = millis(); }

测量车轮行驶距离的逻辑

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

Distance=2πr*number of rotations
Distance=(2 * 3.141 *radius_of_wheel)*(left_intr / 40)

使用公式2πr计算车轮周长,然后将其乘以车轮转数。

测量机器人角度的逻辑

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IbTDoWIq-1618981064174)(C:%5CUsers%5CAdministrator%5CPictures%5Ctypora%5CLogic-Behind-Measuring-the-angle-of-Robot.png)]

初始化机器人时,其面对的角度被认为是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。一旦我们计算了左右角度,就可以通过从右角度减去左角度来简单地获得机器人所面对的有效角度。

angle = angle_right-angle_left;

Arduino机器人代码

速度和角度测量机器人的完整Arduino代码可在此页面末尾找到。该程序的目的是使用上述逻辑来计算机器人的速度,距离和角度,并将其显示在LCD屏幕上。除此之外,它还应该提供使用操纵杆控制机器人选项。

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

#define LM_pos 9 //左马达
#define LM_neg 8 //左马达
#define RM_pos 10 //右马达
#define RM_neg 11 //右马达
#define joyX A2
#define joyY A3

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

float radius_of_wheel = 0.033; //测量车轮的半径,并以厘米为单位在此处输入

设置功能中,我们将所有值初始化为零,然后在LCD上显示Intro Text。我们还初始化了串行监视器以进行调试。然后我们提到速度传感器H206作为外部中断连接到引脚2和3。那就是检测到中断的地方,ISR函数Left_ISRRight_ISR将相应执行。

void setup()
{rotation = rpm = pevtime = 0; //将所有变量初始化为零Serial.begin(9600); lcd.begin(16,2); //初始化16 * 2 LCD lcd.print(" Bot Monitor"); //简介消息行1 lcd.setCursor(0,1); lcd.print("-CircuitDigest"); // Intro Message Line 2 delay(2000); lcd.clear(); lcd.print(" Lt:Rt:"); lcd.setCursor(0,1); lcd.print(" S:D:A:");pinMode(LM_pos,OUTPUT); pinMode(LM_neg,OUTPUT);pinMode(RM_pos,OUTPUT); pinMode(RM_neg,输出);digitalWrite(LM_neg,LOW); digitalWrite(RM_neg,LOW);attachInterrupt(digitalPinToInterrupt(2),Left_ISR,CHANGE); ///当触发左轮传感器时,将调用Left_ISR attachInterrupt(digitalPinToInterrupt(3),Right_ISR,CHANGE); //当触发右轮传感器时,将调用Right_ISR }

在Left_ISR例程中,我们简单地增加了一个名为left_intr的变量,该变量稍后将用于测量机器人的角度。**在Right_ISR内部,我们做同样的事情,但是除此之外,我们还在这里计算速度。**对于每个中断,变量旋转都会增加,然后使用上述逻辑来计算速度。

void Left_ISR()
{ left_intr++; delay(10);
}void Right_ISR()
{ right_intr ++; deoay(10);rotation++; dtime = millis(); if(rotation> = 40){timetaken= millis()-pevtime; //以毫秒为单位的时间rpm =(1000 / timetaken)* 60; //计算转速的公式pevtime = millis(); rotation= 0; }
}

在主要的无限循环函数内部,我们从操纵杆监视X和Y的值。根据值(如果移动了操纵杆),我们将相应地控制机器人。机器人的速度取决于操纵杆被推入多远。

int xValue = analogRead(joyX);int yValue = analogRead(joyY);int acceleration = map (xValue, 500, 0, 0, 200);if (xValue<500)
{
analogWrite(LM_pos, acceleration);
analogWrite(RM_pos, acceleration);
}else
{
analogWrite(LM_pos, 0);
analogWrite(RM_pos, 0);
}if (yValue>550)
analogWrite(RM_pos, 80);if (yValue<500)
analogWrite(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);
angle = angle_right-angle_left;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(distance);
lcd.setCursor(13,1); lcd.print(“”); lcd.setCursor(13,1); lcd.print(angle);

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

准备好硬件后,将代码上传到Arduino,然后使用操纵杆移动机器人。机器人的速度,机器人所覆盖的距离以及角度将在LCD上显示,如下所示。

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

您也可以在本页结尾观看视频,以了解机器人的工作方式。希望您理解该项目并喜欢构建它。如果您有任何疑问,请将其留在评论部分,我会尽力答复。您也可以使用论坛来获得快速的技术帮助。

代码

/** Arduino Vehicle Speed, Distance and angle calculator *//*-------defining pins------*/
#define LM_pos 9       // left motor
#define LM_neg 8       // left motor
#define RM_pos 10       // right motor
#define RM_neg 11       // right motor
#define joyX A2
#define joyY A3#include <LiquidCrystal.h>const int rs = 14, en = 15, d4 = 4, d5 = 5, d6 = 6, d7 = 7; //Mention the pin number for LCD connection
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);int left_intr = 0;
int right_intr = 0;
int angle = 0;/*Hardware details*/
float radius_of_wheel = 0.033;  //Measure the radius of your wheel and enter it here in cmvolatile byte rotation; // variale for interrupt fun must be volatile
float timetaken,rpm,dtime;
float v;
int distance;
unsigned long pevtime;void setup()
{rotation = rpm = pevtime = 0; //Initialize all variable to zeroSerial.begin(9600);lcd.begin(16, 2); //Initialise 16*2 LCDlcd.print("Vechile Monitor"); //Intro Message line 1lcd.setCursor(0, 1);lcd.print("-CircuitDigest "); //Intro Message line 2delay(2000);lcd.clear();lcd.print("Lt:     Rt:    ");lcd.setCursor(0, 1);lcd.print("S:     D:  A:   ");pinMode(LM_pos, OUTPUT);pinMode(LM_neg, OUTPUT);pinMode(RM_pos, OUTPUT);pinMode(RM_neg, OUTPUT);digitalWrite(LM_neg, LOW);digitalWrite(RM_neg, LOW);attachInterrupt(digitalPinToInterrupt(2), Left_ISR, CHANGE); //Left_ISR is called when left wheel sensor is triggered attachInterrupt(digitalPinToInterrupt(3), Right_ISR, CHANGE);//Right_ISR is called when right wheel sensor is triggered
}void loop()
{int xValue = analogRead(joyX);int yValue = analogRead(joyY);int acceleration = map (xValue, 500, 0, 0, 200);if (xValue<500)
{
analogWrite(LM_pos, acceleration);
analogWrite(RM_pos, acceleration);
}
else
{
analogWrite(LM_pos, 0);
analogWrite(RM_pos, 0);
}if (yValue>550)
analogWrite(RM_pos, 80);
if (yValue<500)
analogWrite(LM_pos, 100);/*To drop to zero if vehicle stopped*/if(millis()-dtime>500) //no inetrrupt found for 500ms{rpm= v = 0; // make rpm and velocity as zerodtime=millis();}v = radius_of_wheel * rpm * 0.104; //0.033 is the radius of the wheel in meterdistance = (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) ;angle = angle_right - angle_left;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(distance);
lcd.setCursor(13, 1); lcd.print("   "); lcd.setCursor(13, 1);lcd.print(angle);delay(100);}void Left_ISR()
{left_intr++;delay(10);
}void Right_ISR()
{right_intr++; delay(10);rotation++;dtime=millis();if(rotation>=40){timetaken = millis()-pevtime; //timetaken in millisec rpm=(1000/timetaken)*60;    //formulae to calculate rpmpevtime = millis();rotation=0;}
}

使用Arduino和LM393速度传感器(H206)的移动机器人的速度,距离和角度测量相关推荐

  1. Arduino和LM393传感器的移动机器人的速度、距离和角度测量

    机器人慢慢开始走进我们的社会,让我们的生活更加简单.我们可以在英国的道路上发现Starship的六轮食品运送机器人,它可以巧妙地在城区中航行到达目的地.导航到环境中的每个移动机器人都应该始终了解其相对 ...

  2. arduino笔记32:nRF24l01模块使用 电磁波频率 距离限制 掉电模式 热待机模式

    最近再arduino中文社区看到了一篇介绍nrf24l01基本原理的帖子,内容感觉蛮不错的,学习一下,记录一下学习笔记. 大部分内容都是Arduino中文社区的帖子,附上自己的一点点体会. 目录 一. ...

  3. 使用Arduino开发板制作数字出租车计价器

    现今,数字仪表正在逐步取代各个部门的模拟仪表,无论是电表还是出租车费用表.主要原因是模拟仪表的机械部件在长时间使用后容易磨损,并且不如数字仪表那么精确. 一个很好的例子是模拟速度计和里程表,用于旧摩托 ...

  4. 领航机器人广告段子_一种基于领航跟随的移动机器人编队控制方法

    一种基于领航跟随的移动机器人编队控制方法 [技术领域] [0001] 本发明设及移动机器人运动控制领域,尤其设及一种基于领航跟随的移动机器人 编队运动控制方法. [背景技术] [0002] 随着机器人 ...

  5. arduino和python对接_Python:与Arduino进行交互-后续

    Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 通过Python与Arduino进行交互 首先,我们得导入serial库来连接python与Arduino ...

  6. arduino的矩阵示例程序_用树莓派 Arduino 制造 LED 矩阵彩灯

    MAKER:maketvee/ 译:趣无尽 之前我们介绍过一款非常炫酷的<熔岩特效灯>.这期教程中我将为大家介绍一款更易上手的灯. 这款 LED 矩阵彩灯使用标准的 WS2812b LED ...

  7. 两轮差速移动机器人从A点移动到B点的C++语言代码

    (⊙﹏⊙)如下同样是AI撰写. 您可以使用两轮差速移动机器人的控制代码来控制它从A点移动到B点.可以使用各种语言,如C,C++,Python等来编写控制代码. 从A点移动到B点的C代码应该是:move ...

  8. 移动机器人轮式里程计

    移动机器人灵魂三问:我在哪? 我要去哪里? 怎么去?其中,第一问对应机器人定位问题.定位问题可阐述为:移动机器人根据自身状态.传感器信息实时确定自己在世界(全局或局部)中的位置与姿态. 阿克曼转向的无 ...

  9. 使用麦克风和Arduino测量以dB为单位的声音/噪声水平

    原文:https://circuitdigest.com/microcontroller-projects/arduino-sound-level-measurement 使用麦克风和Arduino测 ...

最新文章

  1. 知识图谱 (1)基本概念
  2. boost::mp11::mp_defer相关用法的测试程序
  3. java图片的导出,并压缩
  4. 95-862-045-源码-runtime-blob-BlobService
  5. c语言计算分段函数_Rust能够取代C语言吗?
  6. [转] GCC 中的编译器堆栈保护技术
  7. 利用dex2jar反编译apk
  8. pip 安装 pytorch环境
  9. 利用红帽Piranha方案实现WEB负载均衡
  10. HTML+CSS网页设计期末课程大作业:【中国传统文化——古诗词】学生网页设计作品 dreamweaver作业静态HTML网页设计
  11. SNK 推出NEOGEO mini 投币配件,还能当作存钱罐?
  12. 图解通信原理与案例分析-28:四大全球卫星导航系统GNSS的基本原理与技术对比---中国的北斗、美国的GPS、欧洲的伽利略、俄罗斯的格洛纳斯
  13. console口设置登录密码
  14. 联想System X 3650M5 服务器装机问题记录
  15. 5G/NR SSB与PRACH occasion如何关联?
  16. 灰色预测的MATLAB程序
  17. 基于MFC实现大华监控摄像头Demo(视频流和抓图)
  18. 智汀智能家居普及篇——智能家居必备的功能控制系统
  19. web 基础练习/设计专业课程导航(7)
  20. UVA 1626括号序列DP

热门文章

  1. 火力全开2不显示服务器,火力全开2 城市狂热一直进不去怎么办
  2. 自动驾驶虚拟仿真测试介绍(7):MIL、SIL、PIL和HIL是个啥
  3. 20190722-deeplearning-note
  4. matlab半张量积,半张量积原理.doc
  5. iOS 富文本~设置字体大小和颜色
  6. 浅谈ConcurrentDictionary与Dictionary
  7. 如何查看网页的发布时间
  8. 88亿美元的交易:HPE旗下大部分软件业务合并到Micro Focus
  9. 故障模块名称kernelbase.dll_凸轮轴位置传感器故障诊断方法及注意事项
  10. 电池容量工作时间如何计算