首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Nodejs映射串行端口写入以接收数据

Nodejs映射串行端口写入以接收数据
EN

Stack Overflow用户
提问于 2016-06-10 12:34:59
回答 2查看 3.5K关注 0票数 2

我目前正在使用node-serialport模块进行串口通信。我将发送一个命令ATEC,它将以ECHO响应。

然而,这个发送和接收数据的过程是异步的(在我发送数据之后,我将不知道数据何时会到达data事件),示例代码如下:

代码语言:javascript
复制
//Register the data event from the serial port
port.on('data', (data) => {
    console.log(data);
});

//Send data using serialport
port.write('ATEC');

有没有什么我可以这样写的?

代码语言:javascript
复制
//When i send the command, I could receive the data
port.write('ATEC').then((data)=> {
    console.log(data);
});

这有可能实现吗?

在使用request客户端进行http通信时,我们可以这样做

代码语言:javascript
复制
request.get('http:\\google.com')
    .on('response', (res) => {
        console.log(res);
    });

我想使用serialport复制相同的行为

EN

回答 2

Stack Overflow用户

发布于 2016-07-11 08:24:09

在我正在做的一个项目中,我们遇到了类似的问题。需要一个用于串行的同步发送/接收循环,而serialport包让这变得有点奇怪。

我们的解决方案是让串口"data“事件服务的函数/promises/generators/等(取决于您的架构)的某种类型的队列。每次你写东西的时候,把一个函数/promise/等放入队列。

让我们假设您只是将函数抛入队列中。当" data“事件被触发时,它将当前聚合的接收缓冲区作为参数发送到队列的第一个元素中,该元素可以查看它是否包含它需要的所有数据,如果包含,则对其执行某些操作,并以某种方式将其从队列中删除。

这允许您使用相同的基本机制来处理多种不同类型的架构(回调/承诺/协程/等等)。

额外的好处是:如果您完全控制了协议的两端,您可以在这些字符串的末尾添加一个"\n“,然后使用serialport的"readline”解析器,这样您就只能获得整个字符串上的数据事件。如果输入是分片的,可能会让事情变得比不断检查输入的有效性容易一些。

更新:

现在,代码已经完成并进行了测试(请参阅http://github.com/metafetish/buttshock-js中的ET312模块),下面是我如何做的:

代码语言:javascript
复制
function writeAndExpect(data, length) {
  return new Promise((resolve, reject) => {
    const buffer = new Buffer(length);
    this._port.write(data, (error) => {
      if (error) {
        reject(error);
        return;
      }
    });
    let offset = 0;
    let handler = (d) => {
      try {
        Uint8Array.from(d).forEach(byte => buffer.writeUInt8(byte, offset));
        offset += d.length;
      } catch (err) {
        reject(err);
        return;
      }
      if (offset === length) {
        resolve(buffer);
        this._port.removeListener("data", handler);
      };
    };
    this._port.on("data", handler);
  });
}

上面的函数接受一个uint8s列表,并返回一个预期的数据量,返回一个promise。我们写入数据,然后将自己设置为" data“事件处理程序。我们使用它来读取,直到我们获得我们期望的数据量,然后解析promise,删除自己作为“数据”侦听器(这是重要的,否则您将堆叠处理程序!),并完成。

这段代码非常符合我的需要,除了使用已知参数非常严格的发送/接收对之外,它不会处理其他情况,但它可能会给您一个开始的想法。

票数 1
EN

Stack Overflow用户

发布于 2016-07-11 09:22:15

我在串行数据接收中包装了一个承诺

代码语言:javascript
复制
function sendSync(port, src) {
    return new Promise((resolve, reject) => {
        port.write(src);
        port.once('data', (data) => {
            resolve(data.toString());
        });

        port.once('error', (err) => {
            reject(err);
        });
    });
}

请注意,事件正在使用once而不是on来防止事件堆叠(请查看下面的评论以了解更多信息-感谢@DKebler发现它)

然后,我可以同步编写代码,如下所示

代码语言:javascript
复制
sendSync(port, 'AThello\n').then((data) => {
    //receive data
});

sendSync(port, 'ATecho\n').then((data) => {
    //receive data
});

或者我可以使用一个生成器,使用co

代码语言:javascript
复制
 co(function* () {
        const echo = yield sendSync(port, 'echo\n');
        const hello = yield sendSync(port, 'hello 123\n');

        return [echo, hello]
    }).then((result) => {
        console.log(result)
    }).catch((err) => {
        console.error(err);
    })
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37739992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档