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

2024-04-25

我正在尝试编写使用以下方法的 Node.js 脚本serialport https://serialport.io/用于读取和写入数据的 npm 包COM5串行端口,使用 RS-232 电缆连接到设备。该设备会自动传输其拥有的数据。

要检索设备内部存储的数据,我需要首先发送一个字节 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确实如此,但输出似乎不正确,但看起来像是随机给出的东西。

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

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

我也尝试过Python,但对我不起作用 -PySerial 包在写入之前读取串行数据? https://stackoverflow.com/q/73054548/10543310.


我相信您错误地监听了您的数据。 SerialPort 是一种称为流的形式duplex https://nodejs.org/api/stream.html#duplex-and-transform-streams它们既可读又可写。要侦听流上的新数据,通常的做法是侦听data event https://nodejs.org/api/stream.html#event-data.

在 Javascript 中,当变量以下划线开头时也值得注意,例如_pool它通常意味着它是一个通常不应该使用的私有变量。看到这个所以问题 https://stackoverflow.com/questions/44734399/what-is-the-underscore-in-javascript了解更多信息

简单地重写sp.on('readable', function () {成为的一部分

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

为了测试这个我用了埃特逻辑 http://www.eterlogic.com/对于由 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));
    }
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 带有路径连接器的 jQuery 可拖动小部件

    参考该图像 Block1 和Block2 都是可拖动的 我的问题是 如何在两个块之间制作红色链状连接器 要求是链条应该延伸到块被拖动的地方 请提供任何教程 学习材料的指示 谢谢 有许多 Jquery 插件可用于创建数据库可视化或流程图的连接
  • 如何在 AWS CDK 堆栈中压缩 Node Lambda 依赖项?

    我正在使用 CDK 通过 API Gateway Lambda 和 DynamoDB 创建一个简单的无服务器项目 到目前为止看起来很酷 但是当我向 Lambda 添加外部依赖项时出现以下错误 Runtime ImportModuleErro
  • iframe 不读取 Chrome 中的 cookie

    Chrome 不允许子 iframe 读取自己的 cookie 我有一个带有子 iframe 的父网页 家长在https first site com 孩子在 父级内部 cookie set with 小路 安全 真实 仅http 假 域名
  • 嵌入式+实时开发培训的建议[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我目前正在学习嵌入式实时工程职业 但发现找到好的培训材料有些困难 特别是因为您无法像桌面应用程序开发那
  • PMT功能 支付方式

    下面是我计算贷款付款的函数 就像在 Excel 中一样 我需要添加另一个参数 即付款类型 function PMT ir np pv fv ir interest rate per month np number of periods mo
  • 如何根据 URL 路径添加 CSS 类?

    如何根据我所在的路径将 CSS 类添加到 div 中 包括如果我在其中包含 则不应该出现问题 div class popup ul li a href vs Example 1 a li li a href bod Example 2 a
  • CasperJS - 在网站上注册并验证 Gmail 上发送的邮件 - 对于 slimer 和 phantom -

    Edit 这是windows的行为 linux就失败了 首先 如果您使用 casper 成功导航 gmail 没有随机等待时间 从 20 秒到 5 分钟 请告诉我 我想在我们的网站上注册 然后使用 Gmail 自动验证我的注册 整个注册步骤
  • 客户端上传并读取文件,角度为2

    我需要用户的日志文件 以便我可以读取和分析这些文件 例如某种放置区域 用户放置一个文件 然后我可以用javascript读取它 我使用 Angular2 rc5 我有 node js 在后台运行 但我不需要那里的数据 我只需要在客户端 是否
  • 装饰器功能不起作用(意外标记)

    刚刚尝试在 React 中使用装饰器 import React from react import Fade from Transitions Fade import withVisible from withVisible withVis
  • 检查消息是否是 DM。 (Discord.js 和 Discord.js-commando)

    如何在 Discord js 中检查消息是否为私信 我尝试了几种方法来测试这一点 我尝试过以下方法 if msg channel isDM Produced undefined if msg isDM Produced undefined
  • canvas:如何在一个变换语句中完成平移、倾斜、旋转...?

    最近几天我在学习 变换 现在我知道如何通过变换的矩阵进行平移 旋转 倾斜 缩放 但如果我想在一个转换语句中执行上述所有操作 我该怎么办 ctx transform a b c d e f 当我们想要通过变换旋转某些东西时 我们必须为每个参数
  • 为什么 Firefox 对“select”标签上的“click”事件的反应与 Webkit 和 IE 不同?

    我意识到 Firefox 对待click事件于
  • 从网站保存嵌入的 pdf

    我正在编写一个小型 C 应用程序来管理供应商提供的 化学品 安全数据表 目前 我手动搜索该化学品并保存 pdf 并在我的程序中添加指向 pdf 的链接 问题是我还有很多化学品需要处理 所以最好将过程自动化 例如 化学品的部件号如下 2710
  • 如何在 jQuery 中检查 null 对象

    我正在使用 jQuery 我想检查页面中是否存在某个元素 我写了以下代码 但它不起作用 if btext i null alert btext i text btext i text Branch i 如何检查元素是否存在 检查jQuery
  • 是否可以从猫鼬文档中获取模型?

    var UserSchema new Schema Schema var User mongoose Model User UserSchema Model var user new User Document 仅给定文档 在本例中为用户
  • 我们可以使用 axios 的 onDownloadProgress 来加载 API 吗?

    我需要使用 axios 创建一个用于在 React 项目中加载 API 的进度条 我为此发现了 onDownloadProgress 函数 但我不知道我们是否可以使用它来获取诸如加载百分比之类的信息 或者它是否仅用于文件下载 所以我不确定我
  • 检测 Service Worker 离线状态的最佳实践

    我有一个服务工作者应该缓存一个offline html客户端没有网络连接时显示的页面 然而 有时它会认为导航器已离线 即使它并未离线 那是 navigator onLine false 这意味着用户可能会得到offline html而不是实
  • 串行端口轮询和数据处理

    我正在尝试通过微控制器从传感器的多个串行端口读取数据 每个串口将接收超过2000个测量值 每个测量值7个字节 全部为十六进制 而且他们同时开火 现在我正在从 4 个串行端口进行轮询 另外 我将每个测量值转换为字符串并将其附加到字符串构建器
  • JavaScript 类继承

    谁能告诉我为什么我的 showDiv boo 在类的方法中未定义 我也无法访问我的类的方法 这是我的 Blink 类及其属性和方法 function Blink div this div div Blink prototype counte
  • jQuery fullCalendar + Fancybox 弹出窗口编辑事件

    我正在使用此代码在 fullCalendar 上生成事件

随机推荐