STM32与ESP32串口数据发送以及网页端数据实时显示和远程遥控

目标:实现网页端速度实时显示以及可以通过点击页面按键达到对小车的位移方位控制。

一、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为对应的字符,随后便可进行判断,

这个一个项目的一部分,如果需要源代码可以在评论区留下邮箱,有不懂的问题可以打在评论区。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/54943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

题解:牛客小白月赛102(A - C)

A 序列中的排列 题意&#xff1a; 每次给你两个正整数 n , k n,k n,k &#xff0c;并给你一段长度为 n n n 的序列。&#xff08;所有输入均为小于等于100的正整数&#xff09; 问&#xff1a;原序列中是否存在子序列&#xff0c;使得这个子序列是 k k k 的排列 子序列&am…

数据仓库中的维度建模:深入理解与案例分析

数据仓库中的维度建模&#xff1a;深入理解与案例分析 维度建模是数据仓库设计中最常用的一种方法&#xff0c;旨在简化数据访问、提高查询效率&#xff0c;特别适用于需要对数据进行多维分析的场景。本文将深入探讨维度建模的核心概念、设计步骤以及如何将其应用于实际案例中…

通过PyTorch 手写数字识别 入门神经网络 详细讲解

通过PyTorch 手写数字识别 入门神经网络 数据集 MNIST数据集中有手写数字图片7万张&#xff0c;划分训练集6万张&#xff0c;划分测试集1万张。 每张图片都会有一张标签&#xff0c;也就是代表着图片的真实值&#xff08;真实含义&#xff09;。 概念 计算机是如何读取图片的…

基于Android11简单分析audio_policy_configuration.xml

开篇先贴上一个高通的例子&#xff0c;后续基于此文件做具体分析。 1 <?xml version"1.0" encoding"UTF-8" standalone"yes"?> 2 <!-- Copyright (c) 2016-2019, The Linux Foundation. All rights reserved 3 Not a Contribut…

Python保存CSV文件,Excel打开后中文乱码

情况描述 在做多语言文件处理时&#xff0c; 使用 pandas&#xff0c; 并且指定了encoding为 UTF-8&#xff0c; 在 IDE&#xff0c; Sublime等编辑器上查看都显示正常&#xff0c;使用Excel打开非英文字符&#xff0c; 例如汉字&#xff0c; 阿拉伯文&#xff0c; 希伯来文等显…

多态常见面试问题

1、什么是多态&#xff1f; 多态&#xff08;Polymorphism&#xff09;是面向对象编程中的一个重要概念&#xff0c;它允许同一个接口表现出不同的行为。在C中&#xff0c;多态性主要通过虚函数来实现&#xff0c;分为编译时多态&#xff08;静态多态&#xff09;和运行时多态…

【Spring AI】Java实现类似langchain的第三方函数调用_原理与详细示例

Spring AI 介绍 &#xff1a;简化Java AI开发的统一接口解决方案 在过去&#xff0c;使用Java开发AI应用时面临的主要困境是没有统一且标准的封装库&#xff0c;导致开发者需要针对不同的AI服务提供商分别学习和对接各自的API&#xff0c;这增加了开发难度与迁移成本。而Sprin…

【数据结构】邻接表

一、概念 邻接表是一个顺序存储与链式存储相结合的数据结构&#xff0c;用于描述一个图中所有节点之间的关系。 若是一个稠密图&#xff0c;我们可以选择使用邻接矩阵&#xff1b;但当图较稀疏时&#xff0c;邻接矩阵就显得比较浪费空间了&#xff0c;此时我们就可以换成邻接…

机器人的应用 基于5G的变电站智慧管控系统

背景概述 一、电力行业面临的挑战与变革 随着全球工业化和信息化的快速发展&#xff0c;电力行业作为国民经济的基础性行业&#xff0c;其重要性日益凸显。然而&#xff0c;随着电力网络的不断扩展和复杂化&#xff0c;变电站和开关站作为电力传输与分配的关键节点&#xff0…

6、Spring Boot 3.x集成RabbitMQ动态交换机、队列

