de Paul Smart | Atualizada: 04/07/2016 | Comentários: 24
Did you know that you can turn your Campbell Scientific data logger into a Modbus TCP/IP server? Do you know why that’s a good idea? Campbell Scientific data loggers are commonly used as Modbus server devices. This means that the data logger is configured to implement the Modbus communications protocol and listen for Modbus polls from a Modbus client, such as a SCADA (supervisory control and data acquisition) system. Turning your data logger into a Modbus TCP/IP server is a great way to allow systems that use the Modbus protocol to have access to your live measurement data.
To better understand how this works, we’ll go through an example exercise to show the basic concepts of how to implement the Modbus protocol on a CR1000 datalogger. We’ll use a CR1000 datalogger connected to a SCADA system. You may remember our previous discussion about SCADA systems and Modbus from the “Why Modbus Matters: An Introduction” blog article.
In our example, the CR1000 is programmed to measure battery voltage, panel temperature, and an analog measurement in a simple program as shown below:
'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 'Main Program BeginProg Scan (1,Sec,0,0) 'Measure the datalogger panel temperature PanelTemp (PTemp,250) 'Measure the battery voltage Battery (batt_volt) 'Measure an analog voltage VoltSe (analog_meas,1,mV5000,1,1,0,_60Hz,1.0,0) 'Call final storage table CallTable Table1 NextScan EndProg
The CR1000 datalogger in our example is connected to a SCADA system using an NL121 Ethernet Interface. Therefore, we need to program our data logger to listen to Modbus polls on the appropriate communications port and to respond with our most current measured data. To do this, we need to use the ModbusServer() instruction, declare a variable array to hold our Modbus data, and then update that array with our measurements.
This is accomplished using the code below:
'Program for a CR1000 Series Datalogger 'Declare Public Variables Public PTemp, batt_volt, analog_meas Public ModbusRegisters(3) Public ModbusCoil As Boolean '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 'Main Program BeginProg 'Configure the datalogger as a Modbus Server ModbusServer (502,0,1,ModbusRegisters(),ModbusCoil,2) Scan (1,Sec,0,0) 'Measure the datalogger panel temperature PanelTemp (PTemp,250) 'Measure the battery voltage Battery (batt_volt) 'Measure an analog voltage VoltSe (analog_meas,1,mV5000,1,1,0,_60Hz,1.0,0) 'Populate Modbus Registers ModbusRegisters(1) = PTemp ModbusRegisters(2) = batt_volt ModbusRegisters(3) = analog_meas 'Call final storage table CallTable Table1 NextScan EndProg
Let’s take a closer look at the ModbusServer() instruction we added to the program code. The instruction is added between the BeginProg and Scan statements. The ModbusServer() instruction is placed between these two statements because it only needs to execute once at compile time rather than being executed during each scan.
The ModbusServer() instruction contains six parameters as shown below:
ModbusServer (COMPort,BaudRate,ModbusAddr,ModbusVariable,BooleanVar,ModbusOption)
For reference, in our program code, our instruction with the parameters looks like this:
ModbusServer (502,0,1,ModbusRegisters(),ModbusCoil,2)
Let’s take a closer look at those parameters and what they mean:
Modbus Registers | Measurement Description | Units |
1,2 |
Data Logger Panel Temperature |
Degrees Celsius |
3,4 |
Data Logger Battery Voltage |
Volts |
5,6 |
Analog Measurement |
Millivolts |
The example exercise above outlines how you can accomplish a simple Modbus TCP/IP server implementation by programming a CR1000 datalogger in CRBasic. Please note that the Short Cut program generator also has the capability to generate the code we have discussed above. By taking advantage of the concepts shown above, you can add more measurements to your program, as well as to the Modbus Register Map of your data logger. The result is that your SCADA system can access live measurement data for a more complete weather station implementation.
You can look forward to blog articles in the future with more details on specific Modbus topics, common pitfalls, and best practices. In the meantime, share any Modbus comments or questions you have below.
Comentários
raichlebw | 10/05/2016 at 05:41 PM
Hi,
I've been trying to set up a Modbus TCP server on a CR1000 with no success so far. I'm testing the server with an Obvius Acquisuite 8810 Modbus TCP client, which has not yet established communition with the logger/server. We're pretty good with Modbus here, but not as good with network communication.
The questions...
1) With the ComPort parameter of ModbusServer set to 502, to which physical port should the NL121 be attached? I assume it's the RS-232 port. It's interestinng that, whichever of the 2 possible answers (RS-232, CS I/O) is the case, there will be Modbus TCP transmitted over a serial cable.
2) With the ComPort parameter of ModbusServer set to ComRS232, is the CR1000 a Modbus RTU server? This must be the case to avoid ambiguity with the TCP server, but I've seen no mention of RTU in any Campbell literature.
Thanks,
Brian
Paul Smart | 10/06/2016 at 03:23 PM
Hi Brian,
Are you using an NL201 rather than an NL121? An NL121 will only connect to the peripheral port of the datalogger, whereas an NL201 can connect to the RS-232 port or the CSI/O port of the datalogger.
If you are using an NL201, then you will need to configure the NL201 either in bridge mode or as a Modbus TCP gateway. If you configure it as a Modbus TCP gateway, then your datalogger will need to use the appropriate port (RS232 or CSI/O) and will function as an RTU. If the NL201 is set up in bridge mode you will connect it to the CSI/O port of the datalogger and use port 502 in the ModbusServer instruction. RTU vs Modbus TCP/IP is determined by the port selection in the ModbusServer instruction. Make sure baud rates and ports in the ModbusServer instruction match the settings of the NL201.
I would recommend taking a look at the settings for the NL201 using Device Configuration Utility.
Please refer to the helps in Device Configuration Utility for information on the options available. The helps explain all of this a lot better than I just did :)
I hope this helps,
-Paul
ariklee | 02/23/2018 at 04:25 PM
Hi Paul, couple questions making CR1000x function as Modbus server over Ethernet:
1. Is port 502 set by the Modbus client? Should I verify with the client that they are indeed using 502, or can that not be changed?
2. Your ModbusCoil parameter is a single value boolean, while in Campbell's Application Note on Modbus Server, they use an 8-value boolean array. I'm a bit confused on this. (In my application, the client should not be sending any commands 01, 02, 05, or 15. Does it matter then?)
3. Can you recommended any modbus client simulators for Windows 10 (besides Modbus Poll)?
Paul Smart | 02/28/2018 at 08:08 PM
Hi Ariklee,
Port 502 is the default port that is typically used. The datalogger can use other ports, but you will need to confirm with the client that it is a match to the port that the datalogger is using.
You can use the 8-value boolean array if you are expecting the client to set those coils in the datalogger. However, in my program I was not expecting this, so I simply used a single value. The only reason to do this was to avoid a warning when I compile the program. If you are not using these coils, then it does not matter.
I've spoken to some of our customers that use ModScan as an alternative to Modbus Poll, but have not used it myself.
-Paul
Geoprojektas | 03/11/2018 at 01:39 AM
Dear Paul,
Regarding ModBUS standard, measurements are stored in the Server device in four different tables:
Device address: Description:
1...10000 Coils outputs
10001...20000 Coils inputs
30001...40000 Input registers
40001...50000 Holding registers
Where will store the measurements ModbusRegisters() in your program?
On 40001-40006 registers?
Thanks,
Gintaris
Paul Smart | 03/12/2018 at 08:22 AM
Hi Gintaris,
Yes, that is correct. The measurements will also populate the Input Registers.
-Paul
Geoprojektas | 03/13/2018 at 09:25 AM
Thanks, Paul
SteveA | 07/24/2018 at 05:42 PM
Paul,
You mention at the end of the article that the modbus code can be generated using ShortCut. I've given it a first try, but haven't been able to see anyway to do that with ShortCut. Is there something obvious I'm missing?
-Steve
Anas Zaatreh | 01/27/2019 at 01:07 PM
Hi Paul,
Is it possible to configure CR1000x as Modbus TCP Client?
GaryTRoberts | 02/04/2019 at 09:17 AM
Anas,
Yes, the CR1000X can be set up as a Modbus TCP Clientr. Instead of using a ComXXX for the ComPort parameter for the ModBusClient() instruction, you would use the handle of the socket created with TCPOpen().
ctorregrosa | 04/15/2020 at 06:19 PM
Hello,
I have the CR300 and I tried the sample code for Modbus Server described in: https://help.campbellsci.com/crbasic/cr300/#Instructions/ and it works correctly.
The problem is that the instructions in the manual and the web do not correctly explain which registers are the registers to consult the Modbus Server.
The solution I found was to load the Modbus Client example and review the device query.
Finally, the code that worked for me for:
ModbusServer (ComRS232,19200,3, ModIn (), Port ())
and obtaining 2 parameters was:
03030000000445EB
03: Address
03: Function -> holding registers
00000004: two parameters
445EB: CRC
ModbusServer's response was:
03030800000000797A41B896C8
03: Address
03: Function -> holding registers
08: Msg Length -> 8 bytes
00000000: (Mid-Little Endian (CDAB)) -> 00000000 (IEEE 754): 0.0000 (voltage) no connected =)
797A41B8: (Mid-Little Endian (CDAB)) -> 41B8797A (IEEE 754): 23.0593 (temperature)
96C8: CRC
I hope this serves others with the same doubt.
Anas Zaatreh | 12/20/2020 at 07:23 AM
Hi Paul,
Is there any limition for the number of tags when using CR1000x as modbus client? i have 1600 tags to read from modbus rtu.
Robin D | 12/22/2020 at 01:57 PM
Thanks, Anas, for your question. Our knowledgeable folks here shared this response: 1600 tags won't hit a hard limit. Memory would be the only hard limit, but it's higher than 1600. The time it takes to transfer that many data values will limit how often data can be updated.
Haidar | 02/28/2023 at 05:24 PM
I am getting error reading register value.
I used cr1000 datalogger rs232 protocol using Arduino mega to fetch the data from datalogger. How can I resolve this issue?
Seth Berger | 02/28/2023 at 06:06 PM
Hi Haidar,
Modbus communication problems can result from a number of issues. If your modbus result code is incrementing upward, most commonly mistmatches in the baud rate or the data format (number data bits, stop bit, parity) are the cause of the error.
For troubleshooting assistance, I believe it would be helpful to gather more information such as the datalogger program. I would recommend that you either contact your local Campbell Scientific office or submit an e-mail support request through our website.
https://www.campbellsci.com/questions?qtype=2
Haidar | 03/06/2023 at 05:19 AM
@seth Berger
Do you have a program to fetch the mateorological data using Arduino mega with max 3232?
Haidar | 03/06/2023 at 05:01 PM
How to access cr1000 datalogger through Arduino mega or any microcontroller??
And How I can give password to the datalogger so that it identify and accept it and begins communication to fetch the mateorological data from Campbell scientific cr1000??
Seth Berger | 03/07/2023 at 12:21 AM
Hi Haidar,
We unfortunately do not have an example program for setting up Modbus communications with an Arduino max 3232 device. Since this is an application specific question that will require sharing your program and other information, I recommend you contact our technical support team directly. You can submit a web request by following the link below.
https://www.campbellsci.com/questions?qtype=2
Ahjoo Engineering | 09/27/2024 at 02:59 AM
Are Data Loggers also allowed to connect to multiple SCADA systems?
jballs | 09/27/2024 at 04:38 PM
Hello Ahjoo Engineering,
Yes, you can connect the data logger to multiple SCADA systems. You would need to use a ModbusServer() instrction for each SCADA connection in your data logger program.
Ahjoo Engineering | 10/02/2024 at 06:37 AM
Is it possible to connect multiple SCADA systems to a single data logger?
The function used within the data logger is 'ModbusSlave(502, 9600, 1, ModbusRegisters(), 0)'.
jballs | 10/02/2024 at 03:22 PM
Hello Ahjoo Engineering,
Yes, that is correct. Each connection will need to have its own ModbusSlave() instruction.
Ahjoo Engineering | 10/03/2024 at 11:43 PM
Thank you for your response. I have an additional question.
Should the program be designed to allow connections by port as shown below?
'Configure the datalogger as a Modbus Server
ModbusSlave (502,9600,1,ModbusRegisters(),0) '// For Siemens(Andritz) PLC
ModbusSlave (503,9600,1,ModbusRegisters(),0) '// For Warnning System
Is it impossible to implement a configuration where multiple SCADAs can connect via Port 502?
jballs | 10/04/2024 at 02:57 PM
Hello Ahjoo Engineering,
Yes, you can have multiple Modbus connections on the same port (502). You would want to set up the Modbus address to be unique for each connection.
I would suggest that you call support at the Campbell Scientific office closest to you for additional programming questions that can be answered quicker for you.
Please log in or register to comment.