0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

安卓與串口通信入門之modbus(下)

jf_78858299 ? 來源:Android技術(shù)之家 ? 作者:Android技術(shù)之家 ? 2023-04-23 17:40 ? 次閱讀

在安卓中使用 Modbus

經(jīng)過上面的介紹,相信大家已經(jīng)對于 Modbus 有了一個大致的了解。

那么,如何在安卓中使用 Modbus 呢?如果你理解了 Modbus 的基礎(chǔ),并且前面的兩篇文章也大致理解了,那么這就不是問題了。

核心思路就是通過上篇文章介紹的使用 android-serialport-api 或使用 USB Host 的方法打開串口,并獲取到輸入輸出流,然后在發(fā)送和接收數(shù)據(jù)時按照 Modbus 協(xié)議標準封裝或解析即可。

其中如何打開串口以及獲取輸入輸出流已經(jīng)在上篇文章介紹,因此現(xiàn)在需要解決的是如何封裝/解析數(shù)據(jù)。

當然,你可以按照 Modbus 標準文檔自己動手寫一個。

或者,你也可以不用重復造輪子,直接使用現(xiàn)成的第三方庫。

這里我們可以使用 modbus4j,但是,從它的名字就可以看出來,這是一個 java 庫,好在我們只需要使用它的解析和封裝的功能,所以在安卓中依舊可以使用。

modbus4j

老規(guī)矩,使用 modbus4j 前需要先引入依賴:

// 添加倉庫地址
repositories {
  ...
  maven { url 'https://jitpack.io' }
}


……
// 添加依賴
implementation 'com.github.MangoAutomation:modbus4j:3.1.0'

然后在正式使用之前,我們需要新建一個類繼承自 SerialPortWrapper ,用于實現(xiàn)在安卓上的串口功能:


class AndroidWrapper : SerialPortWrapper {
    // 關(guān)閉串口
    override fun close() {
        TODO("Not yet implemented")
    }


    // 打開串口
    override fun open() {
        TODO("Not yet implemented")
    }


    // 獲取輸入流
    override fun getInputStream(): InputStream {
        TODO("Not yet implemented")
    }


    // 獲取輸出流
    override fun getOutputStream(): OutputStream {
        TODO("Not yet implemented")
    }


    // 獲取波特率
    override fun getBaudRate(): Int {
        TODO("Not yet implemented")
    }


    // 獲取數(shù)據(jù)位
    override fun getDataBits(): Int {
        TODO("Not yet implemented")
    }


    // 獲取停止位
    override fun getStopBits(): Int {
        TODO("Not yet implemented")
    }


    // 獲取校驗位
    override fun getParity(): Int {
        TODO("Not yet implemented")
    }
}

在我們新建的這個類中重寫上述幾個方法,用于提供串口通信所需要的幾個參數(shù)即可。

然后,初始化 modbus4j 并發(fā)送消息:


val modbusFactory = ModbusFactory()


val wrapper: SerialPortWrapper = AndroidWrapper()


// 創(chuàng)建管理對象
val master = modbusFactory.createRtuMaster(wrapper)

// 發(fā)送消息
val request = ……
val response = master.send(request) // requst 為要發(fā)送的數(shù)據(jù),response 為接收到的響應(yīng)數(shù)據(jù)

上面就是 modbus4j 的簡單使用方法,如果同學們甚至都不想自己去完成串口通信的話,還可以用這個庫 Modbus4Android ,這個庫基于 android-serialport-api 和 上面的 modbus4j 封裝了一個安卓上到手即用的 Modbus 庫。

不過它使用的是 android-serialport-api 實現(xiàn)串口通信,如果需要使用 USB Host 的話可能還是需要自己去封裝一個庫了。(等我找到合適的測試設(shè)備后抽空我也封裝一個)

并且,這個庫使用了 RxJava 如果不喜歡 RxJava 的話也得自己封裝一個了,其實封裝起來也不算難,完全可以基于這個庫自己改一改就好了。

Modbus4Android

使用這個庫的第一步,依舊是導入依賴:

// 添加遠程倉庫
repositories {
   maven { url 'https://jitpack.io' }
}


……


