文章目录

  • 目的
  • 模块安装
  • 快速使用
    • 模块导入
    • 扫描端口
    • 打开端口
    • 发送数据
    • 接收数据
    • 错误处理
  • SerialPort更多说明
    • 构造方法
    • 属性
    • 事件
    • 方法
  • 数据解析器
  • 命令行工具
  • 在Electron渲染进程中使用
  • 总结

目的

上位机与各种电路模块间常常采用串口进行通讯,Node.js中可以使用SerialPort模块操作串口,这篇文章将对其使用进行简单说明。

官网:https://serialport.io/
项目地址:https://github.com/serialport/node-serialport

目前SerialPort模块版本为 10.4.0

模块安装

使用下面命令就可以安装SerialPort模块:

# npm init -y # 初始化项目
npm install serialport
# npm install serialport@10 # 安装10.x.x版本中最新的包

SerialPort模块功能中有部分是用C/C++实现的,所以不同的平台需要该平台可用的二进制文件才能运行,对于常见的平台通常会有预编译好的二进制文件。如果没有的话通常会尝试使用 node-gyp (依赖Python)进行编译,通常包管理器会自动处理相关事务。

在Linux中使用root用户或是sudo方式安装的话需要带上额外参数,不然可能会报错:
sudo npm install serialport --unsafe-perm

快速使用

模块导入

安装完成后使用可以使用下面两种方式导入模块:

const { SerialPort } = require('serialport');
// import { SerialPort } from 'serialport'; // esm方式

扫描端口

使用SerialPort.list()可以得到设备上的串口列表。这是一个Promise对象,可以使用then方式或是使用async/await方式处理:

