Java服务开发者眼中的Modbus及设备接入

本文介绍了ModBus协议的基本特征,针对Java开发者如何在应用中接入工业设备,包括设备映射、信息帧发送、应答帧监听和数据解析的开发思路,以及如何处理半双工通信和CRC校验。
摘要由CSDN通过智能技术生成

1、简介

        ModBus是一种免费的、易于维护的总线通信协议,广泛应用于工业电子化设备通信中,我们日常接触较为频繁的是RS485协议与ModBus-RTU协议,RS-485为硬件层,ModBus为软件层协议。

        各种设备只要遵循该协议,我们就可以按照该协议制定设备数据接入方案。本文主要从一个Java应用开发者初次接入Modbus协议的角度来基本阐述该协议的基本特征,以便在应用中接入该类设备,并从中读取相应的数据,提供相应的开发思路(数据网关)。

        本文只提供相应的开发思路,面向有一定基础的开发人员,具体的代码实现可GPT。

2、特点

        从使用角度来说,Modbus具有免费、简单轻便、易于开发等特征。而从技术角度来看,Modbus在通信模式上主要为主从模式(master/slave),或者理解为半双工模式(双方在一条总线上进行数据交互,同一时刻只允许一个方向的信息流),同时ModBus是面向寄存器进行数据交互的,在信息帧上有特定的规则。


3、常见的名词及解释

        1)主站从站:也有叫主机从机的,由一台主站及多个从站组成,主站可进行单播或广播模式通信,从站有自己特定的设备标识1-255,主站通过特定的标识由特定的信道向从站发送请求,从站在接收到请求后,由该信道向主站发送请求结果,地址码为0时为广播,从站不作答,并且从站不向主站主动发送请求。

        2)信息帧:也叫数据帧,由特定规则组成的数据帧,包括地址码、功能码、数据区、CRC冗余循环码等,具体规则见下文

        3)波特率:串口通信频率,指每秒传输的Bit数量,比如,波特率9600,指每秒可以传输9600个字节,双方通信要指定相同的波特率,否则无法正常的通信

 4、信息帧规则

        Modbus与RS485一样,都拥有自己的信息帧规则,具体的如下     

4.1、地址位

        从站的设备标识,0-255的范围,其中0表示该通信为主站广播,从站不回应;若为1-255,则表示主站向指定的从站发送通信,从站也需要携带自己的地址位向主站回复

4.2、功能码

        协议规定的部分功能代码,最常用的有03、06

                03:查询某些寄存器的数据

                06:修改某些寄存器的数据

4.3、数据区

        通信过程中的主要数据,根据不同的功能码,有相应的格式要求,比如03的查询,会要求指定寄存器及寄存器数量

4.4、校验位

        CRC冗余循环校验,信息接收方通过该校验位与信息帧中某些区段数据进行计算,来判定该通信数据的准确性,采用除法+余数的方式来进行计算(本文不具体阐述)。具体场景中,可根据对应厂商的采取的CRC算法,直接在线搜索计算工具即可。

        使用注意,在线工具计算结果一般以高位低位排序,但主从站发送数据帧则一般以低位高位排序,注意顺序。

4.5、场景举例说明

        目前有一个温湿度传感器,地址为1,其中温度数据在第5、6寄存器内,湿度在第7、8寄存器内,请求与响应数据表现为,其中CRC校验算法采用CRC-16(根据实际场景具体应用):

        读取温度:

        主站问询帧:01030501336C(16进制描述)

                0X01:从站地址

                0X03:查询功能码

                0X05:从第5个寄存器开始读

                0X01:读一个,读到06,为双闭合,体现为要读取的寄存器个数-1

                0X33:CRC冗余校验低位

                0X6C:CRC冗余校验高位

        从站应答帧:010302090BDBD3(16进制描述)

                 0X01:从站地址

                 0X03:查询功能码

                 0X02:数据长度

                 090B:温度数据,转10进制为2315/100=23.15度(具体参考厂商说明)

                 0XDB:CRC冗余校验低位

                 0XD3:CRC冗余校验高位

       读取温湿度(多寄存器读取):

                与单指标数据读取类似,即读取多个寄存器数据,分别处理应答帧数据区数据。

                主站问询帧:01030503B2AD(16进制描述),即从第5个寄存器开始读3个(共四个)

                从站应答帧:010304090B1203DFCC     

                        0103:从站地址+查询功能码

                        0X04:数据长度

                        090B:温度数据

                        1203:湿度数据,转十进制4611/100=46.11%(具体参考厂商说明)

                        DFCC:CRC用于校验低高位

5、开发思路

        整体上使用开发机(充当主站)利用串口与从站设备进行数据交互,将信息帧点对点或广播到从站,并从主站获取到各从站的应答帧,解析应答数据并进行应用,主要分为设备映射、信息帧发送与应答帧监听、数据解析三个主要模块。

        实际应用中,厂商一般会提供数据网关,服务平台接入数据网关API,即可快速获取各从站设备数据(一般要额外购买设备,不在本文讨论范围,本文主要讲如何直接接入设备,类似自己开发数据网关)。

5.1、设备映射

        通过设计平台设备(逻辑设备)与IOT设备(物理设备)的映射关系,例如,可将通过设备组中MD(主设备MasterDevice)与SD(子设备SlaveDevice)概念关系与物理设备中主站从站概念结合,将从站设备地址与子设备DeviceID进行绑定,从而得到相应的设备数据。如下图:

