基于MicroPython与ESP32的超声波测距仪开发实战

发布时间:2026/11/9 2:37:53

基于MicroPython与ESP32的超声波测距仪开发实战 1. 项目概述从想法到实物的距离感知最近在整理工作室的物料发现手头积攒了不少ESP32开发板和HC-SR04超声波传感器。这些硬件单独看都是好东西但总感觉没发挥出全部价值。一个偶然的念头冒出来能不能用它们快速做一个即插即用、带显示功能的距离测量工具比如测量一下书架到墙面的精确距离或者给DIY的智能小车做个简易的避障探头。这个想法让我立刻想到了MicroPython——一种运行在微控制器上的Python实现。它语法简洁交互性强对于快速原型开发来说简直是神器。于是“基于MicroPython的距离测量仪”这个项目就正式启动了。这个项目的核心目标很明确利用ESP32作为主控驱动HC-SR04超声波传感器测量距离并将结果实时显示在一块OLED屏幕上。整个过程我们希望完全用MicroPython来实现从传感器数据读取、距离计算到最终的结果显示。它不仅仅是一个简单的代码拼接更涉及到MicroPython环境部署、硬件引脚驱动、定时器使用、数据显示优化等一系列嵌入式开发中的实际问题。无论你是想学习MicroPython硬件编程的初学者还是希望为某个创意项目快速添加距离感知功能的开发者这个从零到一的构建过程都能提供清晰的路径和可复现的细节。2. 核心硬件选型与电路设计思路2.1 主控芯片为什么是ESP32在众多微控制器中选择ESP32作为本项目的主控是经过多方面权衡的。首先ESP32内置Wi-Fi和蓝牙虽然本项目暂未用到无线功能但这为未来的功能扩展如将测量数据上传到服务器或通过手机APP查看预留了巨大的空间。其次ESP32拥有双核处理器和丰富的外设接口运行MicroPython解释器流畅能够轻松应对传感器数据采集和屏幕刷新这类任务。最重要的是ESP32在MicroPython社区的支持非常完善有大量现成的库和活跃的论坛遇到问题容易找到解决方案。相较于传统的Arduino开发方式使用MicroPython on ESP32的优势在于开发效率。我们无需复杂的IDE配置和编译下载过程通过串口工具如PuTTY、Thonny就能直接以交互式命令或运行脚本的方式操作硬件调试过程直观快捷。对于快速验证想法和迭代功能这种“所见即所得”的体验是无与伦比的。2.2 感知单元HC-SR04超声波传感器工作原理HC-SR04是目前最普及、性价比极高的超声波测距模块。它的原理并不复杂模块上有一个超声波发射器和一个接收器。工作时我们给Trig引脚一个至少10微秒的高电平脉冲模块便会自动发射一组8个40kHz的超声波。超声波在空气中传播遇到障碍物后反射回来被接收器捕获。模块内部的电路会监测这个回波并在Echo引脚输出一个高电平脉冲该脉冲的宽度与超声波从发射到返回所经历的时间成正比。因此测距的核心公式就是距离 (高电平时间 * 声速) / 2。声速在常温下约为340m/s。我们需要用微控制器精确测量Echo引脚高电平的持续时间。这里有一个关键点HC-SR04的有效测量范围官方标称是2cm到400cm但实际使用中在2cm以内由于回波与发射波重叠可能导致无法测量而超过4米后回波信号会变得非常微弱测量结果不稳定。对于精度要求不高的场景误差在几毫米到1厘米它完全够用。2.3 显示单元OLED屏幕的选择与优势为了能直观地看到测量结果我选择了一块0.96英寸的I2C接口OLED屏幕。选择它主要基于以下几点考虑一是自发光无需背光在暗环境下显示清晰且省电二是分辨率通常为128x64足以显示数字、字符和简单的图形三是I2C接口仅需两根数据线SDA, SCL即可通信极大节省了ESP32宝贵的GPIO资源。在MicroPython中通常使用ssd1306库来驱动这类OLED屏幕。我们需要将屏幕的SDA和SCL引脚分别连接到ESP32的任意I2C引脚上例如GPIO21和GPIO22并在代码中初始化I2C总线及屏幕对象。之后就可以像在电脑上打印信息一样调用方法将距离数值“画”到屏幕上了。2.4 电路连接与供电方案整个系统的连接非常简单清晰ESP32与HC-SR04将HC-SR04的Vcc和Gnd分别连接到ESP32的3.3V和GND。特别注意HC-SR04的工作电压是5V但其逻辑电平与3.3V系统兼容。经过实测直接使用ESP32的3.3V为其供电在短距离测量时工作正常。若追求最稳定的长距离性能可以考虑使用外部5V电源为传感器单独供电但Echo引脚信号仍需接入ESP32ESP32的GPIO可耐受5V输入。Trig引脚连接至ESP32的任意GPIO如GPIO5Echo引脚连接至另一GPIO如GPIO18。ESP32与OLEDOLED的VCC接3.3VGND接GND。SDA接GPIO21SCL接GPIO22。供电整个系统可通过ESP32开发板的Micro-USB口供电非常方便。如果希望做成独立设备可以连接一个容量合适的锂电池到ESP32的VIN引脚。注意在面包板上搭建电路时务必确保电源和地线连接牢固避免虚接导致传感器或屏幕工作不稳定。所有信号线不宜过长以减少干扰。3. MicroPython环境部署与基础驱动3.1 为ESP32刷入MicroPython固件这是所有工作的第一步。你需要从MicroPython官网下载针对ESP32的最新稳定版固件.bin文件。然后使用刷机工具如esptool.py通过USB转串口模块连接到ESP32的串口引脚。刷机命令通常如下在电脑命令行中执行具体端口号需根据实际情况修改esptool.py --chip esp32 --port COM3 erase_flash esptool.py --chip esp32 --port COM3 --baud 460800 write_flash -z 0x1000 esp32-xxx.bin第一条命令擦除原有固件第二条命令写入新的MicroPython固件。刷写成功后通过串口工具如Thonny IDE自带的终端或PuTTY以115200的波特率连接ESP32你应该能看到MicroPython的交互式解释器提示符。这意味着你的ESP32已经变成了一个Python运行时环境。3.2 安装必要的驱动库MicroPython固件本身并不包含针对特定硬件如HC-SR04, OLED的驱动库我们需要手动上传。以Thonny IDE为例这是一个极其方便的选择它集成了代码编辑、库管理和串口终端。安装HC-SR04驱动在PC上你可以找到一个名为hcsr04.py的MicroPython库文件可以从开源社区如GitHub获取。在Thonny中打开这个文件然后选择“文件” - “另存为”在弹出的对话框中选择“MicroPython设备”将其保存到ESP32的根目录下。这样在你的主程序中就可以通过import hcsr04来使用它了。安装OLED驱动同理找到ssd1306.py库文件用同样的方式上传到ESP32。3.3 编写传感器与屏幕的测试代码在深入核心逻辑前先分别测试两个外设是否工作正常。测试HC-SR04import machine, time from hcsr04 import HCSR04 # 初始化传感器Trig引脚5, Echo引脚18 sensor HCSR04(trigger_pin5, echo_pin18) while True: distance sensor.distance_cm() # 获取以厘米为单位的距离 print(“距离{} cm”.format(distance)) time.sleep(1) # 每秒测量一次运行这段代码在终端里你应该能看到不断输出的距离数据。用手在传感器前移动观察数值变化。测试OLED屏幕import machine from machine import Pin, SoftI2C import ssd1306 import time # 初始化I2C总线使用软件I2C引脚可自定义 i2c SoftI2C(sclPin(22), sdaPin(21)) # 初始化OLED对象参数为屏幕尺寸 oled ssd1306.SSD1306_I2C(128, 64, i2c) oled.fill(0) # 清屏0代表黑色1代表白色 oled.text(‘Hello World!’, 0, 0) # 在坐标(0,0)处显示文字 oled.text(‘OLED Test OK’, 0, 16) oled.show() # 将缓存内容显示到屏幕上 time.sleep(2)如果屏幕成功显示“Hello World!”则说明I2C通信和屏幕驱动都是正常的。4. 核心测量逻辑与代码实现4.1 超声波测距的MicroPython实现细节虽然我们可以使用现成的hcsr04库但理解其底层实现对于调试和优化至关重要。一个典型的底层测量函数如下def measure_distance(trig_pin, echo_pin): # 确保Trig引脚先拉低 trig Pin(trig_pin, Pin.OUT) echo Pin(echo_pin, Pin.IN) trig.value(0) time.sleep_us(2) # 发送10us的高脉冲触发信号 trig.value(1) time.sleep_us(10) trig.value(0) # 等待Echo引脚变高并记录时间 while echo.value() 0: pulse_start time.ticks_us() # 等待Echo引脚变低并记录时间 while echo.value() 1: pulse_end time.ticks_us() # 计算高电平持续时间微秒 pulse_duration time.ticks_diff(pulse_end, pulse_start) # 计算距离厘米。声速340m/s 0.034 cm/us除以2因为是往返距离 distance (pulse_duration * 0.034) / 2 return distance这段代码揭示了几个关键点时序要求time.sleep_us()函数用于微秒级延时这对产生精确的10us触发脉冲至关重要。时间测量time.ticks_us()获取当前微秒计数time.ticks_diff()计算时间差它能正确处理计数器溢出的情况。阻塞式等待代码中使用while循环等待Echo引脚电平变化这是一种阻塞方式。在等待期间CPU无法执行其他任务。对于简单的单任务测量仪这没问题但如果系统复杂可能需要用到中断或定时器来避免阻塞。4.2 数据滤波与稳定性处理在实际环境中超声波传感器很容易受到干扰偶尔会产生 outliers异常值比如突然一个非常大的数或0。直接显示这些数据会导致读数跳动剧烈体验很差。因此必须加入软件滤波。一个简单有效的方法是中值滤波。我们连续采样N次比如5次将这组数据排序然后取中间值作为最终结果。这能有效滤除偶然的突发干扰。def get_filtered_distance(sensor, sample_size5): readings [] for _ in range(sample_size): try: dist sensor.distance_cm() # 可选增加一个有效范围判断比如只接受2-400cm之间的值 if 2 dist 400: readings.append(dist) except Exception as e: # 捕获传感器超时等异常 print(“测量异常”, e) continue time.sleep_ms(50) # 每次采样间隔一小段时间 if readings: readings.sort() return readings[len(readings)//2] # 返回中值 else: return None # 所有采样都无效4.3 OLED屏幕显示优化直接将数字打印到屏幕上可能不够美观。我们可以进行一些优化清屏与局部更新每次更新数据时不需要用oled.fill(0)清空整个屏幕再重绘所有内容这样会导致闪烁。可以只清除数字显示的区域。例如如果我们固定在一个位置显示距离可以先用白色矩形块覆盖旧数字的区域再绘制新数字。大字体显示MicroPython的text函数默认字体较小。为了更醒目我们可以使用自定义的位图字体或者用画矩形、线条的方式“画”出大号数字。一个取巧的办法是如果距离是整数可以将数字转换成字符串然后用较大的字号通过多次调用text函数模拟显示。添加单位与标识在数字旁边固定显示“cm”单位甚至画一个简单的超声波图标都能让界面更专业。def display_distance(oled, distance): oled.fill_rect(40, 20, 60, 30, 0) # 局部清除数字显示区域 if distance: # 将浮点数格式化为一位小数 dist_str “{:.1f}”.format(distance) # 显示数字可以尝试用两行大字号显示 oled.text(dist_str, 40, 25) oled.text(“cm”, 85, 25) else: oled.text(“—–“, 40, 25) # 显示无效符号 oled.show()4.4 主程序循环与系统集成将以上所有部分整合起来就构成了主程序循环。这个循环需要平衡测量频率、显示刷新率和系统响应性。from machine import Pin, SoftI2C, Timer import ssd1306 from hcsr04 import HCSR04 import time # 初始化硬件 sensor HCSR04(trigger_pin5, echo_pin18) i2c SoftI2C(sclPin(22), sdaPin(21)) oled ssd1306.SSD1306_I2C(128, 64, i2c) # 初始化显示 oled.fill(0) oled.text(“Distance Meter”, 10, 0) oled.text(“—————”, 10, 10) oled.show() last_distance 0 update_interval 500 # 每500毫秒更新一次 def main_loop(timer): global last_distance filtered_dist get_filtered_distance(sensor, 5) # 只有当距离变化超过0.5cm时才更新屏幕减少不必要的刷新 if filtered_dist and abs(filtered_dist - last_distance) 0.5: display_distance(oled, filtered_dist) last_distance filtered_dist elif filtered_dist is None: display_distance(oled, None) # 使用定时器周期性地执行主循环避免使用time.sleep阻塞 timer Timer(-1) timer.init(periodupdate_interval, modeTimer.PERIODIC, callbackmain_loop) # 主程序保持运行 try: while True: time.sleep(1) except KeyboardInterrupt: timer.deinit() oled.fill(0) oled.text(“Bye!”, 50, 30) oled.show() print(“程序退出”)这个设计使用了硬件定时器来触发测量和显示逻辑使得主循环while True可以保持空闲或处理其他潜在任务提高了系统的可扩展性。5. 性能优化与功能扩展思考5.1 提升测量响应速度与精度基础的循环测量在响应速度上已经足够用于手动测距。但如果想用于高速移动的机器人避障就需要优化。首先可以尝试减少get_filtered_distance中的采样次数和间隔但这会牺牲稳定性。更高级的方法是使用中断。可以将Echo引脚配置为中断输入在上升沿和下降沿触发中断来精确记录时间戳。这样主程序完全不会被测量过程阻塞。不过在MicroPython中处理高频中断需要非常小心避免在中断服务程序中进行复杂操作。对于精度温度对声速影响很大。声速v ≈ 331.4 0.6 * T其中T为摄氏温度。如果环境温度变化大可以增加一个温度传感器如DS18B20根据实时温度修正声速值从而将精度从厘米级提升到毫米级。5.2 低功耗设计与电池供电如果希望做成便携设备低功耗是关键。ESP32具有深度睡眠模式。我们可以设计这样的工作流程设备大部分时间处于深度睡眠由一个外部唤醒源如定时器或按键唤醒。唤醒后迅速完成一次测量和显示然后再次进入睡眠。这样两节AA电池可能就能支撑数周甚至数月。在MicroPython中可以使用machine.deepsleep()函数并配合RTC内存保存必要状态。5.3 数据记录与无线传输功能扩展这是ESP32的强项。我们可以轻松添加SD卡模块将带有时间戳的距离数据记录到文件中用于长期监测如监测水位变化。更吸引人的是启用Wi-Fi功能。设备可以连接家庭路由器将实时数据通过MQTT协议发布到本地服务器或云平台如Home Assistant实现远程监控。或者开启一个简单的Web服务器在手机浏览器上输入ESP32的IP地址就能看到一个实时刷新的距离仪表盘。5.4 封装与产品化对于最终成品可以考虑用3D打印一个外壳将ESP32、传感器、屏幕和电池集成在一起。外壳需要为超声波传感器开好窗口并考虑散热和天线位置如果使用无线功能。甚至可以设计一个简单的按键用来切换测量模式单位切换、连续测量/单次测量等。6. 常见问题与调试心得实录在实际制作过程中你几乎一定会遇到下面这些问题。这里记录了我的排查过程和解决方案。6.1 传感器无响应或读数固定不变现象终端始终打印同一个值可能是0.0或者一个极大的数用手遮挡传感器也没有变化。排查步骤检查电源和地线这是最常见的问题。用万用表测量HC-SR04的Vcc和GND之间电压确保在3.3V左右或5V。接触不良是面包板项目的头号杀手。检查信号线连接确认Trig和Echo引脚是否与代码中定义的GPIO号对应且连接无误。检查代码引脚模式确保Trig引脚被设置为Pin.OUTEcho引脚被设置为Pin.IN。检查声波探头观察传感器表面的两个金属圆柱体收发探头是否干净有无异物遮挡。降低测量频率尝试在每次测量之间增加更长的延时如time.sleep(1)给传感器足够的恢复时间。更换传感器或ESP32引脚排除硬件损坏或特定引脚故障的可能性。6.2 测量结果跳动剧烈现象数值在真实值附近快速、无规律地跳动。原因与解决环境干扰超声波传感器对光滑的、角度倾斜的、吸音的如布料表面反射效果差异很大。确保被测物体表面平整且正对传感器。远离风扇、电机等产生空气扰动的设备。供电噪声如果使用开发板的3.3V同时为屏幕和传感器供电在大屏幕刷新时可能导致电压微小波动。尝试在HC-SR04的Vcc和GND之间并联一个10uF-100uF的电解电容以稳定电源。软件滤波不足增加中值滤波的采样次数例如从5次增加到7次或9次。虽然会降低响应速度但稳定性会大幅提升。6.3 OLED屏幕不显示或显示乱码现象屏幕一片漆黑、部分显示或显示奇怪的字符。排查步骤确认电源和I2C地址首先检查VCC和GND。然后运行一段I2C扫描程序确认OLED的地址是否正确通常是0x3C。import machine i2c machine.SoftI2C(sclmachine.Pin(22), sdamachine.Pin(21)) devices i2c.scan() print(“I2C设备地址”, devices)检查上拉电阻I2C总线需要上拉电阻通常4.7kΩ-10kΩ到3.3V。有些OLED模块已内置有些没有。如果模块没有内置需要在SDA和SCL线上各加一个上拉电阻。检查初始化代码确认SSD1306_I2C初始化时传入的宽度、高度参数与你的屏幕匹配常见的是128,64。检查show()函数调用oled.text()后必须执行oled.show()内容才会真正更新到屏幕。6.4 MicroPython程序运行内存不足现象在添加更多功能后程序运行出现MemoryError。优化策略使用.mpy库文件将.py库文件预编译成.mpy格式再上传可以节省RAM和闪存空间。及时释放大对象在函数内部创建的大列表、字符串在函数结束后应尽快删除或置为None。冻结模块将常用的、稳定的库直接编译进MicroPython固件这需要重新编译固件但能极大节省运行时内存。6.5 测量距离与实际距离存在固定偏差现象测量值总是比卷尺测量的实际值大或小一个固定值如2cm。原因与校准这可能是传感器本身的物理误差或者声速常数不精确。我们可以在代码中引入一个校准偏移量。找一个已知精确距离例如50.0cm的物体进行测量得到传感器读数例如52.0cm。那么偏移量就是实际值减去测量值50.0 - 52.0 -2.0cm。在最终返回距离前加上这个偏移量calibrated_distance raw_distance offset。对于更高要求可以在多个距离点进行测量拟合出一个线性校正公式。在整个项目搭建和调试过程中最深刻的体会是嵌入式开发是软件和硬件的紧密结合。一个看似是软件的问题根源可能在硬件连接上。养成系统性的排查习惯——从电源开始到信号连接再到代码逻辑——能节省大量时间。另外MicroPython的动态特性使得交互式调试非常方便多利用print()函数输出中间变量值是定位问题最快的方法。最后不要害怕修改和试验很多最优参数如滤波次数、测量间隔都是在具体的硬件环境和应用场景下试出来的。
延伸阅读

