如何通过Modbus访问实时测量数据

通过保罗聪明|更新日期:04/07/2016 |评论:13

搜索博客


订阅博客

设置你的首选项,当有新的博客文章发布时,你会收到与你的兴趣领域相匹配的电子邮件通知。


区域/应用程序

产品类别

活动

公司/新闻

请输入您的电子邮件地址:



显示一篇文章

你有想了解更多的话题吗?让我们知道。请尽量说得具体些。

让这个字段为空

网络通讯协议

您是否知道您可以将Campbell Scientific Logger转换为Modbus TCP / IP服务器?你知道为什么这是一个好主意吗?坎贝尔科学数据记录器通常用作Modbus Server设备。这意味着数据记录器被配置为实现Modbus通信协议,并从Modbus客户端侦听Modbus轮询,例如SCADA(监督控制和数据采集)系统。将数据记录器转换为Modbus TCP / IP服务器是一种很好的方法,可以允许使用Modbus协议访问您的Live测量数据的系统。

为了更好地理解它是如何工作的,我们将通过一个示例练习来展示如何在CR1000数据记录器上实现Modbus协议的基本概念。我们将使用一个CR1000数据记录仪连接到SCADA系统。您可能还记得我们之前关于SCADA系统和Modbus的讨论“为什么Modbus很重要:简介”博客文章

Modbus通信与模拟测量和数据记录器到SCADA系统

开始

在我们的示例中,CR1000被编程为测量电池电压,面板温度和简单程序中的模拟测量,如下所示:

'Program for a CR1000 Series Datalogger 'Declare Public Variables Public PTemp, batt_volt, analog_meas 'Data Table Definition DataTable (Table1,1,-1) DataInterval (0,10,Min,10) Minimum (1,batt_volt,FP2,0,False) Average (1,PTemp,FP2,False) Average (1,analog_meas,FP2,False) EndTable '主程序BeginProg Scan (1,Sec,0,0)'测量数据记录器面板温度PanelTemp (PTemp,250)电池电压(batt_volt)'测量模拟电压电压(1,mV5000,1,1,0,_60Hz,1.0,0)'调用最终存储表CallTable Table1 NextScan EndProg

Modbus编程

在我们的例子中,CR1000数据记录器使用NL121以太网接口.因此,我们需要对数据记录器进行编程,以便在适当的通信端口上侦听Modbus轮询,并使用最新的测量数据进行响应。要做到这一点,我们需要ModbusSlave ()指令,声明一个变量数组来保存我们的Modbus数据,然后使用我们的测量更新该数组。

这是使用以下代码完成的:

声明公共变量公共PTemp, batt_volt, analog_meas公共ModbusRegisters(3)公共Modbuscoil作为布尔值'数据表定义DataTable(Table1,1,-1)Datainerval(0,10,Min,10)最小(1,Batt_Volt,FP2,0,False)平均(1,PTEMP,FP2,FALSE)平均(1,Analog_MEAS,FP2,FALSE)最终的主程序BENGPROG'将数据记录器配置为Modbus从站modbusslave(502,0,1,modbusregisters(),modbuscoil,2)扫描(1秒,0,0)'测量数据记录器面板温度PanelTemp (PTemp,250)电池电压(batt_volt)'测量模拟电压电压(1,mV5000,1,1,0,_60Hz,1.0,0)“填充Modbus寄存器ModbusRegisters (1) = PTempModbusRegisters(2)= BATT_VOLTModbusRegisters(3)= Ampum_MEAS'调用最终存储表CallTable Table1 NextScan EndProg

更仔细的观察

让我们仔细看看ModbusSlave ()我们添加到程序代码中的指令。指令被添加到BeginProg.扫描语句。的ModbusSlave ()在这两个语句之间放置指令,因为它只需要在编译时执行一次而不是在每次扫描期间执行。

ModbusSlave ()指令包含六个参数,如下图所示:

ModbusSlave(相称,波特率,ModbusAddr、ModbusVariable BooleanVar, ModbusOption)

作为参考,在我们的程序代码中,带参数的指令如下所示:

modbusslave(502,0,1,modbusregisters(),modbuscoil,2)

