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未连接,无法发送指令');
}
});
-
连接WebSocket:创建一个WebSocket连接到
ws://localhost:8081,用于实时数据传输。 -
处理WebSocket消息:当从服务器接收到消息时,解析JSON格式的数据,并根据其类型(如加工、运输、材料需求和库存情况)更新页面上的相应部分。
-
发送指令:添加了一个事件监听器到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连接断开,则更新全局变量globalTcpSocket为null,表示STM32不再连接。
二.stm32硬件端
这里以HC-25为例,但所有WiFi模块都一样,只需要配置以下几样

这里是用到WiFi模块通过TCP发送给电脑的TCP服务器,然后通过解析json数据再将数据转发给web前端.
web前端与stm32单片机进行交互
作者:@苏瑾