摘要: 在系统集成开发过程中,存在着各式的传输途径,其中串口经常因其安全性高获得了数据安全传输的重用,通过串口传输可以从硬件上保证数据传输的单向性,这是其它介质所不具备的物理条件。下面我就串口java开发的过程分享一下,并分享一个SerialPortHandler串口开发帮助类,以提高串口开发效率。并附带了一些近期的总结,出差的体会。

关键词: java, 串口, 经验, 年终总结
需求:  开发串口快速上手

 
1、部署开发环境。
拷贝RXTXcomm.jar 文件到 \jre\lib\ext 目录下,拷贝rxtxSerial.dll文件到 \jre\bin目录下。注意是jre目录下,并非jdk\jre下;注意dll有32位与64位之分,根据自己实际情况操作。
 
2、搭建调试助手。
Virtual Serial Port Driver(7.2)和串口调试助手(CM精装版V3.8.3)简直就是调试串口的一对好基友。Virtual Serial Port Driver可以看到当前所有串口的状态,还能虚拟出硬件不存在的串口出来,虚拟出的串口还是连接好的;串口调试助手可以看到某串口接收到的具体信息,还能向某串口发送信息。我就经常使用Virtual Serial Port Driver虚拟出一对串口COM3和COM4,然后打开两个串口调试助手,一个连接到COM3上,一个连接到COM4,然后在连接到COM3的串口调试助手上输入一段话,点击发送,则会在连接到COM4的串口调试助手上接收并显示此段话,相当于一个本机对话机有木有!
 
 
 
3、下面是我优化过后的串口调用处理器:
 
public class SerialPortHandler implements Runnable, SerialPortEventListener
{
    private String appName = "串口通讯";
    private final static int timeout = 2000;// open 端口时的等待时间
    private final static int dataBits = 8;// 数据位
    private final static int stopBits = 1;// 停止位
    private final static int parity = 0;// 校验位
    private String portName;
    private int baudRate;// 波特率
    private int threadTime = 0;
    private CommPortIdentifier commPort;
    private SerialPort serialPort;
    private InputStream inputStream;
    private OutputStream outputStream;
    private static ConcurrentHashMap<String, SerialPortHandler> instances = new ConcurrentHashMap<String, SerialPortHandler>();
 
    private SerialPortHandler()
    {
    }
 
    public static synchronized SerialPortHandler getInstance(String portName,
        int baudRate) throws NoSuchPortException
    {
        SerialPortHandler instance;
        if (!instances.containsKey(portName))
        {
            instance = new SerialPortHandler();
            instance.portName = portName;
            instance.baudRate = baudRate;
            instances.put(portName, instance);
            instance.selectPort();
        }
        else
        {
            instance = instances.get(portName);
        }
        return instance;
    }
 
    /**
     * @方法名称 :listPort
     * @功能描述 :列出所有可用的串口
     * @返回值类型 :void
     */
    public static void listPort()
    {
        CommPortIdentifier cpid;
        Enumeration en = CommPortIdentifier.getPortIdentifiers();
        System.out.println("now to list all Port of this PC:" + en);
        while (en.hasMoreElements())
        {
            cpid = (CommPortIdentifier) en.nextElement();
            if (cpid.getPortType() == CommPortIdentifier.PORT_SERIAL)
            {
                System.out.println(cpid.getName() + ", "
                    + cpid.getCurrentOwner());
            }
        }
    }
 
    /**
     * @方法名称 :selectPort
     * @功能描述 :选择一个端口,比如:COM1
     * @返回值类型 :void
     * @param portName
     * @throws NoSuchPortException
     */
    @SuppressWarnings("rawtypes")
    private void selectPort() throws NoSuchPortException
    {
        this.commPort = CommPortIdentifier.getPortIdentifier(portName);
        openPort();
    }
 
    /**
     * @方法名称 :openPort
     * @功能描述 :打开SerialPort
     * @返回值类型 :void
     */
    private void openPort()
    {
        if (commPort == null)
            log(String.format("无法找到名字为'%1$s'的串口!", commPort.getName()));
        else
        {
            log("端口选择成功,当前端口:" + commPort.getName() + ",现在实例化 SerialPort:");
            try
            {
                serialPort = (SerialPort) commPort.open(appName, timeout);
                serialPort.setSerialPortParams(baudRate, dataBits, stopBits,
                    parity);
                log("实例 SerialPort 成功!");
            }
            catch (PortInUseException e)
            {
                throw new RuntimeException(String.format("端口'%1$s'正在使用中!",
                    commPort.getName()));
            }
            catch (UnsupportedCommOperationException e)
            {
                throw new RuntimeException(String.format("端口'%1$s'操作命令不支持!",
                    commPort.getName()));
            }
        }
    }
 
