风筝
发表于: 2019-2-24 21:18:45 | 显示全部楼层

机器人慢慢开始走进我们的社会,让我们的生活更加简单。我们可以在英国的道路上发现Starship的六轮食品运送机器人,它可以巧妙地在城区中航行到达目的地。导航到环境中的每个移动机器人都应该始终了解其相对于现实世界的位置和方向。有许多方法,如可以通过使用GPS、RF三角测量、加速度计、陀螺仪等不同技术来实现这一目标。每种技术都有自己的优势,并且本身就是独一无二的。在本篇文章中,我们将使用简单且易于使用的LM393速度传感器来测量一些重要参数,如速度、行进距离和使用Arduino微控制器的机器人角度。通过这些参数,机器人将能够知道其真实世界状态并可以使用它来安全地导航。


Arduino是建造机器人的业余爱好者中最受欢迎的选择,从简单的循迹机器人到更复杂的自平衡或地板清洁机器人。


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


LM393速度传感器模块(H206)

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

LM393-Speed-Sensor-Module.jpg


红外光传感器由红外LED和光电晶体管组成,由小间隙隔开。如上所示,整个传感器装置放置在黑色外壳中。栅板由槽构成,板布置在红外光传感器的间隙之间,使得传感器可以感测栅板中的间隙。栅板中的每个间隙在穿过间隙时触发IR传感器;然后使用比较器将这些触发器转换为电压信号。比较器使用的是是ON半导体的LM393 IC。该模块有三个引脚,其中两个用于为模块供电,一个输出引脚用于计算触发次数。


H206传感器安装

H206-Sensor-Mounting-Arrangement.jpg

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


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


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


电路原理图

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

Circuit-Diagram-for-Speed-Distance-Measurement-for-Mobile-Robots-using-Arduino-a.png


整个电路由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。将整个电路组装在机箱上并按照说明安装速度传感器,机器人在连接完成后看起来像下面的样子。

Speed-Distance-and-Angle-Measurement-for-Mobile-Robots-using-Arduino-and-LM393-Sensor.jpg

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

跳转到指定楼层
风筝
发表于: 2019-2-24 21:28:19 | 显示全部楼层

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

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


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


在Arduino中,我们可以使用millis()函数轻松计算此时间间隔。从器件上电开始,这个毫秒功能将每毫秒递增1。因此,当第一个中断发生时,我们可以将millis()的值保存在虚拟变量中(如此代码中的pevtime),然后当第二个中断发生时,我们可以计算从millis()中减去pevtime值所需的时间 。

  1. Time taken = current time – previous time
  2. timetaken = millis()-pevtime; //timetaken in millisec
复制代码

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

  1. rpm=(1000/timetaken)*60;
复制代码

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

  1. Velocity = 2π × RPS × radius of wheel.
  2. v = radius_of_wheel * rpm * 0.104
复制代码

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


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

  1. if(rotation>=40)
  2.   {
  3.     timetaken = millis()-pevtime; //timetaken in millisec
  4.     rpm=(1000/timetaken)*60;    //formulae to calculate rpm
  5.     pevtime = millis();
  6.     rotation=0;
  7.   }
复制代码

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

  1. /*To drop to zero if vehicle stopped*/
  2. if(millis()-dtime>500) //no inetrrupt found for 500ms
  3. {
  4.   rpm= v = 0; // make rpm and velocity as zero
  5.   dtime=millis();
  6. }
复制代码

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

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

  1. Distance = 2πr * number of rotations
  2. distance = (2*3.141*radius_of_wheel) * (left_intr/40)
复制代码

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


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

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

Logic-Behind-Measuring-the-angle-of-Robot.png


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


例如,如果左轮完成一次旋转(80次中断),那么机器人将向左转90°,同样如果右轮完成一次旋转(80次中断),机器人将向右转90°。现在我们知道如果Arduino在一个车轮上检测到80个中断,那么机器人已经转了90°并且根据我们可以判断机器人是通过正(右)还是负(左)来转动。因此可以使用以下公式计算左右角度

  1. int angle_left = (left_intr % 360) * (90/80) ;
  2. int angle_right = (right_intr % 360) * (90/80) ;
复制代码

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

  1. angle = angle_right - angle_left;
复制代码

回复

使用道具 举报

风筝
发表于: 2019-2-24 21:37:09 | 显示全部楼层

