本来只是随手记录一下,发现看的人多了,想着还是修复一下bug吧,供各位看官指正
2022-10-24本次更新:
1、修复在不支持Serial的情况下,控制台报错
2022-09-19本次更新:
1、修复了传输数据接收分隔的情况(增加数据缓存)
2、修复串口连接没有使用选择的波特率等参数
1、
Serial
接口是 Web Serial API的接口,提供了从网页查找和连接串口的属性和方法。注意:
只能在部分支持
Serial
并且网站为安全上下文(HTTPS)中可用,或者是本机访问
requestPort----获取授权串口
open-----打开串口
close---关闭串口(串口关闭前,需要释放锁住的流)
cancel---立即退出读取的循环,然后去调用releaseLock,最后调用close方法
releaseLock---Reader和.Writer的释放方法
read---port.readable.getReader()的读取字节数组方法
write---port.writable.getWriter()的写入方法
MySerialPort.js 是封装的一个SerialPort的工具类
export default class MySerialPort {
constructor() {
this.state = {
portIndex: undefined,
ports: [],
isOpen: false,
writeType: 1,
readType: 1,
isScroll: true,
readValue: [],
status:false,
//port参数
baudRate: "9600",
dataBits: "8",
stopBits: "1",
parity: "none",
flowControl: "none",
};
this.keepReading=false;
this.getPorts = this.getPorts.bind(this);
this.handleRequestPort = this.handleRequestPort.bind(this);
this.handleChildrenChange = this.handleChildrenChange.bind(this);
this.readText = this.readText.bind(this);
this.writeText = this.writeText.bind(this);
this.handleClear = this.handleClear.bind(this);
this.a2hex = this.a2hex.bind(this);
this.hex2a = this.hex2a.bind(this);
this.hex2atostr=this.hex2atostr.bind(this);
this.reader={};
this.closed;
}
async getPorts() {
// 获取已授权的全部串口
let ports = await navigator.serial.getPorts();
this.setState({
ports,
});
}
async handleRequestPort() {
// 请求授权
try {
await navigator.serial.requestPort();
await this.getPorts();
} catch (e) {
this.$message.error(e.toString());
}
}
async openPort(portIndex, isOpen,callBack=null) {
// 打开串口
let port = this.state.ports[portIndex];
if (!isOpen) {
// 关闭串口
this.keepReading = false;
this.reader.cancel();
await this.closed;
this.handlePortOpen({
portIndex,
isOpen,
});
} else {
await port.open({
baudRate: this.state.baudRate,
dataBits: this.state.dataBits,
stopBits: this.state.stopBits,
parity: this.state.parity,
flowControl: this.state.flowControl,
});
this.handlePortOpen({
portIndex,
isOpen,
});
this.keepReading = true;
this.closed=this.readUntilClosed(portIndex,callBack);
}
}
async readUntilClosed(portIndex,callBack=null) {
let port = this.state.ports[portIndex];
while (port.readable && this.keepReading) {
this.reader = port.readable.getReader();
try {
let readCache=[]
while (true) {
const { value, done } = await this.reader.read();
if (done) {
break;
}
readCache.push(...value)
setTimeout(() => {
if(readCache.length>0){
this.readText(readCache);
callBack(readCache)
readCache=[]
}
}, 300);//串口缓存
}
} catch (error) {
this.$message.error(error.toString());
} finally {
this.reader.releaseLock();
}
await port.close();
}
}
handlePortOpen({ portIndex, isOpen }) {
// 处理打开串口
this.setState({
portIndex,
isOpen,
});
}
handleChildrenChange(type, value) {
this.setState({
[type]: value,
});
}
portWrite(value) {
return new Promise(async (resolve, reject) => {
if (!this.state.isOpen) {
this.$message.error("串口未打开");
reject();
return;
} else {
let port = this.state.ports[this.state.portIndex];
const writer = port.writable.getWriter();
await writer.write(new Uint8Array(value));
writer.releaseLock();
resolve(value);
}
});
}
readText(value) {
console.log(value, "读取");
let newValue = this.state.readValue.concat({
value,
type: 1,
});
this.setState({
readValue: newValue,
});
}
writeText(value) {
console.log(value, "写入");
this.portWrite(value).then((res) => {
let newValue = this.state.readValue.concat({
value: res,
type: 2,
});
this.setState({
readValue: newValue,
});
});
}
handleClear() {
this.setState({
readValue: [],
});
}
componentDidMount() {
this.getPorts();
}
handleState(status) {
this.setState({
status,
});
}
setState(obj){
Object.keys(this.state).forEach(key => {
if(obj[key]!=undefined){
this.state[key]=obj[key]
}
});
}
//字节转字符串
hex2atostr(arr) {
return String.fromCharCode.apply(String,arr);
}
hex2a(hexx) {
return String.fromCharCode(hexx);
}
//字符转16进制
a2hex(str) {
return str.charCodeAt(0);
}
}
vue代码:
仅支持Chrome 89+或者Edge 89+浏览器(安全上下文(HTTPS)中可用)
授权
{{ item.value }}
{{ item.address }}
ASCII
HEX
发送
{{
btnText
}}
新增授权
授权界面:
授权成功后:
使用串口工具调试发送和接收:
1、使用vspd创建一个对虚拟串口,com1和com2
2、网页的连接com1,sscom连接com2就可以进行通信了