Our full technical support staff does not monitor this forum. If you need assistance from a member of our staff, please submit your question from the Ask a Question page.


Log in or register to post/reply in the forum.

CR800 Modbus Master/Slave Program


fizikolog Feb 21, 2018 11:22 AM

Hello,

I have a problem to create ModBus Master and Slave programme. We will use this programme in a Wind Energy Park. There is a SCADA system on the site and they want Campbell CR800 datalogger to connect this mast to SCADA system. My Slave programme is below. I couldnt test this programme. Could you help me to create a master programme to test this slave programme. And  is Slave programme correct or not?

 

'CR800 Series


'Declare Variables and Units
Public BattV
Public PTemp_C
Public Modbus(2)
Public ModbusCoil(8) As Boolean
Public v1 'Windspeed V1
Public v1_Avg
Public v1_Std
Public v1_Min
Public v1_Max

Public v2 'Windspeed V2
Public v2_Avg
Public v2_Std
Public v2_Min
Public v2_Max

Public v3 'Windspeed V3
Public v3_Avg
Public v3_Std
Public v3_Min
Public v3_Max

Public v4 'Windspeed V1
Public v4_Avg
Public v4_Std
Public v4_Min
Public v4_Max

Public d1 'winddirection D1
Public d1_Std
Public d2 'winddirection D2
Public d2_Std
Public t1 'temperature
Public t1_Avg
Public h1 'humidity
Public h1_Avg
Public p1 'barometric pressure
Public p1_Avg
Public roh 'density of the air is calculated below
Public roh_Avg
Public v1max
Public v4max
Public d1_Max_ref_v1
Public d1_Max_ref_v1_Max
Public d2_Max_ref_v4
Public d2_Max_ref_v4_Max
Public i ' Counter that samples every 2s for 10 Minutes Intervall
'Public u_vz ' Voltage of vertical Windspeed
Public u_d1_ref ' Voltage drop of wire for d1 (connected to AGND of Windvane)
Public u_d1 ' Voltage for Wind Direction 1
Public u_d2_ref ' Voltage drop of wire for d2 (connected to AGND of Windvane)
Public u_d2 ' Voltage for Wind Direction 2
Public u_t1 ' Voltage of Temperature Sensor below
Public u_p1 ' Voltage of Barometric Pressur
Public u_h1 ' Voltage of Temperature Sensor below

Const v1_faktor = 1 ' SN: '80m Frequency per m/s
Const v1_offset = 0 ' in m/s

Const v2_faktor = 1 'SN: '80m
Const v2_offset = 0 '

Const v3_faktor = 1 ' SN: '60m
Const v3_offset = 0 '

Const v4_faktor = 1 'SN: '30m
Const v4_offset = 0 '

Const d1_offset = 0 'Thies SN: '79m 'value between 0 -359, if Wind Vane 1 is installed not direct to north
Const d2_offset = 0 'Thies SN: '29m 'value between 0 -359, if Wind Vane 2 is installed not direct to north

Const t1_faktor = 20 'SN: '10m ' (t1_max - t1_min) / (V_max - V_min) = (70 - (-30)) / (5-0)
Const t1_offset = -30 ' t1_min

Const p1_faktor = 22.0586 'SN: '10m ' (p1_max - p1_min) / (V_max - V_min) = (70 - (-30)) / (5-0)
Const p1_offset = 56.3883

Const h1_faktor = 20 'SN: '10m ' (h1_max - h1_min) / (V_max - V_min) = (100 - 0) / (5-0)
Const h1_offset = 0
Units BattV=Volts
Units PTemp_C=Deg C
Units v1=m/s
Units v2=m/s
Units v3=m/s
Units v4=m/s
'Units vz=m/s
Units d1=Degree
Units d2=Degree
Units t1=Degree Cent
Units h1=percent
Units p1=hPa
Units roh=kg/m3