// 添加依賴
dependencies {
   implementation 'com.github.licheedev:Modbus4Android:2.0.2'
}

接下來,為了方便使用,同時為了避免重復初始化,我們可以創(chuàng)建一個全局單例實例 ModbusManager


class ModbusManager : ModbusWorker() {






    /**
     * 釋放整個ModbusManager,單例會被置null
     */
    @Synchronized
    override fun release() {
        super.release()
        sInstance = null
    }


    companion object {
        @Volatile
        private var sInstance: ModbusManager? = null
        fun getInstance(): ModbusManager {
            var manager = sInstance
            if (manager == null) {
                synchronized(ModbusManager::class.java) {
                    manager = sInstance
                    if (manager == null) {
                        manager = ModbusManager()
                        sInstance = manager
                    }
                }
            }
            return manager!!
        }
    }
}
復制代碼

然后初始化串口連接:


private fun initConnect(): Boolean {
    Log.i(TAG, "initConnect: 開始初始化連接 Modbus\\nconfig=$config")


    val param = SerialParam
        .create(config.serialPath, config.serialRate) // 串口地址和波特率
        .setDataBits(config.serialDataBits) // 數(shù)據(jù)位
        .setParity(config.serialParity) // 校驗位
        .setStopBits(config.serialStopBits) // 停止位
        .setTimeout(config.serialTimeout)  //超時時間
        .setRetries(config.serialRetries) // 重試次數(shù)


    try {
        // 初始化前先關(guān)閉,避免串口已經(jīng)被打開過
        ModbusManager.getInstance().closeModbusMaster()
        val modbusMaster = ModbusManager.getInstance().syncInit(param)
        return true
        // 初始化(打開串口)成功
    } catch (e: ModbusInitException) {
        Log.e(TAG, "initConnect: 初始化modbus出錯!", e)
    } catch (e: InterruptedException) {
        Log.e(TAG, "initConnect: 初始化modbus出錯!", e)
    } catch (e: ExecutionException) {
        Log.e(TAG, "initConnect: 初始化modbus出錯!", e)
    } catch (e: ModbusTransportException) {
        Log.e(TAG, "initConnect: 初始化modbus出錯!", e)
    } catch (e: ModbusRespException) {
        Log.e(TAG, "initConnect: 初始化modbus出錯!", e)
    }
    return false
}

完成上述步驟后,我們就可以開始發(fā)送請求并接收數(shù)據(jù)了。

這里依舊以讀取線圈數(shù)據(jù)為例,我們可以使用同步請求:


val slaveId = 1 // 從站地址
val start = 00001 // 讀取的起始位置
val len = 1 // 需要讀取的長度


val response = ModbusManager.getInstance().syncReadCoil(slaveId, start, len)

其中的 response即為響應(yīng)數(shù)據(jù)信息

另外,我們也可以使用異步讀取的方式:

