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

我目前正在使用node-serialport模块进行串口通讯。 我会发一个命令ATEC ,它会回应ECHO

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

 //Register the data event from the serial port port.on('data', (data) => { console.log(data); }); //Send data using serialport port.write('ATEC'); 

无论如何,我可以用这种方式来写吗?

 //When i send the command, I could receive the data port.write('ATEC').then((data)=> { console.log(data); }); 

这可能实现吗?

在使用request客户端的http通信中,我们可以做类似的事情

 request.get('http:\\google.com') .on('response', (res) => { console.log(res); }); 

我想用serialport复制相同的行为

在我正在进行的项目中,我们有类似的问题。 需要一个串行同步发送/接收循环,而串行端口包使得有点奇怪。

我们的解决scheme是做一些sorting的函数/承诺/生成器/等(取决于你的架构),串口“数据”事件服务。 每次你写东西的时候,把一个函数/ promise / etc放入队列中。

让我们假设你只是将函数引入队列中。 当“data”事件被触发时,它将当前聚合的接收缓冲区作为参数发送到队列的第一个元素,它可以看到它是否包含它所需要的所有数据,如果是,就用它做一些事情,以某种方式从队列中删除自己。

这使您可以使用相同的基本机制处理多种不同的体系结构(callback/承诺/协同/等)。

作为一个额外的好处:如果你完全控制了协议的两边,你可以在这些string的末尾添加一个“\ n”,然后使用serialport的“readline”parsing器,所以你只能得到整个数据事件string。 可能会让事情比经常检查input有效性要容易一些。

更新:

现在,代码已经完成并经过testing(请参阅http://github.com/metafetish/buttshock-js中的ET312模块),以下是我的操作:

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

上面的函数获取uint8的列表,并返回一个预期的数据量。 我们编写数据,然后将自己设置为“数据”事件处理程序。 我们使用它来读取数据,直到获得我们期望的数据量,然后parsing承诺,将自己作为“数据”侦听器( 这很重要 ,否则将堆栈处理程序!)移除并完成。

这段代码是非常特定于我的需求的,除了非常严格的带有已知参数的发送/接收对以外,不会处理其他情况,但它可能会给你一个开始的想法。

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

 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而不是为了防止堆叠事件(请检查下面的评论以获取更多信息 – 谢谢@DKebler发现它)

然后,我可以按如下方式编写代码

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

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

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