Dim rTime(9) 'declare as public and dimension rTime to 9
Alias rTime(1) = Year 'assign the alias Year to rTime(1)
Alias rTime(2) = Month 'assign the alias Month to rTime(2)
Alias rTime(3) = Day1 'assign the alias Day to rTime(3)
Alias rTime(4) = Hour 'assign the alias Hour to rTime(4)
Alias rTime(5) = Minute 'assign the alias Minute to rTime(5)
Alias rTime(6) = Second 'assign the alias Second to rTime(6)
Const FloatFormat = "%6.2f"
DisplayMenu("Data",-1) 'Create Custom Menu named DataView; set as main menu
SubMenu("Current Data") 'Create Submenu named PanelTemps
DisplayValue("V1",FormatFloat(V1,FloatFormat)) 'Item for submenu - Final Stg
DisplayValue("V2",FormatFloat(V2,FloatFormat))
DisplayValue("V3",FormatFloat(V3,FloatFormat))
DisplayValue("V4",FormatFloat(V4,FloatFormat))
'DisplayValue("Vz",FormatFloat(Vz,FloatFormat))
DisplayValue("Direction D1",FormatFloat(D1,FloatFormat))
DisplayValue("Direction D2",FormatFloat(D2,FloatFormat))
DisplayValue("Temp T1",FormatFloat(T1,FloatFormat))
DisplayValue("Barometer",FormatFloat(p1,FloatFormat))
DisplayValue("Humidity H1",FormatFloat(h1,FloatFormat))
DisplayValue("PanelTemp",FormatFloat(PTemp_C,FloatFormat))
DisplayValue("BatteryVolt",FormatFloat(BattV,FloatFormat))
EndSubMenu
EndMenu

'Define Data Tables
DataTable(MeasData,True,-1)
DataInterval(0,10,Min,1)
Minimum(1,BattV,FP2,False,False)

Average(1,v1,FP2,v1_Avg) '1
StdDev (1,v1,FP2,v1_Std) '2
Minimum (1,v1,FP2,v1_Min,false) '3
Maximum (1,v1,FP2,v1_Max,false) '4


Average(1,v2,FP2,v2_Avg) '5
StdDev (1,v2,FP2,v2_Std) '6
Minimum (1,v2,FP2,v2_Min,false) '7
Maximum (1,v2,FP2,v2_Max,false) '8

Average(1,v3,FP2,v3_Avg) '9
StdDev (1,v3,FP2,v3_Std) '10
Minimum (1,v3,FP2,v3_Min,false) '11
Maximum (1,v3,FP2,v3_Max,false) '12

Average(1,v4,FP2,v4_Avg) '13
StdDev (1,v4,FP2,v4_Std) '14
Minimum (1,v4,FP2,v4_Min,false) '15sd1x
Maximum (1,v4,FP2,v4_Max,false) '16


WindVector (1,1,d1,FP2,d1_Std,0,0,4) '21 simple Option to calculate the correct Value of the Wind Direction D1
WindVector (1,1,d2,FP2,d2_Std,0,0,4) '23 simple Option to calculate the correct Value of the Wind Direction D2
Average(1,t1,FP2,t1_Avg) '25
Average(1,p1,IEEE4,p1_Avg) '25
Average(1,roh,FP2,roh_Avg) '27
Average(1,BattV,FP2,false) '28
Average(1,PTemp_C,FP2,false) '29
Average(1,h1,FP2,h1_Avg) '30 'humidity

Maximum (1,d1_Max_ref_v1,FP2,d1_Max_ref_v1_Max,false)
Maximum (1,d2_Max_ref_v4,FP2,d2_Max_ref_v4_Max,false)

EndTable

'Main Program
BeginProg
i = 0
v1max=0
v4max=0
d1_Max_ref_v1=0
d2_Max_ref_v4=0
'Use SerialOpen to set RS232 options for Modbus Slave Instruction
SerialOpen(COMRS232,9600,3,0,1000)
'Modbus Slave Instruction
ModbusSlave(COMRS232,9600,40,Modbus(),ModbusCoil(),2)

'Main Scan
Scan(1,Sec,1,0)
'Default Datalogger Battery Voltage measurement 'BattV'
Battery(BattV)
'Default Wiring Panel Temperature measurement 'PTemp_C'
PanelTemp(PTemp_C,_60Hz)
i = i + 1

' Wind Speed Measurement
PulseCount (v1,1,1,0,1,v1_faktor,v1_offset) ' V1 connected to PulseCount P1
PulseCount (v2,1,2,0,1,v2_faktor,v2_offset) ' V2 connected to PulseCount P2
PulseCount (v3,1,11,0,1,v3_faktor,v3_offset)' V3 connected to Port C1
PulseCount (v4,1,12,0,1,v4_faktor,v4_offset)' V4 connected to Port C1

If v1 = NAN Then
v1 = 0
EndIf

If v2 = NAN Then
v2 = 0
EndIf

If v3 = NAN Then
v3 = 0
EndIf

If v4 = NAN Then
v4 = 0
EndIf
If v1 < (v1_offset + 0.1) Then
v1 = 0
EndIf
If v2 < (v2_offset + 0.1) Then
v2 = 0
EndIf

