最近做的專案要用到串口通信,和電子稱通信,第一次接觸,從網上找了一些代碼運行,都是運行幾分鐘(或更短)就報錯,錯誤資訊如下

日志錯誤資訊:
java.lang.NullPointerException
at bing.controller.ChaunkouController.readFromPort(ChaunkouController.java:248)
at bing.controller.ChaunkouController$DataAvailableListener.serialEvent(ChaunkouController.java:161)
at gnu.io.RXTXPort.sendEvent(RXTXPort.java:772)
at gnu.io.RXTXPort.eventLoop(Native Method)
at gnu.io.RXTXPort$MonitorThread.run(RXTXPort.java:1641)
private SerialPort mySerialport = null;
private static final int BAUDRATE = 9600;// 波特率,默認為9600
List<String> list = new ArrayList<>();
public static Dingdandao dingdandao = new Dingdandao();
XQcontroller xQcontroller = new XQcontroller();
/**
* 檢測并獲取當前設備所有的可用埠(此處可包括USB埠和藍牙埠)
*
* @return 回傳包含所有可用埠的名稱的串列(如COM4 、 COM6等)
* 可將回傳的串列依次輸出以查看
* 當然也可以通過‘設備管理器-埠’來查看可用埠
*/
public ArrayList<String> findPorts() {
// 呼叫jar包內的getPortIdentifiers函式,獲得當前所有可用埠的列舉
Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();
ArrayList<String> portNameList = new ArrayList<String>();
// 將可用埠名添加到List并回傳該List
while (portList.hasMoreElements()) {
String portName = portList.nextElement().getName();
portNameList.add(portName);
}
return portNameList;
}
/**
* 通過上一步獲取的埠名來打開串口并設定串口引數
*
* @param portName 埠名
* @param baudrate 波特率(需與電子秤的波特率一致,一般為9600,建議作為final宏觀常量放在程式開頭)
* @return 回傳打開的串口, 若非串口則回傳null
* @throws PortInUseException 當埠已被占用時拋出例外
*/
public SerialPort openPort(String portName, int baudrate) throws PortInUseException {
try {
// 通過埠名識別埠
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
// 打開埠,并給埠名字和一個timeout(打開操作的超時時間)
CommPort commPort = portIdentifier.open(portName, 2000);
// 判斷埠是不是串口
if (commPort instanceof SerialPort) {
SerialPort serialPort = (SerialPort) commPort;
try {
// 設定一下串口的波特率等引數
// 資料位:8
// 停止位:1
// 校驗位:None
serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
e.printStackTrace();
}
return serialPort;
}
} catch (NoSuchPortException e1) {
e1.printStackTrace();
}
return null;
}
/**
* 為打開的串口添加資料到達事件監聽、通信中斷監聽
*
* @param serialPort 已打開的串口
* @param listener 監聽器
*/
public void addListener(SerialPort serialPort, DataAvailableListener listener) {
try {
/**
* 給串口添加監聽器
* 函式addEventListener為jar包自帶函式
* 函式addEventListener的引數listener必須為SerialPortEventListener型別
* 所以DataAvailableListener必須實作SerialPortEventListener介面
*/
serialPort.addEventListener(listener);
// 設定當有資料到達時喚醒監聽接收執行緒
serialPort.notifyOnDataAvailable(true);
// 設定當通信中斷時喚醒中斷執行緒
serialPort.notifyOnBreakInterrupt(true);
} catch (TooManyListenersException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
}
/**
* 自定義監聽器,實作jar包中定義的SerialPortEventListener介面,并覆寫serialEvent方法
*/
public class DataAvailableListener implements SerialPortEventListener {
@Override
@FXML
synchronized public void serialEvent(SerialPortEvent serialPortEvent) {
/**
* 總共有10類事件可以監聽
* 此處只對兩類事件進行了反應和處理
*/
switch (serialPortEvent.getEventType()) {
case SerialPortEvent.DATA_AVAILABLE: //接收到資料事件
byte[] data;
try {
if (mySerialport == null) {
System.out.println("串口物件為空,監聽失敗!");
} else {
// 讀取串口資料
data = readFromPort(mySerialport);
// 將ASCII碼陣列轉化為對應的字串
String text = new String(data);
// 去除不必要的字符
text = text.replaceAll(" ", "");
text = text.replaceAll("\r", "");
text = text.replaceAll("\n", "");
text = text.replaceAll("\t", "");
if (text.length() > 0) {
//將處理后的重量資訊列印輸出
//textdao.setText(text);
// zhongliang=text;
System.out.println(text);
ckzhongliang.setText(text);
//jiaoyizhongliang.setText(text);
// weight.setText(text);
}
}
} catch (Exception e) {
System.out.println(e.toString());
// 發生讀取錯誤時顯示錯誤資訊后退出系統
}
break;
case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2.輸出緩沖區已清空
break;
case SerialPortEvent.CTS: // 3.清除待發送資料
break;
case SerialPortEvent.DSR: // 4.待發送資料準備好了
break;
case SerialPortEvent.RI: // 5.振鈴指示
break;
case SerialPortEvent.CD: // 6.載波檢測
break;
case SerialPortEvent.OE: // 7.溢位(溢位)錯誤
break;
case SerialPortEvent.PE: // 8.奇偶校驗錯誤
break;
case SerialPortEvent.FE: // 9.幀錯誤
break;
case SerialPortEvent.BI: // 10.通訊中斷
System.out.println("與串口設備通訊中斷");
break;
default:
break;
}
}
}
/**
* 從串口中按位元組讀取收到的資料
*
* @param serialPort 打開后有資料傳達的串口
* @return 以位元組陣列的形式回傳收到的資料資訊
*/
public byte[] readFromPort(SerialPort serialPort) {
InputStream in = null;
byte[] bytes = {};// 采用位元組陣列保存傳來的ASCII碼值,方便之后轉化為字串
try {
in = serialPort.getInputStream();//得到串口輸入流
// 緩沖區大小為一個位元組
byte[] readBuffer = new byte[1];
int bytesNum = in.read(readBuffer);
while (bytesNum > 0) {
bytes = concat(bytes, readBuffer);
bytesNum = in.read(readBuffer);//將讀取到的二進制資料存于readBuffer并回傳讀取到的位元組數
} //按照位元組將資料加入到位元組陣列中
} catch (IOException e) {
restart(); //捕獲例外并讀取
} finally {
try {
if (in != null) {
in.close();
in = null;
}
} catch (IOException e) {
restart(); //捕獲例外并讀取
}
}
return bytes;
}
/**
* 將兩位元組陣列合并為同一個
*
* @param firstArray
* @param secondArray
* @return 回傳合并后的位元組陣列
*/
public byte[] concat(byte[] firstArray, byte[] secondArray) {
if (firstArray == null || secondArray == null) {
return null;
}
byte[] bytes = new byte[firstArray.length + secondArray.length];
System.arraycopy(firstArray, 0, bytes, 0, firstArray.length);
System.arraycopy(secondArray, 0, bytes, firstArray.length, secondArray.length);
return bytes;
}
private Thread restartThread = new Thread(new RestartThread());
public void restart() {
if (!restartThread.isAlive() || restartThread.isInterrupted()) {
restartThread.start();
}
}
class RestartThread implements Runnable {
public void run() {
while (true) {
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
closeSerialPort();
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
openSerialPort();
}
}
}
public void closeSerialPort() {
if (mySerialport != null) {
mySerialport.close();
}
mySerialport = null;
}
public void openSerialPort() {
String commName = null;
if (findPorts().size() > 0) {
// 獲取埠名稱,默認取第一個埠
commName = findPorts().get(0); // step_1
}
if (commName == null) { // 說明不存在可用埠
//textdao.setText("沒有搜尋到有效串口");
} else {
try {
mySerialport = openPort(commName, BAUDRATE); //step_2
if (mySerialport != null) {
System.out.println("串口已打開");
}
} catch (PortInUseException e) {
System.out.println("串口已被占用!");
}
// 添加串口監聽
addListener(mySerialport, new DataAvailableListener()); // step_3、step_4
}
}
在網上又搜不到這種錯誤,錯誤定位到105,180行。求助各位,我想知道這是怎么回事
uj5u.com熱心網友回復:
空指標錯誤,檢查下你發的資料是否有例外 決議出錯了uj5u.com熱心網友回復:
我沒發,只是接收資料,運行幾分鐘就拒絕訪問轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/242493.html
標籤:Java SE
