一、目的
这一节我们学习如何使用乐鑫的ESP32开发板连接超声波测距模块HC-SR04,并使用串口SPI控制ILI9341 液晶屏,显示出来。
二、环境
ESP32(固件:esp32-20220618-v1.19.1.bin) + Thonny(V4.0.1) + 超声波测距模块HC-SR04 + ILI9341 液晶屏模块 + 几根杜邦线 + Win10 64位商业版
ILI9341屏幕的接线方法,请查看上篇文章:物联网开发笔记(94)
三、示例代码1
我们接着使用前面几课我们用的ILI9341显示屏,然后来把超声波测量的距离显示在屏幕上。这里的库和字体请从前面文章中获取。
from machine import Pin,SPI,PWM
from ili9341 import Display,color565
from xglcd_font import XglcdFont
import time
# 超声波测距模块
trig = Pin(33,Pin.OUT) # Trig_RX_SCL_I/O
echo = Pin(32,Pin.IN,Pin.PULL_UP) # Echo_Tx_SDA
# 调节显示亮度,初始亮度为400
blk = PWM(Pin(2),duty = (400),freq = (1000))
# 创建SPI对象
spi = SPI(2, baudrate=40000000, polarity=0, phase=0, bits=8, firstbit=0, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
# 创建屏幕对象
tft = Display(spi,cs=Pin(5,Pin.OUT),dc=Pin(26,Pin.OUT),rst=Pin(27,Pin.OUT),width=240,height=320,rotation=180)
# 字库
font9x11 = XglcdFont("font/ArcadePix9x11.c",9,11)
font12x24 = XglcdFont("font/Unispace12x24.c",12,24)
def HCSR04(trig,echo,mode):
trig.value(0) # 先通过GPIO把MCU触发信号信号拉低2us
time.sleep_us(2)
trig.value(1) # 再通过GPIO把MCU触发信号信号拉高10us,触发模块测距
time.sleep_us(10)
trig.value(0) # 再通过GPIO把MCU触发信号信号拉低
while echo.value() == 0:
high = time.ticks_us() # time.ticks_us返回不断递增的微秒计数器
#print("high: ", high)
while echo.value() == 1:
low = time.ticks_us()
#print("low: ", low)
print("high - low: ", high - low) # 此处加打印多了会影响测距
distance = 0
if mode:
# 计算方法1
distance = (low - high) / 58 # us
else:
# 计算方法2 - 根据Echo管脚高电平的持续时间计算距离值
distance = ((low - high) * 0.0340) / 2 # 声速
time.sleep(0.2) # 两次测量时间不能低于200ms
if distance > 400:
distance = 0 # 有效距离2 - 400cm
return number
def main():
blk.duty(800) # 设置屏幕背光
while True:
distance = HCSR04(trig,echo,1) # 听过HCSR04函数返回距离值
# 将距离显示在屏幕上,精度小数点后2位
tft.draw_text(0,0,"distance: %.2f cm%s"%(number,' '),font12x24,color565(0,255,0),color565(0,0,0))
if __name__ == "__main__":
main()
显示效果:
四、示例代码2
不使用屏幕显示
import time
class HCSRX(object):
def __init__(self,trig,echo):
self.trig = trig
self.echo = echo
#mode 模式选择mode = 0:声速 mode = 1:厘米
def Gethcsr(self,mode):
#触发信号
self.trig.value(0)
time.sleep_us(2)
self.trig.value(1)
time.sleep_us(10)
self.trig.value(0)
#检测回响信号
number = 0
while self.echo.value() == 0:
pass
high = time.ticks_us()
while self.echo.value() == 1:
pass
low = time.ticks_us()
if mode:
number = (low - high) / 58 # cm
else:
number = ((low - high) * 0.0340)/2 # 声速340/10000=0.0340
time.sleep(0.1)#两次测量时间要间隔50ms以上
if number > 400:number = 0
return number
#例程
from machine import Pin
from hcsrx import HCSRX
import time
trig = Pin(33,Pin.OUT)
echo = Pin(32,Pin.IN,Pin.PULL_UP)
def main():
while True:
hcsr = HCSRX(trig,echo)
print("%.2f"%hcsr.Gethcsr(0))
if __name__ == "__main__":
main()
示例效果:
五、示例代码3
将测量方法写成库函数,然后在函数中调用
hcsrx.py
import time
class HCSRX(object):
def __init__(self,trig,echo):
self.trig = trig
self.echo = echo
#mode 模式选择mode = 0:声速 mode = 1:厘米
def Gethcsr(self,mode):
#触发信号
self.trig.value(0)
time.sleep_us(2)
self.trig.value(1)
time.sleep_us(10)
self.trig.value(0)
#检测回响信号
number = 0
while self.echo.value() == 0:
pass
high = time.ticks_us()
while self.echo.value() == 1:
pass
low = time.ticks_us()
if mode:
number = (low - high) / 58 # cm
else:
number = ((low - high) * 0.0340)/2 # 声速340/10000=0.0340
time.sleep(0.1)#两次测量时间要间隔50ms以上
if number > 400:number = 0
return number
示例:
from machine import Pin
from hcsrx import HCSRX
import time
trig = Pin(33,Pin.OUT)
echo = Pin(32,Pin.IN,Pin.PULL_UP)
def main():
while True:
hcsr = HCSRX(trig,echo)
print("%.2f"%hcsr.Gethcsr(0))
if __name__ == "__main__":
main()
测量效果:
六、测量时序图
七、HC-SR04超声波测距模块购买
1,低精度不带晶振
2,高精度带晶振