溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Node.js中SerialPort模塊怎么使用

發(fā)布時間:2021-11-25 15:29:36 來源:億速云 閱讀:901 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“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ù):

    Node.js中SerialPort模塊怎么使用

    有時候或是有些平臺下可能需要手動編譯。

    安裝了編譯工具后可以重新安裝SerialPort模塊或者手動進(jìn)行編譯處理

    基礎(chǔ)使用

    安裝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);
    });

    Node.js中SerialPort模塊怎么使用

    需要注意的是同一個端口在這個列表中有可能會重復(fù)出現(xiàn)。

    也可以使用 async / await 方式使用上面方法:

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

    Node.js中SerialPort模塊怎么使用

    打開端口

    默認(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)造方法說明。

    發(fā)送數(shù)據(jù)

    可以使用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ù)組

    Node.js中SerialPort模塊怎么使用

    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ù)

    可以使用下面方式接收數(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);
    });

    Node.js中SerialPort模塊怎么使用

    除了上面方式外,也可以使用 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);
    });

    數(shù)據(jù)解析器

    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ù)
    });

    Node.js中SerialPort模塊怎么使用

    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ù)
    });

    Node.js中SerialPort模塊怎么使用

    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ù)
    });

    Node.js中SerialPort模塊怎么使用

    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模塊主要就是使用SerialPort類

    構(gòu)造方法

    new SerialPort(path [, openOptions] [, openCallback])

    構(gòu)造方法用于創(chuàng)建一個串口對象,path為串口號,openCallback為自動打開失敗時的回調(diào)函數(shù);

    openOptions常用選項如下:

    選項類型說明默認(rèn)值
    autoOpenboolean自動打開端口true
    baudRatenumber波特率9600
    dataBitsnumber數(shù)據(jù)位,可選值:8、7、6、58
    highWaterMarknumber讀和寫緩存大小65536
    lockboolean鎖定端口,防止其它平臺打開(Windows上不支持false)true
    stopBitsnumber停止位,可選值:1、21
    paritystring校驗,可選值:none、even、mark、odd、spacenone
    rtsctsboolean流控制設(shè)置false
    xonboolean流控制設(shè)置false
    xoffboolean流控制設(shè)置false
    xanyboolean流控制設(shè)置false

    屬性

    SerialPort有下面幾個屬性可讀:
    path 、 baudRateisOpen 、 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模塊怎么使用

    感謝各位的閱讀,以上就是“Node.js中SerialPort模塊怎么使用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Node.js中SerialPort模塊怎么使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

    向AI問一下細(xì)節(jié)

    免責(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)容。

    AI