树莓派Model B+超声波测距模块控制继电器故障排查求助
树莓派超声波检测传送带状态控制继电器的代码问题排查与修复
我帮你梳理下代码里的核心问题,再给你对应的修复方案和完整代码:
一、代码里的明显错误
- GPIO引脚冲突:你把超声波的
TRIG和继电器的RelayPin都设成了11号引脚!这会导致两个模块同时占用同一个GPIO,硬件直接冲突,肯定没法正常工作,必须给其中一个换个空闲引脚。 - 语法与变量名错误:
- 循环里你定义了
dis12 = distance(),但判断的时候写成了if dis = dis2——首先变量名写错了(dis12vsdis2),其次Python里判断相等要用==,单等号是赋值,这行代码会直接抛出语法错误。
- 循环里你定义了
- 逻辑不符合需求:你的需求是“距离保持不变持续5秒”才关闭继电器,但当前代码只是间隔5秒测两次距离就判断相等,这太粗糙了——比如传送带只是短暂停顿一下,5秒后又动了,也会触发,而且两次测量相等也不代表中间的5秒距离都没变。
- 超声波测距函数的计时问题:原
distance函数里的time1和time2是在while循环内部赋值,每次循环都会覆盖,这样计算出的时间差是错的,应该在ECHO引脚状态变化的瞬间记录时间。
二、修正后的完整代码
#!/usr/bin/env python import RPi.GPIO as GPIO import time # 修正引脚冲突,给继电器换个空闲引脚 TRIG = 11 ECHO = 12 RelayPin = 13 # 换成空闲的13号引脚,避免和TRIG冲突 def setup(): GPIO.setmode(GPIO.BOARD) GPIO.setup(TRIG, GPIO.OUT) GPIO.setup(ECHO, GPIO.IN) GPIO.setup(RelayPin, GPIO.OUT) GPIO.output(RelayPin, GPIO.HIGH) # 初始继电器保持工作状态(默认HIGH为吸合) def distance(): GPIO.output(TRIG, 0) time.sleep(0.000002) GPIO.output(TRIG, 1) time.sleep(0.00001) GPIO.output(TRIG, 0) # 修正计时逻辑:等待ECHO变高时开始计时 while GPIO.input(ECHO) == 0: pass # 等待ECHO触发信号 time1 = time.time() # 等待ECHO变低时结束计时 while GPIO.input(ECHO) == 1: pass time2 = time.time() during = time2 - time1 return during * 340 / 2 * 100 # 转换为厘米单位 def loop(): stable_start_time = None # 记录距离开始稳定的时间点 last_distance = None # 记录上一次的测量距离 tolerance = 1 # 允许的距离误差(厘米),避免超声波微小波动误判 while True: current_dis = distance() print("%.2f cm" % current_dis) # Python2格式,Python3可改成f"{current_dis:.2f} cm" # 判断当前距离是否和上次测量值在误差范围内 if last_distance is not None and abs(current_dis - last_distance) <= tolerance: # 距离稳定,开始计时或持续计时 if stable_start_time is None: stable_start_time = time.time() else: # 检查稳定时长是否达到5秒 if time.time() - stable_start_time >= 5: print("传送带已停止,关闭继电器") GPIO.output(RelayPin, GPIO.LOW) else: # 距离发生变化,重置计时并恢复继电器工作 stable_start_time = None GPIO.output(RelayPin, GPIO.HIGH) last_distance = current_dis time.sleep(0.1) # 缩短采样间隔,提升监测精准度 def destroy(): GPIO.output(RelayPin, GPIO.HIGH) GPIO.cleanup() # 释放GPIO资源 if __name__ == '__main__': setup() try: loop() except KeyboardInterrupt: destroy()
三、关键修改说明
- 引脚冲突修复:把继电器引脚换成了13号,你可以根据自己GPIO扩展板的空闲引脚调整,只要不和TRIG/ECHO重复就行。
- 超声波计时逻辑修正:现在会在ECHO引脚刚变高时记录开始时间,刚变低时记录结束时间,计算出的距离更准确。
- 符合需求的稳定检测逻辑:
- 增加了误差容忍度,避免超声波的微小波动导致误判。
- 用
stable_start_time持续记录距离稳定的时长,只有当稳定状态持续满5秒时,才关闭继电器。 - 如果距离重新开始变化,会立即重置计时并恢复继电器的工作状态。
- 语法与细节优化:修正了判断相等的语法错误、变量名错误,同时优化了采样间隔和打印格式。
内容的提问来源于stack exchange,提问作者ryan tea
相关产品推荐
相关产品推荐

