Joe*_*Joe 5 javascript embedded serial-port node.js
我正在尝试编写 Node.js 脚本,该脚本使用serialportnpm 包来读取数据并将数据写入COM5串行端口,该串行端口使用 RS-232 电缆连接到设备。该设备会自动传输其拥有的数据。
要检索设备内部存储的数据,我需要首先uInt8向设备发送一个字节 0x80 ( ),并期望从设备接收 81 作为十六进制数字。其次,我需要发送另一个字节 0x81 ( uInt8),然后期望以行形式接收所有存储的数据(大约 130000 字节)。
无法仅通过两个字节一个接一个地检索整个存储的数据。与设备的通信只能通过字节来完成。
我尝试了以下代码:
import SerialPort from 'serialport';
const sp = new SerialPort.SerialPort({path: "COM5", baudRate: 115200});
const buff = Buffer.allocUnsafe(1);
buff.writeUInt8(0x80, 0);
sp.write(buff, function (err){
if (err){
return console.log("Error on write: ", err.message);
}
console.log("Port.write: ", buff);
});
sp.on('readable', function () {
var arr = new Uint8Array(sp._pool);
console.log('Data:', arr);
});
Run Code Online (Sandbox Code Playgroud)
运行我的脚本(使用node myScript.mjs)时,我看到以下内容:
PortWrite: <Buffer 80>
Data: Uint8Array(65536) [
0, 30, 167, 106, 127, 2, 0, 0, 32, 31, 170, 106,
127, 2, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0,
16, 84, 18, 76, 196, 0, 0, 0, 100, 84, 18, 76,
196, 0, 0, 0, 184, 84, 18, 76, 196, 0, 0, 0,
160, 84, 18, 76, 196, 0, 0, 0, 244, 84, 18, 76,
196, 0, 0, 0, 72, 85, 18, 76, 196, 0, 0, 0,
240, 120, 18, 76, 196, 0, 0, 0, 68, 121, 18, 76,
196, 0, 0, 0, 152, 121, 18, 76, 196, 0, 0, 0,
240, 120, 18, 76,
... 65436 more items
]
Run Code Online (Sandbox Code Playgroud)
直到我点击 ,程序才会退出Ctrl+c。我不确定ps._pool是什么,但输出似乎不正确,但看起来像是随机给出一些东西。
我是 Node.js 新手。我也不知道如何TimeOut在对象中添加 10 秒的参数sp。
我尝试使用Matlab进行测试,并且可以成功检索数据。
我也尝试过Python,但对我不起作用 - PySerial 包在写入之前读取串行数据?。
我相信您错误地监听了您的数据。SerialPort 是一种称为双工的流形式,既可读又可写。要侦听流上的新数据,通常的做法是侦听data事件。
在 Javascript 中还值得注意的是,当变量以下划线开头时,_pool它通常意味着它是一个通常不应该使用的私有变量。请参阅此问题以获取更多信息
只需sp.on('readable', function () {将部分重写为
sp.on('data', function(buffer) {
console.log(buffer);
});
Run Code Online (Sandbox Code Playgroud)
应该让您开始看到您期望的数据。
为了测试这一点,我写了您概述的场景,但只在 0x81 之后写入了 10,000 字节进行测试。
请不要将此视为在 JS 中使用流的好方法。这是我尝试“轻量级”,可能有更好的方法来写这个
const {SerialPort} = require('serialport');
const sp = new SerialPort({path: "COM2", baudRate: 115200});
function Deferred(data) {
this.data = data;
this.resolve = null;
this.reject = null;
this.reset = () => {
this.promise = new Promise(function(resolve, reject) {
this.resolve = resolve;
this.reject = reject;
}.bind(this));
}
this.reset();
}
async function run() {
let readBuffer = Buffer.alloc(0);
let nextReadDeferred = new Deferred();
sp.on('data', function(newData) {
readBuffer = Buffer.concat([readBuffer, newData], newData.length + readBuffer.length)
console.log('Got new data: ' + newData.length + ' buffer length is ' + readBuffer.length);
nextReadDeferred.resolve(readBuffer);
nextReadDeferred.reset();
});
console.log('Start 0x80')
sp.write(Buffer.from([0x80]), e => { if(e) throw e; });
await nextReadDeferred.promise;
if(0x81 === readBuffer[0]) {
// clear the buffer in prep of getting our data
readBuffer = Buffer.alloc(0);
console.log('Send 0x81 to start data flow')
sp.write(Buffer.from([0x81]), e => { if(e) throw e; });
console.log('Starting to receive data. Not sure how to know when were done?');
// Dont know what to do here, I dont think the serial port closes. Maybe we are supposed to just expect a duration
// of no data transfer? I dont know a whole lot about COM communication
} else {
console.warn('Expected 0x81 but got', readBuffer)
}
}
run();
Run Code Online (Sandbox Code Playgroud)
输出:
$ node index.js
Start 0x80
Got new data: 1 buffer length is 1
Send 0x81 to start data flow
Starting to receive data. Not sure how to know when were done?
Got new data: 1024 buffer length is 1024
Got new data: 4096 buffer length is 5120
Got new data: 1024 buffer length is 6144
Got new data: 3856 buffer length is 10000
Run Code Online (Sandbox Code Playgroud)
为了测试这一点,我使用eterlogic作为由 TCP 服务器支持的虚拟 com 端口,并将以下节点代码作为我的“设备”
const s = require('net').Socket();
s.connect(5555, '127.0.0.1');
s.on('data', function(d){
console.log('Got', d);
if(d.equals(Buffer.from([0x80]))) {
s.write(Buffer.from([0x81]));
} else if(d.equals(Buffer.from([0x81]))) {
s.write(Buffer.alloc(10000, 1));
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1502 次 |
| 最近记录: |