好久沒更新了,這次為大家推薦一款小巧的串口繪圖軟件——serialchart。
之前我們講過PID調試,而且調PID時候最好有對應曲線生成,這樣我們再對著口訣來調那真是方便多了!這就需要我們今天推薦的這款軟件出場啦=>> SerialChart串口調試工具是一款與眾不同的串口調試軟件,同時也是一款波形圖發(fā)現時分析軟件,它是通過配置文件來進行串口調試,并顯示出波形圖,并對波形圖進行分析,讓你可以更好的觀察串口的通信情況,所以又有 串口示波器 之稱。
長這個樣子:
發(fā)文時,小編正在調MPU6050
data是串口輸出的數據;
chart是自動繪制的圖形;
configuration是設置區(qū)域;
我們先說配置文件,后面再說如何把配置文件導入到軟件中;大家也可直接跳過本部分,直接看下一部分內容——
配置文件示例。
這種是配置文件,可以修改為txt文檔后打開,修改完成后再改為scc后綴。如果 右擊-打開方式-記事本 的話,也能打開,但排版很丑。
Setup 部分
每個配置文件由此部分開始,這里你能設置全局參數比如:
port=COM3 //這就是軟件進行串口通訊的接口啦,比如COM1,COM2.
baudrate=57600 //波特率,目前只支持以下幾種波特率:110,300,600,1200,2400,9600,19200,38400,57600,115200.
width=1000 //chart區(qū)域的象素寬度和高度
height=201
background_color=white //chart的背景顏色,關于顏色的一些提醒 請注意在.SCC文件中(也就是此軟件的配置文件)顏 色可以用16進制來表示(如 #FFF,#FFFFFF)或者用一些已命名的顏色(白色,藍色,品 紅,粉紅,灰色)更多顏色請參考 http://www.w3.org/TR/SVG/types.html#ColorKeywords 請 注意特殊的顏色“透明”代表“沒有顏色”。如果你不想讓一些元素被繪制出來你可以使用它
grid_h_origin=100 //水平方向和豎直方向都有一條原始的軸線,一般和普通的格點線(每條曲線都是由一個個像素組成 的,所以叫格點線)顏色不同這兩個參數確定了軸線在圖表中距離頂點、左側邊界的位移,單位為 像素
grid_h_step=10 //確定了每次畫線的長度
grid_h_color=#EEE //普通格點線的顏色
grid_h_origin_color=#CCC //原始軸線的顏色
grid_v_origin=0
grid_v_step=10 //確定了每次畫線的長度
grid_v_color=#EEE //普通格點線的顏色
grid_v_origin_color=transparent
請注意目前的版本不支持流量控制的參數設置,默認設置為“無”,停止位默認為1,采用最常用的設置
Default and Field Sections(默認設置和區(qū)域設置)
SerialChart能識別CSV(逗號分隔數據)的數據包(將來可能會支持更多的格式)。每一行傳送一份數據包,每一份數據包中的不同數據用逗號來分隔。下面的例子是SerialChart能識別的格式:
100,0.50,0.70
101,0.30,0.50
102,0.25,0.35
在配置文件中,下面的部分為每份數據包中的不同數據設定了參數比如:
min=-1
max=1
color=gray
min=0
max=255
color=blue
color=red
通過你可以對所有區(qū)域進行一個默認設置。這些參數對所有的數據區(qū)都有效除非在區(qū)域中他們被相同的名字覆蓋在上面的例子中,和將繼承區(qū)的默認設置
min=-1,max=1,但中的參數把值改為了min=0 and max=255
在你設置了默認設置后你應該為數據包中每個區(qū)域進行新的設置。設置順序應根據他們在數據包中的先后而設置部分的名字可以隨意命名但不能和,相同,也不能以'_'開頭和結尾,比如可以命名為,,但不能命名為,下面的參數是和區(qū)能識別的參數min,max這兩個值是對應曲線在圖中的上下界。換句話說,如果你設定min=-1,max=1,那數據“1”將會被描繪在圖中的頂端,數據“-1”將被描繪在圖中的底端,而“0”將會描繪在圖的正中間。數據會從映射到圖中的,height就是曲線圖的高度,在開始的中可以設置(這有點像arduino中的map()函數)
color
設置數據所對應曲線的顏色。如果你不想讓某個數據被繪制出來可以設置為transparent(透明)
dash
可將曲線變成一條虛線,如,當dash=3,軟件會將3個數據繪制出來,再停止繪制3個數據,再繪制3個數據,如此反復。
注:只需修改port、baudrate即可。width、height、min、max按需修改
[_setup_]
port=COM7
baudrate=115200
width=700
height=500
background_color=white
grid_h_origin=100
grid_h_step=10
grid_h_color=#EEE
grid_h_origin_color=#CCC
grid_v_origin=100
grid_v_step=10
grid_v_color=#EEE
grid_v_origin_color=transparent
[_default_]
min=-70
max=70
[Acc]
color=green
[Gryo]
color=blue
[angle]
color=yellow
[angle_dot]
color=red
1.點擊【file】,新建或打開已有的配置文件;
2.點擊【run】
3.串口只能同時被一個程序使用,當你要更新程序時,要點SerialChart中的stop。當需要更改參數(如port)時,可以直接在configuration中修改,然后點擊stop--run即可。
SerialPort 是一個用于在 Node.js 環(huán)境中進行串口通信的庫。它允許開發(fā)者通過 JavaScript 或 TypeScript 代碼與計算機上的串口設備進行交互。SerialPort 庫提供了豐富的 API,使得在串口通信中能夠方便地進行設置、監(jiān)聽和發(fā)送數據。
一般我們的設備(電子秤/掃碼槍)會有一根線插入到電腦的USB口或者其他口,電腦上的這些插口就是叫串口。設備上的數據會通過這根線傳輸到電腦里面,比如電子秤傳到電腦里的就是重量數值。那么我們前端怎么接收解析到這些數據的呢?SerialPort的作用就是用來幫我們接收設備傳輸過來的數據,也可以向設備發(fā)送數據。
簡單概括一下:SerialPort就是我們前端和設備之間的翻譯官,可以接收設備傳輸過來的數據,也可以向設備發(fā)送數據。
SerialPort可以在Node項目中使用,也可以在Electron項目中使用,我們一般都是用在Electron項目中,接下來講一下在Electron項目中SerialPort怎么下載和引入
mkdir my-electron-app && cd my-electron-app
npm init -y
npm i --save-dev electron
網上有很多Electron教程,這里不再詳細說了
在package.json中看一下自己的Electron的版本,下一步會用到。
這里先看一下自己使用的Electron對應的Node版本是什么,打開下面electron官網看表格中的Node那一列
Electron發(fā)行時間表:www.electronjs.org/zh/docs/lat…
如果你Electron對應的Node版本高于v12.0.0,直接下載就行
npm install serialport
如果你Electron對應的Node版本低于或等于v12.0.0,請用對應的Node版本對應下面的serialport版本下載
serialport.io/docs/next/g…
我項目的Electron版本是11.5.0,對應的Node版本號是12.0,對應的serialport版本號是serialport@10.0.0
npm install -g node-gyp
cd ./node_modules/@serialport/bindings
node-gyp rebuild --target=11.5.0
如果編譯的時候報錯了就將自己電腦的Node版本切換成當前Electron對應的版本號再編譯一次
查看Electron對應Node版本號:www.electronjs.org/zh/docs/lat…
編譯成功以后就可以在代碼里使用Serialport了
serialport官網使用教程:serialport.io/docs/next/g…
const { SerialPort }=require('serialport')
// or
import { SerialPort } from 'serialport'
創(chuàng)建串口有兩種寫法,新版本是這樣寫法new SerialPort(params, callback)
const port=new SerialPort({
path: 'COM1', // 串口號
baudRate: 9600, // 波特率
autoOpen: true, // 是否自動打開端口
}, function (err) {
if (err) {
return console.log('打開失敗: ', err.message)
}
console.log('打開成功')
})
舊版本是下面這樣的寫法new Serialport(path, params, callback),我用的是serialport@10.0.0版本就是這樣的寫法
const port=new Serialport('COM1', {
baudRate: 9600,
autoOpen: true, // 是否自動打開端口
}, function (err) {
if (err) {
return console.log('打開失敗: ', err.message)
}
console.log('打開成功')
})
創(chuàng)建串口的時候需要傳入兩個重要的參數是path和baudRate,path是串口號,baudRate是波特率。最后一個參數是回調函數
不知道怎么查看串口號和波特率看這篇文章
如何查看串口號和波特率?
如果autoOpen參數是false,需要使用port.open()方法手動打開
const port=new SerialPort({
path: 'COM1', // 串口號
baudRate: 9600, // 波特率
autoOpen: false, // 是否自動打開端口, 默認true
})
// autoOpen參數是false,需要使用port.open()方法手動打開
port.open(function (err) {
if (err) {
return console.log('打開失敗', err.message)
}
console.log('打開成功')
})
接收到的data是一個Buffer,需要轉換為字符串進行查看
port.on('data', function (data) {
// 接收到的data是一個Buffer,需要轉換為字符串進行查看
console.log('Data:', data.toString('utf-8'))
})
接收過來的data就是設備傳輸過來的數據,轉換后的字符串就是我們需要的數據,字符串里面可能有多個數據,我們把自己需要的數據截取出來就可以了
假設通過電子秤設備獲取到的數據就是"205 000 000",中間是四個空格分割的,第一個數字205就是獲取的重量,需要把這個重量截取出來。下面是我的示例代碼
port.on('data', function (data) {
try {
// 獲取的data是一個Buffer
// 1.將 Buffer 轉換為字符串 dataString.toString('utf-8')
let weight=data.toString('utf-8')
// 2.將字符串分割轉換成數組,取數組的第一個值.split(' ')[0]
weight=weight.split(' ')[0]
// 3.將取的值 去掉前后空格
weight=weight.trim()
// 4.最后轉換成數字,獲取到的數字就是重量
weight=Number(weight)
console.log('獲取到重量:'+ weight);
} catch (err) {
console.error(`
重量獲取報錯:${err}
獲取到的Buffer: ${data}
Buffer轉換后的值:${data.toString('utf-8')}
`);
}
})
port.write('Hi Mom!')
port.write(Buffer.from('Hi Mom!'))
const { SerialPort }=require('serialport')
SerialPort.list().then((ports, err)=> {
// 串口列表
console.log('獲取所有串口列表', ports);
})
作者:Yaoqi
鏈接:https://juejin.cn/post/7323464381172301860
項目中難免有桌面設備接入的情況,比如掃碼槍、RFID掃碼器等情況。
1.中間件方案
做一個在客戶端微型http服務或者websoket服務,JavaScript調用這個服務與串口通訊。優(yōu)點兼容瀏覽器,缺點這個服務得兼容操作系統,這種方案落地過。
2.瀏覽器插件方案
做一個瀏覽器插件,JavaScript基于插件與串口通訊。優(yōu)點是你只需要搞定瀏覽器即可,缺點是可能需要兼容多種瀏覽器,這種方案沒試過,理論上是可行的。
3.Chrome瀏覽器讀取方案
通過Chrome瀏覽器的API直接讀取串口數據,有點就是沒有額外的工作,缺點就是只有Chrome瀏覽器能用,這種方案落地過。
串行接口簡稱為串口,也叫串行通信,這是一個統稱,采用串行通信的接口都叫作串口,串口是一個硬件接口。
(1)波特率
串口通信時的速率。常見的有9600、14400、115200等等,這個說的就是bps,重點關注。
(2)數據位
這是衡量通信中實際數據位的參數。當計算機發(fā)送一個信息包,實際的數據不會是8位的,標準的值是5、7和8位。如何設置取決于你想傳送的信息。比如,標準的ASCII碼是0~127(7位)。擴展的ASCII碼是0~255(8位)。
(3)停止位
用于表示單個數據包的最后一位。典型的值為1、1.5或2位。停止位不僅表示傳輸的結束,并且提供計算機校正時鐘同步的機會。停止位的位數越多,不同時鐘同步的容錯程度越大,但同時數據傳輸率也越慢。
(4)校驗位
在串口通信中一種簡單的檢錯方式。有三種檢錯方式:偶(E)、奇(O)、無(N)。
即“廠家標識”和“產品標識”,USB 設備驅動的硬件接口需要識別 Vender ID 和 Product ID,各個平臺的查看方式大家自己查詢一下,也可以使用API查詢
if ("serial" in navigator) {
// The Web Serial API is supported.
}
const filters=[
{ usbVendorId: 0x2341, usbProductId: 0x0043 },
];
// Prompt user to select an Arduino Uno device.
const port=await navigator.serial.requestPort({ filters });
//這個參數是波特率
await port.open({baudRate: 9600});
await port.close();
讀取和寫入數據
const reader=port.readable.getReader();
// Listen to data coming from the serial device.
while (true) {
const { value, done }=await reader.read();
if (done) {
// Allow the serial port to be closed later.
reader.releaseLock();
break;
}
// value is a Uint8Array.
console.log(value);
}
onst writer=port.writable.getWriter();
const data=new Uint8Array([104, 101, 108, 108, 111]); // hello
await writer.write(data);
// Allow the serial port to be closed later.
writer.releaseLock();
async function getCOMData() {
if (!"serial" in navigator) {
console.error("該瀏覽器不支持串口")
return;
}
//這個地方換成自己設備
const filters=[
{usbVendorId: 0x1a86, usbProductId: 0x7521},
];
let port=await navigator.serial.requestPort({filters});
await port.open({baudRate: 9600});
//驗證分割符號
let checkRN=(value)=> {
if (value < 2) {
return -1;
}
for (let i=1; i < value.length; i++) {
if (value[i - 1]==0x0D && value[i]==0x0A) {
return i;
}
}
return -1;
}
const reader=port.readable.getReader();
let tempArray=[];
let readc=true;
setTimeout(()=> {
readc=false;
}, 5000);
//這里是流讀取,一定要根據協議解決分包和黏包的問題
while (true && readc) {
const {value, done}=await reader.read();
if (done) {
// Allow the serial port to be closed later.
reader.releaseLock();
break;
}
let n=checkRN(value);
if (n==-1) {
tempArray=[...tempArray, ...value]
} else {
let fullArray=[...tempArray, ...value.slice(0, n)]
tempArray=[...value.slice(n + 1, value.length)];
let str=String.fromCharCode(...fullArray)
console.log("解析后的數:",str)
}
}
reader.releaseLock();
await port.close();
return undefined;
}
API參考地址:https://web.dev/serial/#close-port
*請認真填寫需求信息,我們會在24小時內與您取得聯系。