    /**
     * @方法名称 :checkPort
     * @功能描述 :检查端口是否正确连接
     * @返回值类型 :void
     */
    private void checkPort()
    {
        if (commPort == null)
            throw new RuntimeException("没有选择端口,请使用 "
                + "selectPort(String portName) 方法选择端口");
 
        if (serialPort == null)
        {
            throw new RuntimeException("SerialPort 对象无效!");
        }
    }
 
    /**
     * @方法名称 :write
     * @功能描述 :向端口发送数据,请在调用此方法前 先选择端口,并确定SerialPort正常打开!
     * @返回值类型 :void
     * @param message
     */
    public void write(String message)
    {
        checkPort();
        try
        {
            outputStream = new BufferedOutputStream(
                serialPort.getOutputStream());
        }
        catch (IOException e)
        {
            throw new RuntimeException("获取端口的OutputStream出错:" + e.getMessage());
        }
        try
        {
            outputStream.write(message.getBytes());
            log("信息发送成功!");
        }
        catch (IOException e)
        {
            throw new RuntimeException("向端口发送信息时出错:" + e.getMessage());
        }
        finally
        {
            try
            {
                outputStream.close();
            }
            catch (Exception e)
            {
            }
        }

}
}

 
使用办法:
public static void sendBySerialPorts(String contant)
    {
        contant = contant.replaceAll("\\$", "");        // 这里使用$符号作为终止符

        contant = contant.concat("$");
        SerialPortHandler sph;
        try
        {
            sph = SerialPortHandler.getInstance(
                DriveOutConductConfig.getPortName(),
                DriveOutConductConfig.getBitRate());
            sph.write(contant);
        }
        catch (NoSuchPortException e)
        {
            e.printStackTrace();
        }

}

 
 
写在2014年马年末。
1、出差感受
在2014年末,我有幸跟随陈工、钟工到甘肃兰州出差,进行项目的现场部署与系统间联调,以及与客户、直接使用者进行面对面的交流与互动,感触良多。现场环境复杂,可能会遇到在开发环境中从未出现过的情况,因此在现场部署前,一定要做好大量的准备工作,避免意外;当然,智者千虑还必有一失,做好备案,面对紧急突发事件要知道如何解决,自己解决不了的要知道问谁。一定要做好系统的质量保证工作,不能在现场演示时出现低级错误,质量是抓住用户的救命稻草。用户是熟悉业务的能手,用心倾听用户需求,才能把握用户。
多系统协调的系统,系统关依赖性强,开发沟通很重要,开发成本也很高,部署时也最容易出错。讲一个故事,我们的系统会调用另一个系统的接口,在我们系统部署完毕后,与其它系统连接也完成后,在前端怎么也调用不成功,日志中写的是服务不可用,我们便以为是其它系统服务有问题;到后来,我们经过细致的排查,才发现,问题出在两系统间网络没有正确连接,最后是因为有一端网线端口没插紧,晕死。
兰州牛肉拉面是极好的,兰州手抓羊肉还是很鲜嫩的,甘肃的鸡汤面味道杠杠。
 
2、年终总结大会
今天被荣幸的评为今年的公司优秀员工,在这一年里我作为项目经理兼系统架构师,圆满完成一个较大项目,并顺利通过系统集成项目管理师考试,不能不谓收获颇多,感谢大家对我今年工作的肯定。在这里我要感谢我的项目团队,谢工、卢工、王工、杨工、陈工、刘工,没有大家这段时间的辛勤努力项目不能进展顺利;感谢我的领导,没有您的支持与帮助我不能如此进步;感谢我的亲爱的老婆,没有你给的爱我不能每天都如此开心。我要在新的一年里,开足马力,从技术上更清晰地把握系统架构前沿技术,从管理上更熟练地使用各项管理技能。

