STM32与Web端透传通信:实现WiFi模块的应用

本文章想记录下自己通过web前端与stm32硬件端实现数据交互的历程,一开始想用阿里云进行数据中转,弄好之后,因为是在学习阶段,所以使用时间比较长,但阿里云只有30天的试用时间,所以就想找找有什么方法可以前端与硬件直接透传的方法,经过不断的摸索,通过weisocket实现这一个方案.

一.WebSocket是一种在单个TCP连接上进行全双工通信的协议,它于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范,WebSocket API也被W3C定为标准。

1.创建一个HTML文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>智能枸杞运输平台</title>
    <link rel="stylesheet" href="styles.css">
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
</head>
<body>
    <header class="header">
        <h1>智能枸杞运输平台</h1>
    </header>
     <!-- 在header标签后添加 -->
<button id="sendCommandButton" class="command-button">发送指令到STM32</button>
    <main class="dashboard">
        <section class="card processing-card">
            <h2>枸杞车间加工状况</h2>
            <div class="card-content" id="processing-info"></div>
        </section>
        <section class="card transport-card">
            <h2>小车运输情况</h2>
            <div class="card-content" id="transport-info"></div>
        </section>
        <section class="card material-card">
            <h2>枸杞加工材料需求</h2>
            <div class="card-content" id="material-info"></div>
        </section>
        <section class="card inventory-card">
            <h2>库存情况</h2>
            <div class="card-content" id="inventory-info"></div>
        </section>
    </main>

    <script src="script.js"></script>