If v3 < (v3_offset + 0.1) Then
v3 = 0
EndIf

If v4 < (v4_offset + 0.1) Then
v4 = 0
EndIf


'=========================================================================================================================================

' Wind Direction Measurement

VoltSe(u_d1,1,mV5000,1,0,0,_50Hz,0.001,0)
VoltSe(u_d2,1,mV5000,2,0,0,_50Hz,0.001,0)
'VoltSe(u_d2_ref,1,mV2500,2,0,0,_50Hz,0.001,0) 'Not Used because Voltage output from Datalogger is very precise
u_d1_ref = 5 'Set to constant value, need to be changed when changing the supply voltage of Windvanes!!
u_d2_ref = 5 'Set to constant value, need to be changed when changing the supply voltage of Windvanes!!
d1 = 360 * u_d1 / u_d1_ref + d1_offset
d2 = 360 * u_d2 / u_d2_ref + d2_offset
If d1 > 359 Then d1 = d1-360
If d2 > 359 Then d2 = d2-360

If v1max < v1 Then
v1max=v1
d1_Max_ref_v1=d1
Else
v1max=v1max
d1_Max_ref_v1=d1_Max_ref_v1
EndIf
If v4max < v4 Then
v4max=v4
d2_Max_ref_v4=d2
Else
v4max=v4max
d2_Max_ref_v4=d2_Max_ref_v4
EndIf
VoltSe (u_t1,1,mV5000,3,1,0,_50Hz,0.001,-0)
t1 = (u_t1 * t1_faktor) + t1_offset

' Barometric Pressure Messurement
' 0...5V 800...1100 Prozent
VoltSe(u_p1,1,mV5000,4,1,0,_50Hz,0.001,-0)
p1 = ((u_p1 * p1_faktor) + p1_offset)*10

' Humidity Measurement
' 0...5.0V = 0...100 Prozent
VoltSe(u_h1,1,mV5000,5,1,0,_50Hz,0.001,-0)
h1 = (u_h1 * h1_faktor) + h1_offset
If h1 <15 Then h1=15
If h1 >98 Then h1=98


' Temperatur INTERN Measurement
PanelTemp(PTemp_C,_50Hz)

'Air Density with Tempeature below Calculation
roh = 0.34823 * p1 / (273.15 + t1)
roh_Avg=roh
'Call Data Tables and Store Data
CallTable(MeasData)
'Copy values/measurements to Modbus Array
Modbus(89)=BattV
Modbus(27)=v1_Avg
Modbus(29)=v3_Avg
Modbus(31)=v4_Avg
Modbus(33)=v1_Std
Modbus(35)=v3_Std
Modbus(37)=v4_Std
Modbus(39)=v1_Max
Modbus(41)=v3_Max
Modbus(43)=v4_Max
Modbus(45)=v1_Min
Modbus(47)=v3_Min
Modbus(49)=v4_Min
Modbus(57)=d1
Modbus(59)=d2
Modbus(63)=d1_Max_ref_v1_Max
Modbus(65)=d2_Max_ref_v4_Max
Modbus(69)=d1_Std
Modbus(71)=d2_Std
Modbus(91)=rTime(1)
Modbus(93)=rTime(2)
Modbus(95)=rTime(3)
Modbus(97)=rTime(4)
Modbus(99)=rTime(5)
Modbus(101)=rTime(6)
Modbus(105)=p1_Avg
Modbus(115)=t1_Avg
Modbus(125)=h1_Avg
Modbus(145)=roh_Avg



NextScan
SlowSequence
Scan(10,Min,1,0) '
v1max=0
v4max=0
d1_Max_ref_v1=0
d2_Max_ref_v4=0
NextScan
EndProg

Thanks a lot.


JDavis Feb 21, 2018 03:58 PM

The best way to test Modbus on a datalogger is connect Modbus software on a PC to the datalogger. We use Modbus Poll for testing. It has a trial version. For the amount of testing we do, we chose to purchase a license.

There are some Modbus master software that are completely free. I don't find them as easy to use.

For testing Modbus master functionality of the datalogger, ModRSsim is a PC Modbus slave simulator that works pretty well. You can find that software on Sourceforge.


fizikolog Feb 22, 2018 06:43 AM

Dear Davis,

Do you have any idea about my Slave code. can it work or not?

thanks,


JDavis Feb 22, 2018 03:48 PM

You really should just test it.


Geoprojektas Mar 8, 2018 06:33 PM

Dear fizikolog,

please write me at geomonitoringas@gmail.com

Log in or register to post/reply in the forum.