首页 > 其他分享 >STM32与ESP32串口数据发送以及网页端数据实时显示和远程遥控

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

时间:2024-10-12 20:21:54浏览次数:3  
标签:cnt container data ESP32 but STM32 串口 margin left

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

一、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 False
    else:
        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 mytime
    html = """<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 mytime
    mytime = 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 = 0
            Enc2_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为对应的字符,随后便可进行判断,

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

标签:cnt,container,data,ESP32,but,STM32,串口,margin,left
From: https://blog.csdn.net/Python_Ghost/article/details/142884104

相关文章

  • linux系统epoll的ET/LT模式-附串口接收代码
    LT模式下,读事件触发后,可以按需收取想要的字节数,不用把本次接收到的数据收取干净(即不用循环到recv或者read函数返回-1,错误码为EWOULDBLOCK或EAGAIN);ET模式下,读事件必须把数据收取干净,因为你不一定有下一次机会再收取数据了,即使有机会,也可能存在上次没读完的数据没有及时......
  • 串口屏在充电桩行业应用
    随着电动汽车销量和保有量的迅速增长,充电需求持续上升,新基建政策的支持使得充电桩建设进入快速发展期。充电桩作为新能源汽车补能的主流方式,其建设和完善对于推广新能源汽车至关重要。串口屏的应用串口屏在充电桩行业的应用主要体现在以下几个方面:信息显示:串口屏可以连接充......
  • 【STM32开发之寄存器版】(九)-模数转换ADC
    一、前言本次DEMO目标:本文将使用STM32F103ZET6的ADC1通道1来采样外部电压值,并使用串口在上位机XCOM上打印出电压值。二、模数转换原理与基本概念2.1ADC基本概念模数转换器(ADC,Analog-to-DigitalConverter)是一种将模拟信号转换为数字信号的电子器件。它的主要功能是将......
  • 【STM32开发之寄存器版】(八)-定时器的编码器接口模式
    一、前言1.1编码器接口原理编码器模式主要用于检测旋转编码器的转动方向和转动速度。旋转编码器一般输出两路相位相差90度的脉冲信号(称为A相和B相),通过这两路信号,定时器可以判断编码器的旋转方向,并计数转动的脉冲数。1.2本次DEMO目标本次DEMO将使用STM32F103ZET6的PA6(......
  • 【STM32开发之寄存器版】(七)-PWM脉冲宽度调制
    一、前言PWM简介PWM(脉宽调制)是一种通过调节信号的脉冲宽度来控制功率输出的技术。其基本原理是保持固定频率的信号,将其高电平和低电平的持续时间调整,达到控制平均功率的目的。应用方面,PWM广泛用于电机控制、LED调光、音频放大、以及电源管理等领域,因为它能有效提高能效并减......
  • 利用STM32VET6控制TEF6686(V102)收音机芯片
    目录TEF6686芯片概述TEF6686芯片的主要特点包括:TEF6686芯片具备的主要功能TEF6686芯片的应用范围I2C协议驱动代码IIC.cIIC.hTEF6686.c(设备初始化)TEF6686.hTEF6686_command.cTEF6686_command.hTEF6686芯片概述TEF6686是一款由NXPSemiconductors生产的高性能单芯片收音机IC,它集......
  • 绿盟防火墙忘记密码串口重置
    密码重置1、设备本身开启了密码恢复功能password-recoveryenable(系统默认开启)重启设备,在设备重启过程中根据提示或者不停按键“ctrl+B”进入bootware界面,查看界面显示botware界面,选择“8”-skipauthenticationforconsolepassword,将console口登录认证删除或者重置console密码......
  • 基于STM32设计自动输液监测系统(241)
    文章目录一、前言1.1项目介绍【1】项目开发背景【2】设计实现的功能【3】项目硬件模块组成1.2设计思路1.3项目开发背景【1】选题的意义【2】参考文献【3】项目背景【4】摘要【5】设计的主要内容和功能1.4开发工具的选择1.5系统功能总结1.6......
  • 基于STM32的智慧超市管理设计与实现(239)
    文章目录一、前言1.1项目背景1.2设计思路1.3功能详细总结【1】环境监测与智能控制【2】商品管理与顾客服务【3】实时数据展示1.4环境监测页面设计1.5超市收银上位机1.6系统框架图1.7硬件原理图1.8硬件实物二、硬件选型2.1STM32开发......
  • STM32中实现下降沿捕获(HAL库)
    配置步骤:1、配置时基工作参数HAL_TIM_IC_Init();主要配置其中的instanceinitautorelaodpreloadcountermodeperiodprescaler2、msp初始化HAL_TIM_IC_MspInit(TIM_HandleTypeDef*htim) __HAL_RCC_TIM2_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE();  HAL_NV......