如何使用Angular 14(TypeScript)从串口读取Arduino RFID设备数据?
实现Angular 14读取Arduino串口RFID数据的方案
核心逻辑
浏览器无法直接访问本地串口,需借助Web Serial API(仅支持Chromium内核浏览器),通过Angular服务封装串口连接、数据读取逻辑,实现接收Arduino返回的RFID UID。
步骤1:封装串口操作服务
创建全局服务统一管理串口生命周期与数据流转:
// serial.service.ts import { Injectable } from '@angular/core'; import { Subject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class SerialService { private port: SerialPort | null = null; private reader: ReadableStreamDefaultReader | null = null; public uidData$ = new Subject<string>(); // 请求用户选择Arduino对应的串口 async requestPort(): Promise<void> { try { this.port = await navigator.serial.requestPort(); await this.port.open({ baudRate: 9600 }); // 匹配Arduino设置的波特率 this.startReading(); } catch (error) { console.error('串口连接失败:', error); } } // 持续读取串口数据 private async startReading(): Promise<void> { if (!this.port) return; const textDecoder = new TextDecoderStream(); const readableStreamClosed = this.port.readable?.pipeTo(textDecoder.writable); const reader = textDecoder.readable.getReader(); this.reader = reader; while (true) { try { const { value, done } = await reader.read(); if (done) { console.log('读取流已关闭'); reader.releaseLock(); break; } // 过滤空行,提取有效UID(Arduino需用Serial.println输出UID) const uid = value.trim(); if (uid) this.uidData$.next(uid); } catch (error) { console.error('读取数据出错:', error); break; } } await readableStreamClosed; } // 关闭串口连接 async closePort(): Promise<void> { if (this.reader) { await this.reader.cancel(); this.reader.releaseLock(); } if (this.port) { await this.port.close(); this.port = null; } } }
步骤2:组件中调用服务实现UI交互
创建组件触发串口连接、展示读取到的UID:
// rfid-reader.component.ts import { Component, OnDestroy, OnInit } from '@angular/core'; import { SerialService } from './serial.service'; import { Subscription } from 'rxjs'; @Component({ selector: 'app-rfid-reader', template: ` <button (click)="connectSerial()" [disabled]="isConnected">连接串口</button> <button (click)="disconnectSerial()" [disabled]="!isConnected">断开连接</button> <div *ngIf="latestUid">读取到的UID: <strong>{{ latestUid }}</strong></div> ` }) export class RfidReaderComponent implements OnInit, OnDestroy { latestUid: string | null = null; isConnected = false; private uidSubscription: Subscription | null = null; constructor(private serialService: SerialService) {} ngOnInit(): void { // 订阅UID数据更新 this.uidSubscription = this.serialService.uidData$.subscribe(uid => { this.latestUid = uid; // 此处可添加业务逻辑,如将UID提交至后端 }); } async connectSerial(): Promise<void> { await this.serialService.requestPort(); this.isConnected = true; } async disconnectSerial(): Promise<void> { await this.serialService.closePort(); this.isConnected = false; this.latestUid = null; } ngOnDestroy(): void { this.uidSubscription?.unsubscribe(); this.serialService.closePort(); } }
关键注意事项
- 浏览器限制:Web Serial API仅支持Chrome、Edge等Chromium内核浏览器,Firefox、Safari暂不兼容。
- Arduino配置:需确保Arduino代码使用
Serial.println(uid)输出UID,保证每条数据以换行符结尾,方便前端解析。 - 权限要求:必须通过用户交互(如点击按钮)触发串口请求,浏览器不允许页面加载时自动访问串口。
- 波特率匹配:前端设置的波特率需与Arduino代码中
Serial.begin(XXX)的参数完全一致,否则会读取到乱码。
内容的提问来源于stack exchange,提问作者Nadeesh Hirushan
相关产品推荐
相关产品推荐