5.2、信息帧发送与应答帧监听

        开发机作为主站时通过串口(com口)与各从站进行通信,而串口无法直接与从站进行通信(协议不一致),上文已经说明,一般来说ModBus设备使用RS-485物理层协议进行通信,所以这时需要一个串口转RS-485的转换模块(USB转RS-485模块)来进行协议转换。

        Java开发上使用RXTX包进行通信开发,该包不在openJDK内,需要自己准备,并将其引入到工程中。

        注意:

        1)ModBus协议是半双工模式,点对点模式一定是先发送询问帧,然后等待应答帧,以间隔时间为完成标识(波特率,相当于对讲机的over机制),RXTX中有相应的配置,在应答帧未完全接收完成时,继续发送询问帧,一定报错。广播模式从站不应答,即无需等待。

        2)串口,在windows中叫com口,在设置-硬件管理-串口中可以看到相应的串口名称,在RXTX包中直接写com口名称即可(例如com3),而linux/mac中以串口文件/dev/ttys*为名称。

        3)建议将问询帧作为配置项封装到相应子设备中,便于调试维护

        4)建议线程与设备组进行绑定,以便进行后续的数据解析

5.3、数据解析

        该模块主要负责解析应答帧中的数据区数据,根据厂商提供的规则,将应答帧的16进制数据转换为相应可读数据。

        同时建议将应答帧规则作为配置封装到相应子设备中,使用script脚本运行,便于调试维护。

        以伪代码的形式描述如下:

// 运行代码
public void run(){

    // 线程池
    ThreadPool pool;

    // 遍历设备组
    for(DeviceGroup group: groups){

        // 构建运行规则
        Rule rule = new Rule();
        rule.build(group);
        // 获取运行线程
        Thread thread = pool.getThread();
        rule.setThread(thread);
        // 运行
        rule.run();
    }

}



// 运行规则定义
public class Rule{

   // 绑定线程
   Thread bindThread;

   // 设备组
   DeviceGroup group;

   // 监听线程
   Thread listenerThread;

   // 问询脚本
   Script askScript;

   // 设备映射路由
   Map<String, SubDevice> subDeviceRoute;

   // 构建规则
   // 线程赋值
   // 脚本编译
   // 路由构建
   public void build(){

      ....
   }

   
   // 运行
   public void run(){
       // 监听器上下文
       Listener listener = new Listener();
       ListenerContext context = new ListenerContext();
       // 绑定线程及映射路由
       context.setBindThread(bindThread);
       context.setSubDeviceRoute(subDeviceRoute);
       context.setThread(listenerThread);
       // 开启监听线程
       listener.execute(context);
       
       // 执行问询脚本
       ScriptExecute.execute(askScript);

       // 由监听线程的interrupt决定bindThread的inerrupt
       while(!listenerThread.getInerrupt()){
            sleep(500);
       }
   }
}

// 监听器,监听com口返回的应答帧数据
public class Listener{
   public void execute(ListenerContext context){
       // 监听到应答帧
       Message msg = getMessage();
       // 从路由中获取子设备
       SubDevice subDevice = context.getSubDeviceRoute.get(msg.getAddress);
       // 执行子设备的解析脚本
       ScriptExecute.execute(subDevice,msg);
   }
}

        

                

  • 27
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
接入支付宝App支付的详细步骤如下: 1. 创建支付宝开发者账号:首先,您需要在支付宝开放平台注册一个开发者账号,并完成实名认证。 2. 创建应用:登录支付宝开放平台,创建一个新的应用,获取对应的AppID。 3. 配置应用信息:配置应用的基本信息,包括应用名称、应用图标、回调地址等。 4. 下载SDK:下载支付宝SDK,其中包含了接入所需的相关库文件和示例代码。 5. 导入SDK:将下载的SDK文件导入到您的项目中,并配置相关依赖。 6. 配置权限:在AndroidManifest.xml文件中,添加必要的权限配置,如网络访问权限、支付回调Activity等。 7. 实现支付逻辑:在您的代码中实现支付功能。以下是一个简单的示例代码: ```java import com.alipay.sdk.app.PayTask; public class AlipayUtil { // 向支付宝发起支付请求 public void requestAlipay(String orderInfo) { // 构造PayTask对象 PayTask task = new PayTask(YourActivity.this); // 调用支付接口,获取支付结果 String result = task.pay(orderInfo, true); // 处理支付结果 handleResult(result); } // 处理支付结果 private void handleResult(String result) { // 解析支付结果 PayResult payResult = new PayResult(result); // 获取支付结果状态码 String resultStatus = payResult.getResultStatus(); // 判断支付结果状态码 if (TextUtils.equals(resultStatus, "9000")) { // 支付成功 // TODO: 处理支付成功逻辑 } else { // 支付失败 // TODO: 处理支付失败逻辑 } } } ``` 请注意,以上代码中的`orderInfo`参数是您自己构建的支付订单信息,包括商品名称、订单号、金额等。您需要根据实际需求生成订单信息。 这是一个简单的接入支付宝App支付的流程和代码示例,具体实现还需要根据您的业务需求进行调整。还有其他一些细节和安全性的考虑,建议您参考支付宝官方文档进行更详细的了解和实现。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值