java串口,Java串口開發

本文目錄一覽:

在java的web程序中怎麼使用串口通訊?

方法如下:

新建eclipse工程,添加comm.jar或者RXTXcomm.jar包。因為javacomm20-win32.zip包里有樣例SimpleRead.java,可以通過這個例子測試串口是否正確。

接收數據正確後,根據傳送接收雙方的協議,採用CRC循環校驗,根據傳輸的一方的校驗函數判定是否是正確傳輸。

把正確結束的數據解析,查看自己指定的通訊規則,然後解析。

插入資料庫,jdbc插入。

數據統計,定時統計每小時,每天,每月,每年的平均值,採用quartz服務來實現。

建立web工程,採用hibernate3,spring3,dwr技術把資料庫數據動態顯示,圖表採用jfreechart,以及AJAX的運用

java優點:

java是純面向對象編程的語言;

平台無關性 (一次編譯,到處運行;Write Once,Run Anywhere);

java提供了許多內置的類庫,通過這些類庫,簡化了開發人員的設計工作,同時縮短了項目開發時間;

提供了對Web應用開發的支持,例如,Applet,Servlet,和JSP可以用來開發Web應用程序,,Socket,RMI可以用來開發分散式應用程序的類庫;

去除了c++中難以理解,容易混淆的特性(如c++中的多繼承,頭文件,指針,結構,單元,運算符重載,虛擬基礎類,使得程序更加嚴謹,整潔。

編程技巧:Java串口通信簡介

嵌入式系統或感測器網路的很多應用和測試都需要通過PC機與嵌入式設備或感測器節點進行通信 其中 最常用的介面就是RS 串口和並口(鑒於USB介面的複雜性以及不需要很大的數據傳輸量 USB介面用在這裡還是顯得過於奢侈 況且目前除了SUN有一個支持USB的包之外 我還沒有看到其他直接支持USB的Java類庫) SUN的CommAPI分別提供了對常用的RS 串列埠和IEEE 並行埠通訊的支持 RS C(又稱EIA RS C 以下簡稱RS )是在 年由美國電子工業協會(EIA)聯合貝爾系統 數據機廠家及計算機終端生產廠家共同制定的用於串列通訊的標準 RS 是一個全雙工的通訊協議 它可以同時進行數據接收和發送的工作

常見的Java串口包

目前 常見的Java串口包有SUN在 年發布的串口通信API m jar(Windows下) m jar(Linux/Solaris);IBM的串口通信API以及一個開源的實現 鑒於在Windows下SUN的API比較常用以及IBM的實現和SUN的在API層面都是一樣的 那個開源的實現又不像兩家大廠的產品那樣讓人放心 這裡就只介紹SUN的串口通信API在Windows平台下的使用

串口包的安裝(Windows下)

到SUN的網站下載javam win zip 包含的東西如下所示

按照其使用說明(l)的說法 要想使用串口包進行串口通信 除了設置好環境變數之外 還要將win dll複製到 \bin目錄下;將m jar複製到 \lib;把m properties也同樣拷貝到 \lib目錄下 然而在真正運行使用串口包的時候 僅作這些是不夠的 因為通常當運行 java MyApp 的時候 是由JRE下的虛擬機啟動MyApp的 而我們只複製上述文件到JDK相應目錄下 所以應用程序將會提示找不到串口 解決這個問題的方法很簡單 我們只須將上面提到的文件放到JRE相應的目錄下就可以了

值得注意的是 在網路應用程序中使用串口API的時候 還會遇到其他更複雜問題 有興趣的話 你可以查看CSDN社區中 關於網頁上Applet用javam 讀取客戶端串口的問題 的帖子

串口API概覽

m CommPort

這是用於描述一個被底層系統支持的埠的抽象類 它包含一些高層的IO控制方法 這些方法對於所有不同的通訊埠來說是通用的 SerialPort 和ParallelPort都是它的子類 前者用於控制串列埠而後者用於控這並口 二者對於各自底層的物理埠都有不同的控制方法 這裡我們只關心SerialPort

m CommPortIdentifier

這個類主要用於對串口進行管理和設置 是對串口進行訪問控制的核心類 主要包括以下方法

l 確定是否有可用的通信埠

l 為IO操作打開通信埠

l 決定埠的所有權

l 處理埠所有權的爭用

l 管理埠所有權變化引發的事件(Event)

m SerialPort

這個類用於描述一個RS 串列通信埠的底層介面 它定義了串口通信所需的最小功能集 通過它 用戶可以直接對串口進行讀 寫及設置工作

串口API實例

大段的文字怎麼也不如一個小例子來的清晰 下面我們就一起看一下串口包自帶的例子 SerialDemo中的一小段代碼來加深對串口API核心類的使用方法的認識

列舉出本機所有可用串口

     void listPortChoices() { CommPortIdentifier portId; Enumeration en = CommPortIdentifier getPortIdentifiers(); // iterate through the ports while (en hasMoreElements()) { portId = (CommPortIdentifier) en nextElement(); if (portId getPortType() == CommPortIdentifier PORT_SERIAL) { System out println(portId getName()); } } portChoice select(parameters getPortName()); }

以上代碼可以列舉出當前系統所有可用的串口名稱 我的機器上輸出的結果是 和

串口參數的配置

串口一般有如下參數可以在該串口打開以前配置進行配置

包括波特率 輸入/輸出流控制 數據位數 停止位和齊偶校驗

SerialPort sPort; try { sPort setSerialPortParams(BaudRate Databits Stopbits Parity); //設置輸入/輸出控制流 sPort setFlowControlMode(FlowControlIn | FlowControlOut); } catch (UnsupportedCommOperationException e) {}

串口的讀寫

對串口讀寫之前需要先打開一個串口

     CommPortIdentifier portId = CommPortIdentifier getPortIdentifier(PortName); try { SerialPort sPort = (SerialPort) portId open( 串口所有者名稱  超時等待時間); } catch (PortInUseException e) {//如果埠被佔用就拋出這個異常 throw new SerialConnectionException(e getMessage()); } //用於對串口寫數據 OutputStream os = new BufferedOutputStream(sPort getOutputStream()); os write(int data); //用於從串口讀數據 InputStream is = new BufferedInputStream(sPort getInputStream()); int receivedData = is read();

讀出來的是int型 你可以把它轉換成需要的其他類型

這裡要注意的是 由於Java語言沒有無符號類型 即所有的類型都是帶符號的 在由byte到int的時候應該尤其注意 因為如果byte的最高位是 則轉成int類型時將用 來佔位 這樣 原本是 的byte類型的數變成int型就成了 這是很嚴重的問題 應該注意避免

串口通信的通用模式及其問題

終於嘮叨完我最討厭的基礎知識了 下面開始我們本次的重點 串口應用的研究 由於向串口寫數據很簡單 所以這裡我們只關注於從串口讀數據的情況 通常 串口通信應用程序有兩種模式 一種是實現SerialPortEventListener介面 監聽各種串口事件並作相應處理;另一種就是建立一個獨立的接收線程專門負責數據的接收 由於這兩種方法在某些情況下存在很嚴重的問題(至於什麼問題這裡先賣個關子J) 所以我的實現是採用第三種方法來解決這個問題

事件監聽模型

現在我們來看看事件監聽模型是如何運作的

l 首先需要在你的埠控制類(例如SManager)加上 implements SerialPortEventListener

l 在初始化時加入如下代碼

     try { SerialPort sPort addEventListener(SManager); } catch (TooManyListenersException e) { sPort close(); throw new SerialConnectionException( too many listeners added ); } sPort notifyOnDataAvailable(true);

l 覆寫public void serialEvent(SerialPortEvent e)方法 在其中對如下事件進行判斷

BI 通訊中斷

CD 載波檢測

CTS 清除發送

DATA_AVAILABLE 有數據到達

DSR 數據設備準備好

FE 幀錯誤

OE 溢位錯誤

OUTPUT_BUFFER_EMPTY 輸出緩衝區已清空

PE 奇偶校驗錯

RI  振鈴指示

一般最常用的就是DATA_AVAILABLE 串口有數據到達事件 也就是說當串口有數據到達時 你可以在serialEvent中接收並處理所收到的數據 然而在我的實踐中 遇到了一個十分嚴重的問題

首先描述一下我的實驗 我的應用程序需要接收感測器節點從串口發回的查詢數據 並將結果以圖標的形式顯示出來 串口設定的波特率是 川口每隔 毫秒返回一組數據(大約是 位元組左右) 周期(即持續時間)為 秒 實測的時候在一個周期內應該返回 多個位元組 而用事件監聽模型我最多只能收到不到 位元組 不知道這些位元組都跑哪裡去了 也不清楚到底丟失的是那部分數據 值得注意的是 這是我將serialEvent()中所有處理代碼都注掉 只剩下列印代碼所得的結果 數據丟失的如此嚴重是我所不能忍受的 於是我決定採用其他方法

串口讀數據的線程模型

這個模型顧名思義 就是將接收數據的操作寫成一個線程的形式:

      public void startReadingDataThread() { Thread readDataProcess = new Thread(new Runnable() { public void run() { while (newData !=  ) { try { newData = is read(); System out println(newData); //其他的處理過程 ……… } catch (IOException ex) { System err println(ex); return; } } readDataProcess start(); }

在我的應用程序中 我將收到的數據打包放到一個緩存中 然後啟動另一個線程從緩存中獲取並處理數據 兩個線程以生產者—消費者模式協同工作 數據的流向如下圖所示

這樣 我就圓滿解決了丟數據問題 然而 沒高興多久我就又發現了一個同樣嚴重的問題 雖然這回不再丟數據了 可是原本一個周期( 秒)之後 感測器節電已經停止傳送數據了 但我的串口線程依然在努力的執行讀串口操作 在控制台也可以看見收到的數據仍在不斷的列印 原來 由於感測器節點發送的數據過快 而我的接收線程處理不過來 所以InputStream就先把已到達卻還沒處理的位元組緩存起來 於是就導致了明明感測器節點已經不再發數據了 而控制台卻還能看見數據不斷列印這一奇怪的現象 唯一值得慶幸的是最後收到數據確實是 左右位元組 沒出現丟失現象 然而當處理完最後一個數據的時候已經快 分半鐘了 這個時間遠遠大於節點運行周期 這一延遲對於一個實時的顯示系統來說簡直是災難!

後來我想 是不是由於兩個線程之間的同步和通信導致了數據接收緩慢呢?於是我在接收線程的代碼中去掉了所有處理代碼 僅保留列印收到數據的語句 結果依然如故 看來並不是線程間的通信阻礙了數據的接收速度 而是用線程模型導致了對於發送端數據發送速率過快的情況下的數據接收延遲 這裡申明一點 就是對於數據發送速率不是如此快的情況下前面者兩種模型應該還是好用的 只是特殊情況還是應該特殊處理

第三種方法

痛苦了許久(Boss天天催我L)之後 偶然的機會 我聽說TinyOS中(又是開源的)有一部分是和我的應用程序類似的串口通信部分 於是我下載了它的 x版的Java代碼部分 參考了它的處理方法 解決問題的方法說穿了其實很簡單 就是從根源入手 根源不就是接收線程導致的嗎 那好 我就乾脆取消接收線程和作為中介的共享緩存 而直接在處理線程中調用串口讀數據的方法來解決問題(什麼 為什麼不把處理線程也一併取消? 都取消應用程序界面不就鎖死了嗎?所以必須保留)於是程序變成了這樣

public byte[] getPack(){ while (true) { // PacketLength為數據包長度 byte[] msgPack = new byte[PacketLength]; for(int i =  ; i  PacketLength; i++){ if( (newData = is read()) !=  ){ msgPack[i] = (byte) newData; System out println(msgPack[i]); } } return msgPack; } }

在處理線程中調用這個方法返回所需要的數據序列並處理之 這樣不但沒有丟失數據的現象行出現 也沒有數據接收延遲了 這裡唯一需要注意的就是當串口停止發送數據或沒有數據的時候is read()一直都返回 如果一旦在開始接收數據的時候發現 就不要理它 繼續接收 直到收到真正的數據為止

結束語

lishixinzhi/Article/program/Java/hx/201311/26605

java,串口CommPortIdentifier問題….

java打開串口的方法如下:

public SerialPort openPort(String port) {

        CommPortIdentifier portId = null;

        try {

            portId = (CommPortIdentifier)CommPortIdentifier.getPortIdentifier(port);

            return (SerialPort)portId.open(“SimpleWriteApp”, 0);

        } catch (NoSuchPortException e) {

           System.out.println(“找不到埠”);

            return null;

        } catch (PortInUseException e) {

            System.out.println(“埠被佔用”);

            return null;

        }

}

注意配置java串口所需的包及添加JRE

我的做法將串口封裝成一個類,有打開、關閉串口方法,讀寫數據方法,你可以參考

java串口通信中怎樣以十六進位數發送

做串口通訊的時候基本都是通過io流讀取、輸出。那麼在java開發中發送數據的時候使用OutputStream,而其write()的參數是位元組數組、int整形。如果使用位元組數組發送的時候,通常可以直接寫成out.write(“1234”.getBytes())。這樣一來單片機讀到的數據則是31 32 33 34。但是在串口發送的時候先把16進位字元串轉化為byte數組在發送出來,則是發送什麼讀取到的就是什麼。使用:out.write(HexString2Bytes(“1234”));那麼讀取到的還是1234。16進位字元串轉化為byte數組的方法為:

public static byte[] HexString2Bytes(String src) {

if (null == src || 0 == src.length()) {

return null;

}

byte[] ret = new byte[src.length() / 2];

byte[] tmp = src.getBytes();

for (int i = 0; i (tmp.length / 2); i++) {

ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);

}

return ret;

}

在用java做串口開發的時候建議使用開源的Rxtx做。效率、使用方法都要優。使用sun開源的comm個人覺得不是很便利。rxtx網上有開源實例。可以根據自己個需求進行加以修飾利用。

java如何從串口讀取數據帶GUI

1.導入支持java串口通信的jar包:

在maven項目的pom.xml中添加RXTXcomm的依賴 或者 下載RXTXcomm.jar並導入到項目中。

支持Java串口通信操作的jar包,java.comm比較老,而且不支持64位系統,推薦使用Rxtx這個jar包(32位/64位均支持)。

注意:運行過程中拋出 java.lang.UnsatisfiedLinkError 錯誤或 gnu.io 下的類找不到時,將rxtx解壓包中的 rxtxParallel.dll,rxtxSerial.dll 這兩個文件複製到 C:\Windows\System32 目錄下可解決該錯誤。

2.編寫代碼操作串口:

串口必要參數類:包含連接串口所必須的參數,方便在調用串口時設置和傳遞串口參數。

java如何向串口發送指令?

需要一個包 comm.jar\x0d\x0a需要一個配置文件 javax.comm.properties (工程根目錄)\x0d\x0a(或者放在JDK里)\x0d\x0a// 取得埠句柄\x0d\x0aCommPortIdentifier id = CommPortIdentifier.getPortIdentifier(portName);\x0d\x0aport = (SerialPort) id .open(“SerialDemo”, 30000);\x0d\x0aport .setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);\x0d\x0a \x0d\x0aport .notifyOnDataAvailable(true);\x0d\x0aport .notifyOnBreakInterrupt(true);\x0d\x0aport .enableReceiveTimeout(delayTime);\x0d\x0a\x0d\x0a讀取之類的自己寫就行了,(port .getInputStream()),完事之後別忘了關掉埠,不然下次就不能用了,只能重啟系統 \x0d\x0a\x0d\x0a配置文件里就一行:\x0d\x0aDriver=com.sun.comm.Win32Driver \x0d\x0a\x0d\x0a———————————-\x0d\x0a你設個斷點單步調試看一下原因,那個SerialBean是你自己寫的,誰也不知道裡面整啥了,單步調試就知道哪裡錯誤。\x0d\x0a拋出異常了Exception in thread “main” java.lang.NullPointerException\x0d\x0a at serial.SerialBean.WritePort(SerialBean.java:114)\x0d\x0a從這裡看,是在SerialBean.java的114行(函數WritePort)的一個東西,它的值是null,所以報錯了

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/271551.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-16 14:56
下一篇 2024-12-16 14:56

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論