用 Modbus4Android 库实现手机 APP 对 Modbus-TCP 协议 PLC 的读写控制

在工业自动化领域,实现手机 APP 与 Modbus-TCP 协议的 PLC 之间的高效通信,能够极大地提升工业控制的便捷性与灵活性。本文将详细介绍如何借助 Modbus4Android 库,在特定开发环境下完成这一功能的实现。

一、开发环境搭建

本次开发选用的是 Android Studio 3.0.0,其安装包为 android-studio-ide-171.4408382-windows.exe。在安装过程中,需按照向导逐步进行操作,注意选择合适的安装路径以及配置相关环境变量。安装完成后,启动 Android Studio,它将为我们提供一个集成开发环境,方便进行 APP 的代码编写、调试等工作。

Java 环境采用的是 java version "1.8.0_181",安装包为 jdk-8u181-windows-x64.exe。安装 Java Development Kit(JDK)时,同样要留意安装路径的选择。安装完成后,需配置系统的环境变量,将 JDK 的安装路径添加到 Path 变量中,确保系统能够正确识别 Java 命令。这一步至关重要,因为 Android 开发依赖于 Java 环境,只有配置正确,Android Studio 才能正常运行并进行 Java 代码的编译和执行。

二、添加 Modbus4Android 库依赖

在 Android Studio 中创建项目后,需要引入 Modbus4Android 库,以便实现与 Modbus-TCP 设备的通信功能。打开项目的build.gradle文件,在dependencies闭包中添加implementation 'com.zgkxzx:modbus4And:1.0.0'(具体版本号可根据实际情况调整)。添加完成后,点击 Android Studio 界面上的 “Sync Now” 按钮,让项目同步依赖库。这一过程中,Gradle 会自动下载 Modbus4Android 库及其相关依赖,并将它们添加到项目中,使我们能够在代码中使用该库提供的功能。

三、APP 功能实现

(一)界面设计

APP 的界面设计参考activity_main.xml文件,整体采用LinearLayout线性布局,且垂直排列。

  1. 标题栏:使用TextView组件显示 “ModbusTcp 调试小工具 V1.0”,用于明确应用的名称和用途,让用户一眼就能了解该 APP 的功能范畴。
  2. 数据显示区:通过多个TextView分别展示机器人的各种关键状态数据,包括当前位置、电机速度、电池电量、电池电流、电机 1 故障码以及电机 2 故障码等。这些TextView的布局和样式经过精心设计,以便清晰、直观地呈现数据,方便用户实时获取设备的运行状态信息。
  3. 功能按钮区:包含 “位置校准”“行走到此”“前进”“停止”“后退”“返航充电” 等多个按钮。每个按钮都对应着特定的控制指令,用户点击这些按钮,即可向 PLC 发送相应的控制信号,实现对机器人的远程操作。按钮的设计注重用户体验,具有明显的视觉区分度,便于用户快速识别和操作。
  4. 速度调节区:利用SeekBar组件实现速度调节功能。用户可以通过滑动SeekBar来改变机器人的运行速度,这种交互方式简单直观,符合用户的操作习惯。SeekBar的进度值与机器人速度之间存在特定的映射关系,通过代码实现这种映射,从而实现对机器人速度的精确控制。
  5. 日志显示区:使用TextView展示 APP 与 PLC 的通信日志。该区域记录了连接状态、操作结果等重要信息,方便开发者在调试过程中查看通信过程中的各种情况,及时发现并解决可能出现的问题。同时,日志显示区的设置也有助于用户了解 APP 的操作历史和设备的响应情况。

(二)功能逻辑实现

  1. 初始化 Modbus 连接:在MainActivityonCreate方法中调用modbusInit方法来初始化 Modbus 连接。

收起

java

