java调用串口详解

java调用串口详解

1,下载调用串口工具包

根据对应平台下载对应工具包
http://fizzed.com/oss/rxtx-for-java

2,拷贝对应文件到jdk指定目录下

RXTXcomm.jar ---> <JAVA_HOME>\jre\lib\ext
rxtxSerial.dll ---> <JAVA_HOME>\jre\bin
rxtxParallel.dll ---> <JAVA_HOME>\jre\bin

3,将工程导入jar

将RXTXcomm.jar安装到java工程中

4,串口操作工具示例代码

工具类

package com.bami.common.serial_com;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.TooManyListenersException;

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
/**
 * 串口通信工具
 * @author ChenWei
 * @email 582900710@qq.com
 * @date 2021年11月11日 上午11:01:23
 * @since 1
 */
public class SerialComKit {
	/**
	 * 查询可用串口
	 * @author ChenWei
	 * @email 582900710@qq.com
	 * @date 2021年11月11日 上午11:45:29
	 * @since 1
	 * @return
	 */
	public static List<String> findPort() {
		//获得当前所有可用串口
        @SuppressWarnings("unchecked")
		Enumeration<CommPortIdentifier> portList = 
        		CommPortIdentifier.getPortIdentifiers();	
        List<String> portNameList = new ArrayList<>(9);
        //将可用串口名添加到List并返回该List
        while (portList.hasMoreElements()) {
            String portName = portList.nextElement().getName();
            portNameList.add(portName);
        }
        return portNameList;
    }
	/**
	 * 开启串口
	 * @author ChenWei
	 * @email 582900710@qq.com
	 * @date 2021年11月11日 上午11:44:55
	 * @since 1
	 * @param portName 串口名称
	 * @param baudrate 波特率
	 * @return
	 * @throws NoSuchPortException 
	 * @throws PortInUseException 
	 * @throws UnsupportedCommOperationException 
	 * @throws Exception
	 */
	public static SerialPort openPort(
			String portName, 
			int baudrate) throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException{
        //通过端口名识别端口
        CommPortIdentifier portIdentifier = 
        		CommPortIdentifier.getPortIdentifier(portName);

        //打开端口,并给端口名字和一个timeout(打开操作的超时时间)
        CommPort commPort = portIdentifier.open(portName, 3000);

        //判断是不是串口
        if (commPort instanceof SerialPort) {
            SerialPort serialPort = (SerialPort) commPort;
            //设置一下串口的波特率等参数
            serialPort.setSerialPortParams(
            		baudrate, SerialPort.DATABITS_8, 
            		SerialPort.STOPBITS_1, 
            		SerialPort.PARITY_NONE);                              
            return serialPort;
        }else {
        	return null;
        }
    }
	/**
	 * 关闭串口
	 * @author ChenWei
	 * @email 582900710@qq.com
	 * @date 2021年11月11日 上午11:47:17
	 * @since 1
	 * @param serialPort
	 */
    public static void closePort(
    		SerialPort serialPort) {
    	if (serialPort != null) {
    		try {
				serialPort.removeEventListener();
				serialPort.close();
				serialPort = null;
			} catch (Exception e) {
			}
    	}
    }
    /**
     * 发送数据到串口
     * @author ChenWei
     * @email 582900710@qq.com
     * @date 2021年11月11日 上午11:51:22
     * @since 1
     * @param serialPort
     * @param data
     * @return
     * @throws Exception
     */
    public static boolean sendToPort(
    		SerialPort serialPort, 
    		byte[] data) throws Exception{

    	OutputStream out = null;
        try {
            out = serialPort.getOutputStream();
            out.write(data);
            out.flush();
            return true;
        } catch (IOException e) {
        	return false;
        } finally {
        	try {
        		if (out != null) {
        			out.close();
        			out = null;
        		}				
			} catch (IOException e) {
			}
        }
        
    }
    /**
     * 读取串口数据
     * @author ChenWei
     * @email 582900710@qq.com
     * @date 2021年11月11日 上午11:55:01
     * @since 1
     * @param serialPort
     * @return 字节数组
     */
    public static byte[] readFromPort(
    		SerialPort serialPort) {
    	InputStream in = null;
        byte[] bytes = null;
        try {
        	in = serialPort.getInputStream();
        	//获取buffer里的数据长度
        	int bufflenth = in.available();		
        	while (bufflenth != 0) {       
        		//初始化byte数组为buffer中数据的长度
                bytes = new byte[bufflenth];
                in.read(bytes);
                bufflenth = in.available();
        	} 
        } catch (IOException e) {
        	return null;
        } finally {
        	try {
            	if (in != null) {
            		in.close();
            		in = null;
            	}
        	} catch(IOException e) {
        	}
        }
        return bytes;
    }
    /**
     * 添加监听事件
     * @author ChenWei
     * @email 582900710@qq.com
     * @date 2021年11月11日 下午2:25:16
     * @since 1
     * @param port
     * @param listener
     * @throws TooManyListenersException
     */
    public static void addListener(
    		SerialPort port, 
    		SerialPortEventListener listener) throws TooManyListenersException{
        	//给串口添加监听器
			port.addEventListener(listener);
			//设置当有数据到达时唤醒监听接收线程
            port.notifyOnDataAvailable(true);
            //设置当通信中断时唤醒中断线程
            port.notifyOnBreakInterrupt(true);
    }
	public static void main(String[] args) {
		List<String> findPort = SerialComKit.findPort();
		System.out.println(findPort);
	}
}