更多相关文章

2026/11/5 3:53:07

钉钉低代码搭建:收费模式与搭建流程详解(以典名科技为例)

1. 钉钉低代码是什么? 钉钉低代码(钉钉宜搭)是钉钉平台内置的可视化应用开发工具。它允许非专业开发人员(如业务人员、行政、运营等)通过拖拽组件、配置逻辑的方式,快速搭建出满足特定业务需求的管理应用&…

2026/11/9 5:43:38

广西贵港电工证年审怎么操作?官方报名入口你搞懂了吗?

广西贵港电工证年审怎么操作?官方报名入口你搞懂了吗? 学历不高怕报不上名,但别担心,广西贵港电工证年审不是难事。关键是你得知道怎么操作,官方报名入口在哪,流程是怎样的。今天就带你一针见血,讲清楚电工证年审的每一步,特别是对于学历不高但想从事…

2026/11/9 5:43:38

什么工作需要考电工证 从零基础多久拿证全攻略

什么工作需要考电工证 从零基础多久拿证全攻略 你还在为找不到工作发愁吗?别忘了,现在 什么工作需要考电工证 ,已经成了很多行业招聘的硬性门槛。电工证不仅是职业资格的象征,更是很多岗位的“入场券”。如果你是郑州的在职建筑工人,想换赛道、升职加…

