当前位置:   article > 正文

使用java进行串口开发测试,超详细(一篇就够了)!

使用java进行串口开发测试,超详细(一篇就够了)!

前言

本次的背景是在一个服务器数据会从R422串口发送数据到R232串口服务器。

开发任务就是在接收数据的服务器上开发一个java程序能监听这个数据并进行数据分析

所以使用的技术大概扯到java ,RXTXcom ,串口 。

不过大部分人会因为电脑上面没有串口而无法测试,所以这个时候就需要虚拟的串口工具进行测试了。这个测试呢分两个部分,一个是在window上面测试,一个是在虚拟环境Centos7上面测试。
在这里插入图片描述


一、开发前准备

在让你们借鉴前,先给你们看本次我所用到的基本环境,好让你们有所对比。
本机系统: window10
虚拟机系统: Centos7
java版本:jdk 1.8
开发工具:Idea2019
服务器视图化工具:finalshell3.0
虚拟机控制工具:VMware 16

我这边提供一些测试工具用品,都是我经过测试使用的,可以没毛病。如果想要其他的什么工具或者软件也可以评论区要哦

链接:https://pan.baidu.com/s/1vJCZr1cA6Hd2C62-a3Xhfg
提取码:cs20

在这里插入图片描述


二、开发java项目时所依赖的RXTXcom.jar包(window)

(1)去下载有关自己系统的jar包(是那个系统就下那个包)
下载地址:http://fizzed.com/oss/rxtx-for-java
在这里插入图片描述
(2)把下载好的文件放到java,也就是jdk文件下对应的地方
在这里插入图片描述
(3)给springboot项目,或者maven项目配置一下这个jar包
在这里插入图片描述


三、开发java代码(window)

这里只发一小部分代码,注意我这个项目的主要目的就是去监听数据,其他功能各位看好加

package com.wl.myclocksource.utils;

import gnu.io.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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


public class SerialPortUtil {

    private static final Logger logger = LoggerFactory.getLogger(SerialPortUtil.class);

    private static SerialPortUtil serialPortUtil = null;

    static {
        //在该类被ClassLoader加载时就初始化一个SerialTool对象
        if (serialPortUtil == null) {
            serialPortUtil = new SerialPortUtil();
        }
    }

    //私有化SerialTool类的构造方法,不允许其他类生成SerialTool对象
    private SerialPortUtil() {
    }

    /**
     * 获取提供服务的SerialTool对象
     *
     * @return serialPortUtil
     */
    public static SerialPortUtil getSerialPortUtil() {
        if (serialPortUtil == null) {
            serialPortUtil = new SerialPortUtil();
        }
        return serialPortUtil;
    }


    /**
     * 查找所有可用端口
     *
     * @return 可用端口名称列表
     */
    public   ArrayList<String> findPort() {
        //获得当前所有可用串口
        Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();

        ArrayList<String> portNameList = new ArrayList<>();

        //将可用串口名添加到List并返回该List
        while (portList.hasMoreElements()) {
            String portName = portList.nextElement().getName();
            portNameList.add(portName);
        }

        return portNameList;
    }

