如何在开发过程中模拟串口?
How can I mock serial port during development?
我正在为我的 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 上运行良好,但我希望能够先 运行 我的开发计算机上的应用程序,而不必注释有关串行端口的每个代码块。
实现此目标的最佳方法是什么?有没有办法模拟串口?
AFAIK,目前没有任何库可以在本机执行此操作。我以前做的是用node-serialport库自带的测试代码为例,eg: https://github.com/Manetos/node-serialport/blob/157e6f9df7989abd72d509c9827d13b2b10258de/test_mocks/linux-hardware.js
如果你看一下那个文件,他们正在为他们自己的测试模拟串口行为,你可以简单地复制他们在那里所做的并在你的东西中使用它,你应该很好去吧。
希望对您有所帮助!
我需要同样的东西,但无法找到具体操作方法的详细信息,但我在搜索中一直遇到这个问题。经过一些研究并在不同领域找到一些模糊的参考资料后,我能够整理出以下内容。希望这对可能登陆这里的其他人有所帮助。
您可以使用自己的扩展 SerialPort - MockBindings class,然后简单地实现自定义 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;
为了您的测试,请准备一个使用上述 class 的可以作为目标的假串口设备:
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 中间件 serialParser.once('data')
回调
我能够使用 https://sourceforge.net/projects/com0com/
提供的 com0com 调制解调器仿真器实现此目的
它将创建两个相互映射的虚拟 COM 端口(例如 COM5 和 COM6)。您可以将您的应用程序连接到其中一个 COM 端口,并将您的仿真器代码连接到另一个 COM 端口。然后可以将仿真器配置为读取输入并相应地写回。
我正在为我的 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 上运行良好,但我希望能够先 运行 我的开发计算机上的应用程序,而不必注释有关串行端口的每个代码块。
实现此目标的最佳方法是什么?有没有办法模拟串口?
AFAIK,目前没有任何库可以在本机执行此操作。我以前做的是用node-serialport库自带的测试代码为例,eg: https://github.com/Manetos/node-serialport/blob/157e6f9df7989abd72d509c9827d13b2b10258de/test_mocks/linux-hardware.js
如果你看一下那个文件,他们正在为他们自己的测试模拟串口行为,你可以简单地复制他们在那里所做的并在你的东西中使用它,你应该很好去吧。
希望对您有所帮助!
我需要同样的东西,但无法找到具体操作方法的详细信息,但我在搜索中一直遇到这个问题。经过一些研究并在不同领域找到一些模糊的参考资料后,我能够整理出以下内容。希望这对可能登陆这里的其他人有所帮助。
您可以使用自己的扩展 SerialPort - MockBindings class,然后简单地实现自定义 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;
为了您的测试,请准备一个使用上述 class 的可以作为目标的假串口设备:
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 中间件 serialParser.once('data')
回调
我能够使用 https://sourceforge.net/projects/com0com/
提供的 com0com 调制解调器仿真器实现此目的它将创建两个相互映射的虚拟 COM 端口(例如 COM5 和 COM6)。您可以将您的应用程序连接到其中一个 COM 端口,并将您的仿真器代码连接到另一个 COM 端口。然后可以将仿真器配置为读取输入并相应地写回。