2026/11/9 5:43:38

别再被忽悠!高压电工作业证叫什么千万别踩坑

别再被忽悠!高压电工作业证叫什么千万别踩坑 你是不是也正愁着 急需特种作业证才能上岗找工作 ?别再等了,高压电工作业证就是你进工地、进工厂、进车间的“通行证”。但你可能还不知道,高压电工作业证 正式名称是“高压电工作业操作证”…

2026/11/9 5:43:38

泊头怎么考电工证郑州报考避坑指南实操考试心里没底怕挂科

泊头怎么考电工证郑州报考避坑指南实操考试心里没底怕挂科 实操考试心里没底怕挂科?这几乎是所有打算考电工证的新手心里都有的念头。尤其是像新乡这样的地方,工程类毕业生刚毕业,找工作压力大,想通过电工证提升竞争力,但又担心流程复杂、考试难度大、培…

2026/11/9 5:43:38

电工证过期异地能审吗 外省证多久拿证流程全解析

电工证过期异地能审吗 外省证多久拿证流程全解析 之前考的证在外省能不能转过来?你不是一个人,南阳卧龙区很多从事市政公用工程的电工师傅都遇到过这个问题。特别是那些在本地考了证、又长期在外地工作的师傅,证件过期后想要异地复审,流程复杂、材料多、…