private void modbusInit() {
    ModbusReq.getInstance().setParam(new ModbusParam()
      .setHost("192.168.0.19")
      .setPort(502)
      .setEncapsulated(false)
      .setKeepAlive(true)
      .setTimeout(2000)
      .setRetries(0))
      .init(new OnRequestBack<String>() {
        @Override
        public void onSuccess(String s) {
            Log.d(TAG, "onSuccess " + s);
            tvRunLogs.setTextColor(Color.GREEN);
            tvRunLogs.setText("连接PLC成功!ModbusTcp服务器IP地址192.168.0.19,端口502");
            tvRunLogs.requestLayout();
            mb_connected = true;
        }
        @Override
        public void onFailed(String msg) {
            Log.d(TAG, "onFailed " + msg);
            tvRunLogs.setTextColor(Color.RED);
            tvRunLogs.setText("连接192.168.0.19:502失败!请确保手机WIFI已连接到机器人调试网络环境!");
            mb_connected = false;
        }
    });
}

在上述代码中,首先创建ModbusParam对象,通过该对象配置连接 PLC 所需的各项参数,如 PLC 的 IP 地址("192.168.0.19")、端口号(502)、是否封装(false)、心跳设置(开启)、超时时间(2000 毫秒)以及重试次数(0 次)。然后调用init方法进行连接初始化,并通过OnRequestBack回调接口处理连接结果。连接成功时,在日志显示区用绿色字体显示成功信息,并设置连接成功标志位mb_connectedtrue;连接失败时,则用红色字体显示错误信息,并将mb_connected设置为false
2. 定时读取寄存器数据:借助HandlerRunnable实现定时任务,每隔 500 毫秒读取一次 PLC 的保持寄存器数据。

收起

java

private void readHoldingRegistersPeriodically() {
    ModbusReq.getInstance().readHoldingRegisters(new OnRequestBack<short[]>() {
        @Override
        public void onSuccess(short[] data) {
            Log.d(TAG, "定时读取寄存器数据成功: " + Arrays.toString(data));
            int originalInt = ((data[1] & 0xFFFF) << 16) | (data[2] & 0xFFFF);
            m_position = (float) originalInt;
            m_batt_soc  = data[10];
            m_batt_curr = (float)((short)data[12]) / 10;  //电池电量
            m_speed_actual = (float)((short)data[29])*0.30f /3000; //电机速度
            // 其他数据解析...
            updateTextViews();
            if (++m_heatbeat_count > 10)  ///心跳下发
            {
                m_heatbeat_count = 0;
                WriteHeartbeat();
            }
        }
        @Override
        public void onFailed(String msg) {
            Log.e(TAG, "定时读取寄存器数据失败: " + msg);
            mb_connected = false;
            tvRunLogs.setTextColor(Color.RED);
            tvRunLogs.setText("连接已断开!请确保手机WIFI已连接到机器人调试网络环境!");
        }
    }, 1, 1000, 40);
}

readHoldingRegistersPeriodically方法中,调用ModbusReq.getInstance().readHoldingRegisters方法读取从地址 1000 开始的 40 个保持寄存器数据。读取成功后,根据寄存器数据的定义和协议规范,解析出当前位置、电池电量、电机速度等关键信息,并更新相应的成员变量。接着调用updateTextViews方法,将解析后的数据更新到界面上的TextView组件中,实现数据的实时显示。同时,在代码中还设置了心跳机制,当心跳计数m_heatbeat_count超过 10 时,将其重置为 0 并发送心跳包,以维持与 PLC 的稳定连接。若读取数据失败,记录错误日志,将连接状态标志位mb_connected设置为false,并在日志显示区用红色字体提示用户连接已断开,要求用户检查网络连接。
3. 写入寄存器控制机器人运动:以 “前进” 按钮的点击事件处理方法MoveFrontClickEvent为例,展示如何通过写入寄存器来控制机器人运动。

收起

java