让我们仔细看看那些参数以及它们的意思:

  • 适合:这个参数定义了数据记录器监听Modbus轮询的通信端口。在我们的示例中,我们使用502.,因为我们使用的是以太网连接502.为默认的Modbus TCP端口。

  • 波特率:我们使用这个参数来设置通信端口的波特率。在我们的例子中,这个参数(0)被忽略,因为我们的通信通过以太网连接。

  • ModbusAddr:此参数设置数据记录器的Modbus地址(或设备ID)。在我们的示例中,我们将数据记录器设置为具有地址1

  • ModbusVariable:我们使用这个参数来定义数据记录器的Modbus寄存器映射。(Modbus Map定义了可用数据的寄存器地址。)

    存储在该阵列中的测量用作Modbus输入和保持寄存器。(寄存器是16位内存位置。)数据记录器不区分输入和保持寄存器。因为我们已宣布为浮点数(32位),因此它将分布在两个Modbus寄存器中(每个16位)。在我们的示例中,我们的Modbus地图如下所示:

    Modbus寄存器 测量描述 单位

    1,2

    数据记录仪面板

    摄氏度

    3,4.

    数据记录器电池电压

    5、6

    模拟测量

    毫伏

  • ModbusBooleanVar:该参数用于定义Modbus Coil Map,当Modbus客户端设备向数据记录仪发送离散开/关命令时(01 Read Coil/Port Status, 02 Read Input Status, 05 Force Single Coil/Port, 15 Force Multiple Coil/ Ports),该参数用于定义Modbus Coil Map,用于保存Modbus客户端设备向数据记录仪发送离散开/关命令的结果。

    如果一个0输入此参数,将离散命令映射到数据记录器控制端口C1至C8,并且生成编译警告。在我们的示例中,我创建了一个充当线圈的变量。

  • modbusoption:这是一个可选参数,用于定义Modbus变量的数据类型和字节顺序。在我们的示例中,我选择使用Byte订单ABCD格式化Modbus Map Floate Point变量。

结论

上面的示例练习概述了如何通过在CRBasic中编程CR1000数据记录器来实现一个简单的Modbus TCP/IP服务器实现。请注意快捷程序生成器也有能力生成我们上面讨论的代码。通过利用上面展示的概念,您可以向您的程序以及数据记录器的Modbus Register Map添加更多的测量值。其结果是,您的SCADA系统可以访问实时测量数据,以实现更完整的气象站实现。

您可以期待未来的博客文章,其中有关于特定Modbus主题、常见陷阱和最佳实践的更多细节。与此同时,分享您下面的任何Modbus评论或问题


分享这篇文章



关于作者

保罗聪明Paul Smart是Campbell Scientific, Inc.的销售和营销副总裁。万博matex网页登录他第一次使用坎贝尔设备是在大学毕业后不久,当时他正在国际空间站进行一系列植物种植实验。Paul喜欢利用独特的Campbell科学技术来解决具有挑战性的测量问题。他拥有电气工程学士学位和工商管理硕士学位。保罗也喜欢户外活动,飞蝇钓鱼,和家人呆在一起。

查看作者的所有文章。


评论

raichlebw|2016/05/10在05:41 PM

你好,

到目前为止,我一直在尝试在CR1000上设置Modbus TCP服务器,而且到目前为止没有成功。我正在使用ASPIUS获取8810 Modbus TCP客户端测试服务器,尚未与记录器/服务器建立通信。我们在这里的Modbus非常好,但不如网络通信那么好。

问题......

1) ModBusSlave的ComPort参数设置为502,NL121应该连接到哪个物理端口?我猜是RS-232端口。有趣的是,无论这两种可能的答案(RS-232, CS I/O)是哪种情况,都会有ModBus TCP通过串行电缆传输。

2)将ModBusSlave的ComPort参数设置为coms232, CR1000是ModBus RTU服务器吗?为了避免与TCP服务器的混淆,必须这样做,但我在任何Campbell文献中都没有看到RTU。

谢谢,

布莱恩

保罗聪明|10/06/2016在PM 03:23

嗨Brian,

您使用的是NL201而不是NL121吗?NL121只能连接到数据记录器的外设端口,而NL201可以连接到数据记录器的RS-232端口或CSI/O端口。

如果您正在使用NL201,那么您将需要将NL201配置为网桥模式或Modbus TCP网关。如果您将它配置为Modbus TCP网关,那么您的数据记录器将需要使用适当的端口(RS232或CSI/O),并将功能作为RTU。如果NL201设置为网桥模式,将其连接到数据采集器的CSI/O端口,并使用ModbusSlave指令中的502端口。RTU和Modbus TCP/IP是由ModbusSlave指令中的端口选择决定的。请确保ModbusSlave指令中的波特率和端口与NL201的设置相匹配。

