You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java使用jSerialPort对接Arduino时串口输出打印异常问题求助

问题修复方案

问题根因说明

Arduino端问题

  • while (Serial.available() < 0) { return; } 逻辑完全无效:Serial.available() 返回的是串口可读字节数,取值范围永远≥0,该判断永远为假,不会触发return逻辑。
  • 你使用Serial.write("Hello")输出内容没有携带换行符,Java端用scanner.nextLine()读取时找不到行结束标识,会一直阻塞等待,同时无分隔符的数据流也会导致读取内容错乱出现乱码。

Java端问题

  1. 未配置串口基础参数:没有设置波特率、数据位、停止位、校验位,和Arduino端9600波特率不匹配时直接会出现乱码。
  2. 超时配置错误:SerialPort.TIMEOUT_READ_BLOCKING模式下两个超时参数设为0,意味着读取操作会永远阻塞直到拿到指定长度的数据,完全不会触发正常读取逻辑。
  3. 输入流被意外关闭:你用try-with-resources包裹Scanner,读取逻辑执行完后会自动关闭Scanner,连带关闭底层的串口输入流,后续再也无法收到任何数据。
  4. 重复创建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事件不会触发,可直接删除该监听
    }
}

验证步骤

  1. 烧写修复后的Arduino代码,打开Arduino IDE自带的串口监视器,确认能正常每秒输出Hello后关闭串口监视器(避免端口被占用)
  2. 运行修复后的Java代码即可看到正常输出

内容的提问来源于stack exchange,提问作者ninesw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 14:24:08