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

打印 上一主题 下一主题

主题 913|帖子 913|积分 2739

在工业自动化范畴,实现手机 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线性结构,且垂直排列。


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



  • 初始化 Modbus 连接:在MainActivity的onCreate方法中调用modbusInit方法来初始化 Modbus 连接。

收起
java
  1. private void modbusInit() {
  2.     ModbusReq.getInstance().setParam(new ModbusParam()
  3.       .setHost("192.168.0.19")
  4.       .setPort(502)
  5.       .setEncapsulated(false)
  6.       .setKeepAlive(true)
  7.       .setTimeout(2000)
  8.       .setRetries(0))
  9.       .init(new OnRequestBack<String>() {
  10.         @Override
  11.         public void onSuccess(String s) {
  12.             Log.d(TAG, "onSuccess " + s);
  13.             tvRunLogs.setTextColor(Color.GREEN);
  14.             tvRunLogs.setText("连接PLC成功!ModbusTcp服务器IP地址192.168.0.19,端口502");
  15.             tvRunLogs.requestLayout();
  16.             mb_connected = true;
  17.         }
  18.         @Override
  19.         public void onFailed(String msg) {
  20.             Log.d(TAG, "onFailed " + msg);
  21.             tvRunLogs.setTextColor(Color.RED);
  22.             tvRunLogs.setText("连接192.168.0.19:502失败!请确保手机WIFI已连接到机器人调试网络环境!");
  23.             mb_connected = false;
  24.         }
  25.     });
  26. }
复制代码

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

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

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

收起
java
  1. public void MoveFrontClickEvent(View view) {
  2.     ModbusReq.getInstance().writeRegisters(new OnRequestBack<String>() {
  3.         @Override
  4.         public void onSuccess(String s) {
  5.             Log.e(TAG, "MoveFront onSuccess " + s);
  6.             tvRunLogs.setTextColor(Color.GREEN);
  7.             tvRunLogs.setText("前进命令写入成功!");
  8.         }
  9.         @Override
  10.         public void onFailed(String msg) {
  11.             Log.e(TAG, "MoveFront onFailed " + msg);
  12.             tvRunLogs.setTextColor(Color.RED);
  13.             tvRunLogs.setText("前进命令写入失败!");
  14.         }
  15.     }, 1, 1101, new short[]{(short)((-3000)*seekBarProgress/100), 3, 0,0});
  16. }
复制代码

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

收起
java
  1. public void locationCalibrationClickEvent(View view) {
  2.     AlertDialog.Builder builder = new AlertDialog.Builder(this);
  3.     builder.setTitle("位置校准(单位mm)");
  4.     final EditText input = new EditText(this);
  5.     builder.setView(input);
  6.     builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
  7.         @Override
  8.         public void onClick(DialogInterface dialog, int which) {
  9.             String inputText = input.getText().toString();
  10.             try {
  11.                 int position = Integer.parseInt(inputText);
  12.                 short[] values = new short[]{(short) (position >> 16),(short) position };
  13.                 ModbusReq.getInstance().writeRegisters(new OnRequestBack<String>() {
  14.                     @Override
  15.                     public void onSucc
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

麻花痒

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表