public void MoveFrontClickEvent(View view) {
    ModbusReq.getInstance().writeRegisters(new OnRequestBack<String>() {
        @Override
        public void onSuccess(String s) {
            Log.e(TAG, "MoveFront onSuccess " + s);
            tvRunLogs.setTextColor(Color.GREEN);
            tvRunLogs.setText("前进命令写入成功!");
        }
        @Override
        public void onFailed(String msg) {
            Log.e(TAG, "MoveFront onFailed " + msg);
            tvRunLogs.setTextColor(Color.RED);
            tvRunLogs.setText("前进命令写入失败!");
        }
    }, 1, 1101, new short[]{(short)((-3000)*seekBarProgress/100), 3, 0,0});
}

在该方法中,根据SeekBar的当前进度值seekBarProgress计算出机器人的前进速度,按照协议规定,将速度值以及相关命令字等信息封装成short数组。然后调用ModbusReq.getInstance().writeRegisters方法,向 PLC 的地址 1101 写入这些数据。当写入操作成功时,在日志显示区用绿色字体显示 “前进命令写入成功!”;若写入失败,则用红色字体显示错误信息,方便用户和开发者了解操作结果。类似地,“后退”“停止” 等其他控制按钮的功能实现原理与之相似,只是写入的速度值和命令字根据不同的操作需求进行相应调整。
4. 位置校准和行走到此功能:这两个功能通过弹出AlertDialog对话框,获取用户输入的位置值,并在用户确认后进行相应的寄存器写入操作。

收起

java

public void locationCalibrationClickEvent(View view) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("位置校准(单位mm)");
    final EditText input = new EditText(this);
    builder.setView(input);
    builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            String inputText = input.getText().toString();
            try {
                int position = Integer.parseInt(inputText);
                short[] values = new short[]{(short) (position >> 16),(short) position };
                ModbusReq.getInstance().writeRegisters(new OnRequestBack<String>() {
                    @Override
                    public void onSucc
用户可以根据需求在驱动里选择相对应的通讯驱动程序,配置相应的通讯握手参数,自由定义需要控制和采集的变量名、通讯地址、数据类型和初始值。功能说明及图片展示: 1.安装完成首次进入将会显示三页功能简要展示页面。 2.点击“立即使用”按钮,进入登录界面(公测账户为admin,密码admin)。 3.登录成功进入APP主页,此时主页所有状态为初始未配置状态。 4.在主页状态下向右滑动,可打开功能模块选择列表。 5.点击“WIFI连接”进入连接现场设备网络页面,如果此时用户已通过手机WIFI页面连接现场设备,则直接跳过此步骤。 6.连接成功后返回功能模块选择列表,点击“参数设置”进入通讯相关参数配置页面(首先进入驱动配置页面),目前驱动中只有支持Modbus TCP的驱动,后续会持续更新,用户通过在驱动列表中长按操作将选中的驱动挑选至已选列表中,如果要取消,可以在已选列表中通过同样的长按操作完成。 7.配置要访问的设备通讯参数,与主页的操作逻辑一致,在驱动配置页面向右滑动打开配置功能列表,点击“通讯参数配置”进入通讯参数配置页,然后点击右上角的加号,此时软件会根据已选的驱动类型自动添加一条相对应的通讯参数,用户可以通过双击的方式打开修改列表,然后在列表的某一条参数处通过长按的方式进入最终的修改对话框,修改完成后,可以通过长按的方式选定当前需要的参数配置信息到已选区域。 8.通讯参数配置完成后,向右滑动进入配置功能列表,点击“IO参数配置”进入地址段的分配,点击右上角的加号,在弹出的对话框中根据实际需求分配响应的起始地址以及地址数量,分配完成后,可在屏幕右侧边缘向左滑动调出隐藏功能菜单,通过功能菜单可查看和修改配置地址段的功能对应的IO点信息。 9.所有配置完成后,可返回主页,此时主页显示当前配置的信息,其中“控制操作”功能可以通过按钮发送布尔值,操作逻辑为当前值为0时发送1,当前值为1时发送0,而“参数设置”功能通过对子项长按可以设置调出输入框设置相应的参数值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ytuan

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值