JAVA 用 JSerialComm 读写串口数据

JAVA 用 JSerialComm 读串口数据


1. MAVEN 添加 JSerialComm 依赖
<!-- java 操作串口包2 -->
<dependency>
    <groupId>com.fazecast</groupId>
    <artifactId>jSerialComm</artifactId>
    <version>[2.0.0,3.0.0)</version>
</dependency>
2. 编写测试类

重要:串口打开后和两次读取之间一定要休眠,不然程序感知不到输入流里有数据!

package com.yhf.serialcommtest.test;//改成你自己的包

import com.fazecast.jSerialComm.SerialPort;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

/**
 * @author yhf
 * @Email 1713139648@qq.com
 * @since 2022-04-26 9:18
 */
public class WeightTest {
    public static void main(String[] args) {
        SerialPort[] serialPorts = SerialPort.getCommPorts();
        SerialPort com3 = null;
        for (SerialPort serialPort : serialPorts) {
            System.out.println("isOpen="+serialPort.isOpen());
            System.out.println("SystemPortPath="+serialPort.getSystemPortPath());
            System.out.println("SystemPortName="+serialPort.getSystemPortName());
            if("COM3".equals(serialPort.getSystemPortName())){
                com3 = serialPort;
            }
            System.out.println("DescriptivePortName="+serialPort.getDescriptivePortName());
            System.out.println("PortDescription="+serialPort.getPortDescription());
            System.out.println("PortLocation="+serialPort.getPortLocation());
            System.out.println("BaudRate="+serialPort.getBaudRate());
            System.out.println("CTS="+serialPort.getCTS());
            System.out.println("DCD="+serialPort.getDCD());
            System.out.println("DeviceReadBufferSize="+serialPort.getDeviceReadBufferSize());
            System.out.println("DeviceWriteBufferSize="+serialPort.getDeviceWriteBufferSize());
            System.out.println("DSR="+serialPort.getDSR());
            System.out.println("DTR="+serialPort.getDTR());
            System.out.println("FlowControlSettings="+serialPort.getFlowControlSettings());
            System.out.println("LastErrorCode="+serialPort.getLastErrorCode());
            System.out.println("LastErrorLocation="+serialPort.getLastErrorLocation());
            System.out.println("NumDataBits="+serialPort.getNumDataBits());
            System.out.println("NumStopBits="+serialPort.getNumStopBits());
            System.out.println("Parity="+serialPort.getParity());
            System.out.println("ReadTimeout="+serialPort.getReadTimeout());
            System.out.println("RI="+serialPort.getRI());
            System.out.println("RTS="+serialPort.getRTS());
            System.out.println("WriteTimeout="+serialPort.getWriteTimeout());
            System.out.println("*************************************************************");
        }

        if (com3 == null){
            throw new NullPointerException("未找到COM3");
        }

        com3.setParity(SerialPort.EVEN_PARITY);//偶校验
        com3.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);//关闭流控
        boolean b = com3.openPort();
        if (b){
            InputStream inputStream = com3.getInputStream();
            try {
                Thread.sleep(1000);//打开串口后要休眠一段时间才能接收到输入流
                System.out.println(com3.getSystemPortName()+"成功开启");
                int available = inputStream.available();
                System.out.println(com3.getSystemPortName()+"可读字节:"+available);
                while (inputStream.available() > 0){
                    byte[] bytes = new byte[1024];
                    int read = inputStream.read(bytes);
                    System.out.println("读取:"+read+"字节");
                    System.out.println(Arrays.toString(bytes));
                    Thread.sleep(1000);//要休眠一段时间才能感知下一波数据
                }
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            } finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                com3.closePort();
            }
        }
    }
}

