关于Java读取串口数据

关于Java读取串口数据

1、准备工作

1.下载RXTX for Java

2.解压文件,Install.txt中有安装方法。我这里使用的Windows所以将rxtxParallel.dll和rxtxSerial.dll复制到jdk安装目录/jdk/jre/bin;将RXTXcomm.jar放入项目的lib中。

2、编码

1.代码整体思路

一个串口数据记录器的Java程序,它可以将从串口接收到的数据记录到文本文件中。程序的界面使用了Swing库来构建,
包括一个下拉框用于选择串口、若干个按钮用于连接、开始记录、停止记录和断开连接、一个用于显示日志的文本区域等。
主要的功能实现在connectToSerialPort()、startLogging()、stopLogging()和closeSerialPort()等方法中,
它们分别对应着连接串口、开始记录、停止记录和关闭串口的操作。
在连接到串口时,程序会弹出文件选择对话框,让用户选择保存数据的文件路径。程序使用了RXTXcomm库来与串口进行交互。

321.上链接

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;

public class SerialDataLogger extends JFrame implements ActionListener {
    /**
     * 串口列表的下拉框
     */
    private JComboBox<String> portList;
    /**
     * 连接按钮
     */
    private JButton connectButton;
    /**
     * 日志显示区域
     */
    private JTextArea logArea;
    /**
     * 开始按钮
     */
    private JButton startButton;
    /**
     * 停止按钮
     */
    private JButton stopButton;
    /**
     * 断开按钮
     */
    private JButton closeButton;
    /**
     * 是否正在记录数据
     */
    private boolean isLogging = false;
    /**
     * 文件写入器
     */
    private FileWriter fileWriter;

    /**
     * 添加文件路径变量
     */
    private String filePath;

    public SerialDataLogger() {
        super("Serial Data Logger");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(800, 400);
        setLocationRelativeTo(null);

        // 初始化UI组件
        JPanel panel = new JPanel(new BorderLayout());
        add(panel);
        JPanel controlPanel = new JPanel(new FlowLayout());
        panel.add(controlPanel, BorderLayout.NORTH);
        // 获取可用串口列表
        portList = new JComboBox<>(getPortNames());
        // 设置JComboBox的大小为宽度200像素,高度30像素
        portList.setPreferredSize(new Dimension(80, 30));
        controlPanel.add(portList);
        connectButton = new JButton("Connect");
        connectButton.addActionListener(this);
        controlPanel.add(connectButton);
        startButton = new JButton("Start");
        startButton.addActionListener(this);
        startButton.setEnabled(false);
        controlPanel.add(startButton);
        stopButton = new JButton("Stop");
        stopButton.addActionListener(this);
        stopButton.setEnabled(false);
        controlPanel.add(stopButton);
        closeButton = new JButton("Close");
        closeButton.addActionListener(this);
        closeButton.setEnabled(false);
        controlPanel.add(closeButton);

        logArea = new JTextArea();
        JScrollPane scrollPane = new JScrollPane(logArea);
        panel.add(scrollPane, BorderLayout.CENTER);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (source == connectButton) {
            // 连接到选定的串口
            connectToSerialPort();
        } else if (source == startButton) {
            // 开始记录数据
            startLogging();
        } else if (source == stopButton) {
            // 停止记录数据
            stopLogging();
        } else if (source == closeButton) {
            // 关闭串口连接
            closeSerialPort();
        }
    }

    InputStream in;
    SerialPort serialPort;

