yaboPP电子
项目

创建一个对象跟踪系统:使用对象检测集成伺服控制

2016年5月10日通过迈克尔的股票

该项目涵盖集成伺服控制和对象检测。

使用对象检测集成伺服控制

该项目将在使用两个超声波传感器跟踪移动对象时涵盖集成伺服控制。这是一个上一个项目的延续,发表这里这里

它在开发了这个项目的这个阶段,即arduino IDE在定制图书馆时具有一些弱点。具体来说,在编写引用其他自定义库的自定义库时,编译器将失败。如果您碰巧创建一个参考循环,就像我在尝试解决此问题时,编译过程实际上就会陷入无限循环,并将“挂断”直到看门狗定时器经过和编译器排出。

参考循环:每个文件指向彼此文件

从文件…

公元前#包括“文件”

从文件B…

#include“文件a.c”

如果您在C ++中编写库,那么一些聪明的人已经找到了这种弱点的一些解决方法,但我在将学习转移到这个项目时,我没有成功地在C.这方面,这最终意味着意味着意味着意味着它的源代替函数,我们只需将所有函数存储在单个源文件中。要重新标准,可以更好的练习以某种意义的方式分组,跨多个源文件分布。所说,让我们继续努力解决问题......

在上一个项目中,最后一步有两个超声波传感器,与一对LED连接到UNO。建立在这个基础之外,我们将从我们以前的工作中添加伺服来完成到目前为止的系统。伺服仅需要一个PWM信号,功率和地面。

为了最小化工作,我将伺服PWM的位置移动到引脚6,因为这比重新加工超声波传感器和LED显着容易。有关伺服的接线图,请参阅上一篇文章。

*免责声明*如果您在不使用面包板的情况下达到此时的情况下,我强烈建议您从这一点上使用一个。我还建议制作5V和GND轨道连接超声波传感器和伺服。

突出显示卷轴:

  • 如果你还没有准备好,可以使用实验板。
  • 开始实施电压和接地轨道。
  • 移动伺服控制销到Uno上的销6。

Three-File结构

此时,我们可以将草图分为三个文件:主要,标题和源文件。我命名为主素描“ObjectTracker”,标题文件“ObjectTrackerHDR.h”和源文件“ObjectTrackersRC.C”。

以下代码段将测试三个文件结构的相互依赖性。如果正常复制,程序将从传感器1采取距离测量并将其输出到串行监视器。输出到串行监视器的值不会转换为测量单位,因此它不会有一个有用的含义。

/ **************** ObjectTracker *********************** / #include“ObjectTrackersrc.c”//Include functions from source file #include "Servo.h" // Include functions from Servo.h Servo ServoOne; // Generates an instance of a servo object void setup() // Initialize { pinMode(Echo_1, INPUT); // Set Pin for Echo_1 as INPUT pinMode(Trigger_1, OUTPUT); // Set Pin for Trigger_1 as OUTPUT Serial.begin(9600); // Establish baud rate for Serial monitoring ServoOne.attach(6); // Assigns pin 6 as a servo } void loop() // Main Loop { PulseInTimeout=6000; // Define PulseTimeout value interrupts(); // Enable interrupts DistanceMeasurementSensor1(); // Function Call Serial.println(EchoTime_1); // Print value of EchoTime_1 to serial monitor followed by newline }
/************************* ObjectTrackerHDR.h *******************/ /************* 销的定义 *****************************/ # 定义LED_2 8 # define Echo_1 9 # define Trigger_1 10 # define LED_1 11 # define Trigger_2 12 # define Echo_2 13  /************* 变量声明 **************************/ 长EchoTime_1;长EchoTime_2;int Distance_1;int Distance_2;int PulseInTimeout;int ServoPosition;
/*************************** ObjectTrackerSRC.c ****************************/ # 包括“Arduino.h”# include“ObjectTrackerHDR.h”空白DistanceMeasurementSensor1 () {digitalWrite (Trigger_1、低);// Hold Trigger Low delayMicroseconds(2);// set Time digitalWrite(Trigger_1, HIGH);//启用触发器delayMicroseconds(10);//保持高位10uS digitalWrite(Trigger_1, LOW);//保持触发低开始范围检测EchoTime_1 = pulseIn(Echo_1, HIGH, PulseInTimeout);//脉冲序列捕获

功能pulseIn现在有了第三个参数:PulseInTimeout。这个参数据说是可选的,但是当在自定义库中引用时,“可选的”参数就变成必需的了。这是Arduino IDE的另一个未被证明的弱点。