ModbusManager.getInstance().readCoil(slaveId, start, len, object : ModbusCallback

該庫支持的所有讀取方法如下:

圖片

所有寫數(shù)據(jù)方法如下:

圖片

總結(jié)

我們在這篇文章中介紹了在安卓中使用串口通信時大概率會接觸到的一種應(yīng)用層協(xié)議 -- Modbus,并講解了如何在安卓中使用 Modbus ,另外介紹了幾個個人認為比較好用的第三方庫。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • MODBUS
    +關(guān)注

    關(guān)注

    28

    文章

    1757

    瀏覽量

    76760
  • 串口通信
    +關(guān)注

    關(guān)注

    34

    文章

    1607

    瀏覽量

    55381
  • 安卓
    +關(guān)注

    關(guān)注

    5

    文章

    2116

    瀏覽量

    56960
收藏 人收藏

    評論

    相關(guān)推薦

    入門

    入門必備?。。。。。。。。。。。。?!
    發(fā)表于 03-11 10:53

    為何選擇智炫胎壓監(jiān)測?

    本帖最后由 recheid 于 2016-9-24 14:39 編輯 一、目前市場接大屏導航的胎壓監(jiān)測分為兩種第一種:串口通信胎壓監(jiān)測。
    發(fā)表于 09-24 10:21

    板子用什么樣的藍牙串口通信程序遙控

    問問各位的板子用什么樣的藍牙串口通信程序遙控?
    發(fā)表于 07-17 06:58

    與ESP8266串口WIFI模塊的通信實現(xiàn)相關(guān)資料推薦

    Button分別對應(yīng)相應(yīng)的功能鍵。通信實現(xiàn)原理使用基于tcp協(xié)議的socket通信。串口WiFi模塊配置成tcp Service模式,然后
    發(fā)表于 01-18 08:34

    HAL庫入門串口通信學習經(jīng)驗分享

    HAL庫入門串口通信學習經(jīng)驗分享
    發(fā)表于 02-15 06:56

    設(shè)備如何通過USB與多串設(shè)備通信?

    本Demo僅適用于支持USB Host功能的設(shè)備與單個CH9342/CH9344多串設(shè)備通信。 點擊Scan按鈕,掃描并顯示多串設(shè)備,如下圖所示 點擊打開相應(yīng)的設(shè)備,將自動獲取串口
    發(fā)表于 07-11 07:47

    QNX操作系統(tǒng)Modbus串口通信設(shè)計

    在分析QNX 設(shè)備驅(qū)動程序體系結(jié)構(gòu)和Modbus 協(xié)議的基礎(chǔ)上,提出QNX 操作系統(tǒng)串行接口設(shè)備驅(qū)動程序設(shè)計的一般方法,用C語言設(shè)計Modbus 在QNX 串口
    發(fā)表于 12-13 17:11 ?33次下載

    單片機串口通信485modbus

    單片機串口通信485modbus.doc單片機串口通信485modbus.doc
    發(fā)表于 07-12 10:42 ?131次下載

    基于QNX操作系統(tǒng)Modbus串口通信設(shè)計

    基于QNX操作系統(tǒng)Modbus串口通信設(shè)計
    發(fā)表于 10-30 14:51 ?16次下載
    基于QNX操作系統(tǒng)<b class='flag-5'>下</b>的<b class='flag-5'>Modbus</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>設(shè)計

    【HAL庫】串口通信

    HAL庫入門串口通信學習經(jīng)驗分享
    發(fā)表于 12-16 16:58 ?5次下載
    【HAL庫】<b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    用單片機串口modbus poll 進行通信

    由于程序中我的stm32單片機都是做的從機來和主機進行通信的,都是modbus協(xié)議通過串口來實現(xiàn)通信的。之前為了調(diào)通串口,所以用的是單片機的
    發(fā)表于 12-28 20:04 ?23次下載
    用單片機<b class='flag-5'>串口</b>和<b class='flag-5'>modbus</b> poll 進行<b class='flag-5'>通信</b>

    串口通信入門modbus(上)

    在之前的兩篇文章中,我們講解了串口的基礎(chǔ)知識和在中使用串口通信的方法,如果還沒看過之前文章的同學們,建議先看一遍,不然可能會不理解這篇文
    的頭像 發(fā)表于 04-23 17:40 ?1842次閱讀
    <b class='flag-5'>安</b><b class='flag-5'>卓</b>與<b class='flag-5'>串口</b><b class='flag-5'>通信</b><b class='flag-5'>入門</b><b class='flag-5'>之</b><b class='flag-5'>modbus</b>(上)

    端的串口通信實踐講解2

    這篇文章我們將講解端的串口通信實踐,即如何使用串口通信實現(xiàn)
    的頭像 發(fā)表于 04-23 17:59 ?1639次閱讀
    <b class='flag-5'>安</b><b class='flag-5'>卓</b>端的<b class='flag-5'>串口</b><b class='flag-5'>通信</b>實踐講解2

    端的串口通信實踐講解1

    這篇文章我們將講解端的串口通信實踐,即如何使用串口通信實現(xiàn)
    的頭像 發(fā)表于 04-23 17:59 ?2900次閱讀
    <b class='flag-5'>安</b><b class='flag-5'>卓</b>端的<b class='flag-5'>串口</b><b class='flag-5'>通信</b>實踐講解1

    串口Modbus教程1_入門教程V1.0

    串口Modbus教程1_入門教程V1.0
    發(fā)表于 04-29 13:29 ?21次下載