0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

安卓与串口通信入门之modbus(下)

jf_78858299 来源:Android技术之家 作者:Android技术之家 2023-04-23 17:40 次阅读

在安卓中使用 Modbus

经过上面的介绍,相信大家已经对于 Modbus 有了一个大致的了解。

那么,如何在安卓中使用 Modbus 呢?如果你理解了 Modbus 的基础,并且前面的两篇文章也大致理解了,那么这就不是问题了。

核心思路就是通过上篇文章介绍的使用 android-serialport-api 或使用 USB Host 的方法打开串口,并获取到输入输出流,然后在发送和接收数据时按照 Modbus 协议标准封装或解析即可。

其中如何打开串口以及获取输入输出流已经在上篇文章介绍,因此现在需要解决的是如何封装/解析数据。

当然,你可以按照 Modbus 标准文档自己动手写一个。

或者,你也可以不用重复造轮子,直接使用现成的第三方库。

这里我们可以使用 modbus4j,但是,从它的名字就可以看出来,这是一个 java 库,好在我们只需要使用它的解析和封装的功能,所以在安卓中依旧可以使用。

modbus4j

老规矩,使用 modbus4j 前需要先引入依赖:

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


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

然后在正式使用之前,我们需要新建一个类继承自 SerialPortWrapper ,用于实现在安卓上的串口功能:


class AndroidWrapper : SerialPortWrapper {
    // 关闭串口
    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")
    }


    // 获取数据位
    override fun getDataBits(): Int {
        TODO("Not yet implemented")
    }


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


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

在我们新建的这个类中重写上述几个方法,用于提供串口通信所需要的几个参数即可。

然后,初始化 modbus4j 并发送消息:


val modbusFactory = ModbusFactory()


val wrapper: SerialPortWrapper = AndroidWrapper()


// 创建管理对象
val master = modbusFactory.createRtuMaster(wrapper)

// 发送消息
val request = ……
val response = master.send(request) // requst 为要发送的数据,response 为接收到的响应数据

上面就是 modbus4j 的简单使用方法,如果同学们甚至都不想自己去完成串口通信的话,还可以用这个库 Modbus4Android ,这个库基于 android-serialport-api 和 上面的 modbus4j 封装了一个安卓上到手即用的 Modbus 库。

不过它使用的是 android-serialport-api 实现串口通信,如果需要使用 USB Host 的话可能还是需要自己去封装一个库了。(等我找到合适的测试设备后抽空我也封装一个)

并且,这个库使用了 RxJava 如果不喜欢 RxJava 的话也得自己封装一个了,其实封装起来也不算难,完全可以基于这个库自己改一改就好了。

Modbus4Android

使用这个库的第一步,依旧是导入依赖:

// 添加远程仓库
repositories {
   maven { url 'https://jitpack.io' }
}


……


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

接下来,为了方便使用,同时为了避免重复初始化,我们可以创建一个全局单例实例 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) // 数据位
        .setParity(config.serialParity) // 校验位
        .setStopBits(config.serialStopBits) // 停止位
        .setTimeout(config.serialTimeout)  //超时时间
        .setRetries(config.serialRetries) // 重试次数


    try {
        // 初始化前先关闭,避免串口已经被打开过
        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
}

完成上述步骤后,我们就可以开始发送请求并接收数据了。

这里依旧以读取线圈数据为例,我们可以使用同步请求:


val slaveId = 1 // 从站地址
val start = 00001 // 读取的起始位置
val len = 1 // 需要读取的长度


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

其中的 response即为响应数据信息

另外,我们也可以使用异步读取的方式:

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

该库支持的所有读取方法如下:

图片

所有写数据方法如下:

图片

总结

我们在这篇文章中介绍了在安卓中使用串口通信时大概率会接触到的一种应用层协议 -- Modbus,并讲解了如何在安卓中使用 Modbus ,另外介绍了几个个人认为比较好用的第三方库。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • MODBUS
    +关注

    关注

    28

    文章

    1803

    浏览量

    76971
  • 串口通信
    +关注

    关注

    34

    文章

    1624

    浏览量

    55514
  • 安卓
    +关注

    关注

    5

    文章

    2127

    浏览量

    57156
收藏 人收藏

    评论

    相关推荐

    入门

    入门必备!!!!!!!!!!!!!!
    发表于 03-11 10:53

    为何选择智炫胎压监测?

    本帖最后由 recheid 于 2016-9-24 14:39 编辑 一、目前市场接大屏导航的胎压监测分为两种第一种:串口通信胎压监测。
    发表于 09-24 10:21

    板子用什么样的蓝牙串口通信程序遥控

    问问各位的板子用什么样的蓝牙串口通信程序遥控?
    发表于 07-17 06:58

    与ESP8266串口WIFI模块的通信实现相关资料推荐

    Button分别对应相应的功能键。通信实现原理使用基于tcp协议的socket通信串口WiFi模块配置成tcp Service模式,然后
    发表于 01-18 08:34

    HAL库入门串口通信学习经验分享

    HAL库入门串口通信学习经验分享
    发表于 02-15 06:56

    设备如何通过USB与多串设备通信

    本Demo仅适用于支持USB Host功能的设备与单个CH9342/CH9344多串设备通信。 点击Scan按钮,扫描并显示多串设备,如下图所示 点击打开相应的设备,将自动获取串口
    发表于 07-11 07:47

    QNX操作系统Modbus串口通信设计

    在分析QNX 设备驱动程序体系结构和Modbus 协议的基础上,提出QNX 操作系统串行接口设备驱动程序设计的一般方法,用C语言设计Modbus 在QNX 串口
    发表于 12-13 17:11 33次下载

    单片机串口通信485modbus

    单片机串口通信485modbus.doc单片机串口通信485modbus.doc
    发表于 07-12 10:42 131次下载

    基于QNX操作系统Modbus串口通信设计

    基于QNX操作系统Modbus串口通信设计
    发表于 10-30 14:51 16次下载
    基于QNX操作系统<b class='flag-5'>下</b>的<b class='flag-5'>Modbus</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>设计

    【HAL库】串口通信

    HAL库入门串口通信学习经验分享
    发表于 12-16 16:58 5次下载
    【HAL库】<b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    用单片机串口modbus poll 进行通信

    由于程序中我的stm32单片机都是做的从机来和主机进行通信的,都是modbus协议通过串口来实现通信的。之前为了调通串口,所以用的是单片机的
    发表于 12-28 20:04 23次下载
    用单片机<b class='flag-5'>串口</b>和<b class='flag-5'>modbus</b> poll 进行<b class='flag-5'>通信</b>

    串口通信入门modbus(上)

    在之前的两篇文章中,我们讲解了串口的基础知识和在中使用串口通信的方法,如果还没看过之前文章的同学们,建议先看一遍,不然可能会不理解这篇文
    的头像 发表于 04-23 17:40 1924次阅读
    <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

    这篇文章我们将讲解端的串口通信实践,即如何使用串口通信实现
    的头像 发表于 04-23 17:59 1689次阅读
    <b class='flag-5'>安</b><b class='flag-5'>卓</b>端的<b class='flag-5'>串口</b><b class='flag-5'>通信</b>实践讲解2

    端的串口通信实践讲解1

    这篇文章我们将讲解端的串口通信实践,即如何使用串口通信实现
    的头像 发表于 04-23 17:59 2960次阅读
    <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
    发表于 04-29 13:29 21次下载