Java串口通信JSerialComm的實(shí)現(xiàn)
一、引入JSerialComm包
目前網(wǎng)上的Java串口通信主要使用RXTXComm,但是這個(gè)庫(kù)已經(jīng)很久沒(méi)有更新(最近的更新似乎在2012年),并且與JavaFX集成打包時(shí)會(huì)出現(xiàn)BUG。JSerialComm是一個(gè)較新的串口通信庫(kù),其主頁(yè)為jSerialComm (fazecast.github.io)。JSerialComm與平臺(tái)無(wú)關(guān),所以不需要配置dll文件,只需要引入jar文件即可使用,更為方便。
一、引入JSerialComm包
JSerialComm可以直接通過(guò)Maven引入,也可以復(fù)制jar包到lib目錄下直接使用。Maven的依賴可以在JSerialComm的主頁(yè)上看到,目前為:
<dependency> <groupId>com.fazecast</groupId> <artifactId>jSerialComm</artifactId> <version>[2.0.0,3.0.0)</version> </dependency>
主頁(yè)上同時(shí)也有其他類(lèi)型的引入方法

二、使用JSerialComm
2.1 尋找、設(shè)置、打開(kāi)及關(guān)閉串口
SerialPort[] serialPorts = SerialPort.getCommPorts();//查找所有串口
for(SerialPort port:serialPorts){
System.out.println("Port:"+port.getSystemPortName());//打印串口名稱,如COM4
System.out.println("PortDesc:"+port.getPortDescription());//打印串口類(lèi)型,如USB Serial
System.out.println("PortDesc:"+port.getDescriptivePortName());//打印串口的完整類(lèi)型,如USB-SERIAL CH340(COM4)
}
SerialPort serialPort = serialPorts[0];//獲取到第一個(gè)串口
serialPort.setBaudRate(112500);//設(shè)置波特率為112500
serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING | SerialPort.TIMEOUT_WRITE_BLOCKING, 1000, 1000);//設(shè)置超時(shí)
serialPort.serRTS();//設(shè)置RTS。也可以設(shè)置DTR
serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);//設(shè)置串口的控制流,可以設(shè)置為disabled,或者CTS, RTS/CTS, DSR, DTR/DSR, Xon, Xoff, Xon/Xoff等
serialPort.setComPortParameters(112500, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);//一次性設(shè)置所有的串口參數(shù),第一個(gè)參數(shù)為波特率,默認(rèn)9600;第二個(gè)參數(shù)為每一位的大小,默認(rèn)8,可以輸入5到8之間的值;第三個(gè)參數(shù)為停止位大小,只接受內(nèi)置常量,可以選擇(ONE_STOP_BIT, ONE_POINT_FIVE_STOP_BITS, TWO_STOP_BITS);第四位為校驗(yàn)位,同樣只接受內(nèi)置常量,可以選擇 NO_PARITY, EVEN_PARITY, ODD_PARITY, MARK_PARITY,SPACE_PARITY。
if(!serialPort.isOpen){
boolean isCommOpeded = serialPort.openPort()//判斷串口是否打開(kāi),如果沒(méi)打開(kāi),就打開(kāi)串口。打開(kāi)串口的函數(shù)會(huì)返回一個(gè)boolean值,用于表明串口是否成功打開(kāi)了
}
serialPort.closePort();//關(guān)閉串口。該函數(shù)同樣會(huì)返回一個(gè)boolean值,表明串口是否成功關(guān)閉
2.2 發(fā)送及接收數(shù)據(jù)
數(shù)據(jù)的發(fā)送函數(shù)是SerialPort.writeBytes(byte[] bytes,int length),第一個(gè)參數(shù)是要發(fā)送的字節(jié)數(shù)組,第二個(gè)參數(shù)是要發(fā)送的數(shù)據(jù)長(zhǎng)度。
數(shù)據(jù)的讀取函數(shù)是SerialPort.readBytes(byte[] bytes,int length),第一個(gè)參數(shù)是要將數(shù)據(jù)讀入的字節(jié)數(shù)組,第二個(gè)參數(shù)是要接收的數(shù)據(jù)長(zhǎng)度。
可以用SerialPort.bytesAvailable來(lái)獲取目前串口中可以讀取的字符長(zhǎng)度。如果目前沒(méi)有可讀取的數(shù)據(jù),則會(huì)返回-1
使用示例如下
if(serialPort.isOpen()){
String writeData = "hello world";//要發(fā)送的字符串
byte[] bytes = writeData.getBytes();//將字符串轉(zhuǎn)換為字節(jié)數(shù)組
serialPort.writeBytes(bytes,bytes.length);//將字節(jié)數(shù)組全部寫(xiě)入串口
Thread.sleep(100);//休眠0.1秒,等待下位機(jī)返回?cái)?shù)據(jù)。如果不休眠直接讀取,有可能無(wú)法成功讀到數(shù)據(jù)
String readData = "";
while(port.bytesAvailable>0){//循環(huán)讀取所有的返回?cái)?shù)據(jù)。如果可讀取數(shù)據(jù)長(zhǎng)度為0或-1,則停止讀取
byte[] newData = new byte[port.bytesAvailable()];//創(chuàng)建一個(gè)字節(jié)數(shù)組,長(zhǎng)度為可讀取的字節(jié)長(zhǎng)度
int numRead = port.readBytes(newData, newData.length);//將串口中可讀取的數(shù)據(jù)讀入字節(jié)數(shù)組,返回值為本次讀取到的字節(jié)長(zhǎng)度
String newDataString = new String(newData);//將新數(shù)據(jù)轉(zhuǎn)為字符串
readData = readData + newDataString;//組合字符串
Thread.sleep(20);//休眠0.02秒,等待下位機(jī)傳送數(shù)據(jù)到串口。如果不休眠,直接再次使用port.bytesAvailable()函數(shù)會(huì)因?yàn)橄挛粰C(jī)還沒(méi)有返回?cái)?shù)據(jù)而返回-1,并跳出循環(huán)導(dǎo)致數(shù)據(jù)沒(méi)讀完。休眠時(shí)間可以自行調(diào)試,時(shí)間越長(zhǎng),單次讀取到的數(shù)據(jù)越多。
}
System.out.println("readString:"+readData);
}
2.3 監(jiān)聽(tīng)串口
可以對(duì)串口添加一個(gè)監(jiān)聽(tīng)器來(lái)實(shí)時(shí)監(jiān)聽(tīng)串口。監(jiān)聽(tīng)器位于一個(gè)獨(dú)立的線程,使用時(shí)需要注意多線程通信的問(wèn)題;
if(serialPort.isOpen){
serialPort.addDataListener(new SerialPortDataListener() {//添加監(jiān)聽(tīng)器。由于該監(jiān)聽(tīng)器有兩個(gè)函數(shù),無(wú)法使用Lambda表達(dá)式
@Override
public int getListeningEvents() {
// TODO Auto-generated method stub
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;//返回要監(jiān)聽(tīng)的事件類(lèi)型,以供回調(diào)函數(shù)使用。可發(fā)回的事件包括:SerialPort.LISTENING_EVENT_DATA_AVAILABLE,SerialPort.LISTENING_EVENT_DATA_WRITTEN,SerialPort.LISTENING_EVENT_DATA_RECEIVED。分別對(duì)應(yīng)有數(shù)據(jù)在串口(不論是讀的還是寫(xiě)的),有數(shù)據(jù)寫(xiě)入串口,從串口讀取數(shù)據(jù)。如果AVAILABLE和RECEIVED同時(shí)被監(jiān)聽(tīng),優(yōu)先觸發(fā)RECEIVED
}
@Override
public void serialEvent(SerialPortEvent event) {//事件處理函數(shù)
// TODO Auto-generated method stub
String data = "";
if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE){
return;//判斷事件的類(lèi)型
}
while(port.bytesAvailable()!=0) {
byte[] newData = new byte[port.bytesAvailable()];
int numRead = port.readBytes(newData, newData.length);
String newDataString = new String(newData);
data = data + string;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}//同樣使用循環(huán)讀取法讀取所有數(shù)據(jù)
//由于這里是監(jiān)聽(tīng)函數(shù),所以也可以不使用循環(huán)讀取法,在監(jiān)聽(tīng)器外創(chuàng)建一個(gè)全局變量,然后將每次讀取到的數(shù)據(jù)添加到全局變量里
}
})
}
到此這篇關(guān)于Java串口通信JSerialComm的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java串口通信JSerialComm內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springBoot?@Scheduled實(shí)現(xiàn)多個(gè)任務(wù)同時(shí)開(kāi)始執(zhí)行
這篇文章主要介紹了springBoot?@Scheduled實(shí)現(xiàn)多個(gè)任務(wù)同時(shí)開(kāi)始執(zhí)行,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
java學(xué)習(xí)之理解自動(dòng)拆裝箱特性
這篇文章主要介紹java自動(dòng)拆裝箱特性以及java自動(dòng)拆裝箱的應(yīng)用,有需要的朋友可以借鑒參考下,希望可以有所幫助,祝大家早日升職加薪2021-09-09
使用Jackson-json解析一個(gè)嵌套的json字符串
這篇文章主要介紹了使用Jackson-json解析一個(gè)嵌套的json字符串,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
springboot新建項(xiàng)目pom.xml文件第一行報(bào)錯(cuò)的解決
這篇文章主要介紹了springboot新建項(xiàng)目pom.xml文件第一行報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
Java異常處理 Throwable實(shí)現(xiàn)方法解析
這篇文章主要介紹了Java異常處理 Throwable實(shí)現(xiàn)方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
SpringBoot優(yōu)雅實(shí)現(xiàn)計(jì)算方法執(zhí)行時(shí)間
這篇文章主要為大家詳細(xì)介紹了SpringBoot中優(yōu)雅實(shí)現(xiàn)計(jì)算方法執(zhí)行時(shí)間的相關(guān)方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-04-04

