Java使用Rxtx编写串口助手

Java使用Rxtx编写串口助手

最近由于一些需要,了解了一下如何使用java来操作串口,花费了好几天时间,所以现在单独整理出来一篇文章,方便大家的同时也方便自己,整个程序的界面是用java的SWT写的。

环境搭建

相关环境:

  1. window 7 64位;
  2. jdk 1.8;
  3. eclipse 2019-12;
  4. Rxtx版本:rxtx-2.2-20081207-win-x64;
  5. 如何获取Rxtx
    下载链接:http://fizzed.com/oss/rxtx-for-java
    如图所示
  6. 如何使用Rxtx

解压压缩包,找到Rxtxcomm.jar和rxtxserial.dll文件,并将Rxtxcomm.jar放到jdk的安装目录下,即<JAVA_HOME>\jre\lib\ext,然后将 rxtxSerial.dll文件放到下面的目录里 —> <JAVA_HOME>\jre\bin,重启eclipse即可使用解压如图所示
7. 虚拟串口工具VSPD
下载地址: https://www.cr173.com/soft/21406.html
下载的时候不要下载错,点击普通下载地址,注意观察文件名后缀是.zip格式的
这个工具会直接虚拟出串口,每次虚拟一队,一个发送的数据,另一个可以接收到,所以我在程序中,直接默认打开COM4口接受数据,所以在运行代码选择端口时,请选择COM3。另外,请先虚拟端口,在运行我所给的代码,不然会报异常。
8. 相关注意事项
注意win10系统,Rxtx 64位基本是用不了的,或者说可能有哪些配置我还没有找到,但是Rxtx32位是可以使用的。

代码相关

咱这个人不喜欢啰唆,下面直接上代码。
代码分为三块:界面类MainFrame、串口操作类serialPortManage、和程序启动SerialPort。结构如下图所示:
结构就是这样
界面类MainFrame:

package com.lyrics.SerialAssistant.ui;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;

import javax.swing.JOptionPane;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Button;
import com.lyrics.SerialAssistant.util.serialPortManage;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
/**
 * 串口相关操作方法的实现与封装
 * 
 * @author  LyRics1996
 * @since  2020-01-04
 */
public class MainFrame {

	protected Shell shlSerialAssistant;
	private Text textDisplay;
	private Text textDatebitSet;
	private Text textCheckbitSet;
	private Text textStopbitSet;
	private Text textSendData;
	
	serialPortManage com=new serialPortManage(); // 就是界面选择打开的端口
	serialPortManage com2=new serialPortManage(); // 我将此端口直接设置为"COM4"
	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 设置日期格式
	