JAVA串口开发帮助类分享-及写在马年末的更多相关文章

  1. Java Web 开发利用Struts2+Spring+mybatis写一个用户登录界面以及简单的数据交互

    框架的东西太复杂也难以讲通,直接上代码: 一.首先得配置环境 和导入必要的jar包 有一些重要的如下: Filter文件夹下的SafetyFilter.java   model文件夹下的 Global ...

  2. java常用开发工具类之 图片水印,文字水印,缩放,补白工具类

    import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphic ...

  3. java ee开发常用类和接口

    1.javax.Validation接口,做mvc传入数据验证用 2.javax.servlet接口 3.javax.datasource接口 4.javax.session接口 5.javax.ht ...

  4. 近期Java高级开发岗面试总结

    原文出处:公众号:编程大道 作者:walking 近期Java高级开发岗面试总结 哈喽大家好,我是walking,这是我的公众号:编程大道. 很久没和大家见面了,文章更新的速度略有延后.这个公众号断断 ...

  5. 分享:写了一个 java 调用 C语言 开发的动态库的范例

    分享:写了一个 java 调用 C语言 开发的动态库的范例 cfunction.h   代码#pragma once#ifdef __cplusplusextern "C" {#e ...

  6. 分享 Java微信开发SDK

    分享 Java微信开发SDK •发布于 4周前  •作者 朋也  •432 次浏览  •最后一次编辑是 2周前  •来自 分享 给大家分享两个java开发微信公众号的sdk jfinal-weixin ...

  7. 自己写的java excel导出工具类

    最近项目要用到excel导出功能,之前也写过类似的代码.因为这次项目中多次用到excel导出.这次长了记性整理了一下 分享给大伙 欢迎一起讨论 生成excel的主工具类: public class E ...

  8. 【Java面试题】53 能不能自己写个类,也叫java.lang.String?

    可以,但是即使你写了这个类,也没有用. 这个问题涉及到加载器的委托机制,在类加载器的结构图(在下面)中,BootStrap是顶层父类,ExtClassLoader是BootStrap类的子类,ExtC ...

  9. 【分享】Java后台开发精选知识图谱

    地址 引言: 学习一个新的技术时,其实不在于跟着某个教程敲出了几行.几百行代码,这样你最多只能知其然而不知其所以然,进步缓慢且深度有限,最重要的是一开始就对整个学习路线有宏观.简洁的认识,确定大的学习 ...

随机推荐

  1. Hibernate 一对一映射(惟一外键)

  2. <数据挖掘导论>读书笔记2

    1.频率和众数 frequency(vi)=具有属性值vi的对象数/m 分类属性的众数mode是具有最高频率的值. 2.百分位数 3.位置度量:均值和中位数 4.散布度量:极差和方差 绝对平均偏差 A ...

  3. TypeLoadException: Could not load type 'Microsoft.AspNetCore.Mvc.Internal.IHttpResponseStreamWriterFactory' from assembly 'Microsoft.AspNetCore.Mvc.Core, Version=2.1.2.0 ...

    今天调试 asp.net core 2.0 项目时遇到了如下错误: TypeLoadException: Could not load type 'Microsoft.AspNetCore.Mvc.I ...

  4. [PY3]——内置数据结构(4)——字符串格式化(format)

    字符串格式化是拼接字符串的一种手段 join和+拼接字符串的方法,难以控制格式 printf style 字符串格式化 这种方法是从c语言继承过来的 # 待格式化的字符串:一个字符串存在占位符 In ...

  5. Map集合遍历的4种方法

    完全复制https://www.cnblogs.com/blest-future/p/4628871.html import java.util.HashMap; import java.util.I ...

  6. Git中.gitignore, 忽略追踪

    在目录下 创建: .gitignore文件,将不需要被追踪的文件地址, 写在该文件中, 此时git软件就不会追踪列出的文件进行版本同步: windows不允许创建没有文件名的文件,可以用编辑器创建.g ...

  7. Firebird Case-Insensitive Searching 大小写不敏感查找

    Firebird 默认是大小写敏感,在检索的时候. 要想不敏感检索,两种方法: 1.where upper(name) = upper(:flt_name) 2.检索时指定字符集collation,例 ...

  8. Silverlight & Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化、波感特效

    当我们在进行Silverlight & Blend进行动画设计的过程中,可能需要设计出很多效果不一的图形图像出来作为动画的基本组成元素.然而在设计过程中可能会出现许多的问题,比如当前绘制了一个 ...

  9. 利用canvas制作图片(可缩放和平移)+相框+文字

    前言: 公司一个售前问我能不能用H5做一个手机拍照,给相片添加相框和添加文字上传到服务器的功能,我当时一琢磨觉得可行,就利用空余时间做了一个demo,去掉了拍照和上传,如果以后有机会,会给补上,当然对 ...

  10. java 并发(五)---AbstractQueuedSynchronizer(4)

    问题 : rwl 的底层实现是什么,应用场景是什么 读写锁 ReentrantReadWriteLock 首先我们来了解一下 ReentrantReadWriteLock 的作用是什么?和 Reent ...