我建议使用设备配置实用程序查看NL201的设置。

有关可用选项的信息,请参阅设备配置实用程序中的帮助。帮助解释所有这些比我刚才做的更好:)

我希望这能有所帮助,

保罗

ariklee|02/23/2018 04:25 PM

Paul你好,关于CR1000x作为以太网Modbus从站的几个问题:

1.502端口是否由Modbus主机设置?我是否应该与客户确认他们确实在使用502,还是不能更改?

2.您的Modbuscoil参数是一个值Boolean,而在Campbell在Modbus Slave的应用笔记中,它们使用了一个8值布尔数组。我有点困惑。(在我的应用程序中,主人不应该发送任何命令01,02,05或15.这是否重要?)

3.你能推荐Windows 10的modbus主模拟器吗(除了modbus Poll)?

保罗聪明|02/28/2018 08:08 PM

嗨Ariklee,

端口502是通常使用的默认端口。数据记录器可以使用其他端口,但您需要与主服务器确认它与数据记录器正在使用的端口匹配。

如果您希望主设备在数据记录器中设置这些线圈,则可以使用8值布尔数组。但是,在我的程序中,我不期待这一点,所以我只是使用一个价值。这样做的唯一原因是在我编译程序时避免警告。如果您没有使用这些线圈,那么无关紧要。

我和一些使用ModScan来替代Modbus Poll的客户谈过,但我自己没有使用过。

保罗

Geoprojektas.|03/11/2018 01:39 AM

亲爱的保罗,

对于ModBUS标准,测量数据在Slave设备中存储在四个不同的表中:

设备地址:描述:

10000……线圈输出

10001年20000年……线圈的输入

30001年40000年……输入寄存器

40001 ... 50000控股寄存器

测量数据将存储在哪里modbusregisters()在你的计划中?

40001 - 40006注册吗?

谢谢,

Gintaris

保罗聪明|03/12/2018在08:22 AM

嗨Gintaris,

是的,没错。测量值也将填充输入寄存器。

保罗

Geoprojektas.|03/13/2018在09:25 AM

谢谢你,保罗

斯图亚亚|07/24/2018在PM 05:42

保罗,

在本文的最后,您提到可以使用ShortCut生成modbus代码。我已经给了它一个第一次尝试,但还没有能够看到无论如何做的快捷方式。有什么明显是我遗漏的吗?

也表示

阿拉斯Zaatreh|01/27/2019 01:07 PM

嗨,保罗,

是否可以将CR1000x配置为Modbus TCP Master?

GaryTRoberts|02/04/2019上午09:17

anas,

是的,CR1000X可以设置为Modbus TCP Master。与其在ModBusMaster()指令的ComPort参数中使用ComXXX,不如使用TCPOpen()创建的套接字句柄。

ctorrogrosa.|04/15/2020 06:19 PM

你好,

我有CR300,我尝试了Modbus Slave的样例代码描述在:https://help.campbellsci.com/crbasic/cr300/#instructions/modbusslave.htm,它工作正常。

问题是,手册和网络上的说明没有正确地解释哪些寄存器是可以咨询Modbus Slave的寄存器。

我找到的解决方案是加载Modbus Master示例并查看设备查询。

最后,适合我的代码是:

ModbusSlave (coms232,19200,3, ModIn (), Port ())

得到2个参数为:

03030000000445 eb
03:地址
03:函数->持有寄存器
00000004:两个参数
445EB:CRC.

ModbusSlave的反应是:
03030800000000797 a41b896c8
03:地址
03:函数->持有寄存器
08: Msg长度-> 8字节
00000000: (Mid-Little Endian (CDAB)) -> 00000000 (IEEE 754): 0.0000 (voltage) no connected =)
797A41B8 :(中小型联邦(CDAB)) - > 41B8797A(IEEE 754):23.0593(温度)
96 c8: CRC

我希望这为其他人提供了同样的怀疑。

阿拉斯Zaatreh|12/20/2020 07:23 AM

嗨,保罗,

使用CR1000x作为modbus客户端,标签的数量有限制吗?我要从modbus rtu读取1600个标签。

罗宾·D|12/22/2020在下午01:57

谢谢你的问题,Anas。我们的专家在这里分享了这样的回答:1600个标签不会达到硬性限制。内存是唯一的硬限制,但它高于1600。传输这么多数据值所花费的时间将限制数据更新的频率。

登录或注册置评。

我们在社交媒体上很活跃!
通过在这些平台上关注我们,了解我们的最新消息:

Baidu