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.
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.
Dear Davis,
Do you have any idea about my Slave code. can it work or not?
thanks,
You really should just test it.
Dear fizikolog,
please write me at geomonitoringas@gmail.com