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