(7)ESP32 Python 使用看门狗 脱坑HC-SR04

超声波测距与WDT应用

在使用超声波探测器的时候,因为计算距离是需要靠echo引脚的高低电平变化的时间差来进行数据的判断。在某些未知的情况下,有可能echo引脚不会返回高电平,程序将会一直等待返回。
解决这个问题考虑使用TIMMER或者WDT来解决,这里我使用WDT(看门狗)来解决。
先来一段百度上关于看门狗的定义。

**看门狗,又叫watchdog timer,是一个定时器电路,一般有一个输入,叫喂狗(kicking the dog/service the dog),一个输出到MCU的RST端,MCU正常工作的时候,每隔一段时间输出一个信号到喂狗端,给 WDT清零,如果超过规定的时间不喂狗(一般在程序跑飞时),WDT定时超过,就会给出一个复位信号到MCU,使MCU复位。防止MCU死机. 看门狗的作用就是防止程序发生死循环,或者说程序跑飞。
**
接着上一篇文章的代码进行改进。

import utime
from driver import GPIO
from machine import WDT # 引用WDT
class HAASHCSR04:
    wdt = None
    triger_gpio = None
    echo_gpio = None
    def __init__(self): 
        global triger_gpio, echo_gpio, wdt 
        wdt = WDT(timeout=2000)    # 初始化WDT,设定喂狗时间为2S
        triger_gpio = GPIO()
        triger_gpio.open('hc_triger')
        triger_gpio.write(0)
        echo_gpio = GPIO()
        echo_gpio.open('hc_echo')
        echo_gpio.write(0)
        
    def start_scan(self): 
        cnt = 0 
        
        while True:
            try
