目标:实现网页端速度实时显示以及可以通过点击页面按键达到对小车的位移方位控制。
一、ESP32代码
首先,需要让ESP32连接到WiFi,这样才能为后续的操作做准备。
ssid="xxxxxx"
password="xxxxxx"#WIFI连接
def wifi_connect():wlan=network.WLAN(network.STA_IF) #STA模式if not wlan.isconnected():print("conneting to network...")wlan.active(True) #激活wlan.connect(ssid,password) #输入 WIFI 账号密码while not wlan.isconnected():time.sleep(10)return Falseelse:print("network information:", wlan.ifconfig())return True
上面代码中ssid:WiFi账号;password:WiFi密码。
可以在if __name__=="__main__":下进行对应的判断,当连接成功后进行接下来的操作。
当WiFi连接好后,可以启动自己的WEB服务端,设置好对应的参数。
# 启动Web服务器
def start_server():s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.bind(("",3389))s.listen(3)while True:cl, addr = s.accept()#print('Client connected from', addr)request = cl.recv(1024)request = str(request)go = request.find("go")back = request.find("back")left = request.find("left")right = request.find("right")stop = request.find("stop")Inst_jud([go,back,left,right,stop])if '/data' in request:response = get_data()cl.send('HTTP/1.0 200 OK\r\nContent-type: application/json\r\n\r\n')cl.send(response)elif 'GET /' in request:cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')cl.send(web_page())cl.close()
在这部分,需要设置是tcp还是udp,确定好端口号以及可以监听到的数量。然后可以打印出自己的addr,在同一局域网下输入http://IP:3389,就可以访问自己的页面,那么这个页面如何写呢,可以简单学一下前端相关的知识,在本人的博客中也有对应的教程,可以了解一下。
#网页数据
def web_page():global mytimehtml = """<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>TOMAS语音控制系统</title><script src="http://code.jquery.com/jquery.js"></script><style>body {background-color: #e4e4e4;}* {margin: 0;padding: 0;}.container {text-align: center;}.container .data_board {margin-top: 40px;margin-left: auto;margin-right: auto;width: 300px;height: 200px;border: 5px dashed #999999;background-color: aqua;border-radius: 10%;margin-bottom: 50px;}.container .data_board .data {margin-top: 80px;}.container .data_board .data .speed {width: 50px;height: 80px;float: left;margin-left: 10px;}.container .data_board .data .speed #time {float: left;margin-left: 10px;}.container .data_board .data .distance {width: 50px;height: 80px;float: right;margin-right: 10px;}.container .data_board .data .distance #dist {float: left;}.container .but_swit {margin-top: 10px;margin-bottom: 10px;}.container .but_swit .switch_block {margin-left: auto;margin-right: auto;width: 100px;height: 100px;}.container .but_swit .switch_block #switch {width: 100%;height: 50%;margin-top: 25px;background-color: aquamarine;border-radius: 20px;}.container .control_but {margin-left: auto;margin-right: auto;width: 300px;height: 300px;border: 5px dashed burlywood;border-radius: 50px;}.container .control_but .go,.back {width: 100px;height: 100px;}.container .control_but .go {margin-left: auto;margin-right: auto;}.container .control_but .mid_box {width: 100%;height: 100px;}.container .control_but .mid_box .left {float: left;width: 100px;height: 100%;}.container .control_but .mid_box .stop {float: left;margin-left: auto;margin-right: auto;width: 100px;height: 100%;}.container .control_but .mid_box .right {float: right;width: 100px;height: 100%;}.container .control_but .back {margin-left: auto;margin-right: auto;}.container .control_but .go #go,.container .control_but .back #back,.container .control_but .mid_box .stop #stop,.container .control_but .mid_box .left #left,.container .control_but .mid_box .right #right{width: 80%;height: 80%;margin-top: 10px;background-color: aquamarine;border-radius: 20px;}</style><script>$(document).ready(function () {setInterval(function () {$.get("/data", function (result, status) {console.log(result)$("#time").html(result.tim)$("#dist").html(result.dis)});}, 1000);//button$("button").click(function () {$.post("/cmd", this.id, function (data, status) {});});/**<img id="bg" src="{{ url_for('video_feed') }}"><meta http-equiv="refresh" content="1">**/});var i = 1;function openClo() {var butt = document.querySelector(".control_but");if(butt!=1){i++;if(i % 2 == 0){butt.style = "display: block;";}else{butt.style = "display: none;";}}}</script>
</head>
<body>
<div id="container" class="container"><div><h1 class="m">TOMAS语音控制系统</h1></div><div class="data_board"><div class="data"><div class="speed"><p class="tim">左轮速度: </p><i id="time">......</i></div><div class="distance"><p class="dis">右轮速度:</p><i id="dist">......</i></div></div></div><hr><div class="but_swit"><div class="switch_block"><button id="switch" onclick="openClo()">功能切换</button></div></div><div class="control_but" style="display: none;"><div class="go"><button id="go">向前</button></div><div class="mid_box"><div class="left"><button id="left">左转</button></div><div class="stop"><button id="stop">复位</button></div><div class="right"><button id="right">右转</button></div></div><div class="back"><button id="back">向后</button></div></div>
</div>
<script src="http://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>"""return html
以上便是前端的设计程序,可以自己尝试设计一个属于自己的页面,然后就可以将这个返回数据发送到前端页面进行显示了,那么如何实现数据的实时显示呢。在start_server函数中进行了对应的判断,当是数据请求时则发送get_data返回的JSON数据,当时主页请求时,则发送web_page返回的页面数据。
其中get_data函数如下:
#串口通信
uart=UART(2,115200)
uart.init(115200,bits=8,parity=None,stop=1)#8N1
# 获取数据
def get_data():global mytimemytime = uart.read()print(mytime)if type(mytime) == bytes:Enc_cnt = mytime.decode('utf-8')print(Enc_cnt)if "Enc_cnt" not in mytime:Enc1_cnt = 0Enc2_cnt = 0#print(Enc_cnt)else:Enc_cnt = Enc_cnt.split('Enc_cnt: ')[1].split('|')Enc1_cnt = Enc_cnt[0]Enc2_cnt = Enc_cnt[1]return json.dumps({'tim': str(Enc1_cnt), 'dis': str(Enc2_cnt)})else:return json.dumps({'tim': '0', 'dis': '0'})
需要注意的是波特率要和STM32那边一致,然后通过串口数据接收STM32发送的数据,之后进行数据处理便可发送数据到前端。
在start_server函数中有一个Inst_jud函数的调用,这是将前端页面按键返回的数据传输到指令判断函数,然后进行对应的判断,从而发送对应的字符给STM32后进行控制。
#串口发送
def switch(choice):if choice==0:#print("go")uart.write("0")elif choice==1:#print("back")uart.write("1")elif choice==2:#print("left")uart.write("2")elif choice==3:#print("right")uart.write("3")else:#print("stop")uart.write("4")#指令判断
def Inst_jud(locL):for i in locL:if i>0:locLi=locL.index(i)switch(locLi)
二、STM32
STM32的配置这篇就不写了,后面在另一篇会有写到。
因ESP32接收STM发送的速度值,因此在STM32部分需要采集霍尔编码器电机的脉冲计数量,然后计算出对应的速度值。
short Enc1_cnt = 0;
short Enc2_cnt = 0;
short EncALL_cnt = 0;
float motor1_speed = 0.00;
float motor2_speed = 0.00;
float dist = 0.00;
char buffer[50];//Tim_encoder CallBack
Enc1_cnt = (short)__HAL_TIM_GET_COUNTER(&htim2);
Enc2_cnt = -(short)__HAL_TIM_GET_COUNTER(&htim3);EncALL_cnt += Enc1_cnt;motor1_speed = (float)Enc1_cnt*100/30/13/4/60;
motor2_speed = (float)Enc2_cnt*100/30/13/4/60;dist = (float)EncALL_cnt * 2 * 3.14 * 2.45 / 30 / 13 / 10;sprintf(buffer, "Enc_cnt: %.2f|%.2f|%.2f", motor1_speed, motor2_speed, dist); //Transmit
HAL_UART_Transmit(&huart2,(uint8_t *)&buffer, strlen(buffer),0xffff);__HAL_TIM_SET_COUNTER(&htim2, 0);
__HAL_TIM_SET_COUNTER(&htim3, 0);
HAL_Delay(10);
其中sprintf是为了格式化发送的数据,用HAL_UART_Transmit函数进行串口发送。
然后对于接收ESP32所发送的数据
利用下面的程序进行数据的接收
uint8_t data= 0;
//Switch Control
HAL_UART_Receive(&huart2, &data, 1, 100);
接收到的data为对应的字符,随后便可进行判断,
这个一个项目的一部分,如果需要源代码可以在评论区留下邮箱,有不懂的问题可以打在评论区。