    /**
     * 打开串口
     *
     * @param portName 端口名称
     * @param baudrate 波特率
     * @param databits 数据位
     * @param parity   校验位(奇偶位)
     * @param stopbits 停止位
     * @return 串口对象
//     * @throws SerialPortParameterFailure 设置串口参数失败
//     * @throws NotASerialPort             端口指向设备不是串口类型
//     * @throws NoSuchPort                 没有该端口对应的串口设备
//     * @throws PortInUse                  端口已被占用
     */
    public  SerialPort openPort(String portName, int baudrate, int databits, int parity, int stopbits)  {

        try {
            //通过端口名识别端口
            CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);

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

            //判断是不是串口
            if (commPort instanceof SerialPort) {

                SerialPort serialPort = (SerialPort) commPort;
                try {
                    //设置一下串口的波特率等参数
                    serialPort.setSerialPortParams(baudrate, databits, stopbits, parity);
                } catch (UnsupportedCommOperationException e) {
//                    throw new SerialPortParameterFailure();
                }

                //System.out.println("Open " + portName + " sucessfully !");
                return serialPort;
            } else {
                //不是串口
//                throw new NotASerialPort();
                logger.error("不是串口");
            }
        } catch (NoSuchPortException e1) {
            logger.error("没有找到端口");
            e1.printStackTrace();
//            throw new NoSuchPort();
        } catch (PortInUseException e2) {
            logger.error("端口被占用");
            e2.printStackTrace();
//            throw new PortInUse();
        }
        return null;
    }

    /**
     * 关闭串口
     *
     * @param serialPort 待关闭的串口对象
     */
    public  void closePort(SerialPort serialPort) {
        if (serialPort != null) {
            serialPort.close();
            serialPort = null;
        }
    }

    /**
     * 往串口发送数据
     *
     * @param serialPort 串口对象
     * @param order      待发送数据
//     * @throws SendDataToSerialPortFailure        向串口发送数据失败
//     * @throws SerialPortOutputStreamCloseFailure 关闭串口对象的输出流出错
     */
    public  void sendToPort(SerialPort serialPort, byte[] order)  {
        OutputStream out = null;
        try {
            out = serialPort.getOutputStream();
            out.write(order);
            out.flush();
        } catch (IOException e) {
//            throw new SendDataToSerialPortFailure();
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                    out = null;
                }
            } catch (IOException e) {
//                throw new SerialPortOutputStreamCloseFailure();
                e.printStackTrace();
            }
        }
    }

    /**
     * 从串口读取数据
     *
     * @param serialPort 当前已建立连接的SerialPort对象
     * @return 读取到的数据
//     * @throws ReadDataFromSerialPortFailure     从串口读取数据时出错
//     * @throws SerialPortInputStreamCloseFailure 关闭串口对象输入流出错
     */
    public  byte[] readFromPort(SerialPort serialPort)  {

        InputStream in = null;
        byte[] bytes = null;

        try {
            in = serialPort.getInputStream();
            int bufflenth = in.available();        //获取buffer里的数据长度

            while (bufflenth != 0) {
                bytes = new byte[bufflenth];    //初始化byte数组为buffer中数据的长度
                in.read(bytes);
                bufflenth = in.available();
            }
        } catch (IOException e) {
            e.printStackTrace();
//            throw new ReadDataFromSerialPortFailure();
        } finally {
            try {
                if (in != null) {
                    in.close();
                    in = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
//                throw new SerialPortInputStreamCloseFailure();
            }
        }

        return bytes;

    }

    /**
     * 添加监听器
     *
     * @param port     串口对象
     * @param listener 串口监听器
//     * @throws TooManyListeners 监听类对象过多
     */
    public  void addListener(SerialPort port, SerialPortEventListener listener)  {

        try {
            //给串口添加监听器
            port.addEventListener(listener);
            //设置当有数据到达时唤醒监听接收线程
            port.notifyOnDataAvailable(true);
            //设置当通信中断时唤醒中断线程
            port.notifyOnBreakInterrupt(true);
        } catch (TooManyListenersException e) {
//            throw new TooManyListeners();
            logger.error("太多监听器");
            e.printStackTrace();
        }
    }

    /**
     * 删除监听器
     *
     * @param port     串口对象
     * @param listener 串口监听器
//     * @throws TooManyListeners 监听类对象过多
     */
    public  void removeListener(SerialPort port, SerialPortEventListener listener) {
        //删除串口监听器
        port.removeEventListener();
    }

  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237

四、开发java项目后进行测试(window)

(1)创建两个虚拟串口,使用VspdPro_CN_Free工具

在这里插入图片描述
(2)启动项目监听功能
在这里插入图片描述
(3)使用串口调试工具
在这里插入图片描述


五、打包后jar包测试环境配置(liunx)

(1)安装好liunx版的jdk 1.8
在这里插入图片描述
(2)去下载有关自己系统的jar包(是那个系统就下那个包)
下载地址:http://fizzed.com/oss/rxtx-for-java
在这里插入图片描述

(3)把下载好的文件放到java,也就是jdk文件下对应的地方
在这里插入图片描述
(4)然后就可以启动项目不报错了
在这里插入图片描述


六、打包后jar包虚拟串口的创建,第一种方式(liunx)

(1)创建一个物理串行端口(因为你在window上也有开启虚拟端口,会认为你的虚拟端口就是物理端口)
在这里插入图片描述
(2)开启之后就连接上了,就可以使用串口调测助手进行测试
在这里插入图片描述
(3)可以通过命令进行监控,也可以用minicom软件监控

# 发送消息
echo hello >/dev/ttyS1

# 监听消息,但是好像不太灵
cat /dev/ttyS1
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述
使用minicom的监听工具
在这里插入图片描述

(4)这个东西是有局限的
就是不知道为什么两个虚拟端口通是通了,但是就是java项目也就启动不了了,显示端口被占用了,也不知道解决方式,因为没试过。


七、打包后jar包虚拟串口的创建,第二种方式(liunx)

(1)创建一个管道进行连接测试
在这里插入图片描述
(2)开启Putty软件进行配置
在这里插入图片描述
开启PuTTY软件
在这里插入图片描述
(3)开启java项目进行测试,或者你也可以输入echo 、cat 等命令
在这里插入图片描述


八、出现bug问题,一定得看这里!!!

(1)查看串口命令
查看串口命令
查看串口是否可用 可以对串口发送数据比如对com1口,echo hello > /dev/ttyS0
查看串口名称使用 ls -l /dev/ttyS* 一般情况下串口的名称全部在dev下面,如果你没有外插串口卡的话默认是dev下的ttyS* ,一般ttyS0对应com1,ttyS1对应com2,当然也不一定是必然的;
查看串口驱动:cat /proc/tty/driver/serial
查看串口设备:dmesg | grep ttyS*

(2)在传输数据的时候可能会报错。

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f1c7dacdd9d, pid=94106, tid=0x00007f1c7e3a9700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_151-b12) (build 1.8.0_151-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.151-b12 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [librxtxSerial.so+0x6d9d]  read_byte_array+0x3d
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/initpath/clock_20201113001/hs_err_pid94106.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

这个时候可以参考我写的另一个解决方案:https://blog.csdn.net/weixin_43943548/article/details/109843689

后言

ヾ(•ω•`)o

这篇博客我找了很多的博客,然后自己经过测试后写出来的。

之前没整过串口这个东西,现在需要了就开整了。

欢迎各位大佬或小伙伴一起讨论

我这个项目是用来接受标准时间格式的R422线传过来的,然后进行修改系统时间,需要的可以参考。
项目源码在这:
链接:https://pan.baidu.com/s/1Kik4uPokinctlDXILkKh6g
提取码:qxel

( ゚д゚)つBye

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/289761
推荐阅读
相关标签
  

闽ICP备14008679号