繁体   English   中英

Node.js | 如何通过串口向设备发送和接收一个字节?

[英]Node.js | How to send and receive one byte to a device through serial port?

我正在尝试编写 Node.js 脚本,该脚本使用serialport package 读取和写入数据到COM5串口,该串口使用 RS-23 连接到设备。 该设备正在自动传输其拥有的数据。

要检索存储在设备内的数据,我需要首先向设备发送一个字节 0x80 ( uInt8 ),并期望从设备接收 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);
});

运行我的脚本(使用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
]

在我按下Ctrl+c之前程序不会退出。 我不确定ps._pool做了什么,但似乎 output 不正确,但看起来像是随机给出的东西。

我是 Node.js 的新手。 我也不确定如何在sp object 中添加 10 秒的参数TimeOut

我尝试使用Matlab进行测试,我可以成功检索到数据。

我也试过 Python 但对我不起作用 - PySerial package 在写入之前读取串行数据? .

我相信您正在错误地收听您的数据。 SerialPort 是 stream 的一种形式,称为双工,可读写。 要在 stream 上侦听新数据,通常的做法是侦听data事件

在 Javascript 中还值得注意的是,当变量以下划线开头时,例如_pool它通常意味着它是一个通常不应该使用的私有变量。 有关更多信息,请参阅此SO 问题

只需重写sp.on('readable', function () { part to be

sp.on('data', function(buffer) {
    console.log(buffer);
});

应该让您开始看到您期望的数据。


为了测试这一点,我写了你概述的场景,但在 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();

Output:

$ 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

为了测试这一点,我将eterlogic用于虚拟 com 端口,该端口支持 TCP 服务器和以下节点代码作为我的“设备”

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM