Node.js中SerialPort(串口)模块使用详解
Node.js中SerialPort(串口)模块使用详解
在现代物联网和嵌入式系统中,串口通信作为一种经典且高效的数据传输方式,依然扮演着重要角色。Node.js作为一款强大的JavaScript运行环境,通过SerialPort模块,为我们提供了一套简洁而强大的串口操作接口。本文将深入探讨SerialPort模块的使用方法,帮助开发者快速掌握串口通信的精髓。
模块简介
SerialPort模块是Node.js中用于串口通信的核心库,其官网为https://serialport.io/,提供了详尽的文档和丰富的示例。项目地址位于https://github.com/serialport/node-serialport,当前版本为9.2.7。
模块安装
安装SerialPort模块非常简单,只需在命令行中执行以下命令:
npm install serialport
由于SerialPort模块部分功能依赖于C/C++实现,不同平台需要相应的二进制文件。常见的平台通常有预编译好的二进制文件,若没有,包管理器会尝试使用node-gyp进行编译,这需要Python 3.x的支持。在某些特殊情况下,可能需要手动编译,具体步骤可参考SerialPort模块文档。
基础使用
安装完成后,可以通过以下方式导入SerialPort模块:
const SerialPort = require('serialport');
扫描端口
使用SerialPort.list()静态方法可以获取设备上的串口列表:
SerialPort.list().then((ports) => { console.log(ports); // 打印串口列表 }).catch((err) => { console.log(err); });
也可以使用async/await语法:
(async () => { try { let ports = await SerialPort.list(); console.log(ports); // 打印串口列表 } catch (error) { console.log(error); } })();
打开端口
创建SerialPort对象时,默认会自动打开端口:
const port = new SerialPort('COM6', (err) => { if (err) { console.log('端口打开失败!'); return; } console.log('端口打开成功!'); });
可以通过autoOpen选项控制是否自动打开端口:
const port = new SerialPort('COM6', { autoOpen: false }); port.open(function (err) { if (err) { console.log('端口打开失败!'); return; } console.log('端口打开成功!'); });
还可以设置串口通信的波特率,默认为9600:
const port = new SerialPort('COM6', { baudRate: 115200 });
发送数据
使用write方法发送数据:
port.write('Hello world!\n'); // 发送字符串 port.write(Buffer.from('Hey!\n')); // 发送Buffer数据 port.write(new Uint8Array([0x48, 0x69, 0x21, 0x0A])); // 发送字节数组
write方法可以添加回调函数:
port.write('Hello world!\n', (err) => { if (err) { console.log('write操作失败!'); return; } console.log('write操作成功!'); });
若需确保数据完全发送,可使用drain方法:
port.write('Hello world!\n'); port.drain(err => { if (err) return; console.log('发送完成!'); });
接收数据
接收数据有两种模式:paused mode和flowing mode。
// paused mode port.on('readable', () => { console.log(port.read()); // 使用read方法读取数据 }); // flowing mode port.on('data', (data) => { console.log(data); });
错误处理
通过error事件统一处理异常:
port.on('error', err => { console.log(err); });
数据解析器
SerialPort模块提供多种数据解析器,方便处理常见格式的串口数据。
ByteLength Parser
以收到的数据长度为单位进行解析:
const ByteLength = require('@serialport/parser-byte-length'); const parser = port.pipe(new ByteLength({ length: 8 })); parser.on('data', chunk => { console.log(chunk); });
Delimiter Parser
以指定字符为界限处理数据:
const Delimiter = require('@serialport/parser-delimiter'); const parser = port.pipe(new Delimiter({ delimiter: '\n' })); parser.on('data', chunk => { console.log(chunk.toString()); });
InterByteTimeout Parser
指定时间未收到数据触发解析:
const InterByteTimeout = require('@serialport/parser-inter-byte-timeout'); const parser = port.pipe(new InterByteTimeout({ interval: 2000 })); parser.on('data', chunk => { console.log(chunk); });
Readline Parser
以行为单位解析数据:
const Readline = require('@serialport/parser-readline'); const parser = port.pipe(new Readline({ delimiter: '\r\n' })); parser.on('data', line => { console.log(line); });
SerialPort类
SerialPort类是模块的核心,其构造方法如下:
new SerialPort(path [, openOptions] [, openCallback])
常用选项包括:
- autoOpen: 是否自动打开端口,默认为true
- baudRate: 波特率,默认为9600
- dataBits: 数据位,可选值:8、7、6、5,默认为8
- stopBits: 停止位,可选值:1、2,默认为1
- parity: 校验,可选值:none、even、mark、odd、space,默认为none
SerialPort类的属性包括path、baudRate、isOpen和binding。
主要事件有:
- open: 端口打开时触发
- error: 发生错误时触发
- close: 端口关闭时触发
- data: 收到数据时触发
- drain: 如果write方法返回false,则再次调用write方法时触发
常用方法包括:
- open(): 打开端口
- update(): 更改波特率
- write(): 发送数据
- read(): 读取数据
- close(): 关闭端口
- set(): 设置流控制
- get(): 获取流控制状态
- flush(): 清空接收和发送缓存
- drain(): 等待数据发送完成
- pause(): 暂停flowing mode
- resume(): 恢复flowing mode
命令行工具
SerialPort模块还提供了一些命令行工具,方便在命令行界面中使用。更多内容可参考Command Line Tools章节。
总结
通过本文的介绍,相信大家对Node.js中的SerialPort模块有了更深入的了解。无论是基础的串口操作,还是复杂的数据解析,SerialPort模块都提供了简洁而强大的接口。在实际开发中,结合具体需求,灵活运用这些功能,必将大大提升开发效率。需要注意的是,SerialPort模块并非直接操作串口,而是调用各平台底层接口,若需深入了解,可参考模块文档中的Binding相关内容。