3. 不用 while 循环,用监听器监听串口数据变化:
public static void testDataListener(String[] args) {
    SerialPort[] serialPorts = SerialPort.getCommPorts();
    SerialPort com1 = null;
    for (SerialPort serialPort : serialPorts) {
        System.out.println("isOpen="+serialPort.isOpen());
        System.out.println("SystemPortPath="+serialPort.getSystemPortPath());
        System.out.println("SystemPortName="+serialPort.getSystemPortName());
        if("COM1".equals(serialPort.getSystemPortName())){
            com1 = serialPort;
        }
        System.out.println("DescriptivePortName="+serialPort.getDescriptivePortName());
        System.out.println("PortDescription="+serialPort.getPortDescription());
        System.out.println("PortLocation="+serialPort.getPortLocation());
        System.out.println("BaudRate="+serialPort.getBaudRate());
        System.out.println("CTS="+serialPort.getCTS());
        System.out.println("DCD="+serialPort.getDCD());
        System.out.println("DeviceReadBufferSize="+serialPort.getDeviceReadBufferSize());
        System.out.println("DeviceWriteBufferSize="+serialPort.getDeviceWriteBufferSize());
        System.out.println("DSR="+serialPort.getDSR());
        System.out.println("DTR="+serialPort.getDTR());
        System.out.println("FlowControlSettings="+serialPort.getFlowControlSettings());
        System.out.println("LastErrorCode="+serialPort.getLastErrorCode());
        System.out.println("LastErrorLocation="+serialPort.getLastErrorLocation());
        System.out.println("NumDataBits="+serialPort.getNumDataBits());
        System.out.println("NumStopBits="+serialPort.getNumStopBits());
        System.out.println("Parity="+serialPort.getParity());
        System.out.println("ReadTimeout="+serialPort.getReadTimeout());
        System.out.println("RI="+serialPort.getRI());
        System.out.println("RTS="+serialPort.getRTS());
        System.out.println("WriteTimeout="+serialPort.getWriteTimeout());
        System.out.println("*************************************************************");
    }

    if (com1 == null){
        throw new NullPointerException("未找到COM1");
    }

    com1.setParity(SerialPort.EVEN_PARITY);//偶校验
    com1.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);//关闭流控
    boolean b = com1.openPort();
    if (b){
        try {
            Thread.sleep(1000);//打开串口后要休眠一段时间才能接收到输入流
            SerialPort finalCom = com1;
            com1.addDataListener(new SerialPortDataListener() {
                @Override
                public int getListeningEvents() {
                    return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;//返回要监听的事件类型,以供回调函数使用。可发回的事件包括:SerialPort.LISTENING_EVENT_DATA_AVAILABLE,SerialPort.LISTENING_EVENT_DATA_WRITTEN,SerialPort.LISTENING_EVENT_DATA_RECEIVED。分别对应有数据在串口(不论是读的还是写的),有数据写入串口,从串口读取数据。如果AVAILABLE和RECEIVED同时被监听,优先触发RECEIVED
                }

                @Override
                public void serialEvent(SerialPortEvent event) {
                    if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE){
                        return;//判断事件的类型
                    }
                    //同样使用循环读取法读取所有数据
                    while(finalCom.bytesAvailable()!=0) {
                        byte[] newData = new byte[finalCom.bytesAvailable()];
                        int numRead = finalCom.readBytes(newData, newData.length);
                        System.out.println(finalCom.getSystemPortName()+"接收到字节数:"+numRead);
                        System.out.println(finalCom.getSystemPortName()+"数据:"+Arrays.toString(newData));
                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

监听器可以一直监听串口,适合实时的数据抓取,而且不用 while 循环空转:
在这里插入图片描述

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
Java jSerialComm是一款串口通信库,它提供了在Java应用程序中与串口通信的能力。要在多线程环境中使用jSerialComm进行串口通信,您可以使用以下步骤: 1. 在您的应用程序中引入jSerialComm库,具体步骤请参考jSerialComm官方文档。 2. 创建一个SerialPort对象,该对象将用于打开和关闭串口,并设置串口参数,如波特率、数据位、停止位和校验位。 ```java SerialPort serialPort = SerialPort.getCommPort("COM1"); serialPort.setBaudRate(9600); serialPort.setNumDataBits(8); serialPort.setNumStopBits(1); serialPort.setParity(SerialPort.NO_PARITY); ``` 3. 创建一个线程,该线程将用于从串口读取数据并处理它。您可以使用SerialPort.getInputStream()方法获取输入流,并从中读取数据。 ```java Thread readThread = new Thread(() -> { try { InputStream inputStream = serialPort.getInputStream(); byte[] buffer = new byte[1024]; int len = -1; while ((len = inputStream.read(buffer)) > -1) { // 处理收到的数据 } } catch (IOException e) { e.printStackTrace(); } }); ``` 4. 创建另一个线程,该线程将用于向串口写入数据。您可以使用SerialPort.getOutputStream()方法获取输出流,并将数据写入其中。 ```java Thread writeThread = new Thread(() -> { try { OutputStream outputStream = serialPort.getOutputStream(); byte[] data = new byte[] {0x01, 0x02, 0x03}; outputStream.write(data); outputStream.flush(); } catch (IOException e) { e.printStackTrace(); } }); ``` 5. 打开串口并启动线程。 ```java serialPort.openPort(); readThread.start(); writeThread.start(); ``` 请注意,以上代码仅作为示例,您需要根据自己的需求进行修改和扩展。同时,由于串口通信可能会出现各种问题,例如读取超时、奇偶校验错误等,您需要对这些问题进行适当处理,以确保您的应用程序具有良好的健壮性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值