</body>
</html>
  • 使用了一个header标签来展示页面的标题

  • 在header后添加了一个按钮,其ID为sendCommandButton,可以用来发送指令到STM32。

  • main标签内包含了四个卡片(section),每个卡片都有特定的主题(如加工状况、运输情况等),并使用了id属性以便于通过JavaScript进行内容填充或操作。

  • 最后,通过<script src="script.js"></script>引入了一个外部JavaScript文件,用来实现动态内容更新与服务器通信功能。

  •  2.js文件通过WebSocket与服务器进行通信,以实时更新web的网页界面。

    const processingInfo = document.getElementById('processing-info');
    const transportInfo = document.getElementById('transport-info');
    const materialInfo = document.getElementById('material-info');
    const inventoryInfo = document.getElementById('inventory-info');
    
    const socket = new WebSocket('ws://localhost:8081');
    
    socket.onmessage = function(event) {
        const data = JSON.parse(event.data);
    
        if (data.type === 'processing') {
            processingInfo.innerHTML = `
                <p>加工进度: ${data.progress}%</p>
                <p>状态: ${data.status}</p>
            `;
        } else if (data.type === 'transport') {
            transportInfo.innerHTML = `
                <p>位置: ${data.location}</p>
                <p>状态: ${data.status}</p>
                <p>任务: ${data.task}</p>
            `;
        } else if (data.type === 'material') {
             materialInfo.innerHTML = `
                <p>枸杞: ${data.location}</p>
                <p>包装盒: ${data.status}</p>
            `;
        } else if (data.type === 'inventory') {
            inventoryInfo.innerHTML = `
                <p>枸杞: ${data.location}</p>
                <p>包装盒: ${data.status}</p>
            `;
        }
    };
    
    socket.onopen = function() {
        console.log('WebSocket connection established');
    };
    
    socket.onerror = function(error) {
        console.error('WebSocket error:', error);
    };
    
    socket.onclose = function() {
        console.log('WebSocket connection closed');
    };
    
    
    // 获取按钮元素
    const sendButton = document.getElementById('sendCommandButton');
    
    // 绑定点击事件
    sendButton.addEventListener('click', () => {
      // 定义要发送的消息(根据STM32协议调整格式)
      const command = "DATA"; // 示例指令(如启动运输)
    
      // 发送消息到WebSocket服务器
      if (socket.readyState === WebSocket.OPEN) {
        socket.send(command);
        console.log('发送指令:', command);
      } else {
        console.error('WebSocket未连接,无法发送指令');
      }
    });
    
    1. 连接WebSocket:创建一个WebSocket连接到ws://localhost:8081,用于实时数据传输。

    2. 处理WebSocket消息:当从服务器接收到消息时,解析JSON格式的数据,并根据其类型(如加工、运输、材料需求和库存情况)更新页面上的相应部分。

    3. 发送指令:添加了一个事件监听器到ID为sendCommandButton的按钮上,使得用户可以点击按钮向STM32设备发送预定义的指令(在这个例子中是字符串"DATA")。

  • socket.onmessage: 处理来自服务器的消息,根据不同类型更新页面内容。

  • socket.onopen: 当WebSocket连接建立时触发,这里仅打印日志。

  • socket.onerror: 发生错误时触发,记录错误信息。

  • socket.onclose: 连接关闭时触发,同样记录日志。

  • 3.websocket服务端 

    通过Node.js创建一个结合WebSocket和TCP协议的服务器,用于在前端网页与STM32设备之间进行通信。该服务器主要分为两部分:WebSocket服务器和TCP服务器。

     const WebSocket = require('ws');
    const net = require('net');
    const wss = new WebSocket.Server({ port: 8081 });
    
    // 声明全局变量存储STM32的TCP socket
    let globalTcpSocket = null;
    // ------------------- WebSocket服务器 -------------------
    wss.on('connection', (ws) => {
      console.log('WebSocket客户端已连接');
    // 监听客户端发送的消息
      ws.on('message', (clientMessage) => {
        console.log('收到客户端消息:', clientMessage.toString());
    
        // 将消息转发给STM32(需要STM32的TCP socket)
        if (globalTcpSocket) {
          const messageToSend = clientMessage.toString() ; // 添加换行符(根据STM32协议)
          globalTcpSocket.write(messageToSend, (err) => {
            if (err) {
              console.error('转发失败:', err);
            } else {
              console.log('消息已转发到STM32:', messageToSend);
            }
          });
        } else {
          console.error('STM32未连接,无法转发消息');
        }
      });
    
    
    });
    
    // ------------------- TCP服务器 -------------------
    const tcpServer = net.createServer((socket) => {
      console.log('STM32已通过TCP连接');
    
     // 更新全局变量为当前socket
      globalTcpSocket = socket;
    
      socket.on('data', (data) => {
        try {
          const rawData = data.toString().trim();
          console.log('收到STM32数据:', rawData);
    
          // 解析数据并转发给WebSocket客户端
          const message = JSON.parse(rawData);
          wss.clients.forEach((client) => {
            if (client.readyState === WebSocket.OPEN) {
              client.send(JSON.stringify(message));
            }
          });
        } catch (error) {
          console.error('数据处理失败:', error);
    
        }
      });
    
      socket.on('close', () => {
        console.log('STM32断开连接');
        globalTcpSocket = null; // 连接断开后重置全局变量
      });
    });
    
    // 启动TCP服务器
    tcpServer.listen(8080, () => {
      console.log('TCP服务器运行在 port 8080');
      console.log('WebSocket服务器运行在 port 8081');
    });

    WebSocket服务器

  • 监听来自客户端(例如您的HTML页面)的WebSocket连接。

  • 当收到消息时,检查是否已经与STM32建立了TCP连接。如果有,则将消息转发给STM32;如果没有,则记录错误信息。

  • TCP服务器

  • 监听来自STM32设备的TCP连接。

  • 当接收到数据时,尝试解析数据并将其广播给所有连接的WebSocket客户端。

  • 如果TCP连接断开,则更新全局变量globalTcpSocketnull,表示STM32不再连接。

  • 二.stm32硬件端

    这里以HC-25为例,但所有WiFi模块都一样,只需要配置以下几样

    这里是用到WiFi模块通过TCP发送给电脑的TCP服务器,然后通过解析json数据再将数据转发给web前端.

    web前端与stm32单片机进行交互

    作者:@苏瑾

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32与Web端透传通信:实现WiFi模块的应用

    发表回复