    private void connectToSerialPort() {
        // 获取选定的串口名称
        String portName = (String) portList.getSelectedItem();
        try {
            // 获取选定的串口标识符
            CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
            // 打开选定的串口
            serialPort = (SerialPort) portIdentifier.open(getClass().getName(), 2000);
            // 设置串口参数
            serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
            // 获取串口输入流
            in = serialPort.getInputStream();
            // 在连接时选择文件地址
            filePath = getFileName();
            if (filePath == null) {
                logArea.append("Failed to connect to " + portName + ": Invalid file path\n");
                return;
            }
            // 创建文件写入器
            fileWriter = new FileWriter(filePath);
            receiveMsg();
            connectButton.setEnabled(false);
            closeButton.setEnabled(true);
            startButton.setEnabled(true);
            logArea.append("Connected to " + portName + "\n");
        } catch (Exception e) {
            logArea.append("Failed to connect to " + portName + ": " + e.getMessage() + "\n");
            e.printStackTrace();
        }
    }

    private void receiveMsg() {
        // 创建读取数据的线程
        Thread readThread = new Thread(() -> {
            byte[] buffer = new byte[1024];
            int len = -1;
            try {
                // 从串口读取数据并写入文件
                while ((len = in.read(buffer)) > -1 && isLogging) {
                    String data = new String(buffer, 0, len, StandardCharsets.UTF_8);
//                    //调试
//                    if (data != null && !"".equals(data)) {
//                        System.out.println("=============" + data + "=============");
//                    }
                    logArea.append(data);
                    logArea.setCaretPosition(logArea.getDocument().getLength());
                    fileWriter.write(data);
                    fileWriter.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        // 启动读取数据的线程
        readThread.start(); 
    }

    private void startLogging() {
        if (!isLogging) {
            // 创建文件写入器时不再选择文件地址,直接使用连接时选择的文件地址
            if (filePath == null) {
                logArea.append("Failed to start logging: Invalid file path\n");
                return;
            }
            try {
                // 追加模式打开文件写入器
                fileWriter = new FileWriter(filePath, true);
                isLogging = true;
                startButton.setEnabled(false);
                stopButton.setEnabled(true);
                logArea.append("Started logging data\n");
                receiveMsg();
            } catch (IOException e) {
                logArea.append("Failed to start logging: " + e.getMessage() + "\n");
                e.printStackTrace();
            }
        }
    }

    private void stopLogging() {
        if (isLogging) {
            try {
                fileWriter.close(); // 关闭文件写入器
                isLogging = false;
                startButton.setEnabled(true);
                stopButton.setEnabled(false);
                logArea.append("Stopped logging data\n");
            } catch (IOException e) {
                logArea.append("Failed to stop logging: " + e.getMessage() + "\n");
                e.printStackTrace();
            }
        }
    }

    private void closeSerialPort() {
        try {
            in.close(); // 关闭输入流
            fileWriter.close(); // 关闭文件写入器
            serialPort.close(); // 关闭串口对象
            // 启用连接按钮  ,停关闭按钮
            connectButton.setEnabled(true);
            closeButton.setEnabled(false);
            startButton.setEnabled(false);
            stopButton.setEnabled(false);
            logArea.append("Serial port closed\n");
        } catch (Exception e) {
            logArea.append("Failed to close serial port: " + e.getMessage() + "\n");
            e.printStackTrace();
        }
    }

    private String[] getPortNames() {
        // 获取可用串口的枚举
        Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();
        java.util.List<String> portList = new java.util.ArrayList<>();
        while (portEnum.hasMoreElements()) {
            CommPortIdentifier portIdentifier = portEnum.nextElement();
            // 只添加串口类型的端口
            if (portIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                portList.add(portIdentifier.getName());
            }
        }
        return portList.toArray(new String[portList.size()]);
    }

    private String getFileName() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setDialogTitle("Choose save location");
        fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        // 弹出文件选择对话框,获取用户选择的保存路径
        if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
            String fileName = fileChooser.getSelectedFile().toString();
            if (!fileName.endsWith(".txt")) {
                fileName += ".txt";
            }
            return fileName;
        } else {
            return null;
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new SerialDataLogger().setVisible(true));
    }
}

3、测试

1.选择串口连接并选择数据输出文件(txt)

2.使用xcom发送数据;打完收工。
在这里插入图片描述

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值