Java使用jSerialPort对接Arduino时串口输出打印异常问题求助
问题修复方案
问题根因说明
Arduino端问题
while (Serial.available() < 0) { return; }逻辑完全无效:Serial.available()返回的是串口可读字节数,取值范围永远≥0,该判断永远为假,不会触发return逻辑。- 你使用
Serial.write("Hello")输出内容没有携带换行符,Java端用scanner.nextLine()读取时找不到行结束标识,会一直阻塞等待,同时无分隔符的数据流也会导致读取内容错乱出现乱码。
Java端问题
- 未配置串口基础参数:没有设置波特率、数据位、停止位、校验位,和Arduino端9600波特率不匹配时直接会出现乱码。
- 超时配置错误:
SerialPort.TIMEOUT_READ_BLOCKING模式下两个超时参数设为0,意味着读取操作会永远阻塞直到拿到指定长度的数据,完全不会触发正常读取逻辑。 - 输入流被意外关闭:你用try-with-resources包裹Scanner,读取逻辑执行完后会自动关闭Scanner,连带关闭底层的串口输入流,后续再也无法收到任何数据。
- 重复创建Scanner:每次数据可用事件触发都新建Scanner包裹输入流,会导致流读取位置错乱,加重乱码问题。
修复后代码
Arduino代码
void setup() { Serial.begin(9600); } void loop() { Serial.println("Hello"); // println会自动在内容末尾加换行符,匹配Java端行读取逻辑 delay(1000); }
Java代码
import com.fazecast.jSerialComm.SerialPort; import com.fazecast.jSerialComm.SerialPortDataListener; import com.fazecast.jSerialComm.SerialPortEvent; import java.util.Scanner; public class Arduino { private static final SerialPort port = SerialPort.getCommPort("/dev/cu.usbmodem1101"); private static Scanner scanner; public static void main(String[] args) { // 配置串口参数和Arduino端完全匹配:波特率9600、8数据位、1停止位、无校验 port.setComPortParameters(9600, 8, 1, 0); // 改用半阻塞读取模式,读超时设为100ms避免永久阻塞 port.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 100, 0); if (port.openPort()) { System.out.println("Port opened"); } else { System.out.println("Error opening port: May be in use or doesn't exist"); return; } // 全局仅创建一次Scanner,不随事件触发重复创建,也不用try-with-resources自动关闭 scanner = new Scanner(port.getInputStream()); port.addDataListener(new SerialPortDataListener() { @Override public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_AVAILABLE; } @Override public void serialEvent(SerialPortEvent event) { if (event.getEventType() == SerialPort.LISTENING_EVENT_DATA_AVAILABLE) { while (scanner.hasNextLine()) { System.out.println(scanner.nextLine()); } } } }); // 当前没有Java往Arduino写数据的逻辑,LISTENING_EVENT_DATA_WRITTEN事件不会触发,可直接删除该监听 } }
验证步骤
- 烧写修复后的Arduino代码,打开Arduino IDE自带的串口监视器,确认能正常每秒输出Hello后关闭串口监视器(避免端口被占用)
- 运行修复后的Java代码即可看到正常输出
内容的提问来源于stack exchange,提问作者ninesw
相关产品推荐
相关产品推荐

