Node.js连接4个Arduino串口异常:仅一个可接收数据其余无响应
Hey there! Let's figure out why only one of your Arduino devices is sending data when connected together. Looking at your code, the issue is pretty clear: you're only listening for data events on the first serial port, and your listener setup is tied to individual client connections in a way that breaks things for multiple devices.
What's Wrong With Your Current Code?
- Redundant SerialPort Requires: You don't need to
require('serialport')four times—once is enough, and you can create multiple instances from that single import. - Missing Listeners for Other Ports: You've initialized
serial1,serial2, andserial3, but you never added adataevent listener to any of them. That's why only the first port (serial) is sending data to your frontend. - Client-Tied Listener Logic: You're binding the
serialdata listener every time a client connects, and removing it when a client disconnects. If multiple clients connect, you'll end up with duplicate listeners, and disconnecting one client will stop data from that port for everyone else.
Fixed Code Examples
1. Optimized Serial Port Initialization
First, clean up your port setup—no need for repeated imports:
// Load all required modules once const http = require('http'); const fs = require('fs'); const path = require('path'); const SerialPort = require('serialport'); // Single import is enough // Initialize all four serial ports in an array for easier management const serialPorts = [ new SerialPort('/dev/cu.usbserial-1411140', { baudRate: 115200 }, () => console.log('1411140 ready')), new SerialPort('/dev/cu.usbserial-141120', { baudRate: 115200 }, () => console.log('141120 ready')), new SerialPort('/dev/cu.usbmodem-1411301', { baudRate: 115200 }, () => console.log('1411301 ready')), new SerialPort('/dev/cu.usbserial-1411130', { baudRate: 115200 }, () => console.log('1411130 ready')) ]; const port = 8080;
2. Updated Socket.IO & Data Forwarding Logic
We'll decouple the serial port listeners from client connections, and add listeners for all ports:
const io = require('socket.io')(server); // Reusable message forwarding function (works for all ports) function forwardMessage(data) { let message = data.toString().replace(/\n*/, ''); // Forward messages to frontend just like you did before if (message.includes('Coinv')) { io.emit('CoinvChange', message.substring(7)); // Use io.emit to send to all connected clients } if (message.includes('Impor')) { io.emit('ImporChange', message.substring(7)); } if (message.includes('Piace')) { io.emit('PiaceChange', message.substring(7)); } if (message.includes('Cresc')) { io.emit('CrescChange', message.substring(7)); } if (message.includes('Press')) { io.emit('PressChange', message.substring(7)); } } // Attach the listener to EVERY serial port when the server starts serialPorts.forEach(port => { port.on('data', forwardMessage); }); io.on('connection', (socket) => { console.log('a new client connected'); socket.emit('greetings', 'You are now connected to the server through Socket IO'); socket.on('disconnect', () => { console.log('client disconnected'); // No need to remove serial listeners here—they're global and persist for all clients }); });
Extra Tips (Optional)
If you need to tell which Arduino device is sending each message, modify your Arduino code to add a unique prefix to every message (e.g., Device1:Coinv:5). Then update the forwardMessage function to parse that prefix and include it in the Socket.IO emit—this way your frontend can distinguish between data from different devices.
内容的提问来源于stack exchange,提问作者Lab Sintesi

