您好,登錄后才能下訂單哦!
這篇文章主要講解了“Node.js中SerialPort模塊怎么使用”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Node.js中SerialPort模塊怎么使用”吧!
上位機(jī)與各種電路模塊間常常采用串口進(jìn)行通訊,Node.js中可以使用SerialPort模塊操作串口,這篇文章將對其使用進(jìn)行簡單說明。
官網(wǎng):https://serialport.io/
目前SerialPort模塊版本為 9.2.7
使用下面命令就可以安裝SerialPort模塊:
npm install serialport
SerialPort模塊功能中有部分是用C/C++實現(xiàn)的,所以不同的平臺需要該平臺可用的二進(jìn)制文件才能運行,對于常見的平臺通常會有預(yù)編譯好的二進(jìn)制文件。如果沒有的話通常會嘗試使用 node-gyp (依賴Python 3.x)進(jìn)行編譯,通常包管理器會自動處理相關(guān)事務(wù):
有時候或是有些平臺下可能需要手動編譯。
安裝了編譯工具后可以重新安裝SerialPort模塊或者手動進(jìn)行編譯處理
安裝SerialPort模塊后可以使用 const SerialPort = require('serialport')
方式導(dǎo)入。
使用 SerialPort.list(): Promise<PortInfo[]>
靜態(tài)方法可以獲取設(shè)備上的串口列表,比如下面演示:
const SerialPort = require('serialport'); SerialPort.list().then((ports) => { console.log(ports); // 打印串口列表 }).catch((err) => { console.log(err); });
需要注意的是同一個端口在這個列表中有可能會重復(fù)出現(xiàn)。
也可以使用 async / await 方式使用上面方法:
const SerialPort = require('serialport'); (async () => { try { let ports = await SerialPort.list(); console.log(ports); // 打印串口列表 } catch (error) { console.log(error); } })();
默認(rèn)情況下創(chuàng)建 SerialPort 對象就會打開端口,比如下面這樣:
const SerialPort = require('serialport'); const port = new SerialPort('COM6', (err) => { if (err) { console.log('端口打開失??!'); return; } console.log('端口打開成功!'); });
SerialPort類的構(gòu)造方法中有一個 autoOpen 選項用于控制創(chuàng)建對象是是否自動打開端口,默認(rèn)為自動打開,也可以將它關(guān)閉,這樣可以后面手動進(jìn)行打開端口動作:
const SerialPort = require('serialport'); const port = new SerialPort('COM6', { autoOpen: false }); port.open(function (err) { if (err) { console.log('端口打開失?。?#39;); return; } console.log('端口打開成功!'); });
SerialPort類的構(gòu)造方法中可以使用 baudRate 選項設(shè)置串口通訊波特率,默認(rèn)為9600:
const SerialPort = require('serialport'); const port = new SerialPort('COM6', { baudRate: 115200 }); // 設(shè)置波特率為115200
更多內(nèi)容可以參考下面章節(jié)SerialPort類的構(gòu)造方法說明。
可以使用SerialPort對象的 write
方法發(fā)送數(shù)據(jù),該方法會將要發(fā)送的數(shù)據(jù)放入發(fā)送緩存,然后依次發(fā)送,比如下面這樣:
const SerialPort = require('serialport'); const port = new SerialPort('COM6'); port.write('Hello world!\n'); // 發(fā)送字符串 port.write(Buffer.from('Hey!\n')); // 發(fā)送Buffer數(shù)據(jù) port.write(new Uint8Array([0x48, 0x69, 0x21, 0x0A])); // 發(fā)送字節(jié)數(shù)組
write
方法也可以添加回調(diào)函數(shù):
const SerialPort = require('serialport'); const port = new SerialPort('COM6'); port.write('Hello world!\n', (err) => { if (err) { console.log('write操作失??!'); return; } console.log('write操作成功!'); });
需要注意的是上面的回調(diào)函數(shù)非異常狀態(tài)下觸發(fā)的時候只是表示 write
方法本身操作完成,并不代表數(shù)據(jù)完全從端口發(fā)送完成,可以使用 drain
方法來處理,該方法會阻塞直到發(fā)送完成:
const SerialPort = require('serialport'); const port = new SerialPort('COM6'); port.write('Hello world!\n'); port.drain(err => { if (err) return; console.log('發(fā)送完成!'); });
可以使用下面方式接收數(shù)據(jù):
const SerialPort = require('serialport'); const port = new SerialPort('COM6'); // 以 paused mode 監(jiān)聽收到的數(shù)據(jù),需要主動讀取數(shù)據(jù) port.on('readable', () => { console.log(port.read()); // 使用read方法讀取數(shù)據(jù),可以指定讀取字節(jié)數(shù) }); // 以 flowing mode 監(jiān)聽收到的數(shù)據(jù) port.on('data', (data) => { console.log(data); });
除了上面方式外,也可以使用 pipe
將數(shù)據(jù)傳送到另一個流。
SerialPort對象大多數(shù)操作都有回調(diào)函數(shù),回調(diào)函數(shù)中的第一個參數(shù)都是異常對象。另外也可以通過 error 事件來統(tǒng)一處理異常:
const SerialPort = require('serialport'); const port = new SerialPort('COM6'); port.on('error', err => { console.log(err); });
SerialPort模塊中準(zhǔn)備了一些數(shù)據(jù)解析器,主要用來處理收到的一些一些常見形式的串口數(shù)據(jù),主要提供的功能如下:
ByteLength Parser
以收到的數(shù)據(jù)長度為單位進(jìn)行解析:
const SerialPort = require('serialport'); const port = new SerialPort('COM6'); const ByteLength = require('@serialport/parser-byte-length'); const parser = port.pipe(new ByteLength({ length: 8 })); // 每收到8個字節(jié)觸發(fā) parser.on('data', chunk => { console.log(chunk); // 打印收到的數(shù)據(jù) });
ccTalk Parser
解析 ccTalk 格式數(shù)據(jù)
以指定字符為界限處理數(shù)據(jù):
const SerialPort = require('serialport'); const port = new SerialPort('COM6'); const Delimiter = require('@serialport/parser-delimiter'); const parser = port.pipe(new Delimiter({ delimiter: '\n' })); // 以 \n 分隔處理數(shù)據(jù) parser.on('data', chunk => { console.log(chunk.toString()); // 打印收到的數(shù)據(jù) });
delimiter選項可以是 string|Buffer|number[] ;includeDelimiter選項表示數(shù)據(jù)中是否包含分隔符,默認(rèn)不包含。
InterByteTimeout Parser
指定時間未收到數(shù)據(jù)觸發(fā)解析:
const SerialPort = require('serialport'); const port = new SerialPort('COM6'); const InterByteTimeout = require('@serialport/parser-inter-byte-timeout'); const parser = port.pipe(new InterByteTimeout({interval: 2000})); // 2000毫秒未接到數(shù)據(jù)觸發(fā) parser.on('data', chunk => { console.log(chunk); // 打印收到的數(shù)據(jù) });
maxBufferSize選項用于指定接收到該數(shù)量數(shù)據(jù)后就算沒有超時也將觸發(fā)動作。
Readline Parser
以行為單位解析數(shù)據(jù),默認(rèn)行分隔符為 \n
,可以使用 delimiter 選項重新設(shè)置為其它的,比如 \r\n
。
Ready Parser
以開始標(biāo)志進(jìn)行解析。
Regex Parser
以正則表達(dá)式為分隔進(jìn)行解析。
使用SerialPort模塊主要就是使用SerialPort類
new SerialPort(path [, openOptions] [, openCallback])
構(gòu)造方法用于創(chuàng)建一個串口對象,path為串口號,openCallback為自動打開失敗時的回調(diào)函數(shù);
openOptions常用選項如下:
選項 | 類型 | 說明 | 默認(rèn)值 |
---|---|---|---|
autoOpen | boolean | 自動打開端口 | true |
baudRate | number | 波特率 | 9600 |
dataBits | number | 數(shù)據(jù)位,可選值:8、7、6、5 | 8 |
highWaterMark | number | 讀和寫緩存大小 | 65536 |
lock | boolean | 鎖定端口,防止其它平臺打開(Windows上不支持false) | true |
stopBits | number | 停止位,可選值:1、2 | 1 |
parity | string | 校驗,可選值:none、even、mark、odd、space | none |
rtscts | boolean | 流控制設(shè)置 | false |
xon | boolean | 流控制設(shè)置 | false |
xoff | boolean | 流控制設(shè)置 | false |
xany | boolean | 流控制設(shè)置 | false |
SerialPort有下面幾個屬性可讀:path
、 baudRate
、 isOpen
、 binding
SerialPort會觸發(fā)的事件有下面幾個:
open
端口打開時觸發(fā);
error
發(fā)送錯誤時觸發(fā);
close
端口關(guān)閉時觸發(fā);
data
收到數(shù)據(jù)時觸發(fā);
drain
如果write方法返回false,則再次調(diào)用write方法時將觸發(fā)該事件;
SerialPort可用的一些方法如下:
open(() => {}): void
打開端口;
update(options: updateOptions, callback?: err => {}): void
更改波特率;
write(data: string|Buffer|Array<number>, encoding?: string, callback?: error => {}): boolean
發(fā)送數(shù)據(jù);
read(size?: number): string|Buffer|null
讀取數(shù)據(jù);
close(callback?: error => {}): void
關(guān)閉端口;
set(options: setOptions, callback?: error => {}): void
設(shè)置流控制;
get(callback: (error, data: ModemStatus) => {}): void
獲取已打開端口的流控制狀態(tài);
flush(callback? error => {}):void
清空接收和發(fā)送緩存中未處理數(shù)據(jù);
drain(callback? error => {}):void
等待數(shù)據(jù)發(fā)送完成;
pause(): this
暫停 flowing mode 觸發(fā)data事件,轉(zhuǎn)為 paused mode;
resume(): this
恢復(fù) data 事件,從 paused mode 轉(zhuǎn)為 flowing mode;
SerialPort模塊也提供了一些命令行工具,用于直接在命令行界面中使用。下面是官網(wǎng)首頁的使用演示:
感謝各位的閱讀,以上就是“Node.js中SerialPort模塊怎么使用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Node.js中SerialPort模塊怎么使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。