'OXYBase RS485 Modbus working with a CSI CR1000X ' '2 units at Datalogger control terminals C5 and C6 ' '2024, Dr. Thomas Gareis, PreSens Precision Sensing GmbH, Am BioPark 11, 93053 Regensburg - Germany 'Comments or questions to: thomas.gareis@presens.de 'defining variables Public OpenPortOK As Boolean Public Comm1Result_Start, Comm1Result_Unit, Comm1Result_T_Comp, Comm1Result_Poll, Comm1Result_T_Poll As Long Public Comm2Result_Start, Comm2Result_Unit, Comm2Result_T_Comp, Comm2Result_Poll, Comm2Result_T_Poll As Long Public PTemp, batt_volt Public CommPause As Long Public Data1(6) As Float Public Data2(6) As Float Public RegisterValue1(2) As Long Public RegisterValue2(2) As Long Alias Data1(1) = Pressure_Value1 Alias Data1(2) = Reference_Amplitude1 Alias Data1(3) = Oxygen_Amplitude1 Alias Data1(4) = Phase_Value1 Alias Data1(5) = Temperature_Value1 Alias Data1(6) = Calculated_Oxygen1 'variable for handling errors Public Error_Unit1(1) As Long Alias Error_Unit1(1) = Err_Unit1 Public ErrorOx_Unit1 As String 'variables for setting and checking for the onboard temperature compensation Public T_Comp_Unit1(1) As Long Alias T_Comp_Unit1(1) =T_Compensation_Unit1 Alias Data2(1) = Pressure_Value2 Alias Data2(2) = Reference_Amplitude2 Alias Data2(3) = Oxygen_Amplitude2 Alias Data2(4) = Phase_Value2 Alias Data2(5) = Temperature_Value2 Alias Data2(6) = Calculated_Oxygen2 'variable for handling errors Public Error_Unit2(1) As Long Alias Error_Unit2(1) = Err_Unit2 Public ErrorOx_Unit2 As String 'variables for setting and checking for the onboard temperature compensation Public T_Comp_Unit2(1) As Long Alias T_Comp_Unit2(1) = T_Compensation_Unit2 'defines the data tables DataTable (OXYbaseRS485M1,1,-1) Sample(1, batt_volt, FP2) Sample(1, PTemp, FP2) Sample(1, Comm1Result_Start, Long) Sample(1, Comm1Result_Poll, Long) Sample(1, Comm1Result_Unit, Long) Sample(1, Comm1Result_T_Comp, Long) Sample(1, Comm1Result_T_Poll, Long) Sample(1, OpenPortOK, Boolean) Sample(1, Pressure_Value1, Float) Sample(1, Reference_Amplitude1, Float) Sample(1, Oxygen_Amplitude1, Float) Sample(1, Phase_Value1, Float) Sample(1, Temperature_Value1, Float) Sample(1, Calculated_Oxygen1, Float) Sample(1, Err_Unit1, Long) Sample(1, ErrorOx_Unit1, String) Sample(1, T_Compensation_Unit1, Long) EndTable DataTable (OXYbaseRS485M2,1,-1) Sample(1, Comm2Result_Start, Long) Sample(1, Comm2Result_Poll, Long) Sample(1, Comm2Result_Unit, Long) Sample(1, Comm2Result_T_Comp, Long) Sample(1, Comm2Result_T_Poll, Long) Sample(1, Pressure_Value2, Float) Sample(1, Reference_Amplitude2, Float) Sample(1, Oxygen_Amplitude2, Float) Sample(1, Phase_Value2, Float) Sample(1, Temperature_Value2, Float) Sample(1, Calculated_Oxygen2, Float) Sample(1, Err_Unit2, Long) Sample(1, ErrorOx_Unit2, String) Sample(1, T_Compensation_Unit2, Long) EndTable Sub OXYBaseSerialSetup 'subroutine to initialize the RS485 interface OpenPortOK = false OpenPortOK = SerialOpen (ComC5,19200,16,500,512,4) EndSub BeginProg CommPause = 250 Call OXYBaseSerialSetup 'Very important: The Modbus RTU communication has a base of '0' for PreSens addresses, while Campbell Scientific uses '1" as base. 'Therefore, increase all addresses +1 to communicate correctly. 'So, in the communication protocols coming from PreSens: 3499, 2089, 4895 are necessary; here 3500, 2090 and 4896 have to be used. 'starting the measurement by setting intervals <> 0 RegisterValue1(1)=3 '3 sec measurement interval RegisterValue1(2)=0 ModbusMaster (Comm1Result_Start,ComC5,19200,1,16,RegisterValue1(),3500,2,1,500,0) Delay(0,CommPause,mSec) RegisterValue2(1)=3 '3 sec measurement interval RegisterValue2(2)=0 ModbusMaster (Comm2Result_Start,ComC5,19200,2,16,RegisterValue2(),3500,2,1,500,0) Delay(0,CommPause,mSec) 'setting the oxygen units RegisterValue1(1)=16 '16 => "% vol" RegisterValue1(2)=0 ModbusMaster (Comm1Result_Unit,ComC5,19200,1,16,RegisterValue1(),2090,2,1,500,0) Delay(0,CommPause,mSec) RegisterValue2(1)=16 '16 => "% vol" RegisterValue2(2)=0 ModbusMaster (Comm2Result_Unit,ComC5,19200,2,16,RegisterValue2(),2090,2,1,500,0) Delay(0,CommPause,mSec) 'activate onboard temperature compensation unit1 RegisterValue1(1)=0 'any value <> 0 will activate RegisterValue1(2)=0 ModbusMaster (Comm1Result_T_Comp,ComC5,19200,1,16,RegisterValue1(),5612,2,1,500,0) Delay(0,CommPause,mSec) 'activate onboard temperature compensation unit2 RegisterValue2(1)=0 'any value <> 0 will activate RegisterValue2(2)=0 ModbusMaster (Comm2Result_T_Comp,ComC5,19200,2,16,RegisterValue2(),5612,2,1,500,0) Delay(0,CommPause,mSec) 'check For onboard temperature compensation unit1 ModbusMaster (Comm1Result_T_Poll,ComC5,19200,1,3,T_Comp_Unit1(1),5612,1,1,500,0) Delay(0,CommPause,mSec) 'check For onboard temperature compensation unit2 ModbusMaster (Comm2Result_T_Poll,ComC5,19200,2,3,T_Comp_Unit2(1),5612,1,1,500,0) Delay(0,CommPause,mSec) Scan (3, sec, 0, 20) 'exemplary 3 sec as interval, 20 loops 'get the data from the registers: the 6 float values ModbusMaster (Comm1Result_Poll,ComC5,19200,1,3,Data1(),4896,6,1,500,0) Delay(0,CommPause,mSec 'the last value (error code) is a Modbus integer and is handled differently ModbusMaster (Comm1Result_Poll,ComC5,19200,1,3,Error_Unit1(),4908,1,1,500,0) If Err_Unit1=0 Then ErrorOx_Unit1="no error" ElseIf Err_Unit1=320 Then 'the most common error: the cap is not attached => bits 6 and 8 are set (2^6 + 2^8 = 256 + 64 = 320) 'see Modbus protocol for OXYBase for more information ErrorOx_Unit1="no sensor calculation/amplitude too low & reference amplitude out of range" Else ErrorOx_Unit1="other error" EndIf Delay(0,CommPause,mSec) 'get the data from the registers: the 6 float values ModbusMaster (Comm2Result_Poll,ComC5,19200,2,3,Data2(),4896,6,1,500,0) Delay(0,CommPause,mSec) 'the last value (error code) is a Modbus integer and is handled differently ModbusMaster (Comm2Result_Poll,ComC5,19200,2,3,Error_Unit2(),4908,1,1,500,0) If Err_Unit2=0 Then ErrorOx_Unit2="no error" ElseIf Err_Unit2=320 Then 'the most common error: the cap is not attached => bits 6 and 8 are set (2^6 + 2^8 = 256 + 64 = 320) 'see Modbus protocol for OXYBase for more information ErrorOx_Unit2="no sensor calculation/amplitude too low & reference amplitude out of range" Else ErrorOx_Unit2="other error" EndIf Delay(0,CommPause,mSec) 'getting board data: temperature and voltage PanelTemp(PTemp, 250) Battery(batt_volt) 'storing the obtained values in the data table CallTable OXYBaseRS485M1 Delay(0,CommPause,mSec) CallTable OXYBaseRS485M2 Delay(0,CommPause,mSec) NextScan RegisterValue1(1)= 0 '0 sec => stop measurements RegisterValue1(2)= 0 ModbusMaster (Comm1Result_Start,ComC5,19200,1,16,RegisterValue1(),3500,2,1,500,0) Delay(0,CommPause,mSec) RegisterValue2(1)= 0 '0 sec => stop measurements RegisterValue2(2)= 0 ModbusMaster (Comm2Result_Start,ComC5,19200,2,16,RegisterValue2(),3500,2,1,500,0)