Arduino编程

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


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

  1. #define LM_pos 9       // left motor
  2. #define LM_neg 8       // left motor
  3. #define RM_pos 10       // right motor
  4. #define RM_neg 11       // right motor
  5. #define joyX A2
  6. #define joyY A3
复制代码

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

  1. float radius_of_wheel = 0.033;  //Measure the radius of your wheel and enter it here in cm
复制代码

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

  1. void setup()
  2. {
  3.   rotation = rpm = pevtime = 0; //Initialize all variable to zero
  4.   Serial.begin(9600);
  5.   lcd.begin(16, 2); //Initialise 16*2 LCD
  6.   lcd.print("Bot Monitor"); //Intro Message line 1
  7.   lcd.setCursor(0, 1);
  8.   lcd.print("-CircuitDigest "); //Intro Message line 2
  9.   delay(2000);
  10.   lcd.clear();
  11.   lcd.print("Lt:     Rt:    ");
  12.   lcd.setCursor(0, 1);
  13.   lcd.print("S:     D:  A:   ");

  14.   pinMode(LM_pos, OUTPUT);
  15.   pinMode(LM_neg, OUTPUT);

  16.   pinMode(RM_pos, OUTPUT);
  17.   pinMode(RM_neg, OUTPUT);

  18.   digitalWrite(LM_neg, LOW);
  19.   digitalWrite(RM_neg, LOW);

  20.   attachInterrupt(digitalPinToInterrupt(2), Left_ISR, CHANGE); //Left_ISR is called when left wheel sensor is triggered
  21.   attachInterrupt(digitalPinToInterrupt(3), Right_ISR, CHANGE);//Right_ISR is called when right wheel sensor is triggered
  22. }
复制代码

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

  1. void Left_ISR()
  2. {
  3.   left_intr++;delay(10);
  4. }


  5. void Right_ISR()
  6. {
  7.   right_intr++; delay(10);

  8.   rotation++;
  9.   dtime=millis();
  10.   if(rotation>=40)
  11.   {
  12.     timetaken = millis()-pevtime; //timetaken in millisec
  13.     rpm=(1000/timetaken)*60;    //formulae to calculate rpm
  14.     pevtime = millis();
  15.     rotation=0;
  16.   }
  17. }
复制代码

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

  1. int xValue = analogRead(joyX);
  2. int yValue = analogRead(joyY);

  3. int acceleration = map (xValue, 500, 0, 0, 200);

  4. if (xValue<500)
  5. {
  6. analogWrite(LM_pos, acceleration);
  7. analogWrite(RM_pos, acceleration);
  8. }

  9. else
  10. {
  11. analogWrite(LM_pos, 0);
  12. analogWrite(RM_pos, 0);
  13. }

  14. if (yValue>550)
  15. analogWrite(RM_pos, 80);

  16. if (yValue<500)
  17. analogWrite(LM_pos, 100);
复制代码

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

  1. v = radius_of_wheel * rpm * 0.104; //0.033 is the radius of the wheel in meter
  2. distance = (2*3.141*radius_of_wheel) * (left_intr/40);
  3. int angle_left = (left_intr % 360) * (90/80) ;
  4. int angle_right = (right_intr % 360) * (90/80) ;
  5. angle = angle_right - angle_left;

  6. lcd.setCursor(3, 0); lcd.print("    "); lcd.setCursor(3, 0); lcd.print(left_intr);
  7. lcd.setCursor(11, 0); lcd.print("    "); lcd.setCursor(11, 0);lcd.print(right_intr);
  8. lcd.setCursor(2, 1); lcd.print("  "); lcd.setCursor(2, 1);lcd.print(v);
  9. lcd.setCursor(9, 1); lcd.print("  "); lcd.setCursor(9, 1);lcd.print(distance);
  10. lcd.setCursor(13, 1); lcd.print("   "); lcd.setCursor(13, 1);lcd.print(angle);
复制代码

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

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

Testing-Speed-Angle-Measurement-for-Mobile-Robots-using-Arduino-and-LM393-Sensor.jpg


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


希望您了解该项目并享受制作过程。如果您有任何疑虑,请在本帖进行回复。


代码

本文使用的完整代码如下: main.rar (1.31 KB, 下载次数: 31)

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 700 | 回复: 1480



手机版|

GMT+8, 2024-4-25 11:35 , Processed in 0.042220 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表