深色模式
第 12 章:看懂四路循迹代码
本章任务
看懂四路循迹传感器的读取代码。巡线小车就靠它:四个探头排成一排,检测地上的黑线在哪一路。
接线回顾
| 循迹模块 | Pico | 说明 |
|---|---|---|
| VCC | 3V3 | 3.3V 供电 |
| GND | GND | 共地 |
| X1 通道 | GP11 | 数字输出 |
| X2 通道 | GP10 | 数字输出 |
| X3 通道 | GP12 | 数字输出 |
| X4 通道 | GP13 | 数字输出 |
特别提醒:四个探头的物理排列(从左到右)是 X2、X1、X3、X4,不是 1234 顺序!读数对不上时先查这里。
传感器原理
数字输出型传感器,每一路只报两种状态。探头向下发射红外光并接收回波,据此判断:
- 压到黑色:黑色吸光,探头收不到回波,输出
0,模块上的指示灯亮 - 对着白色:白色反射回波,输出
1,指示灯灭
注意这和"探测到东西 = 1"的直觉正好相反:压黑线读 0、灯亮;压白面读 1、灯灭。先记住这个对应关系,再看后面的代码。
Mind+ 生成的典型代码
python
from machine import Pin # 引脚工具
import time # 时间工具
pins = [10, 11, 12, 13] # 四路探头接的引脚号(一个列表)
sensors = [Pin(p, Pin.IN) for p in pins] # 一口气把四路都设为输入模式
while True: # 一直重复检测
values = [s.value() for s in sensors] # 一口气读出四路的值,存成列表
# 比如 [1, 0, 1, 1] 表示第 2 路压到黑线
print(f"GP10={values[0]} GP11={values[1]} GP12={values[2]} GP13={values[3]}")
for i, v in enumerate(values): # 逐路检查(i 是第几路,v 是读数)
if v == 0: # 这路压到黑线了(黑 = 0)
print(f" -> GP{pins[i]} 检测到黑线")
print("-" * 30) # 打印一条分隔线,方便看
time.sleep(0.5) # 每 0.5 秒检测一轮代码讲解
这段代码展示了第 6 章"列表 + 循环"的实战威力:
[Pin(p, Pin.IN) for p in pins]:列表推导,一行顶四行——把 10、11、12、13 四个引脚都登记成输入[s.value() for s in sensors]:同样一行,把四路读数全收进values列表enumerate(values):遍历时同时拿到"第几路"(i)和"读数"(v),方便报告是哪一路发现了黑线
读数 [1, 0, 1, 1] 表示:GP11(X1 通道)正压着黑线,其余三路对着白色。
运行效果
程序每 0.5 秒打印一次四路读数。把黑色胶带移到某个探头下方,对应那一路就从 1 变 0,模块上对应的指示灯也会亮。
常见坑
- 极性和直觉相反:压黑线 = 0、灯亮;白色区域 = 1、灯灭——记反了,后面所有判断都会跟着错
- 悬空也读 0:把模块拿在手里悬空(探头离地太远)时收不到回波,读数和压黑线一模一样。调程序时要把探头对着铺好黑线的纸面,别举着看
- 四路物理顺序是 X2X1X3X4——读数不符先查编号
- 读数在 0/1 之间乱跳:环境光干扰,调整探头高度(离纸面约 1~2cm 最佳)或适当遮光
想一想
读数
[1, 1, 0, 1]表示黑线在哪一路?对应哪个引脚、哪个探头编号?💡 查看答案
是第三路(
values[2])检测到黑线,对应引脚 GP12、探头编号 X3。别忘了物理排列是 X2、X1、X3、X4——所以 X3 实际上是从左数第三个探头。如果把四路读数加起来(
sum(values)),和为 4 说明什么?和为 0 说明什么?💡 查看答案
- 和为 4:四路全是白色——黑线完全丢了(循迹小车最怕的情况)
- 和为 0:四路全是黑色——可能整张纸都是黑的、遇到了终点横线,或者探头离纸面太近、太灵敏