这个新参数是时间的长度pulseIn功能将等待脉冲结束。如果脉冲不通过PulseIntImeout指示的时间结束,则它将返回值0.下一节将添加将距离测量输出转换为有意义的值:厘米。

转换成厘米

现在我们将为源文件添加新功能,在主循环中进行新的函数调用,并将变量输出更改为以厘米的计算距离。

将下面的代码更改添加到上面的代码中。注意,头文件没有任何更改。如果成功,您将看到以厘米为单位的滚动距离。

/ *********添加到源文件************* / void calculdistsensor1(){teasting_1 =(echotime_1 / 58);//从Echo计算距离}
/ ************添加到设置循环*********** / plustureImeout = 6000;//定义pulsetimeout值/ ************新主循环*************** / void循环()//主循环{中断();//启用中断DistanceMeasurementSensor1();//函数调用CalculateDistanceSensor1();//函数调用serial.println(距离_1);//打印距离_1_buffer到串行监视器,然后是ewhline}

接下来,我们将用与上一步相似的方法,将第二次距离测量值及其互补转换为厘米。修改你的代码,加入以下内容:

/************************** 添加到源文件  *****************/ 空白DistanceMeasurementSensor2 () {digitalWrite (Trigger_2、低);// Hold Trigger Low delayMicroseconds(2);// set Time digitalWrite(Trigger_2, HIGH);//启用触发器delayMicroseconds(10);//保持高位10uS digitalWrite(Trigger_2, LOW);//保持触发低开始范围检测EchoTime_2 = pulseIn(Echo_2, HIGH, PulseInTimeout);//脉冲序列捕获定时器}void CalculateDistanceSensor2() {Distance_2 = (EchoTime_2/58);//从Echo计算距离}
/************ 新主循环  ***************/ 无效循环()/ /主循环{中断();//启用中断DistanceMeasurementSensor1();//函数调用CalculateDistanceSensor1();//函数调用DistanceMeasurementSensor2();//函数调用CalculateDistanceSensor2();//函数调用Serial.println(Distance_2);//打印Distance_2的值}

如果操作正确,您将在串行监视器上看到一个输出:从第二个传感器测量的距离。下一步是从距离测量的输出中引入一些逻辑。我们在一个名为ObjectPresent()的新函数中这样做。

ObjectPresent()函数

通过比较来自每个传感器的两个测量值,我们可以确定对象是否位于左侧,右侧或两个传感器的前面。当传感器输出变化时,我们告诉伺服沿对象的方向旋转,从而跟踪其运动。

下一段代码很重要。有很多新的变量和参数可以调整。下面的代码是完整的,并不意味着是一个修正,而不是继续显示代码片段。检查下面的代码并手工集成算法,而不只是复制和粘贴,这可能是有益的。

/*************** ObjectTracker  ***************/ # 包括“ObjectTrackerSRC.c”# include“Servo.h”伺服ServoOne;//创建一个伺服对象的实例pinMode (Trigger_1、输出);pinMode (Echo_2、输入);pinMode (Trigger_2、输出);ServoOne.attach (6);//指定引脚6作为伺服伺服位置=90;//默认伺服位置PulseInTimeout=8000;MaxDistance=40; //设置脉冲超时时间// MaxDistance in cm ServoPositionMin=30; // Min Servo Position ServoPositionMax=150; // Max Servo Position ServoPivotSpeed=2; // The Servo angle step size } void loop() // main loop { interrupts(); // Enable interrupts DistanceMeasurementSensor1(); // Function Call CalculateDistanceSensor1(); // Function Call DistanceMeasurementSensor2(); // Function Call CalculateDistanceSensor2(); // Function Call ObjectPresent(); // Function Call ServoOne.write(ServoPosition); // Rotates Servo to position stored in ServoPosition LEDsOff(); // Turns LEDs off }
/*************** ObjectTrackerHDR.h ***************/ #define LED_2 8 #define Echo_1 9 #define Trigger_1 10 #define LED_1 11 #define Trigger_2 12 #define Echo_2 13 unsigned long EchoTime_1;无符号长EchoTime_2;int Distance_1;int Distance_2;int PulseInTimeout;int ServoPosition;int MaxDistance;int ServoPositionMin;int ServoPositionMax;int ServoPivotSpeed;
/*************** ObjectTrackerSRC.c ***************/ #include "Arduino.h" #include "ObjectTrackerHDR.h" void DistanceMeasurementSensor1() //测量距离传感器1 {digitalWrite(Trigger_1, LOW);// Hold Trigger Low delayMicroseconds(10);// set Time digitalWrite(Trigger_1, HIGH);//启用触发器delayMicroseconds(5);//保持高位10uS digitalWrite(Trigger_1, LOW);//保持触发低开始范围检测EchoTime_1 = pulseIn(Echo_1, HIGH, PulseInTimeout);//脉冲序列捕获定时器}void CalculateDistanceSensor1() //转换EchoTime_1到cm的距离{Distance_1 = (EchoTime_1/58);if (Distance_1 > MaxDistance) //限制Distance_1到MaxDistance {Distance_1 = MaxDistance;}} void DistanceMeasurementSensor2() //测量距离传感器2 {digitalWrite(Trigger_2, LOW);// Hold Trigger Low delayMicroseconds(10); // Settle Time digitalWrite(Trigger_2, HIGH); // Enable Trigger delayMicroseconds(5); // Hold High for 10uS digitalWrite(Trigger_2, LOW); // Hold Trigger Low to start range detect EchoTime_2 = pulseIn(Echo_2, HIGH, PulseInTimeout); // Timer sequence for pulse train capture } void CalculateDistanceSensor2() // Converts Distance from EchoTime_1 to cm { Distance_2 = (EchoTime_2/58); if (Distance_2 > MaxDistance) // Constrains Distance_2 to MaxDistance { Distance_2 = MaxDistance; } } void ObjectPresent() // Object Detection Algorithm { if(ServoPosition<90) // Detection if less than 90 degrees { if((Distance_2-Distance_1)>0) // Direction comparison { ServoPosition=ServoPosition+ServoPivotSpeed; // Increment Servo position by ServoPivotSpeed digitalWrite(LED_1, HIGH); // Turn LED ON } if((Distance_1-Distance_2)>0) // Direction comparison { ServoPosition=ServoPosition-ServoPivotSpeed; // Increment Servo position by ServoPivotSpeed digitalWrite(LED_2, HIGH); // Turn LED ON } } if(ServoPosition>89) // Detection if more than 89 degrees { if((Distance_2-Distance_1)>0) // Direction comparison { ServoPosition=ServoPosition+ServoPivotSpeed; // Increment Servo position by ServoPivotSpeed digitalWrite(LED_1, HIGH); // Turn LED ON } if((Distance_1-Distance_2)>0) // Direction comparison { ServoPosition=ServoPosition-ServoPivotSpeed; // Increment Servo position by ServoPivotSpeed digitalWrite(LED_2, HIGH); // Turn LED ON } } if(ServoPositionServoPositionMax) // Restricts Servo position to Max { ServoPosition=ServoPositionMax; } } void LEDsOff() // Turns LEDs Off { digitalWrite(LED_1, LOW); digitalWrite(LED_2, LOW); }

ObjectPresent()函数执行以下步骤:

  1. 确定伺服当前是否面临左或右。
  2. 确定哪个传感器检测到一个对象。
  3. 将伺服位置递增或减少等于servopivotspeed的金额。
  4. 打开代表兴趣方向的LED灯。
  5. 检查伺服位置是否小于最小值并更改为最小值,如果较少。
  6. 检查伺服位置是否大于最大值并更改为最大值,如果它更大。

定义这个系统如何运行的变量可以进行调整——我建议您这样做。具体地说,调整值servopositionmin.ServoPositionMaxSERMOPIVOTSPEED, 和Maxdistance.

  • servopositionmin:伺服移动到伺服的最小允许角度。如果太低,伺服可能会发生故障。
  • ServoPositiaMax:伺服移动到伺服的最大允许角度。如果太高,伺服可能会发生故障。
  • ServoPivotSpeed:跟踪对象时从当前伺服角度加减的整数值。
  • MaxDistance:传感器将读取的最大距离,厘米,以厘米。任何大于此值的值都会更改为此值。这可以防止传感器检测小空间中的墙壁和“跟踪”静止物体。

建立你的系统

要构建自己的系统,您需要安装面向对象将通过的字段的传感器。我用强力双面胶带把所有碎片粘在一起。在开始测试之前,请确保线缆有足够的间隙。

在上图中,你可以看到我的两个传感器正对着我。这个小面包板放在一个伺服上,伺服放在一块塑料上。

我想指出的是,该系统是基于两个距离探测器,而不是一个复杂的雷达系统。我鼓励您尝试一下检测算法,并尝试改进它的性能。它远非完美。

ObjectTracker.zip.zip.