const { SerialPort } = require('serialport');(async () => {try {let ports = await SerialPort.list();console.log(ports); // 打印串口列表} catch (error) {console.log(error);}
})();

需要注意的是同一个端口在这个列表中有可能会重复出现。

打开端口

可以使用下面方法创建并打开端口:

const { SerialPort } = require('serialport');const serialport = new SerialPort({ path: 'COM7', baudRate: 9600 });

打开端口这个动作可以添加回调函数:

const { SerialPort } = require('serialport');const port = new SerialPort({ path: 'COM7', baudRate: 9600 }, (err) => {if (err) {console.log('端口打开失败!');return;}console.log('端口打开成功!');
});

另外也可以在创建时不打开端口,在使用前用open方法打开:

const { SerialPort } = require('serialport');const serialport = new SerialPort({ path: 'COM7', baudRate: 9600, autoOpen: false });serialport.open();

发送数据

打开端口后可以使用write方法发送数据:

const { SerialPort } = require('serialport');
const sp = new SerialPort({ path: 'COM7', baudRate: 115200 });sp.write('Hello world!\n'); // 发送字符串
sp.write(Buffer.from('Hey!\n')); // 发送Buffer数据
sp.write(new Uint8Array([0x48, 0x69, 0x21, 0x0A])); //发送字节数组

需要注意的是打开端口的动作是异步的,所以上面代码的write执行的时候端口可能还没打开,write会先将数据写入到缓存中,等到端口打开时再发送。

需要注意的是write方法返回true或是触发回调函数并不代表发送完成,需要结合drain方法才能判断发送完成:

const { SerialPort } = require('serialport');
const sp = new SerialPort({ path: 'COM7', baudRate: 115200 });port.write('Hello world!\n');
port.drain(err => {if (err) return;console.log('发送完成!');
});

接收数据

可以使用下面两种方式来接收数据:

const { SerialPort } = require('serialport');
const sp = new SerialPort({ path: 'COM7', baudRate: 115200 });// 以 paused mode 监听收到的数据,需要主动读取数据
sp.on('readable', () => {console.log(sp.read()); // 使用read方法读取数据,可以指定读取字节数
});// 以 flowing mode 监听收到的数据
sp.on('data', (data) => {console.log(data);
});

错误处理

SerialPort对象大多数操作都有回调函数,回调函数中的第一个参数都是异常对象。另外也可以通过 error 事件来统一处理异常:

const { SerialPort } = require('serialport');
const sp = new SerialPort({ path: 'COM7', baudRate: 115200 });sp.on('error', err => {console.log(err);
});

SerialPort更多说明

构造方法

new SerialPortStream(openOptions, [openCallback])
构造方法用于创建一个串口对象,openOptions为参数,openCallback为打开端口失败时的回调函数;
openOptions常用选项如下:

选项 类型 说明 默认值
path string 端口号
baudRate number 波特率
dataBits number 数据位,可选值:5、6、7、8 8
lock boolean 锁定端口,防止其它平台打开(Windows上不支持false) true
stopBits number 停止位,可选值:1、1.5、2 1
parity string 校验,可选值:none、even、mark、odd、space none
rtscts boolean 流控制设置 false
xon boolean 流控制设置 false
xoff boolean 流控制设置 false
xany boolean 流控制设置 false
hupcl boolean 流控制设置(关闭串口时将DTR设置为低) true
autoOpen boolean 自动打开端口 true
highWaterMark number 读和写缓存大小 64k (65536?)
endOnClose boolean 当串口关闭时发送end事件 false

属性

SerialPort有下面几个属性可读:
pathbaudRateisOpenbinding

事件

SerialPort会触发的事件有下面几个:

  • open 端口打开时触发;
  • error 发生错误时触发;
  • close 端口关闭时触发;
  • data flowing mode下收到数据时触发;
  • drain 如果write方法返回false,则在恢复可以发送数据时将触发该事件;

方法

SerialPort可用的一些方法如下:

  • open(callback?: (err: Error | null) => {}): void 打开端口;
  • update(options: updateOptions, callback?: err => {}): void 更改波特率;
  • write(data: string|Buffer|Array<number>, encoding?: string, callback?: error => {}): boolean 发送数据;
  • read(size?: number): string|Buffer|null 读取数据;
  • close(callback?: error => {}): void 关闭端口;
  • set(options: setOptions, callback?: error => {}): void 设置流控制;
  • get(callback: (error, data: ModemStatus) => {}): void 获取已打开端口的流控制状态;
  • flush(callback? error => {}):void 清空接收和发送缓存中未处理数据;
  • drain(callback? error => {}):void 等待数据发送完成;
  • pause(): this 暂停 flowing mode 触发data事件,转为 paused mode;
  • resume(): this 恢复 data 事件,从 paused mode 转为 flowing mode;

数据解析器

SerialPort模块中准备了一些数据解析器,主要用来处理收到的一些常见形式的串口数据。

parser-byte-length
以收到的数据长度为单位进行解析:

const { SerialPort } = require('serialport');
const sp = new SerialPort({ path: 'COM7', baudRate: 115200 });const { ByteLengthParser } = require('@serialport/parser-byte-length');
const parser = sp.pipe(new ByteLengthParser({ length: 8 })); // 每收到8个字节触发
parser.on('data', chunk => {console.log(chunk); // 打印收到的数据
});

parser-cctalk
解析 ccTalk 格式数据,格式详见:https://en.wikipedia.org/wiki/CcTalk

parser-delimiter
以指定字符为界线处理数据:

const { SerialPort } = require('serialport');
const sp = new SerialPort({ path: 'COM7', baudRate: 115200 });const { DelimiterParser } = require('@serialport/parser-delimiter');
const parser = sp.pipe(new DelimiterParser({ delimiter: ';' })); // 以 ; 分隔处理数据
parser.on('data', chunk => {console.log(chunk.toString()); // 打印收到的数据
});

DelimiterParser可用参数有:

  • delimiter : string | Buffer | number[]
  • includeDelimiter : 表示数据中是否包含分隔符,默认为false(不包含)

parser-inter-byte-timeout
指定时间未收到数据触发解析:

const { SerialPort } = require('serialport');
const sp = new SerialPort({ path: 'COM7', baudRate: 115200 });const { InterByteTimeoutParser } = require('@serialport/parser-inter-byte-timeout');
const parser = sp.pipe(new InterByteTimeoutParser({ interval: 2000, maxBufferSize: 4 }));
parser.on('data', chunk => {console.log(chunk); // 打印收到的数据
});

maxBufferSize选项用于指定接收到该数量数据后就算没有超时也将触发动作。

parser-packet-length
以分隔符数据长度等标识数据包进行解析。

parser-readline
以行为单位解析数据,默认行分隔符为 \n,可以使用 delimiter 选项重新设置为其它的,比如 \r\n

parser-ready
以标志字符串进行解析。触发时会触发一个以标志字符串为名称的事件。

parser-regex
以正则表达式为分隔进行解析。

parser-slip-encoder

parser-spacepacket

命令行工具

SerialPort模块也提供了一些命令行工具,用于直接在命令行界面中使用。下面是官网首页的使用演示:

更多内容可以参考SerialPort模块文档中 Command Line Packages 章节内容。

在Electron渲染进程中使用

SerialPort模块10.x.x版本最大的变化是可以直接在Electron的渲染进程中使用了:

总结

Node.js的SerialPort模块使用主要就是上面一些内容了。

另外需要提一点的是SerialPort模块并不是直接操作串口,而是调用了各个平台上底层的接口来使用串口,如果有进行相关内容的开发或是有特殊需求的话可以参考SerialPort模块文档中binding相关内容。

Node.js笔记:SerialPort(串口)模块使用(基于10.x.x)相关推荐

  1. Node.js笔记:SerialPort(串口)模块使用(基于9.x.x)

    文章目录 目的 模块安装 基础使用 扫描端口 打开端口 发送数据 接收数据 错误处理 数据解析器 SerialPort类 构造方法 属性 事件 方法 命令行工具 总结 目的 上位机与各种电路模块间常常 ...

  2. node.js 笔记

    目录 项目需求分析 node.js 是怎么跑起来的?它的底层实现是如何的? 安装 node.js,配置 node.js 环境 Node.js 应用是由哪几部分组成的: 创建 Node.js 第一个 & ...

  3. 学习Node.js笔记

    什么是Node.js 官方解释: Node.js 是一个基于 Chrome V8引擎的 JavaScript运行环境.Node.js使用了一个事件驱动.非阻塞式I/O的模型( Node.js的特性), ...

  4. node.js笔记(千锋kerwin老师同款)

    [toc] Node.js (最全)基础+全栈项目 作者:kerwin 版本:QF1.0 版权:千锋HTML5大前端教研院 公众号: 大前端私房菜 一.Node.js基础 1. 认识Node.js N ...

  5. Node.js笔记总结(day4)

    Node第四天 文章目录 Node第四天 今日目标 1. Express 路由 1.1 路由的概念 1.2 路由的使用 2. Express 中间件 2.1 中间件的概念 2.2 Express 中间 ...

  6. 如何在Node JS中卸载NPM模块?

    本文翻译自:How to uninstall npm modules in node js? As commonly known, any npm module can be installed by ...

  7. Node.js 笔记 http服务器

    入门学习参考: http://www.nodebeginner.org/index-zh-cn.html#javascript-and-nodejs 初步学习了node.js架设http的基础知识,其 ...

  8. [Node.js] 模块化 -- path路径模块

    路径问题 nodejs中相对路径,相对的是运行这个node文件的小黑框的路径而言的. 相关变量 __dirname 获取的是当前这个文件所在的这个文件夹的绝对路径 __filename 拿到的是当前这 ...

  9. 【笔记整理】node.js笔记

    第一天: - Node.js 是什么   + JavaScript 运行时   + 既不是语言,也不是框架,它是一个平台 - Node.js 中的 JavaScript   + 没有 BOM.DOM ...

最新文章

  1. Python爬虫入门教程 33-100 《海王》评论数据抓取 scrapy
  2. php+mysqli实现批量执行插入、更新及删除数据的方法
  3. 基于matlab的pointnet++深度学习网络点云数据分类
  4. 洛谷P3763 [Tjoi2017]DNA 【后缀数组】
  5. java内存泄露问题
  6. ksu7对讲机调频软件_数字对讲机的群呼功能原理是什么?你了解多少?
  7. 问题总结2015/05/05
  8. (最小生成树)prim算法
  9. JavaScript表单处理的返回值问题
  10. Deep Glow mac(AE高级辉光特效插件)支持AE2022
  11. C# MVC 过滤器
  12. 数字IC笔试题,大疆校招16题(仅供参考)
  13. Double和Float类型的max、min、isNaN、isFinite、isInfinite方法
  14. Mac系统下Cypress使用初体验
  15. 借Kinect 扫描 软件 reconstructMe skanect ksan3d
  16. [Python爬虫] 九、机器视觉与机器图像识别之Tesseract
  17. 【产品集】什么是堡垒机?为什么需要堡垒机
  18. 机器学习 第三节 第十课
  19. 小程序的退出登陆功能实现代码
  20. Scratch3.0 运动和绘图

热门文章

  1. 微博html5轮博,微博轮博号购买_第1页_经管新媒
  2. 极光认证初始化失败8005和极光一键登录的流程
  3. 【论文分享】AURORA: Statistical Crash Analysis for Automated Root Cause Explanation
  4. 西门子去年在欧洲提交专利申请数量最多 华为排第二
  5. JS下载图片到本地,解决跨域问题
  6. 大四毕业生的牌局:谁输了就去骚扰女生宿舍
  7. python保存logo_如何用python 在视频上添加自己的logo
  8. 机器学习实战的数据集在哪找_在哪里找到很棒的机器学习数据集
  9. Geode 分布式缓存配置
  10. 去中心化身份(Decentralized ID, DID)介绍