java实现串口通信COM3,读取扫码枪信息

附上码云地址
https://gitee.com/guyuanman/scanproject.git附上码云地址java实现串口通信COM3,读取扫码枪信息_System

当你的设备(扫码枪)连接到电脑上的时候,在设备管理器中可以看到串口

java实现串口通信COM3,读取扫码枪信息_System_02

我们只需要打开对应的串口捕捉就行

java实现串口通信COM3,读取扫码枪信息_java_03


我这里写死了,开启COM3的串口

其实就几个类

PortInit 项目启动就扫描串口

MyLister 监听开启的串口

PortController 开启关闭串口

java实现串口通信COM3,读取扫码枪信息_java_04


pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wl</groupId>
    <artifactId>myclocksource</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>myclocksource</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

<!--        <!– https://mvnrepository.com/artifact/org.rxtx/rxtx –>-->
<!--        <dependency>-->
<!--            <groupId>org.rxtx</groupId>-->
<!--            <artifactId>rxtx</artifactId>-->
<!--            <version>2.1.7</version>-->
<!--        </dependency>-->

        <!--管理web请求的配置(不加的则无法等待浏览器的请求)-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>



        <dependency>
            <groupId>org.rxtx</groupId>
            <artifactId>rxtx</artifactId>
            <version>2.2</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/lib/RXTXcomm.jar</systemPath>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

PortInit

package com.wl.myclocksource.init;

import com.wl.myclocksource.lister.MyLister;
import com.wl.myclocksource.utils.SerialPortUtil;
import gnu.io.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.TooManyListenersException;


/**
 * @author liwangwang
 * @site Liwangwang321@163.com
 * @create 2020-11-10 15:23
 */
@Component
public class PortInit implements ApplicationRunner {

    public  static  SerialPort serialPort =null;

    @Value("${portname}")
    private String portname;


    @Override
    public void run(ApplicationArguments args) throws Exception {

        System.out.println("当前portname:"+portname);
        TestA();
        //查看所有串口
        SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();
        ArrayList<String> port = serialPortUtil.findPort();
        port.forEach(u-> System.out.println("发现:"+u.toString()));

    }

    private void TestA(){
        try {
            String str = System.getProperty("sun.arch.data.model");
            System.out.println("This JVM is " + str + "-bit");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

MyLister

package com.wl.myclocksource.lister;

import com.wl.myclocksource.init.PortInit;
import com.wl.myclocksource.utils.SerialPortUtil;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author liwangwang
 * @site Liwangwang321@163.com
 * @create 2020-11-10 13:47
 */
public class MyLister implements SerialPortEventListener {

    private  String str = "";
    private  int strCount = 0;
    private  Pattern pattern= Pattern.compile("\\\\G\\d+");


    @Override
    public void serialEvent(SerialPortEvent arg0) {
        // TODO Auto-generated method stub
        //对以下内容进行判断并操作
        /*
        如果这个不行的话就换这个参考:
        BI -通讯中断
      CD -载波检测
      CTS -清除发送
      DATA_AVAILABLE -有数据到达
      DSR -数据设备准备好
      FE -帧错误
      OE -溢位错误
      OUTPUT_BUFFER_EMPTY -输出缓冲区已清空
      PE -奇偶校验错
        RI - 振铃指示
        */
        //switch多个,if单个
        if (arg0.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            strCount++;
            SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();
            byte[] bytes = serialPortUtil.readFromPort(PortInit.serialPort);
//            System.out.println(PortInit.serialPort);
            String byteStr = new String(bytes);

            System.out.println("===========start===========");
            System.out.println(new Date() + "【读到的字节数组】:-----" + byteStr);
            String needData = printHexString(bytes);
            System.out.println(new Date() + "【字节数组转字符串】:-----" + needData);
            System.out.println(new Date() +"【16进制字符串转字符串】:"+hexStringToString(needData));
            System.out.println("===========end===========");
            str+=byteStr;

            if(strCount==2){
                System.out.println("=========最后得到的时间字符串:"+str);
                if(pattern.matcher(str).lookingAt()){
                    setLiunxDate(str);
                }
                strCount=0;
                str = "";
            }
        }
    }

    private  void setLiunxDate(String date){
//        String d = "\\G202012023122845022";
        System.out.println(date);
        String time = date.replaceAll(" ","");
//        System.out.println("清理后的时间格式:"+time);
        String year = time.substring(2,6);
        String month = time.substring(6,8);
        String day = time.substring(8,10);
//        System.out.println("年:"+year);
//        System.out.println("月:"+month);
//        System.out.println("日:"+day);

        String hour = time.substring(11,13);
        String min = time.substring(13,15);
        String sec = time.substring(15,17);
//        System.out.println("分:"+min);
//        System.out.println("时:"+hour);
//        System.out.println("秒:"+sec);

        String osName = System.getProperty("os.name").toLowerCase();
        System.out.println("osName:"+osName);
        String rq = year+"-"+month+"-"+day;
        String sj = hour+":"+min+":"+sec;
        System.out.println("日期:"+rq);
        System.out.println("时间:"+sj);

        try {
            System.out.println("shell脚本启动==========");
            //通过exec 来运行Linux shell脚本:在这个demo中 setDate.sh 是和 LinuxTimeSetter 在同一个文件夹中
            String[] command = new String[]{"sh","./date.sh",rq,sj};
            Process proc = Runtime.getRuntime().exec(command);
            BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String text = null;
            //输出操作结果
            while ((text = br.readLine()) != null) {
                System.out.println("操作结果:"+text);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }


    };



    // 字节数组转字符串
    private String printHexString(byte[] b) {

        StringBuffer sbf = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sbf.append(hex.toUpperCase() + " ");
        }
        return sbf.toString().trim();
    }

    /**
     * 16进制转换成为string类型字符串
     * @param s
     * @return
     */
    public static String hexStringToString(String s) {
        if (s == null || s.equals("")) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "UTF-8");
            new String();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }

}

PortController

package com.wl.myclocksource.controller;

import com.wl.myclocksource.init.PortInit;
import com.wl.myclocksource.lister.MyLister;
import com.wl.myclocksource.utils.SerialPortUtil;
import gnu.io.SerialPort;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author: wangwang
 * @Date: 2020/11/18 13:49
 */
@RestController
@RequestMapping("api")
public class PortController {

    @Value("${portname}")
    private String portname;

    private   ResponseEntity responseEntity = null;


    @RequestMapping("start")
    public ResponseEntity start(){
        try {
            SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();
            //打开该对应portname名字的串口
            PortInit.serialPort = serialPortUtil.openPort("COM3", 9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
            //给对应的serialPort添加监听器
            serialPortUtil.addListener(PortInit.serialPort,new MyLister());

            responseEntity = new ResponseEntity("开启成功",HttpStatus.OK);
        }catch (Exception e){
            responseEntity = new ResponseEntity("开启失败",HttpStatus.NO_CONTENT);
        }
        return responseEntity;
    }

    @RequestMapping("stop")
    public ResponseEntity stop(){
        try {
            SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();
            serialPortUtil.removeListener(PortInit.serialPort,new MyLister());
            serialPortUtil.closePort(PortInit.serialPort);

            responseEntity = new ResponseEntity("关闭成功",HttpStatus.OK);
        }catch (Exception e){
            responseEntity = new ResponseEntity("关闭失败",HttpStatus.NO_CONTENT);
        }
        return responseEntity;
    }

}