自定义监听类

package com.bami.service.v1.instruc;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;

import com.bami.common.serial_com.SerialComKit;
import com.bami.common.spring.SpringUtils;
import com.bami.pojo.client.B9JiYunClient;

import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

/**
 * 事件监听
 * @author ChenWei
 * @email 582900710@qq.com
 * @date 2021年11月15日 下午9:31:14
 * @since 1
 */
public class SerialPortListener implements SerialPortEventListener{
	
	private String dataFlag;
	
	private SerialPort serialPort;
	
	public SerialPortListener(SerialPort serialPort) {
		this.serialPort = serialPort;
	}
	@Override
	public void serialEvent(SerialPortEvent event) {
		B9JiYunClient b9JiYunClient = 
				SpringUtils.getBean(B9JiYunClient.class);
		if(event.getEventType() != SerialPortEvent.DATA_AVAILABLE)
			return;
		if(serialPort == null)
			return;
		//存在可用数据
		//读取数据
		byte[] dataByte = SerialComKit.readFromPort(serialPort);
		String data = new String(dataByte);
		//去除重复数据
		String[] split = data.split("[^\\d^\\.]+");
    	List<String> list = Arrays.asList(split);
    	list = list.stream().distinct().filter(p ->p!=null && p.length() != 0).collect(Collectors.toList());
    	if(list == null || list.isEmpty())
    		return;
    	data = list.get(0);
    	if(StringUtils.isEmpty(this.dataFlag) ||
    			!this.dataFlag.equals(data)) {
    		//替换新值
    		this.dataFlag = data;
    		//上报数据
    		b9JiYunClient.pushWeight(data);
    	}
	}

}

自定义监听业务

package com.bami.service.v1.instruc;

import java.util.TooManyListenersException;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.bami.common.serial_com.SerialComKit;
import com.bami.pojo.annotation.ExecInstruc;
import com.bami.pojo.dict.Config;
import com.bami.pojo.dict.DeviceNews;
import com.bami.pojo.dict.InstrucChannel;
import com.bami.pojo.dict.InstrucInfo;

import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;

/**
 * 开启串口监听
 * @author ChenWei
 * @email 582900710@qq.com
 * @date 2021年11月12日 上午10:55:38
 * @since 1
 */
@ExecInstruc(instruc = InstrucInfo.OpenComListen)
public class OpenComListenInstrucService implements InstrucChannel {
	@Autowired
	private Config config;
	@Override
	public String exceInstruc(String instruc) {
		String portName = config.getPortName();
		Integer baudrate = config.getBaudrate();
		SerialPort serialPort = config.getSerialPort();
		if(StringUtils.isEmpty(portName))
			return DeviceNews.instance()
					.error()
					.result("无法开启串口监听,串口名称未设置.")
					.toString();
		if(baudrate == null)
			return DeviceNews.instance()
					.error()
					.result("无法开启串口监听,串口波特率未设置.")
					.toString();
		try {
			//关闭旧串口对象资源
			SerialComKit.closePort(serialPort);
			SerialPort openPort = 
					SerialComKit.openPort(portName,baudrate);
			//保存新的串口对象
			serialPort = openPort;
			config.setSerialPort(openPort);
			SerialComKit.addListener(
					openPort, 
					new SerialPortListener(openPort));
		} catch (NoSuchPortException e) {
			return DeviceNews.instance()
					.error()
					.result("开启串口监听失败,没有找到与该端口名匹配的串口设备")
					.toString();
		} catch (PortInUseException e) {
			return DeviceNews.instance()
					.error()
					.result("开启串口监听失败,端口已被占用")
					.toString();
		} catch (UnsupportedCommOperationException e) {
			return DeviceNews.instance()
					.error()
					.result("开启串口监听失败,请检查串口参数是否正确")
					.toString();
		} catch (TooManyListenersException e) {
			return DeviceNews.instance()
					.error()
					.result("串口监听数量过多,开启串口监听失败")
					.toString();
		}
		return DeviceNews.instance()
				.success()
				.result("开启串口监听成功")
				.toString();
	}

}

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是一条酸菜鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值