我正在为我的Raspberry Pi开发一个node.js应用程序,它从串口接收数据,但是我没有直接在它上面开发应用程序,而是使用我的主计算机。所以我在app.js
:
var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
var sp = new SerialPort("/dev/ttyACM0", {
parser: serialport.parsers.readline("\n")
});
sp.on("data", function (rawData) {
...
这在Rasperry Pi上运行良好,但我希望能够首先在我的开发计算机上运行该应用程序,而不必评论有关串行端口的每个代码块。
实现这一目标的最佳方法是什么?有没有办法模拟串口?
答案 0 :(得分:2)
AFAIK,目前还没有任何图书馆本地执行此操作。我过去所做的是使用node-serialport库自己的测试代码作为示例,例如:https://github.com/voodootikigod/node-serialport/blob/master/test_mocks/linux-hardware.js
如果您查看该文件,他们会为自己的测试嘲笑串口行为,您可以简单地复制他们在那里做的事情并在您的内容中使用它,您应该是很高兴。
希望有所帮助!
答案 1 :(得分:0)
我需要同样的东西,但无法找到具体操作方法的详细信息,但是在我的搜索中一直遇到这个问题。经过一些研究并在不同领域找到了一些模糊的参考资料,我能够将以下内容放在一起。希望这对可能登陆这里的其他人有所帮助。
您可以使用自己的类扩展 SerialPort - MockBindings 类,然后简单地实现一个自定义 write
函数,该函数将接收数据,形成正确的响应,然后将其发送回调用者。
const MockSerialBinding = require('@serialport/binding-mock');
class EmulatedDeviceSerialBinding extends MockSerialBinding {
constructor(opt = {}) {
super(opt);
}
// THIS IS THE METHOD THAT GETS TRIGGERED WHEN THE CODE TO TEST WRITES TO A DEVICE
async write(buffer) {
// Use this method to detect the supported commands and emulate a response
const cmd = Buffer.from(buffer).toString();
let response = 'Unknown Command!'; // Default response
// Custom logic here to determine the proper response
super.emitData(response);
}
}
module.exports = EmulatedDeviceSerialBinding;
为了您的测试,准备一个可以使用上述类的假串行设备:
const SerialPort = require('serialport');
SerialPort.Binding = EmulatedDeviceSerialBinding;
// Setup a new mock serial device that can be the target
EmulatedDeviceSerialBinding.createPort('ttyUSB_TestTarget', {
echo: true,
readyData: '\r\nhostname@user:~$ ' // This will append a 'prompt' to the end of each response (like a linux terminal would)
});
现在您的逻辑将是相同的,只是您将连接到模拟设备端口而不是真实端口。以下是 Express Route 中间件的片段:
const SerialPort = require('serialport');
const SerialRegexParser = require('@serialport/parser-regex');
const serialParser = new SerialRegexParser({regex: /(?<Prompt>.*[$#]\s*$)/m});
const serialPortOptions = {
baudRate: 115200
};
// The req.params.devicePort value be the name of the emulated port
const port = new SerialPort(req.params.devicePort, serialPortOptions, (err) => {
if (err) {
return res.status(400).send({error: err.message});
}
});
port.pipe(serialParser);
// THIS WILL BE TRIGGERED WHEN THE EmulatedDeviceSerialBinding does the emitData call
serialParser.once('data', (data) => {
if (res.headersSent) return; // We've already responded to the client, we can't send more
const dataString = Buffer.from(data).toString();
// Remove the command executed from the beginning if it was echoed
respDoc.data = dataString.replace(cmdToExecute, '').trimEnd();
return res.send(respDoc);
});
// Send the command to the device
// THIS WILL TRIGGER THE EmulatedDeviceSerialBinding.write() FUNCTION
port.write(cmdToExecute, (err) => {
if (err) {
return res.status(400).send({error: err.message});
}
});
程序流程为:
Express 中间件 port.write(cmdToExecute)
-> EmulatedDeviceSerialBinding.write()
-> Express Middleware serialParser.once('data')
回调