模块熟悉
第 15 课:超声波模块——量个距离
套件里唯一能告诉你"多少厘米"的模块,代价是它得除以 2
我是吴老师。这节课的模块,是套件里唯一一个能测距离的。
你先回头看看手上这些传感器,它们的"性格"是这样的:
| 模块 | 它能回答的问题 |
|---|---|
| 光敏 | 有多亮? |
| 按钮 | 按了没按? |
| 红外 | 前面有没有东西? |
| 超声波 | 前面那个东西,离我多少厘米? |
看到最后一行的分量没有? 红外只会喊一声"有东西!",然后就没词了。超声波会给你一个具体的数字。
这就是为什么倒车雷达用它、扫地机器人用它、你后面第 28 课的"倒车雷达"和第 30 课的"坐姿提醒器"也用它——因为"有多远"这件事,只有它能说。
看视频时注意的 3 件事
这一课有配套的录屏,先看一遍再往下读。
第一,数一数它有几根针。四根。 别的模块都是三根,它多一根。
| 针脚 | 干什么 |
|---|---|
| VCC | 电源 |
Trig |
触发——"喂,喊一声" |
Echo |
回响——"我听到了" |
| GND | 地 |
为什么多一根? 因为它要又喊又听。别的模块一根信号线就够了(要么是读、要么是写),它得一个脚负责"喊"、一个脚负责"听",一个脚干不了两件事。
第二,盯住 Trig 和 Echo 分别接在哪。 这俩在代码里是分开填的。接反了不会烧坏,但读数一定是错的——通常就是一个 0,或者一个吓死人的巨大数字。
第三,注意手掌移远的时候数字怎么变。 慢慢把手往远处移,看数字一点点变大。你会看到它不是完全平滑的——偶尔会跳一下。这不是坏了,别慌,后面第四、五节专门讲为什么。
一、认识它:那两只"眼睛"
模块最显眼的,是板子正面两个圆圆的金属筒,像两只眼睛:一个里头是发射头,负责"喊";一个是接收头,负责"听"。
它俩长得一模一样,你分不出来也正常。 好在不用分——板子已经焊好了,你只管接那四根针。
顺带说一句:超声波是声音,不是光。 它的频率高到人耳听不见(所以叫"超声"),但它跟声音是一回事——需要空气才能传,真空里它就是个哑巴。
这一条很重要,后面讲"为什么读数会跳"的时候要用到。
二、原理:对着山谷喊一声
超声波的原理,是这节课最不难的部分——因为它就是你小时候干过的事。
你站在山谷这头,对着对面喊一声"喂——",过一会儿听到"喂……喂……喂……"的回声。你怎么知道山谷有多远?看你喊出去到听见回声,中间隔了多久。
- 隔得短 → 山谷近
- 隔得长 → 山谷远
超声波模块干的就是这件事,一秒能喊几十次:
看图,从上往下三步走:
第一步,Trig 上给它一个 10 微秒的高电平。 这叫"喊一声"。10 微秒短到你根本反应不过来,但对板子来说够了。
第二步,它开始喊,同时把 Echo 拉高。 Echo 高着不动的这段时间,就是"喊出去到听见回声"的时间。 声音回来了,Echo 就落回低电平。
第三步,程序量出 Echo 高电平持续了多久,换算成距离。
所以这一整套东西,本质上就是一个"掐秒表"的活。 模块负责喊和听,板子负责计时。
注意
Echo给的是一个"持续时间",不是距离。 距离是你算出来的。这个区别很重要——它意味着:算错了,读数就是错的,而且是那种"看着挺像那么回事"的错。比如下面这个。
三、那个最经典的错误:别忘了除以 2
这是本节课最重要的一节。
声音是跑过去,再跑回来。它走的路,是你到物体的两倍。
所以:
距离 = 声速 × 时间 ÷ 2
那个 ÷ 2 是整节课最容易漏的东西。 而且它特别阴险——漏了它,程序照样跑,读数照样出,只是所有的数字都正好是真实距离的两倍。 你可能要过很久才发现:"咦,我明明量的是 30 厘米,它怎么说 60?"
来,一起算一遍,你就再也不会忘了。
声速在空气里大概是 340 米/秒。换成厘米每微秒就是 0.034 厘米/微秒——声音每走 1 微秒,前进 0.034 厘米。
那么,如果 Echo 高电平持续了 2000 微秒:
| 步骤 | 算出来 |
|---|---|
| 声音走的总路程 | 2000 × 0.034 = 68 厘米 |
| 这是来回的路程 | 所以真实距离要除以 2 |
| 真实距离 | 68 ÷ 2 = 34 厘米 |
漏掉 ÷ 2 的话,你会得到 68 厘米。差了整整一倍。
代码长这样
#define TRIG 4
#define ECHO 5
void setup() {
Serial.begin(115200);
pinMode(TRIG, OUTPUT); // Trig 是板子往外发信号,所以是 OUTPUT
pinMode(ECHO, INPUT); // Echo 是板子读它,所以是 INPUT
}
void loop() {
// 1. 先把 Trig 拉低一下,确保电平是干净的
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
// 2. 给它一个 10 微秒的高电平——"喊一声"
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
// 3. 量 Echo 高电平持续了多久(单位:微秒)
long duration = pulseIn(ECHO, HIGH);
// 4. 换算成厘米——注意那个 / 2!
float cm = duration * 0.034 / 2;
Serial.print(cm);
Serial.println(" cm");
delay(200);
}注意 pinMode 那两行,它俩是反的:
Trig是OUTPUT——板子往外发触发信号Echo是INPUT——板子往里读回响
这是你第一次见到一个模块上有两个信号脚、而且方向相反。 想不清的时候就用那句话问自己:这个脚上的信号,是板子发出去的,还是板子读进来的?
还有个细节值得你知道:
pulseIn如果一直等不到回声,它会等一秒钟然后返回 0。所以对着空气(没有东西反射)的时候,程序会明显卡一下——那不是死机,是它在傻等。这个现象你一定会遇到,先告诉你,免得到时候慌。
四、为什么读数会跳
第一次跑起来,你大概率会有点失望:这个数字怎么不安分? 手不动,它也在 33、34、33、35、34 之间晃,有时候还蹦一个 200 出来。
这是超声波的"天性",不是你的代码有问题。 三个原因:
第一,物体表面是什么材质。 声音遇到软的、多孔的东西——衣服、毛巾、海绵、窗帘——会被吸进去,几乎不反射。
声音被吸到哪去了? 变成了材料内部的一点点热。这就是为什么录音棚墙上贴满了软包——不是为了好看,是为了不让声音弹来弹去。
第二,角度。 超声波不是一根直线,它是喇叭形散出去的。物体正对着它,回波最强;歪一点,回波就弱一截。
第三,斜面和尖角。 声音打到一个斜面上,会像台球一样弹到别处去,根本不往回来。尖角更惨——它把声音散射到四面八方。
所以别拿单个读数做判断。 想让读数稳一点,最简单的办法是连续读几次,去掉最大最小,取中间那几个的平均。这个技巧你在做倒车雷达的时候一定会用到——总不能让蜂鸣器跟着读数一起抽风吧。
这跟第 13 课麦克风那节的思路是同一个:传感器的原始数据都是毛的,变干净是你的活,不是传感器的活。
五、它有量程:太近测不出,太远也测不出
太近——测不出。 物体贴到模块脸上了(大概两三厘米以内),它反而读不出来,或者给你个乱数。
为什么? 因为它刚"喊"完,还没切换到"听"的模式,回声就已经回来了——自己喊的声音还没停,怎么听得见回声? 这个区域有个专门的名字,叫盲区。
太远——超出量程。 一般这类模块的上限在四米左右(具体多少看你的模块,以实测为准)。再远,声音散得太厉害,回来的那点动静它听不见。这也解释了 pulseIn 那个"等一秒返回 0"——对着墙外或者天花板,读数就会是 0,或者一个明显不靠谱的大数。
所以你的程序里迟早要加一句"这个是有效读数吗"的判断:比如小于 2 厘米、大于 400 厘米的,直接丢掉不算。这一步不做,你的倒车雷达会被一个野数据吓得乱叫。
六、动手:拿尺子验一验
这节课的动手环节,是我最喜欢的——因为你能自己验证它对不对。
第一步:接线。
| 超声波 | 接到 |
|---|---|
| VCC | 3.3V |
| GND | GND |
Trig |
GPIO4 |
Echo |
GPIO5 |
第二步:跑上面的代码,打开串口监视器,用手在它前面晃。 看数字跟着你的手变大变小。
第三步——这一步是重点:把尺子拿出来。把一本书立在桌上,量出它到模块的距离,先量 10 厘米,然后看串口里读出来是多少。
- 对上了? 恭喜,你刚才亲手验证了一个物理公式。这不是"教程说它对",是你自己量出来的。
- 差了正好一倍? 那去看看公式里那个
÷ 2是不是漏了。 - 差一点点(你量 10 厘米,它说 12)? 正常。"你眼睛看到的位置"和"模块认定的位置"本来就不完全是一回事,加上声速是个近似值、温度也有影响,百分之几的误差很正常。
换几个距离再量:20 厘米、30 厘米、50 厘米,画个小表格记下来。你会发现越远误差越大——声音散得越开,回波越弱,越容易判早或判晚。
第四步:换材料挡。 手、书本、衣服、一块毛巾——同样放在 20 厘米的地方,读数一样吗?衣服和毛巾多半会让你读不到,或者数字跳得厉害。
做完这一步你就明白了一件事:超声波的"准",是"在特定条件下的准"。 换个材质、换个角度,它就不一样了。这不叫"不准",这叫"你要知道它的边界在哪"。
这跟第 14 课结尾那句是一回事——先搞清楚一个传感器的物理极限,再动手。
七、读数一直是 0,怎么查
这个故障你八成会碰到,我提前把排查顺序给你。
看这张图:不用串口,你只能对着一个不动的数字猜;用了串口,你能直接看到数值。第 7 课那句"先打印,再判断",在这儿就是救命的话。按顺序查,别跳步:
| 顺序 | 查什么 | 怎么查 |
|---|---|---|
| 1 | Trig / Echo 接反了吗 |
这是最常见的。对调一下试试,十秒钟的事 |
| 2 | VCC / GND 对吗,板上灯亮吗 | 灯不亮,后面全白搭 |
| 3 | 前面有东西吗?是不是太远了 | 对着天花板测,当然读不到 |
| 4 | 是不是太近了 | 挪到 5 厘米以外再试 |
| 5 | 物体是不是软的、斜的 | 换本书、正对着再试 |
| 6 | 最后才怀疑代码 | 代码里的 Trig/Echo 编号跟实际接线对得上吗 |
注意最后一行——代码排在最后,不是因为它不重要,是因为前面的更常见。
"先测,再猜"(第 5 课)、"先打印,再判断"(第 7 课)——这两句话你从第 5 课听到现在,今天终于用在一个真正的"疑难杂症"上了。
你以后面对的任何一块不工作的板子,排查顺序都是这个套路:先看电,再看线,再看信号,最后才改代码。
自测
答案与解析
多的是 Trig 和 Echo 这一对——Trig 负责触发发射(喊),Echo 负责输出回响(听)。别的模块只有一根信号线,是因为它们要么只读、要么只写;超声波得同时干这两件事,所以信号线要两根。接线时注意:Trig 是 OUTPUT,Echo 是 INPUT。
Echo 高电平持续了 2000 微秒,物体大概在多远?(声速按 340 m/s)答案与解析
2000 微秒 = 0.002 秒,声音走的总路程 = 340 × 0.002 = 0.68 米 = 68 厘米。但这 68 厘米是"去 + 回"的距离,所以真实距离要除以 2,约 34 厘米。忘了除以 2 是这里最经典的错误——程序照样跑、数字照样出,只是所有读数都正好是真实值的两倍,你可能很久都发现不了。
答案与解析
声音遇到软的、多孔的材料会被吸收,能量变成了那点材料内部的微小热量——录音棚贴满软包就是这个道理。回波一弱,模块就判不准,甚至完全收不到。同理还有"斜着放"和"尖角":声音会像台球一样弹到别处去,不往回来。
答题要点
答题要点应该包含:① 先看 Trig/Echo 有没有接反或接错脚(最常见);② 再看 VCC/GND 和板上电源灯;③ 确认前面确实有东西、而且没超出量程;④ 确认不是太近(盲区,两三厘米以内测不出);⑤ 确认物体不是软的、斜的;⑥ 最后才去对代码里的引脚编号。为什么代码排最后:因为前面那几项出问题的概率高得多,而且查起来只要几秒钟(对调一根线 vs 通读一遍代码)。这就是第 5 课"先测,再猜"和第 7 课"先打印,再判断"的顺序。
拓展声速是"340 米/秒",可这个数其实不是固定的。什么东西会影响它?影响有多大?
这个问题课上不讲,留给你自己找答案——**问 AI 是最好的办法**。
提示:搜"声速 温度 公式 331+0.6t"。想一想:冬天在室外测、夏天在室外测,同一个距离读数会差多少?这算不算一个"你必须知道的误差来源"?
拓展扫地机器人一边走一边测距,它是怎么做到不撞墙的?为什么很多扫地机器人后来改用激光了?
这个问题课上不讲,留给你自己找答案——**问 AI 是最好的办法**。
提示:搜"扫地机器人 激光雷达 LDS 超声波 避障"。想一想:超声波是喇叭形散出去的,这对"看清一个桌腿"来说是好事还是坏事?
本节你要动手做的事
- [ ] 认清四根针:
VCC、Trig、Echo、GND,接之前先断电 - [ ] 接好线:
Trig→GPIO4,Echo→GPIO5,用一个本子记下你接的是哪两个脚 - [ ] 跑通读数:手在它前面慢慢移动,看数字跟着变
- [ ] 拿尺子验证:量 10 / 20 / 30 / 50 厘米,记下读数和实际值的差
- [ ] 故意漏掉
÷ 2:把代码改成duration * 0.034,看读数变成什么样——亲眼见一次,以后就忘不了 - [ ] 换材料:手、书本、衣服、毛巾,同样距离各测一次,看哪个读不出来
- [ ] 试一次"没有东西":对着空气测,看程序卡一下然后打出 0(这就是
pulseIn在傻等);做完自测题
这节课你第一次拿到了一个"带单位"的读数。
前面所有的传感器给你的都是"相对值"——光敏读 3000,什么意思?不知道,得看你那个房间。而超声波说的是"34 厘米",这是个谁都听得懂的数。
代价是:这个数得你自己算,而且算错了它不会报错。
所以这节课真正教你的,不是 pulseIn 这个函数,是"换算"这件事——一个物理量,从传感器到你手上,中间隔了几步?每一步有没有可能出错?那步 ÷ 2 有没有漏?
这个习惯你后面会一直用。 比如下一课的温度,DHT11 给你的是一串二进制位,你得知道怎么把它读成"26.5°C",不然读出来就是个莫名其妙的整数。
而且你今天验证公式的方式,是拿尺子量。 这件事听起来特别土——但它就是硬件工程的样子。 没有人靠"我觉得应该对"来验收,都是拿个东西量一下。
从今天起,你手上那块板子有了"感知空间"的能力。 这是它第一次知道"世界有多大"。
下一节我们学温湿度传感器 DHT11——它跟今天这个正好相反。
超声波是你自己算的,算错了也没人管你;DHT11 是模块自己算好了,直接告诉你"26.5 度"。听起来省事多了,但它有另一套脾气——它用一种叫"单总线"的方式跟你说话,讲错一个字,它转身就走。
下节课见。