Raspberry Pi Pico上HC-SR04超声波传感器工作异常求助
HC-SR04超声波传感器在Raspberry Pi Pico上的测量异常分析
问题概述
在Raspberry Pi Pico上使用C/C++开发HC-SR04驱动时,出现以下异常:
- 测量距离始终比实际值小约30%
- 偶尔触发第一个while循环超时,输出
I got here 1 - 无规律出现
0.02cm这类极小测量值
驱动代码
#include <FreeRTOS.h> #include <task.h> #include <stdio.h> #include <queue.h> #include <memory> #include "pico/stdlib.h" #include "pico/binary_info.h" #include "one_wire.h" #include "LCD_I2C.hpp" #include "i2c-display-lib.h" #include "hardware/gpio.h" #include "hardware/timer.h" void setupUltrasonicPins(uint trigPin, uint echoPin) { gpio_init(trigPin); gpio_init(echoPin); gpio_set_dir(trigPin, GPIO_OUT); gpio_set_dir(echoPin, GPIO_IN); gpio_pull_up(echoPin); } int getPulse(uint trigPin, uint echoPin) { int loop1 = 0; int loop2 = 0; sleep_us(2); gpio_put(trigPin, 1); sleep_us(20); gpio_put(trigPin, 0); sleep_us(2); while (gpio_get(echoPin) == 0) { loop1++; sleep_us(1); if(loop1 > 5000){ printf("\n I got here 1"); break; } } while (gpio_get(echoPin) != 0 ) { loop2++; sleep_us(1); if(loop2 > 3000){ printf("I got here 2"); return 0; } } return loop2; } float getCm(uint trigPin, uint echoPin) { int pulseLength = getPulse(trigPin, echoPin); return (float)pulseLength/2 * 0.0343; } int main() { stdio_init_all(); //sleep_ms(10000); uint trigPin = 17; uint echoPin = 16; setupUltrasonicPins(trigPin, echoPin); while(1){ printf("\n %.2f cm",getCm(trigPin, echoPin)); sleep_ms(100); } }
输出示例
31.59 cm 31.73 cm 31.59 cm 0.02 cm 31.59 cm 31.59 cm 31.73 cm 32.02 cm 31.59 cm 31.61 cm 31.86 cm 31.61 cm 31.73 cm 31.66 cm 31.86 cm 31.88 cm 31.88 cm 31.88 cm 32.00 cm I got here 1 0.00 cm I got here 1 0.00 cm 31.88 cm 31.61 cm 31.61 cm 31.88 cm 31.92 cm I got here 1 0.00 cm 31.88 cm 31.88 cm 32.00 cm 0.02 cm 0.02 cm 31.59 cm 31.59 cm 31.88 cm 32.16 cm 0.02 cm 0.00 cm 32.43 cm 32.16 cm 32.43 cm I got here 1 0.00 cm I got here 1 0.00 cm
硬件说明
实际使用引脚:触发引脚17,回波引脚16;忽略连接示意图中的蜂鸣器。
异常原因分析
1. 测量值偏小30%
- 软件计时精度不足:使用
sleep_us(1)配合循环计数的方式无法保证严格1微秒计时,循环指令执行、sleep_us调度开销都会导致实际计数的loop2远小于真实回波脉冲时长,最终距离被低估。 - 电平不匹配隐患:HC-SR04是5V工作器件,而Pico GPIO输出为3.3V,未做电平转换时,3.3V触发信号可能无法稳定触发传感器,导致回波脉冲输出异常,间接影响距离计算。
2. 第一个while循环超时(输出I got here 1)
- 回波引脚错误上拉:HC-SR04回波引脚未检测到回波时输出低电平,代码中添加的上拉电阻会强制拉高引脚电平,与传感器输出冲突;若传感器未正常触发,回波引脚持续为低,循环会一直等待直至超时。
- 触发后检测时机延迟:触发信号结束后调用
sleep_us(2)再检测回波,可能错过传感器回波信号起始沿,导致循环一直等待低电平状态。
3. 无规律出现极小值(如0.02cm)
- 信号干扰与电平不稳定:电平不匹配或无屏蔽布线会导致回波信号被噪声干扰,出现虚假电平跳变,使第二个计数循环提前退出,
loop2数值极小,计算出接近0的距离。 - 超时逻辑缺陷:第二个循环超时直接返回0,会产生
0.00cm结果;若循环仅计数1-2次就因干扰退出,就会出现0.02cm这类极小值。
解决建议
- 修正电平匹配:给触发引脚添加3.3V转5V电平转换电路,回波引脚添加5V转3.3V电平转换电路,确保传感器与Pico信号兼容。
- 替换为硬件计时:使用Pico的
hardware/timer模块或GPIO中断精确测量回波脉冲时长,比如用timer_get_time()记录回波起始和结束时间戳,彻底消除软件计时误差。 - 移除回波引脚上拉:删除
gpio_pull_up(echoPin),避免与传感器输出信号冲突。 - 优化检测时机:移除触发后的
sleep_us(2),触发信号结束后立即开始检测回波信号。 - 添加数据滤波:对多次测量结果取平均值,过滤小于1cm或大于HC-SR04最大量程(400cm)的异常值,提升数据稳定性。
内容的提问来源于stack exchange,提问作者Vlad Dobritoiu
相关产品推荐
相关产品推荐

