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

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

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

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

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

在安卓中使用 Modbus

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

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

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

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

當(dāng)然,你可以按照 Modbus 標(biāo)準(zhǔn)文檔自己動(dòng)手寫(xiě)一個(gè)。

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

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

modbus4j

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

// 添加倉(cāng)庫(kù)地址
repositories {
  ...
  maven { url 'https://jitpack.io' }
}


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

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


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


    // 打開(kāi)串口
    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")
    }


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

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

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


val modbusFactory = ModbusFactory()


val wrapper: SerialPortWrapper = AndroidWrapper()


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

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

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

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

并且,這個(gè)庫(kù)使用了 RxJava 如果不喜歡 RxJava 的話也得自己封裝一個(gè)了,其實(shí)封裝起來(lái)也不算難,完全可以基于這個(gè)庫(kù)自己改一改就好了。

Modbus4Android

使用這個(gè)庫(kù)的第一步,依舊是導(dǎo)入依賴:

// 添加遠(yuǎn)程倉(cāng)庫(kù)
repositories {
   maven { url 'https://jitpack.io' }
}


……


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

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


class ModbusManager : ModbusWorker() {






    /**
     * 釋放整個(gè)ModbusManager,單例會(huì)被置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!!
        }
    }
}
復(fù)制代碼

然后初始化串口連接:


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


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


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

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

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


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


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

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

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

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

該庫(kù)支持的所有讀取方法如下:

圖片

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

圖片

總結(jié)

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

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

    關(guān)注

    28

    文章

    1742

    瀏覽量

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

    關(guān)注

    34

    文章

    1604

    瀏覽量

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

    關(guān)注

    5

    文章

    2113

    瀏覽量

    56884
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    入門(mén)

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

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

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

    板子用什么樣的藍(lán)牙串口通信程序遙控

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

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

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

    HAL庫(kù)入門(mén)串口通信學(xué)習(xí)經(jīng)驗(yàn)分享

    HAL庫(kù)入門(mén)串口通信學(xué)習(xí)經(jīng)驗(yàn)分享
    發(fā)表于 02-15 06:56

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

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

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

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

    單片機(jī)串口通信485modbus

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

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

    基于QNX操作系統(tǒng)Modbus串口通信設(shè)計(jì)
    發(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è)計(jì)

    【HAL庫(kù)】串口通信

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

    用單片機(jī)串口modbus poll 進(jìn)行通信

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

    串口通信入門(mén)modbus(上)

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

    端的串口通信實(shí)踐講解2

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

    端的串口通信實(shí)踐講解1

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

    串口Modbus教程1_入門(mén)教程V1.0

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