2026/11/9 5:38:38

茂名安监局查电工证千万别踩坑,实操考试心里没底怕挂科

茂名安监局查电工证千万别踩坑,实操考试心里没底怕挂科 实操考试心里没底怕挂科,这是很多想报考电工证的学员最真实的心理写照。尤其是面对茂名安监局查电工证的最新政策变化,不少人在报名前都担心自己是否符合条件、考试是否难通过、挂科后怎么办等问题。…

2026/11/9 0:37:55

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/9 0:03:09

建设厅的特种工有哪些含金量高?别交完钱考不过

建设厅的特种工有哪些含金量高?别交完钱考不过 怕考不过白交培训费?别急,先搞清楚建设厅的特种工有哪些含金量高的证,再决定是不是值得投入时间和金钱。 建设厅的特种工证是建筑行业里最基础、也最实用的证书之一,涉及多个作业类别,每种证的 含金量…

2026/11/9 0:03:09

荆门市电工证报名怎么考才靠谱 全国通用证别交冤枉钱

荆门市电工证报名怎么考才靠谱 全国通用证别交冤枉钱 怕考不过白交培训费?荆门市电工证报名前必须知道这些避坑指南。别看网上一堆培训机构广告,真要报个电工证,很多人被坑得一塌糊涂。特别是那些打着“包过”旗号的,最后不是考试不过,就是证不是全国通…

2026/11/9 0:03:09

高空电工作业过程通过率揭秘:怎么选靠谱机构不被坑

高空电工作业过程通过率揭秘:怎么选靠谱机构不被坑 不知道去哪报名怕被中介坑?你不是一个人。现在特种作业证报名渠道五花八门,从线下培训机构到线上代理,真假难辨。尤其是像高空电工作业这类高风险、高门槛的作业类型,证书含金量和考试通过率直接影响你…

2026/11/7 14:54:47

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/7 14:50:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