'OXYBase RS485 Modbus working with a CSI CR1000X ' '1 unit 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 'variable for the Modbus address (device ID) of the OXYBase that is wired to the OXYBase 'this has to be set first! (e. g. with the software "EOM STS Pro" from PreSens) Public DeviceID As Long = 1 'variable for checking for correct port opening Public OpenPortOK As Boolean 'variables to control Modbus communication Public CommResult_Start, CommResult_Unit, CommResult_T_Comp, CommResult_Poll As Long 'variables for board temperature and voltage Public PTemp, batt_volt 'array to send Modbus data Public RegisterValue(2) As Long 'array to receive Modbus data Public Data(6) As Float 'Aliases as an elegant way to allocate array values to characteristic variable names Alias Data(1) = Pressure_Value Alias Data(2) = Reference_Amplitude Alias Data(3) = Oxygen_Amplitude Alias Data(4) = Phase_Value Alias Data(5) = Temperature_Value Alias Data(6) = Calculated_Oxygen 'variable for handling errors Public Error(1) As Long Alias Error(1) = Err Public ErrorOx As String 'variables for setting and checking for the onboard temperature compensation Public T_Comp(1) As Long Alias T_Comp(1) =T_Compensation 'defines the data table 'name, trigger yes => record, autoallocate size DataTable (OXYbaseRS485M,1,-1) Sample(1, batt_volt, FP2) Sample(1, PTemp, FP2) Sample(1, CommResult_Start, Long) Sample(1, CommResult_Poll, Long) Sample(1, CommResult_Unit, Long) Sample(1, CommResult_T_Comp, Long) Sample(1, OpenPortOK, Boolean) Sample(1, Pressure_Value, Float) Sample(1, Reference_Amplitude, Float) Sample(1, Oxygen_Amplitude, Float) Sample(1, Phase_Value, Float) Sample(1, Temperature_Value, Float) Sample(1, Calculated_Oxygen, Float) Sample(1, Err, Long) Sample(1, ErrorOx, String) Sample(1, T_Compensation, Long) EndTable Sub OXYBaseSerialSetup 'subroutine to initialize the RS485 interface OpenPortOK = false ' ComPort, BaudRate, Format, TXDelay, BufferSize, CommsMode: 'Format = Logic 1 high; No parity, one stop bit, 8 data bits; No error checking; PakBus communication can occur concurrently on the same port 'CommsMode 4 = Configures the port as RS-485 half-duplex, transparent (ComC5 or ComC7 only. Odd ports = A-; Even ports = B+) OpenPortOK = SerialOpen (ComC5,19200,16,500,512,4) EndSub BeginProg Call OXYBaseSerialSetup 'open RS485-communication 'starting the measurement by setting an interval <> 0 RegisterValue(1)=3 '3 sec measurement interval RegisterValue(2)=0 'ResultCode, ComPort, BaudRate, ModbusAddr, Function, Variable, Start, Length, Tries, TimeOut, ModbusOption 'ResultCode can be checked by visualizing its value (e. g. with PC400's "Monitor Data") 'Function = 16: Write Multiple Registers Writes values into a series of holding registers in the ModbusSlave 'Start: "The data address, or offset, in the Modbus frame sent to the slave will be equal to "Start-1" '3500 translates into the correct (3500-1 = )3499 here 'TimeOut is not optimized! 'ModbusOption; Code 0 or absent => Description: "Default; 32-bit float or Long, the standard ordering of the 2 byte registers are reversed (CDAB)." ModbusMaster (CommResult_Start,ComC5,19200,DeviceID,16,RegisterValue(),3500,1,1,500,0) 'setting the oxygen unit RegisterValue(1)=16 '16 => "% vol" | 32 => "% air saturation" RegisterValue(2)=0 'please see above: Correct address is 2089 (= 2090-1) ModbusMaster (CommResult_Unit,ComC5,19200,DeviceID,16,RegisterValue(),2090,1,1,500,0) 'activate onboard temperature compensation RegisterValue(1)=1 'any value <> 0 will activate RegisterValue(2)=0 ModbusMaster (CommResult_T_Comp,ComC5,19200,DeviceID,16,RegisterValue(),5612,1,1,500,0) 'check for onboard temperature compensation ModbusMaster (CommResult_Poll,ComC5,19200,DeviceID,3,T_Comp(1),5612,1,1,500,0) Scan (3, sec, 0, 20) 'exemplary 3 sec as interval, 20 loops 'get the data from the registers: the 6 float values ModbusMaster (CommResult_Poll,ComC5,19200,DeviceID,3,Data(),4896,6,1,500,0) 'the last value (error code) is a Modbus integer and is handled differently ModbusMaster (CommResult_Poll,ComC5,19200,DeviceID,3,Error(),4908,1,1,500,0) If Err=0 Then ErrorOx="no error" ElseIf Err=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="no sensor calculation/amplitude too low & reference amplitude out of range" Else ErrorOx="other error" EndIf 'getting board data: temperature and voltage PanelTemp(PTemp, 250) Battery(batt_volt) 'storing the obtained values in the data table CallTable OXYBaseRS485M NextScan 'end of loop RegisterValue(1)= 0 '0 sec as interval => stops measurements RegisterValue(2)= 0 ModbusMaster (CommResult_Start,ComC5,19200,DeviceID,16,RegisterValue(),3500,2,1,500,0)