一、前言 本篇主要是围绕着 Spring Boot 3.x 与 RabbitMQ 的动态配置集成&#xff0c;比如动态新增 RabbitMQ 交换机、队列等操作。二、默认RabbitMQ中的exchange、queue动态新增及监听 1、新增RabbitMQ配置 RabbitMQConfig.java import org.springframework.amqp.rabbit.a…

Excel中Ctrl+e的用法

重点&#xff1a;想要使用ctrle&#xff0c;前提是整合或拆分后的结果放置的单元格必须和被提取信息的单元格相邻&#xff0c;且被提取信息的单元格也必须相连。 下图为错误示例 这样则可以使用ctrle 1、信息整合 2、提取信息 3、添加符号 4、信息顺序调换 5、数字提取 crtle还…

HarmonyOS NEXT 应用开发实战(三、ArkUI页面底部导航TabBar的实现)

在开发HarmonyOS NEXT应用时&#xff0c;TabBar是用户界面设计中不可或缺的一部分。本文将通过代码示例&#xff0c;带领大家一同实现一个常用的TabBar&#xff0c;涵盖三个主要的内容页&#xff1a;首页、知乎日报和我的页面。以模仿知乎日报的项目为背景驱动&#xff0c;设定…

解决ubuntu 下 VS code 无法打开点击没反应问题

从Ubuntu 22.04 升级到ubuntu 24.04 后&#xff0c;发现Vsode无法打开&#xff0c;不论是点击图标&#xff0c;还是terminator里面运行code 可执行程序&#xff0c;均没有反应。debug如下: 提示权限不够。 解决方案&#xff1a; sudo sysctl -w kernel.apparmor_restrict_unp…

C语言题目练习2

前面我们知道了单链表的结构及其一些数据操作&#xff0c;今天我们来看看有关于单链表的题目~ 移除链表元素 移除链表元素&#xff1a; https://leetcode.cn/problems/remove-linked-list-elements/description/ 这个题目要求我们删除链表中是指定数据的结点&#xff0c;最终返…

C语言 | Leetcode C语言题解之第460题LFU缓存

题目&#xff1a; 题解&#xff1a; /* 数值链表的节点定义。 */ typedef struct ValueListNode_s {int key;int value;int counter;struct ValueListNode_s *prev;struct ValueListNode_s *next; } ValueListNode;/* 计数链表的节点定义。 其中&#xff0c;head是数值链表的头…

腾讯云Android 与 iOS 相关

移动端&#xff08;Android/iOS&#xff09;支持哪几种系统音量模式&#xff1f; 支持2种系统音量类型&#xff0c;即通话音量类型和媒体音量类型&#xff1a; 通话音量&#xff1a;手机专门为通话场景设计的音量类型&#xff0c;使用手机自带的回声抵消功能&#xff0c;音质…

java使用socket模拟咖啡馆场景,客户与服务器多线程交互场景

java使用socket模拟咖啡馆场景,客户与服务器多线程交互场景 任务的目标是使用客户机 - 服务器架构构建一个“虚拟咖啡馆”系统每个客户端应用程序将扮演 Customer 谁想点茶或咖啡。服务器应用程序将扮演咖啡馆虚拟的角色 Barista 负责处理订单&#xff0c;准备茶和啡&#xff…

OpenCV-风格迁移

文章目录 一、原理二、关键步骤三、实现方法四、可选参数五、示例代码六、总结 OpenCV中的风格迁移是一种计算机视觉技术&#xff0c;它允许用户将一种图像的风格转移到另一幅图像上&#xff0c;从而创造出具有独特美学效果的新图像。这种技术在艺术、设计和娱乐等领域有着广泛…

elementui中table标题和内容插槽

代码 <template> <el-table :data"tableData"> <el-table-column> <template slot"header" slot-scope"scope"> <el-tooltip content"这是列的提示信息" placement"top"> <span>…

谷歌浏览器 文件下载提示网络错误

情况描述&#xff1a; 谷歌版本&#xff1a;129.0.6668.90 (正式版本) &#xff08;64 位&#xff09; (cohort: Control)其他浏览器&#xff0c;比如火狐没有问题&#xff0c;但是谷歌会下载失败&#xff0c;故推断为谷歌浏览器导致的问题小文件比如1、2M会成功&#xff0c;大…