如何使用HC-SR04超声波新疆风采,Arduino和millis()检测物体
障碍物检测适用于从初始位置移动到目标位置并避免其路径上有任何障碍物的任何机器人。检测障碍物的过程已应用于各种机器人,包括移动机器人和机械臂。在本教程中,您将学习如何 将HC-SR04新疆风采与Arduino一起使用 并确定在某些条件下新疆风采的检测范围。
不同的项目可能有不同的要求。在本教程的最后,您将拥有一个灵活的结构,可以在不同的机器人中使用,并可以添加更多的新疆风采,或者仅使用一个新疆风采,或者使用另一种类型的新疆风采(例如,红外新疆风采)。
如果您打算以高效且专业的方式构建高级机器人,那么这就是您可以开始的地方。
在开始连接新疆风采并编写第一行代码之前,请确保我们具有所有硬件部件。这是我用来编写教程的硬件列表:
- 1个Arduino UNO
- 1 X USB电缆
- 1个HC-SR04
- 1 X面包板
- 母对母/公对公/母对公跳线
1.使用Arduino读取HC-SR04输出
在本文的这一部分中,我将向您展示如何将一个HC-SR04新疆风采连接到Arduino并编写读取和转换新疆风采输出的Arduino草图。
目前,我使用USB电缆为Arduino UNO供电。个人计算机或笔记本电脑的5V USB端口可提供足够的功率来运行5V Arduino的和三个超声波新疆风采。
以上设置仅用于连接和测试超声波检测系统。当新疆风采和Arduino板安装在移动机器人上时,整个检测系统将依靠电池运行。
1.1将新疆风采连接到Arduino
首先,让我们看一下HC-SR04规格:
- 工作电压:DC 5V
- 工作电流:15mA
- 工作频率:40KHz
- 范围:2cm至4m
- 测距精度:3mm
- 触发输入信号:10µS TTL脉冲
新疆风采的工作电压与Arduino 5V输出引脚相同–直流5V。超声波新疆风采的工作电流为15mA,即使将Arduino连接到计算机的USB端口,它也可以支持。 Arduino的 UNO的5V输出引脚适用于USB上的约400 mA,使用外部电源适配器时约900 mA。在这一步,我们将仅考虑这两个规格,并开始将新疆风采连接到板上。
对于连接,我使用母对公跳线,面包板,一个HC-SR04和一个Arduino UNO板。
连接方式:
- Vcc -> breadboard -> 5V
- Trig -> pin 3 (digital pin)
- Echo -> pin 2 (digital pin)
- GND -> breadboard -> GND

