Vue中使用Web Serial API连接串口,实现通信交互
Vue中使用Web Serial API连接串口,实现通信交互
Web Serial API,web端通过串口与硬件通信;
该API是JS本身 navigator 对象上就独有的,所以与Vue和React框架开发都没有太大的关系,
串口是一个双向通信接口,允许字节发送和接收数据。
Web Serial API为网站提供了一种使用JavaScript对串行设备进行读写的方法。串行设备可以通过用户系统上的串行端口连接,也可以通过模拟串行端口的可移动USB和蓝牙设备连接。
换句话说,Web Serial API通过允许网站与串行设备(如微控制器和3D打印机)通信来连接网络和物理世界。
这个API也是WebUSB的好伙伴,因为操作系统要求应用程序使用它们的高级串行API而不是低级的USB API与一些串行端口通信。
Web Serial API 是一项 Web 技术,用于在浏览器中访问串行端口设备(如 Arduino、传感器等)并与之通信。它提供了一组 JavaScript 接口,使得 Web 应用程序可以通过 USB 串行端口连接到硬件设备,并进行数据发送和接收操作。
判断浏览器支持串口通信
if ("serial" in navigator) {
console.log(true);
} else {
console.log(false);
}
常用的API
- requestPort----获取授权串口
- open-----打开串口
- close—关闭串口(串口关闭前,需要释放锁住的流)
- cancel—立即退出读取的循环,然后去调用releaseLock,最后调用close方法
- releaseLock—Reader和.Writer的释放方法
- read—port.readable.getReader()的读取字节数组方法
- write—port.writable.getWriter()的写入方法
参考文档
Web Serial API
MDN Web Docs Web Serial API
示例完整代码
<template>
<div class="serial-port">测试串口</div>
<el-button type="primary" @click="connectToSerialPort">连接串口</el-button>
<el-input
v-model="inputData"
maxlength="50"
placeholder="输入发送数据内容"
show-word-limit
type="textarea"
/>
<el-button type="success" @click="sendData">发送数据</el-button>
<el-button type="danger" @click="cutPort">断开串口</el-button>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ElMessage } from "element-plus";
const port = ref("");
const ports = ref([]);
const reader = ref("");
const connectToSerialPort = async () => {
try {
// 提示用户选择一个串口
port.value = await navigator.serial.requestPort();
// 获取用户之前授予该网站访问权限的所有串口。
ports.value = await navigator.serial.getPorts();
// console.log(port.value, ports.value);
console.log(port.value);
// 等待串口打开
await port.value.open({ baudRate: 9600 });
// console.log(typeof port.value);
ElMessage({
message: "成功连接串口",
type: "success",
});
// readData(port.value);
readData();
} catch (error) {
// 处理连接串口出错的情况
console.log("Error connecting to serial port:", error);
}
};
const readData = async () => {
reader.value = port.value.readable.getReader();
console.log(reader);
// 监听来自串口的数据
while (true) {
const { value, done } = await reader.value.read();
if (done) {
// 允许稍后关闭串口
reader.value.releaseLock();
break;
}
// 获取发送的数据
const serialData = new TextDecoder().decode(value);
console.log(serialData);
// value 是一个 Uint8Array
console.log(value);
}
};
const inputData = ref("");
//
const sendData = async () => {
// if (port.value && port.value.isOpen) {
if (port.value) {
if (inputData.value) {
const writer = port.value.writable.getWriter();
console.log("发送数据");
await writer.write(new TextEncoder().encode(inputData.value));
await writer.close();
} else {
return ElMessage({
message: "输入需要发送的数据内容",
type: "warning",
showClose: true,
grouping: true,
duration: 2000,
});
}
} else {
ElMessage({
message: "串口未连接或未打开!",
type: "warning",
showClose: true,
grouping: true,
duration: 2000,
});
// console.error("串口未连接或未打开!");
}
};
// 断开接口
const cutPort = async () => {
if (port.value !== "") {
await reader.value.cancel();
await port.value.close();
port.value = "";
console.log("断开串口连接");
ElMessage({
message: "已成功断开串口连接",
type: "success",
});
} else {
ElMessage({
message: "请先连接或打开串口",
type: "warning",
showClose: true,
grouping: true,
duration: 2000,
});
// console.error("串口未连接或未打开!");
}
};
onMounted(() => {
// 判断浏览器支持串口通信
if ("serial" in navigator) {
console.log(true);
} else {
console.log(false);
}
// 页面刷新提示
// window.onbeforeunload = e => {
// console.log(e);
// // 兼容IE8和Firefox 4之前的版本
// if (e) {
// e.returnValue = '关闭提示'
// }
// // Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
// return '关闭提示'
// }
});
</script>