	/**
	 * Open the window.
	 * @wbp.parser.entryPoint
	 */
	public void open() {
		Display display = Display.getDefault();
		createContents();
		shlSerialAssistant.open();
		shlSerialAssistant.layout();
		while (!shlSerialAssistant.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	/**
	 * Create contents of the window.
	 */
	protected void createContents() {
		// 创造顶层容器
		shlSerialAssistant = new Shell();
		shlSerialAssistant.setSize(454, 304);
		shlSerialAssistant.setText("Serial Asssistant");
		
		// 创建文本类控件
		textDisplay = new Text(shlSerialAssistant, SWT.BORDER | SWT.MULTI);
		textDisplay.setBounds(10, 10, 271, 168);
		textSendData = new Text(shlSerialAssistant, SWT.BORDER);
		textSendData.setBounds(89, 237, 222, 23);
		textDatebitSet = new Text(shlSerialAssistant, SWT.BORDER);
		textDatebitSet.setText("8");
		textDatebitSet.setBounds(355, 67, 73, 23);
		textCheckbitSet = new Text(shlSerialAssistant, SWT.BORDER);
		textCheckbitSet.setText("0");
		textCheckbitSet.setToolTipText("");
		textCheckbitSet.setBounds(355, 104, 73, 23);
		textStopbitSet = new Text(shlSerialAssistant, SWT.BORDER);
		textStopbitSet.setText("1");
		textStopbitSet.setToolTipText("");
		textStopbitSet.setBounds(355, 143, 73, 23);
		
		// 创建标签类控件		
		Label lblBaudrate = new Label(shlSerialAssistant, SWT.NONE);
		lblBaudrate.setBounds(287, 23, 61, 17);
		lblBaudrate.setText("Baud rate:");
		Label lblDataBite = new Label(shlSerialAssistant, SWT.NONE);
		lblDataBite.setBounds(287, 67, 61, 17);
		lblDataBite.setText("Data bit:");
		Label lblCheckBite = new Label(shlSerialAssistant, SWT.NONE);
		lblCheckBite.setBounds(287, 110, 61, 17);
		lblCheckBite.setText("Check bit:");
		Label lblStopBit = new Label(shlSerialAssistant, SWT.NONE);
		lblStopBit.setBounds(287, 149, 61, 17);
		lblStopBit.setText("Stop bit:");
		Label lblSerialPort = new Label(shlSerialAssistant, SWT.NONE);
		lblSerialPort.setBounds(20, 196, 63, 17);
		lblSerialPort.setText("Serial Port:");
		Label lblSendData = new Label(shlSerialAssistant, SWT.NONE);
		lblSendData.setBounds(20, 240, 63, 17);
		lblSendData.setText("Send Data:");
		
		// 创建Combo类控件
		Combo comboBaudrateSelect = new Combo(shlSerialAssistant, SWT.NONE);
		comboBaudrateSelect.setItems(new String[] {"9600", "115200"});
		comboBaudrateSelect.setBounds(355, 20, 74, 25);
		comboBaudrateSelect.setText("9600");
		Combo comboSeralPort = new Combo(shlSerialAssistant, SWT.NONE);
		comboSeralPort.setBounds(89, 192, 88, 25);
		addListPort(comboSeralPort);
		
		// 创建按钮类控件
		Button btnOpenPort = new Button(shlSerialAssistant, SWT.NONE);
		btnOpenPort.setBounds(231, 191, 80, 27);
		btnOpenPort.setText("Open Port");
		Button btnClosePort = new Button(shlSerialAssistant, SWT.NONE);
		btnClosePort.setBounds(336, 191, 80, 27);
		btnClosePort.setText("Close Port");		
		Button btnSendData = new Button(shlSerialAssistant, SWT.NONE);
		btnSendData.setBounds(336, 235, 80, 27);
		btnSendData.setText("Send Data");
		
		// 添加监听事件
		btnOpenPort.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				com.setBaudrate(Integer.parseInt(comboBaudrateSelect.getText()));
				com.setDatabit(Integer.parseInt(textDatebitSet.getText()));
				com.setCheckbit(Integer.parseInt(textCheckbitSet.getText()));
				com.setStopbit(Integer.parseInt(textStopbitSet.getText()));
				if(!com.openPort(comboSeralPort.getText())) {
					JOptionPane.showMessageDialog(null, "open port failed! This device not exist or using","warning", JOptionPane.INFORMATION_MESSAGE);
					return;
				}
				JOptionPane.showMessageDialog(null, "open port successed!","warning", JOptionPane.INFORMATION_MESSAGE);
			}
		});
		btnClosePort.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				com.close();
				JOptionPane.showMessageDialog(null, "close port successed!","warning", JOptionPane.INFORMATION_MESSAGE);
			}
		});
		btnSendData.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				String message = textSendData.getText();
				com2.openPort("COM4");
				com2.startRead(1);
				com.write(message);
				textDisplay.append(df.format(new Date())+"\r\n");
				textDisplay.append(comboSeralPort.getText()+':'+message);
				textDisplay.append("\r\n");
				textDisplay.append(df.format(new Date())+"\r\n");
				textDisplay.append("COM4"+':'+com2.getReadStr());
				textDisplay.append("\r\n");
			}
		});
	}
	
	/**
	 * 打开软件时,comboSeralPort控件中列出所有的端口
	 * 
	 * @author  LyRics1996
	 * @since  2020-01-04
	 */
	@SuppressWarnings("unchecked")
	private void addListPort(Combo comboSeralPort) {
		Vector<String> port=new Vector<String>();
		port=com.listPort();
		for(int i=0;i<port.size();i++)
		{
			comboSeralPort.add(port.elementAt(i));
		}
			comboSeralPort.setText(port.elementAt(0));
	}
}

串口操作类serialPortManage

package com.lyrics.SerialAssistant.util;
 
import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;
import java.util.Vector;
 
/**
 * 串口相关操作方法的实现与封装
 * 
 * @author  LyRics1996
 * @since  2020-01-04
 */
public class serialPortManage implements Runnable, SerialPortEventListener
{  
	private int baudrate=9600;
	private int databit=8;
	private int checkbit=0;
	private int stopbit=1;
    private int m_iWaitTime = 2000;
    private String readStr = "";
    private int m_iThreadTime = 0;
    private CommPortIdentifier m_commPort;
    private SerialPort m_serialPort;
    private InputStream m_inputStream;
    private OutputStream m_outputStream;
	public void setBaudrate(int baudrate) {
		this.baudrate = baudrate;
	}

