如何在Node.js中通过SerialPort正确读取Arduino串口数据?
解决Node.js读取Arduino串口数据拆分的问题
嘿,我知道你为啥会遇到串口数据拆分的问题了!这是因为串口数据是按字节流传输的,有时候会分批到达,而你的代码没正确利用解析器来整合成完整的行。让我帮你改改代码,搞定这个问题~
问题根源
你当前的代码有两个关键问题:
- Readline解析器的换行符配置错误,Arduino的
Serial.println()会发送\r\n(回车+换行)作为行结束符,但你代码里的解析器参数写得不对 - 你同时监听了串口原始的
data事件,这会绕过解析器,直接拿到拆分的字节块,导致输出不完整
修改后的Node.js代码
var SerialPort = require('serialport'); var io = require('socket.io').listen(3000); // 正确配置Readline解析器,匹配Arduino发送的\r\n行结束符 var serialPort = new SerialPort("COM4", { baudRate: 9600, parser: new SerialPort.parsers.Readline('\r\n') }); io.sockets.on('connection', function(socket){ socket.on('message', function(msg){ console.log(msg); }); socket.on('disconnect', function(){ // 修正事件名:是disconnect不是disconnected console.log('Client disconnected'); }); }); serialPort.on('open', function(){ console.log('Serial port opened successfully'); // 现在监听的是解析器处理后的data事件,每次拿到的都是完整的一行 serialPort.on('data', function(data){ console.log('完整数据:', data); // 这里会输出完整的"Hello" io.sockets.emit('message', data); }); }); // 增加错误监听,方便排查串口连接问题 serialPort.on('error', function(err){ console.error('Serial port error:', err); });
关键改动说明
- 修正解析器配置:把Readline的分隔符改成
\r\n,完全匹配ArduinoSerial.println()发送的结束符,这样解析器会自动把字节流整合成完整的行 - 利用解析器的data事件:现在监听的串口
data事件已经是解析器处理后的结果,每次回调拿到的都是完整的"Hello"字符串,不需要自己手动拼接数据 - 修正socket.io事件名:把
disconnected改成正确的disconnect,确保能监听到客户端断开连接的事件
Arduino代码无需改动
你的Arduino代码是没问题的,Serial.println("Hello")每隔2秒发送带换行的字符串,正好和我们配置的解析器匹配。
这样修改后,Node.js控制台每次就会完整输出"Hello",不会再出现拆分的情况,同时socket.io也会把完整的消息推送给客户端啦!
内容的提问来源于stack exchange,提问作者user4959618




