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