	public void setDatabit(int databit) {
		this.databit = databit;
	}

	public void setCheckbit(int checkbit) {
		this.checkbit = checkbit;
	}

	public void setStopbit(int stopbit) {
		this.stopbit = stopbit;
	}
    public String getReadStr() {
			return readStr;
		}
    /**
     * 列出当前电脑所有端口
     * 
     * @author  LyRics1996
     * @since  2020-01-04
     */
    @SuppressWarnings("rawtypes")
    public Vector listPort()
    {
    	Vector<String> listPort=new Vector<String>();
        CommPortIdentifier commPortIdentifier;
        Enumeration enumeration = CommPortIdentifier.getPortIdentifiers();
        
        while (enumeration.hasMoreElements())
        {
            commPortIdentifier = (CommPortIdentifier)enumeration.nextElement();
            if (commPortIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL)
            {
            	listPort.addElement(commPortIdentifier.getName());
            }
        }
		
		return listPort;
    }
    
    /**
     * 传入端口名,例如"COM1",打开端口
     * 
     * @author  LyRics1996
     * @since  2020-01-04
     */
    @SuppressWarnings("rawtypes")
    public boolean openPort(String sPortName)
    {
        m_commPort = null;
        CommPortIdentifier commPortIdentifier;
        Enumeration enumeration = CommPortIdentifier.getPortIdentifiers();
        
        while (enumeration.hasMoreElements())
        {
            commPortIdentifier = (CommPortIdentifier)enumeration.nextElement();
            
            if (commPortIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL
                && commPortIdentifier.getName().equals(sPortName))
            {
                m_commPort = commPortIdentifier;
                try {
					m_serialPort = (SerialPort)m_commPort.open(null, m_iWaitTime);
				} catch (PortInUseException e) {
					return false;
				}
                try {
					m_serialPort.setSerialPortParams(baudrate, databit, stopbit, checkbit);
				} catch (UnsupportedCommOperationException e) {
					e.printStackTrace();
				}
                addListener();
                return true;
            }
        }
        return false;
        
    }
    
    /**
     * 检查端口连接情况
     * 
     * @author  LyRics1996
     * @since  2020-01-04
     */
    public void checkPort()
    {
        if (m_commPort == null)
        {
            throw new RuntimeException("请选择端口");
        }
        if (m_serialPort == null)
        {
            throw new RuntimeException("serialPort对象为null");
            
        }
    }
    
    /**
     * 发送数据
     * 
     * @author  LyRics1996
     * @since  2020-01-04
     */
    public void write(String sMessage)
    {
        checkPort();
        try
        {
            m_outputStream = new BufferedOutputStream(m_serialPort.getOutputStream());
        }
        catch (IOException e)
        {
            throw new RuntimeException("获取端口的OutputStream出错" + e.getMessage());
        }
        
        try
        {
            m_outputStream.write(sMessage.getBytes());
        }
        catch (IOException e)
        {
            throw new RuntimeException("向端口发送信息时出错:" + e.getMessage());
        }
        finally
        {
            try
            {
                m_outputStream.close();
            }
            catch (Exception e)
            {
                
            }
            
        }
    }
    /**
     * 添加监听,该方法在打开端口时自动被调用
     * 
     * @author  LyRics1996
     * @since  2020-01-04
     */
    public void addListener()
    {
    	try
        {
            m_serialPort.addEventListener(this);
        }
        catch (TooManyListenersException e)
        {
            throw new RuntimeException(e.getMessage());
        }
    }
    /**
     * 开始监听数据
     * 
     * @author  LyRics1996
     * @since  2020-01-04
     */
    public void startRead(int iTime)
    {
        checkPort();
        try
        {
            m_inputStream = new BufferedInputStream(m_serialPort.getInputStream());
        }
        catch (IOException e)
        {
            throw new RuntimeException("获取端口的InputStream出错:" + e.getMessage());
        }

        m_serialPort.notifyOnDataAvailable(true);
        
        if (iTime > 0)
        {
            m_iThreadTime = iTime * 1000;
            Thread thread = new Thread(this);
            thread.start();
        }
    }
    /**
     * 关闭端口
     * 
     * @author  LyRics1996
     * @since  2020-01-04
     */
    public void close()
    {
        m_serialPort.close();
        m_serialPort = null;
        m_commPort = null;
    }
    
    /**
     * run
     * 
     * @author  LyRics1996
     * @since  2020-01-04
     */
    @Override
    public void run()
    {
        try
        {
            Thread.sleep(m_iThreadTime);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    /**
     * 串口相关事件
     * 
     * @author  LyRics1996
     * @since  2020-01-04
     */
    @Override
    public void serialEvent(SerialPortEvent arg0)
    {
        switch (arg0.getEventType())
        {
            case SerialPortEvent.BI:/*Break interrupt,通讯中断*/
            case SerialPortEvent.OE:/*Overrun error,溢位错误*/
            case SerialPortEvent.FE:/*Framing error,传帧错误*/
            case SerialPortEvent.PE:/*Parity error,校验错误*/
            case SerialPortEvent.CD:/*Carrier detect,载波检测*/
            case SerialPortEvent.CTS:/*Clear to send,清除发送*/
            case SerialPortEvent.DSR:/*Data set ready,数据设备就绪*/
            case SerialPortEvent.RI:/*Ring indicator,响铃指示*/
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY:/*Output buffer is empty,输出缓冲区清空*/
                break;
            case SerialPortEvent.DATA_AVAILABLE:/*Data available at the serial port,端口有可用数据。读到缓冲数组,输出到终端*/
                byte[] readBuffer = new byte[1024];
                readStr = "";
                
                try
                {
                    while (m_inputStream.available() > 0)
                    {
                        m_inputStream.read(readBuffer);
                        readStr += new String(readBuffer).trim();
                    }
                    
                }
                catch (IOException e)
                {
                }
        }
        
    }
    
}

程序启动SerialPort

package com.lyrics.SerialAssistant;

import com.lyrics.SerialAssistant.ui.MainFrame;
/**
 * SerialPort
 * 
 * @author  LyRics1996
 * @since  2020-01-04
 */
public class SerialPort {

	public static void main(String[] args) {
		try {
			MainFrame window = new MainFrame();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

运行结果

首先打开串口虚拟工具,虚拟出com3和com4
串口虚拟工具
运行代码,程序员运行界面如图所示
程序运行界面
选中COM3端口,点击OpenPort按钮,在senddata中输入要发送的数据,例如:LyRics1966,我们可以看到COM3将数据发送出去,COM4将数据接收并显示到界面上。
运行状态

写在最后

本次的代码只是粗略的实现基础功能,很多地方写的也不够严谨,也没有将功能模块区分的更加清楚,所以有些不尽如人意是肯定的,请大家多多包涵,本篇文章也只是希望诸位能够借鉴后直接调通代码,不要在调通代码这一步就浪费了很多时间。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java编写串口助手可以使用Java串口通信库进行操作和管理串口,并提供用户友好的图形界面界面,方便用户进行串口的配置和数据的收发。 首先,需要导入Java串口通信库,如RXTX或者JSSC。通过引入这些库,可以实现对串口的打开、关闭、设置波特率、数据位、停止位、校验位等串口参数的配置。 接下来,可以通过图形界面设计工具(如Swing或JavaFX)创建一个用户界面。该界面应该包含串口的选择、打开/关闭串口按钮、发送数据的文本输入框、接收数据的文本框等控件。 当用户点击打开串口按钮时,程序会打开并配置所选串口,并接收串口返回的数据。如果串口打开成功,则按钮变为关闭串口按钮,用户可以点击关闭串口按钮来关闭串口。 用户可以在文本输入框中输入需要发送的数据,并点击发送按钮将数据发送至串口。同时,接收数据的文本框会显示串口返回的数据。 为了方便用户操作,可以提供配置串口参数的选项,如波特率、数据位、停止位和校验位等。用户可以通过下拉菜单选择所需的参数,点击应用按钮来应用新的配置。 此外,可以在用户界面的界面上添加其他功能,如清空接收数据、保存接收数据到文本文件、发送文件等。 编写Java串口助手时还需要考虑一些异常情况的处理,如串口被其他程序占用、串口打开失败等。可以通过使用异常处理机制来捕获并处理这些异常。 最后,可将Java程序打包成可执行文件或者将源代码编译为jar文件,方便其他用户使用和安装。 总之,通过使用Java串口通信库以及图形界面技术,可以实现一个功能完善、操作简便的串口助手。用户可以方便地配置串口并进行数据的收发操作,提高串口通信的效率和便利性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值