<think>我们正在讨论使用ESP32控制机器人实现固定路线移动、避障和人员检测功能。根据之前对话,用户提到需要实现固定路线、避障,并且现在增加了人员检测功能。我们需要整合这些功能,并考虑硬件配置和程序框架。参考引用[1]中提到了传感器配置,我们可以借鉴:-超声波传感器:用于测距和避障-红外传感器:用于检测碰撞和边界-加速度传感器和陀螺仪:用于姿态和方向控制(在固定路线中可能需要)此外,为了实现人员检测,我们可能需要添加:-红外热释电传感器(PIR)或-摄像头(如OV7670)结合图像识别(但ESP32处理能力有限,可能考虑使用简单的人体红外传感器)因此,硬件配置建议:-主控:ESP32(具有WiFi/蓝牙,便于扩展)-电机驱动:L298N或TB6612FNG-轮子:直流电机或步进电机,带编码器(可选,用于精确控制移动距离)-避障传感器:超声波传感器(如HC-SR04)和红外避障传感器(用于近距离)-人员检测:人体红外传感器(HC-SR501)或更高级的,如ESP32-CAM(但图像处理复杂)-姿态传感器:MPU6050(加速度计+陀螺仪)用于保持方向(固定路线可能需要)功能实现思路:1.固定路线:可以使用预编程的指令(如前进1米,左转90度等),结合编码器或定时控制。更精确的可以使用PID控制电机转速,结合MPU6050进行方向校准。2.避障:在移动过程中,超声波传感器实时检测前方障碍物,红外传感器检测两侧近距离障碍物。当检测到障碍物时,停止并重新规划路径(如绕行)。3.人员检测:使用人体红外传感器检测附近是否有人。如果检测到人,可以触发某种行为(如停止、避让或发出警报)。程序框架:我们将使用ArduinoIDE进行ESP32编程。主要步骤:a.初始化电机驱动、传感器(超声波、红外避障、人体红外)和MPU6050(如果需要)。b.固定路线移动:编写函数控制电机按照预定的路径移动(例如,前进一定时间或距离,然后转向)。c.在移动过程中,循环读取避障传感器,如果检测到障碍物,则中断固定路线,执行避障动作(如停止、转向避开,然后尝试回到原路线)。d.同时,循环读取人体红外传感器,如果检测到人,则执行相应动作(如停止并报警,或者通过WiFi发送通知)。注意:避障和人员检测都是中断性质的,因此主循环中需要不断检测这些传感器。下面给出一个简化的代码框架:```cpp#include<Wire.h>//如果需要MPU6050,可以包含相关库,比如Adafruit_MPU6050//定义引脚#defineTRIG_PIN5//超声波Trig#defineECHO_PIN18//超声波Echo#defineIR_OBSTACLE_PIN19//红外避障传感器#definePIR_PIN23//人体红外传感器//电机驱动引脚(以L298N为例)#defineMOTOR_A_IN112#defineMOTOR_A_IN214#defineMOTOR_B_IN127#defineMOTOR_B_IN226#defineENA13//使能A#defineENB25//使能Bvoidsetup(){Serial.begin(115200);//初始化传感器引脚pinMode(TRIG_PIN,OUTPUT);pinMode(ECHO_PIN,INPUT);pinMode(IR_OBSTACLE_PIN,INPUT);pinMode(PIR_PIN,INPUT);//初始化电机驱动引脚pinMode(MOTOR_A_IN1,OUTPUT);pinMode(MOTOR_A_IN2,OUTPUT);pinMode(MOTOR_B_IN1,OUTPUT);pinMode(MOTOR_B_IN2,OUTPUT);pinMode(ENA,OUTPUT);pinMode(ENB,OUTPUT);//初始化PWM通道(ESP32有16个通道,0-15)ledcSetup(0,30000,8);//通道0,30KHz,8位分辨率ledcSetup(1,30000,8);//通道1ledcAttachPin(ENA,0);ledcAttachPin(ENB,1);}//超声波测距函数floatgetDistance(){digitalWrite(TRIG_PIN,LOW);delayMicroseconds(2);digitalWrite(TRIG_PIN,HIGH);delayMicroseconds(10);digitalWrite(TRIG_PIN,LOW);longduration=pulseIn(ECHO_PIN,HIGH);returnduration*0.034/2;//声速340m/s,除以2(往返)}//控制电机函数voidmotorControl(intspeedA,intspeedB,boolforwardA,boolforwardB){//设置电机A方向digitalWrite(MOTOR_A_IN1,forwardA?HIGH:LOW);digitalWrite(MOTOR_A_IN2,forwardA?LOW:HIGH);//设置电机B方向digitalWrite(MOTOR_B_IN1,forwardB?HIGH:LOW);digitalWrite(MOTOR_B_IN2,forwardB?LOW:HIGH);//设置速度(PWM)ledcWrite(0,speedA);ledcWrite(1,speedB);}//停止电机voidstopMotor(){ledcWrite(0,0);ledcWrite(1,0);}//固定路线移动函数voidfollowFixedRoute(){//示例:前进2秒,右转1秒,再前进2秒motorControl(200,200,true,true);//前进,速度200(0-255)delay(2000);motorControl(150,0,true,true);//右转(右轮不动,左轮转)delay(1000);motorControl(200,200,true,true);delay(2000);stopMotor();}voidloop(){//读取避障传感器floatdistance=getDistance();intirObstacle=digitalRead(IR_OBSTACLE_PIN);//0表示有障碍,1表示无(根据传感器逻辑可能不同)//读取人员检测intpersonDetected=digitalRead(PIR_PIN);//高电平表示检测到人//如果检测到人,停止并报警(这里用串口打印代替)if(personDetected==HIGH){Serial.println("Persondetected!Stopping.");stopMotor();//可以添加其他动作,比如声音报警delay(1000);//等待1秒//注意:这里只是示例,实际可能需要更复杂的处理}//避障判断:如果超声波检测到障碍物(比如小于30cm)或者红外避障传感器检测到障碍物,则避障if(distance<30||irObstacle==0){Serial.println("Obstacledetected!Avoiding.");stopMotor();delay(500);//避障动作:后退一点,然后右转motorControl(150,150,false,false);//后退delay(500);motorControl(150,0,true,true);//右转delay(500);stopMotor();//避障后重新回到固定路线?这里需要根据情况调整//但注意,固定路线可能已经被中断,所以需要重新规划或继续执行后续步骤}else{//没有障碍物,执行固定路线followFixedRoute();}}```注意:上述代码只是一个框架,实际中固定路线和避障可能会冲突。我们需要设计一个状态机,使得机器人能够完成固定路线,同时遇到障碍物时避障,然后尝试继续完成路线。另外,人员检测作为更高优先级的中断。优化方向:-使用编码器反馈实现精确距离控制。-使用MPU6050校准方向,避免转向偏差。-避障策略可以更复杂(如寻找最佳绕行方向)。-人员检测后,可能需要持续跟踪或者等待人员离开。由于ESP32的资源限制,复杂的图像识别人员检测可能不太现实,因此建议使用热释电红外传感器(PIR)进行简单的人体检测。以上是一个基本的实现方案,用户可以根据实际硬件和需求调整。§§相关问题§§1.如何为ESP32机器人添加编码器反馈以实现精确移动控制?2.使用ESP32-CAM进行人员检测有哪些可行的方法?3.如何设计状态机来协调固定路线、避障和人员检测这三个功能?4.在避障过程中,如何让机器人回到原来的固定路线上?</think>以下是针对使用ESP32控制机器人实现固定路线移动、避障及人员检测功能的完整解决方案: ### 一、硬件配置建议 1. **核心控制器** ESP32-WROOM-32D(双核处理器,支持WiFi/蓝牙,适合多任务处理) 2. **运动系统** - 电机:2×直流减速电机(带编码器) - 驱动模块:TB6612FNG电机驱动板 - 轮子类型:橡胶轮胎(直径6-8cm) $$ \text{移动精度} = \frac{\text{编码器脉冲数}}{\text{轮周长}} \times \text{减速比} $$ 3. **感知系统** | 功能 | 传感器 | 检测范围 | 安装位置 | |---|---|---|---| | 固定路线 | 红外循迹模块×3 | 1-5cm | 底盘前部 | | 避障 | HC-SR04超声波×2 | 2-400cm | 前方/两侧 | | 人员检测 | HC-SR501 PIR传感器 | 5-7m | 机器人顶部 | | 防跌落 | 红外接近开关×2 | 2-30cm | 底盘四角 | 4. **扩展接口** - I²C接口:MPU6050陀螺仪(用于路径校准) - UART接口:预留GPS模块(室外导航) ### 二、软件架构设计 ```mermaid graph TD A[主控制器 ESP32] --> B[运动控制模块] A --> C[路径跟踪模块] A --> D[多级避障系统] A --> E[人员检测逻辑] B --> F[PID电机控制] C --> G[红外循迹算法] D --> H[超声波分层检测] E --> I[热释电信号处理] ``` ### 三、核心代码实现 ```cpp // 引脚定义 #define TRIG_LEFT 12 // 左侧超声波Trig #define ECHO_LEFT 13 // 左侧超声波Echo #define PIR_PIN 14 // 人员检测传感器 #define TRACE_L 27 // 左侧循迹传感器 // 路径跟踪状态机 void pathTracking() { bool leftTrace = digitalRead(TRACE_L); bool rightTrace = digitalRead(TRACE_R); if(leftTrace && !rightTrace) { motorTurn(LEFT, 30); // 左转修正 } else if(!leftTrace && rightTrace) { motorTurn(RIGHT, 30); // 右转修正 } else { motorForward(SPEED_NORMAL); // 直行 } } // 多级避障策略 void obstacleAvoid() { float dist = getUltrasonicDist(TRIG_FRONT, ECHO_FRONT); if(dist < EMERGENCY_DIST) { // 紧急制动距离 emergencyStop(); replanPath(); // 路径重规划 } else if(dist < WARNING_DIST) { // 预警距离 adaptiveSpeed(dist); // 动态调速 } } // 人员检测处理 void personDetection() { if(digitalRead(PIR_PIN) == HIGH) { logPersonDetected(); // 记录检测事件 if(safetyModeEnabled) { stopMotors(); // 安全模式停止 playAlertTone(); // 发出提示音 } } } // 主循环 void loop() { pathTracking(); // 固定路线跟踪 obstacleAvoid(); // 实时避障 personDetection(); // 人员监测 vTaskDelay(10); // FreeRTOS任务延时 } ``` ### 四、关键算法说明 1. **固定路线跟踪** 采用三路红外循迹传感器: $$ \text{偏差值} = k_p \times \Delta_{position} + k_d \times (\Delta_{position} - \Delta_{prev}) $$ 其中 $k_p=0.8$, $k_d=0.2$(需现场调试) 2. **分层避障策略**: - 50cm外:正常速度 - 30-50cm:线性降速 $v = v_{max} \times \frac{d - d_{min}}{d_{max} - d_{min}}$ - 20cm内:紧急转向+路径重规划 3. **人员检测优化**: - 信号滤波:5秒移动窗口平均 - 误触发抑制:双检测阈值(持续高电平>1s才触发) ### 五、调试要点 1. **循迹校准**: ```python # 地面反射值测试脚本 def calibrate_line_sensor(): white_val = read_sensor(WHITE_SURFACE) black_val = read_sensor(BLACK_LINE) threshold = (white_val + black_val) * 0.35 # 动态阈值 ``` 2. **电机PID调参**: ```cpp // Ziegler-Nichols参数整定法 void tunePID() { setGains(Kp=0.6, Ki=0.001, Kd=0.2); // 初始值 observeOvershoot(); adjustBasedOnResponse(); } ``` ### 六、安全设计 1. **紧急停止电路**:硬件看门狗+物理急停按钮 2. **双电源管理**: - 主电源:18650锂电池组(7.4V) - 备份电源:超级电容(5V/1F) 3. **故障代码系统**: - 0x01:电机过流 - 0x02:传感器失效 - 0x05:人员检测超时 > **重要提示**:在人员密集区域使用时,建议设置安全半径 $R_{safe} \geq 1.5m$,当检测到人员进入此区域时触发降速模式[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炒陈饭老司机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值