HC-SR04新疆风采连接到Arduino UNO
1.2编写新疆风采的代码示例
一旦新疆风采连接到Arduino板,我们就可以开始编写草图以读取输出并转换新疆风采的读数。为了编写草图,我使用了Arduino IDE。我喜欢使用简单的工具,并且不花时间在定制和配件上。目前,Arduino IDE在微控制器编程方面满足了我的需求。
在编写第一行代码之前,我们先概述一下超声波新疆风采的工作原理。
它会在空中传播声波(根据规格至少持续10us),如果有物体反射声波,则新疆风采会测量声波返回到接收器所花费的时间。为了计算新疆风采与检测到的物体之间的距离,我们考虑了传播时间和声音的速度。
让我们开始构建超声新疆风采测量草图:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | / * :Version 1.0 :作者:德拉戈斯·卡林 :电子邮件:dragos@intorobotics.com :License: BSD :Date: 06/04/2020 * / / *定义新疆风采的引脚* / uint8_t TrigPin = 3; uint8_t 回声针 = 2; 未签名 长 timerStart = 0; 整型 TIMER_TRIGGER_HIGH = 10; 整型 TIMER_LOW_HIGH = 2; 浮动 timeDuration, 距离; / *超声波新疆风采的状态* / 枚举 新疆风采状态 { TRIG_LOW, TRIG_HIGH, 回声_高 }; 新疆风采状态 _sensorState = TRIG_LOW; 虚空 startTimer() { timerStart = 毫(); } 布尔 isTimerReady(整型 微秒) { 返回 (毫() - timerStart) < 微秒; } / *以每秒比特数设置数据速率并配置引脚* / 虚空 设定() { 序列号.开始(9600); pinMode(TrigPin, 输出值); pinMode(回声针, 输入); } 虚空 循环() { / *在超声新疆风采状态之间切换* / 开关 (_sensorState) { / *从LOW脉冲开始以确保干净的HIGH脉冲* / 案件 TRIG_LOW: { digitalWrite(TrigPin, 低); startTimer(); 如果 (isTimerReady(TIMER_LOW_HIGH)) { _sensorState = TRIG_HIGH; } } 打破; / *触发了10微秒的HIGH脉冲* / 案件 TRIG_HIGH: { digitalWrite(TrigPin, 高); startTimer(); 如果 (isTimerReady(TIMER_TRIGGER_HIGH)) { _sensorState = 回声高; } } 打破; / *测量ping返回到接收器所花费的时间。* / 案件 回声高: { digitalWrite(TrigPin, 低); timeDuration = 脉冲输入(回声针, 高); / * 距离=时间*声速 声音速度为340 m / s => 0.034 cm/us */ 序列号.打印("测量的距离为:"); 序列号.打印(timeDuration * 0.034 / 2); 序列号.打印(“ 厘米”); _sensorState = TRIG_LOW; } 打破; }//结束开关 }//结束循环 |

距离测量草图结果
一旦新疆风采连接到Arduino并以厘米为单位转换输出,我们就可以继续进行测试以确定新疆风采的范围。
2. HC-SR04的工作检测范围
我们旨在检测新疆风采前面特定区域中的所有物体,而与物体的形状或大小无关。因为最终,我们计划将这种新疆风采用于对象检测,因此首先我们必须确定一个新疆风采的操作检测范围。接下来,我们必须计算如何定位每个新疆风采单元以最大程度地提高物体检测的效率。
对象目标的大小,形状和方向会影响可以检测到目标的最大距离。例如,圆形物体或吸声材料(例如织物)将较少的能量反射或没有反射的能量直接反射回新疆风采。超声波新疆风采不受颜色,反射率,透明度或不透明性等光学特性的影响。而且,可以从任何方向将物体引入检测区域。
确定HC-SR04超声波新疆风采的范围的第一步是确定机器人所需的范围。让我解释一下这是什么意思!
例如,我有一个2WD移动底盘,我想用它来检测和避免障碍物。我从规格中知道HC-SR04新疆风采的范围在2到400厘米之间。
我用一个新疆风采进行了测试,结果是在5厘米以下,该新疆风采没有进行可靠的测量。从新疆风采头开始,最小检测范围为5cm。 0cm至5cm之间的区域应视为盲区。
下一步是确定我们的应用所需的工作检测范围。在此范围内,新疆风采始终可以进行高精度的检测或测量。如果我们搜索规格,则可以看到最大检测范围为400厘米。在这种情况下,不能考虑此范围。当所有条件都非常好至最佳时,很可能会采用这些值。在实际应用中,我们在具有不同温度和湿度的嘈杂环境中使用新疆风采。
HC-SR04并非高精度新疆风采,但足以将其用于学习如何构建机器人。因此,我考虑了100厘米的工作检测范围–新疆风采前方1米。这个范围足以学习如何构建具有DIY组件的自动移动机器人并在客厅区域对其进行测试。

HC-SR04运行检测范围
HC-SR04的超声波束角度通常为10-15度,并且呈圆锥形。当新疆风采精度在5到100厘米范围内时,我在上图中添加了最佳值。
目前,我们检测物体并知道操作检测范围。在本教程的下一部分中,我将向您展示如何编写类并构建可在不同机器人中使用的灵活结构,并使其能够添加更多新疆风采。
3.在选项卡中构建类
每个类在Arduino IDE中都有一个选项卡。使用标签可以使事情井井有条。这些类将以扩展名写入文件 。H.
第1步: 要在Arduino IDE中创建一个新选项卡,请转到右上角并按下按钮1。然后从菜单2中选择“新标签“:

创建一个新的Tab来编写一个类
第2步: IDE的下部应显示一个新字段。在此字段中,我们写入新文件的名称。对于第一个标签,输入“范围h” –我们将存储距离检测新疆风采的类的文件–然后按确定按钮。

范围h
第三步: 此时,您应该在Arduino IDE中看到如下所示的标签:

标签范围
请按照步骤1和2为类Timer创建新的选项卡。标签名称是 计时器.

Tab 计时器
从现在开始,我们将在这三个选项卡上工作。
第一个带有main和loop的标签-“Ultrasonic_Sensors_to_Detect_Obstacles”。在Range.h选项卡中编写了超声波新疆风采的类,在Timer.h中编写了计时器类。
让我们在三个标签中的每个标签中查看代码:
3.1 Ultrasonic_Sensors_to_Detect_Obstaclecles

Ultrasonic_Sensors_to_Detect_Obstacles
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | / * :Version 2.0 :作者:德拉戈斯·卡林 :电子邮件:dragos@intorobotics.com :License: BSD :Date: 06/04/2020 :最后更新:2020/09/04 :应用最佳实践方法并创建两个类:范围和计时器 * / #include“ 范围h” #include“ 计时器” / *为每个新疆风采创建一个对象* / 范围 范围(3, 2); 计时器 timerLoop; 虚空 设定() { 序列号.开始(9600); } 虚空 循环() { 如果 (timerLoop.isTimeForLoop(50)) { / *每50毫秒循环一次* / 序列号.打印("测量的距离为:"); 序列号.打印(范围.sensorRange()); 序列号.打印(“ 厘米”); timerLoop.startTimer(); } }//结束循环 |
上 11-12行 我们导入所需的类。
第15-16行: 我们正在使用面向对象的程序设计,因此我们必须实例化 范围 和 计时器 类创建一个对象和该类的实例。
第19行: 我们处于设置功能,我们要做的第一件事是打开串行端口并将数据速率设置为9600 bps。
第23和27行: 我们检查时间并每50毫秒发布一次。
3.2 范围h

标签范围
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #ifndef RANGE_H #定义RANGE_H #include“ 计时器” 计时器 Tm值; 类 范围 { 枚举 新疆风采状态 { TRIG_LOW, TRIG_HIGH, 回声_高 }; 新疆风采状态 _sensorState = TRIG_LOW; 整型 _TrigPin; 整型 _EchoPin; 整型 _triggerHigh = 10; 整型 _timerLow = 2; 上市: 范围(整型 TRIG_PIN, 整型 回声_PIN) { _TrigPin = TRIG_PIN; _EchoPin = 回声_PIN; pinMode(_TrigPin, 输出值); pinMode(_EchoPin, 输入); } 浮动 sensorRange() { 开关 (_sensorState) { 案件 TRIG_LOW: { trigStateLOW(); Tm值.startTimer(); 如果 (Tm值.isTimerReady(_timerLow)) { _sensorState = TRIG_HIGH; } } 打破; 案件 TRIG_HIGH: { trigStateHIGH(); Tm值.startTimer(); 如果 (Tm值.isTimerReady(_triggerHigh)) { _sensorState = 回声高; } } 打破; 案件 回声高: { trigStateLOW(); _timeDuration = 脉冲输入(_EchoPin, 高); _sensorState = TRIG_LOW; 返回 (_timeDuration * 0.034 / 2); } 打破; } } 私人的: 浮动 _timeDuration, _距离; 虚空 trigStateLOW() { digitalWrite(_TrigPin, 低); } 虚空 trigStateHIGH() { digitalWrite(_TrigPin, 高); } }; #万一 |
第1-2和68行: 防止标题包含多个内容。它检查是否有一个唯一值 范围h 被定义为。那如果’没有定义,它定义 范围h 并继续该页面的其余部分。
第4行: 我们导入我们的 计时器 类。
第6行: Tm值 对象是从类Timer创建的。
9-14行: 枚举新疆风采的状态。我们开始停用触发引脚,然后激活触发,最后,我们激活回波引脚以返回脉冲的持续时间。
第22-27行: 类的构造函数 范围。在构造函数中定义了引脚和引脚的模式。
第29-54行: 我使用switch语句一一选择新疆风采的状态。在第一种情况下 TRIG_LOW,请确保触发引脚为低电平,然后计数两毫秒,直到我们切换到 TRIG_HIGH –新疆风采的第二状态。
如果是 TRIG_HIGH,请确保触发引脚为高电平并计数十毫秒,直到切换到下一个状态 回声高.
如果是 回声高,确保触发引脚为低电平,读取脉冲的持续时间,将下一个状态设置为 TRIG_LOW,并以厘米为单位转换新疆风采的读数。
第57-65行: 在该类的私有部分中添加了两个功能。一种功能是将触发状态更改为低,另一种功能是将触发状态更改为高。
3.3计时器

Tab 计时器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #ifndef TIMER_H #定义TIMER_H 类 计时器 { 私人的: 未签名 长 _timerStart = 0; 上市: 虚空 startTimer() { _timerStart = 毫(); } 布尔 isTimerReady(整型 _mSec) { 返回 (毫() - _timerStart) < _mSec; } 布尔 isTimeForLoop(整型 _mSec) { 返回 (毫() - _timerStart) > _mSec; } }; #万一 |
第1,2和21行: 防止标题包含多个内容。它检查是否有一个唯一值 计时器 被定义为。然后,如果未定义,则定义 计时器 并继续该页面的其余部分。
第4-5行: 在课程的私有部分中,定义启动变量的时间。
第8-10行: 使用以下命令开始计时的功能 毫()。我更喜欢使用 毫() 代替 延迟() 有两个原因: 毫() 比 延迟(),并且是 延迟().
第12-18行: 两个函数做同样的事情,检查时间是否过去并返回 真正。根据情况,我们调用两个函数之一。
编译并将草图上传到Arduino。
阅读完本教程后,您将学习如何使用millis(),如何构建类,确定检测范围以及打印超声新疆风采的输出。
1条评论 » Write a comment
很棒的教程…而不是使用millis()为什么不’您使用micros()吗?以毫秒为单位的millis(),<2 ms or 2) {
curState = trigHigh;
timStart = sys;
}
打破;
案例trigHigh:
TrigPin(1);
如果(sys– timStart > 10) {
curState = echoHigh;
timStart = sys;
}
打破;
大小写echoHigh:
TrigPin(0);
timeDuration = 脉冲输入(echoPin,HIGH);
curState = trigLow;
打破;
}
序列号.print(“测量的距离为:“);
序列号.print(timeDuration / 29 / 2);
序列号.println(” cm”);
}