Javascript串口编程例程

该HTML页面展示了如何利用WebSerialAPI在浏览器中与串口设备进行交互,包括请求访问串口、选择端口、打开/关闭串口、读取和发送数据的功能。用户可以选择并打开特定的USB设备(如通过VID和PID识别),并在文本区域实时显示接收到的数据和发送的数据。
摘要由CSDN通过智能技术生成
<!DOCTYPE html>   
<html>   
<head>   
<meta charset=" utf-8">   
<title>串口</title>
</head>
<body>
	<button id="btnRequest">请求访问串口</button><p/><p/><p/>
	<select id="sltPort" style="width: 152px; height: 24px;"></select>&nbsp;&nbsp;<button id="btnOpen">打开串口</button><p/><p/><p/>
	<textarea id="txtIn" style="width: 512px; height: 256px;"></textarea><p/><p/><p/><p/>
	<textarea id="txtOut" style="width: 256px; height: 24px;">020004A23100009303</textarea><p/><button id="btnSend">发送</button>
	<script type="text/javascript">
		var g_ports;
		var g_portIndex;
		var g_isOpen = false;
		var g_closed;
		var g_keepReading;
		var g_reader;

		// 定义打开/关闭串口函数
		async function openPort(portIndex, isOpen) {
			// 打开串口
			let port = g_ports[portIndex];
			if (!isOpen) {
				// 关闭串口
				g_keepReading = false;
				g_reader.cancel();
				await g_closed;
				g_portIndex = portIndex;
				g_isOpen = isOpen;
			} else {
				await port.open({
					baudRate: "115200",
	      			dataBits: "8",
    	  			stopBits: "1",
      				parity: "none",
      				flowControl: "none",
				});
				g_portIndex = portIndex;
				g_isOpen = isOpen;
				g_keepReading = true;
				g_closed = readUntilClosed(portIndex);
			}
			document.getElementById("btnOpen").textContent = isOpen ? '关闭串口' : '打开串口';
		}

		// 定义读串口函数
		async function readUntilClosed(portIndex) {
			let port = g_ports[portIndex];
			while (port.readable && g_keepReading) {
				g_reader = port.readable.getReader();
				try {
					while (true) {
						const { value, done } = await g_reader.read();
						console.log(value, '已接收');

						let txtIn = document.getElementById("txtIn");
						let content = txtIn.value + '\n';
						value.map((item, index) => {
							content = content + ' ' + item.toString(16).toLocaleUpperCase();
						});
						console.log(content);
						txtIn.value = content;
						if (done) {
							console.log('done');
							break;
						}
					}
				} catch (error) {
					console.log(error.message);
				} finally {
					g_reader.releaseLock();
				}
			}
			await port.close();
		}

		// 定义写串口函数
		function portWrite(value) {
			return new Promise(async (resolve, reject) => {
			if (!g_isOpen) {
				console.log("串口未打开");
				reject();
				return;
			} else {
				let port = g_ports[g_portIndex];
				const writer = port.writable.getWriter();
				await writer.write(new Uint8Array(value));
				writer.releaseLock();
				resolve(value);
			}
			});
		}

		// 选择端口 事件处理
		var sltPort = document.getElementById("sltPort");
		sltPort.addEventListener('onchange', function() {
			g_portIndex = sltPort.selectedIndex;
		});

		// 请求端口 事件处理
		const btnRequest = document.getElementById("btnRequest");
		btnRequest.addEventListener('click', async function() {
			// Prompt user to select any serial port.
			const port = await navigator.serial.requestPort();
			// Wait for the serial port to open.
			g_ports = await navigator.serial.getPorts();
			
			// VID_1A86&PID_7523
			g_ports.map((port, index) => {
				const { usbProductId, usbVendorId } = port.getInfo();
				if (usbProductId === undefined || usbVendorId === undefined) {
					sltPort.options.add(new Option("未知设备", index));
				} else {
					sltPort.options.add(new Option("VID_" + usbVendorId.toString(16).toUpperCase() + "&PID_" + usbProductId.toString(16).toUpperCase(), index));					
				}
				g_portIndex = index;
			});
		});

		// 打开端口 事件处理
		const btnOpen = document.getElementById("btnOpen");
		btnOpen.addEventListener('click', function() {
		    // 设置串口
    		if (g_portIndex === undefined) {
      			alert("请选择串口");
      			return;
    		}
    		openPort(g_portIndex, !g_isOpen);
		});

		// 发送数据 事件处理
		const btnSend = document.getElementById("btnSend");
		btnSend.addEventListener('click', async function() {
			const txtOut = document.getElementById("txtOut");
			const content = txtOut.value.trim();
			const value = content.trim();
			if (value.length != 0) {
				let arr = [];
				if (/^[0-9A-Fa-f]+$/.test(value) && value.length % 2 === 0) {
					for (let i = 0; i < value.length; i = i + 2) {
						arr.push(parseInt(value.substring(i, i + 2), 16));
					}
				} else {
					alert("格式错误");
					return;
				}
				portWrite(arr).then((res) => {
					console.log(arr, '已发送');
				});
			} else {
				alert("请输入");
			}
		});	
	</script>
</body>
</html>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值