基于ESP32的超声波测距控制系统

技术栈:MicroPython + MicroDot + HC-SR04 + HTML/CSS

任务分解:

项目实现

上节课网页控制开发板LED灯的代码:

from microdot import Microdot
print('hello microdot')
import network
from time import sleep
from machine import Pin

def connect_wifi():
    wifi=network.WLAN(network.STA_IF)
    wifi.active(True)
    sleep(1)
    while True:
        sleep(2)
        if wifi.ifconfig()[0]=='0.0.0.0':
            wifi.connect('422','micro422')
        else:
            print('wifi连接成功,IP',wifi.ifconfig()[0])
            break
led=Pin(2,Pin.OUT)   
app=Microdot()
@app.route('/')
def index(request):
    return 'Hello,MicroDot!'

@app.route('/hello/<xxx>')
def hello(request,xxx):
    return f'Hello,{xxx}!'

@app.route('/led/on')
def on(request):
    led.value(1)
    return '开灯成功!'

@app.route('/led/off')
def off(request):
    led.value(0)
    return '关灯成功!'

@app.route('/web')
def web(request):
    gpio_state="ON" if led.value()==1 else "OFF"
#     if led.value()==1:
#         gpio_state="ON"
#     else:
#         gpio_state="OFF"
    html="""
<html>
    <head>
        <title>ESP Control Server</title>
        <meta name="viewport" content='width=device-width ,initial-scale=1'>
        <link rel="icon" href="data:,">
        <style>
            html{
            font-family:Helvetica;
            display:inline-block;
            margin:0px auto;
            text-align:center;
            }
            
            h1{
            color:#0F3376;
            padding:2vh;
            }
            
            p{font-size:1.5rem;}
            
            .button{
                display:inline-block;
                background-color:#e7bd3b;
                border:none;
                border-radius:4px;
                color;white;
                padding:16px 40px;
                text-decoration:none;
                font-size:30px;
                margin:2px;
                cursor:pointer;
                }
            .button2{background-color:#4286f4;}
        </style>
        </head>
        <body>
            <h1>ESP Web Server</h1>
            <p>GPIO state:<strong id="gpio-state">"""+gpio_state+"""</strong></p>
            <p><button class="button" onclick="controlLED('on')">ON</button></a></p>
            <p><button class="button button2" onclick="controlLED('off')">OFF</button></a></p>
        </body>
        <script>
            function controlLED(state){
            var xhr=new XMLHttpRequest();
            xhr.open("GET","/led/"+state,true);
            xhr.send();
            xhr.onreadystatechange=function(){
            if (xhr.readyState==4 && xhr.status ==200){
            document.getElementById("gpio-state").innerText=state.toUpperCase();
                                                        }
                                            };
                                        }
        </script>
        </html>
         """
    return html,{"Content-Type":"text/html"}
    
    
    
    
    

if __name__=='__main__':
    connect_wifi()
    app.run(host='0.0.0.0',port=5000)

超声波测距功能实现,回顾前面课程实现的测距代码,这里做了一些改动,将 trig,echo 两个GPIO对象改为使用形参传入


def measure_sro4(trig,echo):
    trig.value(0)
    echo.value(0)
        #触发超声波模块测距
    trig.value(1)
    time.sleep_us(10)#触发信号 >= 10us
    trig.value(0) 
  
      #超声波信号发出后,echo为低信号,不断更新微秒计数器t1
    while(echo.value() == 0):
        t1 = time.ticks_us()
        
      #检测回响信号,echo为高时,超声波信号到达,设置微秒计数器t2
    while(echo.value() == 1):
        t2 = time.ticks_us()
    
      #计算两次调用 ticks_ms(), ticks_us(), 或 ticks_cpu()之间的时间,得到当前时间
    t3 = time.ticks_diff(t2,t1)/1000000 #计算出时间差,再换算为秒
  
      # ticks_diff获取的时间差就是测距总时间,再乘声音的传播速度340米/秒,除2(来回)就是距离。
    distance=t3*340/2
    
    #转换为厘米
    result=distance*100 
    
    print('sro4: ',result)
    return result

创建两个GPIO对象,分别是超声波测距的trigecho信号,然后添加了一个 global distance 作为存储数据的全局变量

trig=Pin(14,Pin.OUT) 
echo=Pin(12,Pin.IN)

global distance
distance=0

添加一个测距按键的CSS样式配置

  /*其他代码*/
  
  .button2 {
            background-color: #4286f4;
        }
 .button_distance {
            background-color: #006400;
            
  /*其他代码*/

在网页主内容中添加测距内容显示和测距按键


<-- 其他代码 -->
<body>
    <h1>ESP Web Server</h1>
    <p>GPIO 状态(板载LED): <strong>""" + gpio_state + """</strong></p>
    <p><a href="/led/on"><button class="button">ON</button></a></p>
    <p><a href="/led/off"><button class="button button2">OFF</button></a></p>
    
    <-- 超声波测距数据显示,round用于指定显示两位小数 -->
    <p>超声波测距: <strong>""" + str(round(distance, 2))+"CM"+"""</strong></p>
    <-- 超声波测距功能按键,按下按键自动调用一个路由 -->
    <p><a href="/sro4/distance"><button class="button button_distance">按下检测距离</button></a></p>

</body>
<-- 其他代码 -->

创建超声波按键功能调用的路由,访问 /sro4/distance 路由后,调用超声波测距函数,将测距数据绑定到 global distance 这个全局变量,然后返回网页请求,网页同时就会刷新,从而更新页面上的测距数据