Serialport.js 鏈接 web 和硬件設備編程

Serialport 簡介

想象這樣一個世界,在那裏你能用 JavaScript 代碼控制榨汁機,燈,安防系統,甚至機器人。嗯,是機器人!你會不會以爲很新奇以至興奮?node

Serialport 庫(也稱 Node-Serialport,基於 Node),爲低級串口編碼提供必要的 steam 接口,以控制 Arduino 芯片組,X10 接口,Zigbee 無線技術,公路路標,LCD 顯示屏,收銀抽屜,電機控制器,傳感器,叉車,調制解調器,無人機,數控機牀,繪圖儀器,自動販賣機,基於 ccTalk 協議的投幣設備,SMS 網關,RFID 掃描器等等很是多設備。若是你手中有一塊可以異步收發消息的硬件設備(咱們姑且這樣說),那麼這個物理世界將成爲你的掌中玩物。git

Serialport 爲 JavaScript 開發者打開了硬件開發之門。它是一個比編寫固件更好的方案!github

獲取到 USB 串口路徑

PC 機通常會帶有 2 ~ 4 個 USB 插口, 如下稱 port 口。不一樣的操做系統,獲取到的串口信息不一樣。web

欲瞭解 port 口信息,能夠在命令行工具中輸入命令:serialport-listnpm

Mac OSX 的 port 口爲:promise

{
  comName: '/dev/tty.usbmodem1421',
  manufacturer: 'Arduino (www.arduino.cc)'
}

Linux 的 port 口爲:瀏覽器

{
  comName: '/dev/ttyACM0',
  manufacturer: 'Arduino (www.arduino.cc)'
}

Windows 的 port 口爲:框架

{
  comName: 'COM3',
  manufacturer: 'Arduino LLC (www.arduino.cc)'
}

其中, comName 字段,指的就是 USB 串口的路徑。該路徑是 SerialPort 實例化的依據。異步

獲取串口列表SerialPort.list([callback]) ⇒ Promise工具

因歷史版本的緣故,該接口支持兩種形式調用,推薦 v6.0.0 版本的 promise 方式:

// v4.0.7 的 callback 形式
SerialPort.list((error, ports) => console.log(ports))

// v6.0.0 的 promise 形式
SerialPort.list().then(ports => console.log(ports))

建立一個 SerialPort 對象

建立 SerialPort 對象new SerialPort(path, [options], [openCallback])

有了 port 口路徑,就能夠建立一個 port 口實例,並創建鏈接。

let port = new SerialPort('/dev/tty.usbmodem1421');

該實例化是首先產生一個 port 實例,而後再嘗試創建鏈接的。即實例化過程當中有一個異步操做,實例化完成了,鏈接的結果可能尚未返回。

鏈接創建成功,就會觸發 open 事件——事件稍後再解說。

合併以上兩步的代碼,就是:

import SerialPort from serialport;

SerialPort.list().then( ports => {
    // 假設選擇第一個串口實例化
    let path = ports[0].comName;
    let myPort = new SerialPort(path);
})
.catch(err => console.log(err))

綁定事件監聽

當獲取到了 SerialPort 的實例對象 myPort 後,就能夠進行事件監聽了。

// 當鏈接創建時
myPort.on('open', callback);

// 當接收到數據時
myPort.on('data', callback);

// 當出現錯誤時
myPort.on('error', callback);

事件監聽,主要用來在合適的時間點發送數據,以及處理接收到來自串口的數據信息。

值得注意的是,不少錯誤來自:因串口路徑不對致使的鏈接錯誤(但此時實例對象已存在)、串口被佔用鎖定時仍嘗試鏈接的錯誤。

向串口寫入數據

向串口寫入數據serialPort.write(data, [encoding], [callback]) ⇒ boolean

實例建立完,而且正確創建鏈接後,就能夠向串口寫數據了。數據會經串口發送至與 PC 鏈接的硬件設備,好比 Arduino 板,或者 Raspberry Pi 板等等。

// 直接寫入字符串
myPort.write('hello world', (err) => {
    if (err) return console.log('write Error: ', err.message);
})

// 寫入 Buffer
myPort.write(Buffer.from('hello world'), callback)

寫入數據完畢,就會調用上述回調。

若寫數據出錯——可能由於數據非法或斷開了鏈接等緣由——一樣會調用上述回調,只不過有些錯誤狀況下,可能 err 參數不存在。可是 error 事件必定會被觸發。

鏈接未創建,即 open 事件未被觸發,若此前就寫入數據,寫操做會被阻塞,直到創建鏈接以後再執行。

串口每次傳輸數據是有必定長度限制的。一個數據包寫完,纔會開始寫下一個數據包;若一條數據太長,會被切分紅多個包,依次寫入。寫完後會當即調用 drain 方法表示本條數據已寫完,drain 意爲排幹了擁塞的數據。

一些安裝 trouble

這裏主要是 serialport 一些安裝不成功的問題,包括 Windows 系統,Electron (跨平臺的框架),一些 Linux 發行版以及 Raspberry Pi 板,都有可能發生一些安裝的麻煩。 難以一一呈現,需耐心 Google~

文末彩蛋

如開篇說說,Serialport 是基於 Node 的一個 JS 庫,那麼上述代碼須要在 Node 環境中運行,也就是咱們平常的命令行。但若是想直接在瀏覽器中使用,還有一段距離。

因此,爲更好的服務於 web 開發,這裏有一款本人封裝的 npm 工具——sensorium-server,只需在命令行中開啓此工具,就能夠輕鬆搭建一個從 HTML 頁面到硬件設備的鏈接通道,這樣就能夠在 Browser 中輕鬆的調試硬件了。

相關文章
相關標籤/搜索