JAVA串口開發幫助類分享-及寫在馬年末


摘要: 在系統集成開發過程中,存在着各式的傳輸途徑,其中串口經常因其安全性高獲得了數據安全傳輸的重用,通過串口傳輸可以從硬件上保證數據傳輸的單向性,這是其它介質所不具備的物理條件。下面我就串口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(appNametimeout);
                serialPort.setSerialPortParams(baudRatedataBitsstopBits,
                    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、年終總結大會
今天被榮幸的評為 今年的 公司優秀員工,在這一年里我作為項目經理兼系統架構師,圓滿完成一個較大項目,並順利通過系統集成項目管理師考試,不能不謂收獲頗多,感謝大家對我今年工作的肯定。在這里我要感謝我的項目團隊,謝工、盧工、王工、楊工、陳工、劉工,沒有大家這段時間的辛勤努力項目不能進展順利;感謝我的領導,沒有您的 支持與 幫助 我不能如此進步;感謝我的親愛的老婆,沒有你給的愛我不能每天都如此開心。我要在新的一年里,開足馬力,從技術上更清晰地把握系統架構前沿技術,從管理上更熟練地使用各項管理技能。






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM