📜 ⬆️ ⬇️

Connecting KELLER sensors to MATLAB

Introduction


KELLER manufactures high-precision sensors with digital output that connect to proprietary software for display and accumulation of readings. Often, the user needs to integrate sensors into their own monitoring and control systems. In this paper, using the example of the high-precision pressure sensor PR-33X, shows the connection of KELLER sensors to the integrated environment MATLAB, originally developed for the analysis and synthesis of control systems, which has powerful means of processing and displaying signal data.

Brief specification of the pressure transmitter KELLER PR 33X


Standard pressure range (VPI), bar 30
Accuracy of pressure measurement, total (10 ... 40 ° C) 0.025% VPI
RS 485 output
Baud rate 9600 or 115200 baud
Power supply (U) 8 ... 28 V
Service life 10 million cycles 0 ... 100% VPI

The pressure transmitter contains an integrated temperature sensor.

Interface


All KELLER products with an X index have a digital interface (RS485 half duplex) that supports MODBUS RTU and Keller Bus protocols.

Connecting to a PC via RS485-USB converter. For best compatibility, the company recommends using a K-114 Keller converter.

Software


To set up and record sensor readings, the CCS30 free software is used, the interface of which is shown in Figure 1.

image
Figure 1. The accumulation and display of graphical and tabular data program CCS30 [3].

PC connection


The pressure sensor PR-33X was connected to a PC using a USB to RS-232/422/485 MOXA USB Serial Port converter as shown in Figure 2.

image
Figure 2. Connection diagram of the pressure transmitter PR-33X to a PC and a power source of 12 V. When the power supply is below 5.69 V (up to 4.95 V), the sensor reading increases. When power is below 4.95V, data is not transmitted (the sensor does not work).

After installing the driver and attaching the MOXA converter to the PC, the COM port appears in the device manager list image and adapter image . The tab (Figure 3) of the last device for our option is RS-485 interface with a two-wire connection scheme.

image
Figure 3. Configuring MOXA converter for RS-485 2W interface.

Transmitted Data Formats


Data exchange between the computer (control device) and the sensor (slave device) is carried out via the Modbus protocol with messages containing the following fields [2].

image

First, the computer sends a request-message to the sensor, then the sensor responds with its own message with its own checksum if the requested action is successfully completed or sends a function with code 1 when an error occurs (invalid function or data address, etc.).

The response (response) of the sensor is issued only after receiving a request from the control device.

The message transmitted to the sensor contains one of the following function codes.

image

image
Figure 4. Format of transmitted and received messages according to the Modbus RTU standard [1].

Addresses of the used registers of the PR-33X sensor


image

Examples of Modbus messages (reading from the built-in pressure and temperature sensor) [2]


image

Converting sensor readings to IEEE754 floating point format


The recommended procedure for converting four received bytes of the sensor to a floating-point number is shown in Figure 5. The example uses the data [2] given in the table above.

image
Figure 5. Rules for converting a four-byte sensor reading to a floating point number.

The MATLAB program for reading and displaying pressure sensor and temperature sensors of the PR-33X converter


The PR-33X sensor reading and displaying program includes the main module and three subroutines. The converter operates at a frequency of 115200 baud. These pressures and temperatures are read by their own requests.

The input data of the program are the COM port of your device (variable Com_Port =) and the address of your converter. If only one converter is connected, then, as a rule, Device_Addr = 1.

The number of readings is given by the constant Loop (in the example Loop = 1000;).

The main module:

clear all; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Input data %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Com_Port = 'COM9'; Device_Addr = 1; % Address of Sensor, 8 bit: 1..255 Function = 3; % 3 or 4 is read; Pr_Rg_Addr = 2; % First address of two pressure data registers (4 bytes) Temp_Rg_Addr = 8; % First address of two temperature data registers Address_Range = 2; % Range of data address %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % End of Input data %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Make COM port connection s=serial(Com_Port,'Baudrate',115200); % 9600 115200 fopen (s); pause(0.1); Loop = 1000; pr(1:Loop) = 0; temp(1:Loop) = 0; for i = 1:Loop %%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Read pressure %%%%%%%%%%%%%%%%%%%%%%%%%%%%% RTU_request = RTU_code(Device_Addr,Function,Pr_Rg_Addr,Address_Range); fwrite(s, RTU_request); %pause(0.01); % >=0.001s for PR-33X, for 115200 Baudrate while ~(get(s,'BytesAvailable')>8) end BytesAvailable = get(s,'BytesAvailable'); Rx = fread(s,BytesAvailable)'; pr(i) = sensorOUT_to_float(Rx); % in bar %%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Read temperature %%%%%%%%%%%%%%%%%%%%%%%%%%%%% RTU_request = RTU_code(Device_Addr,Function,Temp_Rg_Addr,Address_Range); fwrite(s, RTU_request); while ~(get(s,'BytesAvailable')>8) end BytesAvailable = get(s,'BytesAvailable'); % if BytesAvailable > 0 Rx = fread(s,BytesAvailable)'; temp(i) = sensorOUT_to_float(Rx); % in bar end % Close COM port fclose (s); delete (s); figure (3) clf('reset'); % Clear current figure window [AX,H1,H2] = plotyy (1:length(pr),pr,1:length(temp),temp); hold(AX(1)); hold(AX(2)); set(H1,'LineWidth',2); grid(AX(2),'on'); xlabel('Sampling, num'); % Y1_max = max(get(AX(1),'ytick')); % set(AX(1),'ytick',[0:Y1_max/10:Y1_max]); % set(AX(2),'ytick',[0:0.2:2]); set(get(AX(1),'Ylabel'),'String','Давление, бар'); set(get(AX(2),'Ylabel'),'String','Температура, град. С'); title(sprintf('Изменение давления и температуры')); % End of m file 

Subprogramming the Modbus RTU request


 function RTU_request = RTU_code(Device_Addr,Function,Data_First_Address,Address_Range) % Device_Addr == Device Address 8 bit: 1..255 % Function == % 3 or 4 is read; 6 is write in one register; 16 - write in two registers, % Data_First_Address == Address of first register data (2 bytes) % Addrress_Range == Range of Addreses; % Data_First_Address_Bytes = [floor(Data_First_Address/256) rem(Data_First_Address,256)]; Address_Range_Bytes = [floor(Address_Range/256) rem(Address_Range,256)]; % Master's Tx data without Check sum Code = [Device_Addr Function Data_First_Address_Bytes Address_Range_Bytes]; Code_Char = dec2hex(Code); if size(Code_Char,2)==1 Code_Char(:,2)=Code_Char(:,1); Code_Char(:,1)='0'; end Code_Char_line = []; for I = 1:length(Code) Code_Char_line = [Code_Char_line Code_Char(I,1:2)]; end % Check sum calculation Check_Sum = crc_calculator(Code_Char_line); % Master's Tx data with Check sum RTU_request = [Code hex2dec(Check_Sum(1:2)) hex2dec(Check_Sum(3:4))]; % End of m file 

The routine for calculating the Modbus RTU checksum sequence


 function output_hex_string = crc_calculator (Input_hex); %Input_hex = 'F70302640008'; % <= 2 * 16 Char F = [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]; xor_constant = [1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1]; for i = 1 : length (Input_hex) / 2; A = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]; if ~(i > length (Input_hex)/2) A_hex = Input_hex ((i-1)*2+1:i*2); % Two HEX bytes A_bin = dec2bin (hex2dec (A_hex)); length_A_bin = length (A_bin); for j = 0 : length_A_bin - 1 A (16 - j) = str2num(A_bin (length_A_bin - j)); end end F = xor (F,A); for ii = 1 : 8 if F(16) ==1 if xor_constant (1) == 0 F_shift (1) = 0; else F_shift (1) = 1; end for j = 2 : 16; if xor_constant (j) == F (j-1); F_shift (j) = 0; else F_shift (j) = 1; end end else F_shift = circshift(F',1)'; end F = F_shift; end end h = num2str(F); h = h(1:3:length(h)); output_hex_string = num2str([dec2hex(bin2dec(h(9:12))) dec2hex(bin2dec(h(13:16))) dec2hex(bin2dec(h(1:4))) dec2hex(bin2dec(h(5:8)))]); % End of m file 

Subroutine for converting four bytes of the sensor to a floating point


 % Transmission Sensor's output bytes to float value function val = sensorOUT_to_float(Rx) B(1) = Rx(4); B(2) = Rx(5); B(3) = Rx(6); B(4) = Rx(7); %1 bit of sign + 8 bits of exponent + 23 bits of mantis ( = 32 bits or 4x8 bytes) v_res = []; for i = 1:4 v_bit = dec2bin(B(i)); if length(v_bit)<8 % add zeros to get 8 bits for j = 1:(8-length(v_bit)) v_bit = ['0' v_bit]; end end v_res = [v_res v_bit]; end % Checking % v_res = ['0' '10000010' '01010010000001011011110'] == 10.5631999969482421875 бар s_mnt = bin2dec(v_res(1)); %sign of mantis E = bin2dec(v_res(2:9)); %exponent M = bin2dec(v_res(10:32)); % mantis if s_mnt==0 val = (1+M/8388608)*2^(E-127); % 8388608 = 2^23 else val = -(1+M/8388608)*2^(E-127); end % End of m file 

Examples of graphical displays of pressure and temperature of the PR-33X converter, read by the above program, are shown in Figure 6.

image
Figure 6. PR-33X converter output data obtained by the program developed in MATLAB. The program reads 1000 pressure readings at a speed of 115200 baud in 9 seconds. The program reads 1000 pressure readings and 1000 temperature readings (separately) at a speed of 115200 baud in 17 seconds.

Program MATLAB switching speed data transfer converter


To switch to a new frequency, you need to set the program's COM port address of your device (variable Com_Port =) and the required frequency of the converter (BR_Rate = 9600; or BR_Rate = 115200;)

ATTENTION. To switch to the new data transmission frequency after setting the zero bit of the register of the UART converter, you must turn OFF (de-energize) and then turn ON the converter again.

 % ПЕРЕХОД НА НОВУ СКОРОСТЬ ОБМЕНА (9600 ИЛИ 115200 БОД) ВЫПОЛНЯЕТСЯ ПОСЛЕ УСТАНОВКИ UART РЕГИСТРА И ВЫКЛЮЧЕНИЯ-ВКЛЮЧЕНИЯ ПРЕОБРАЗОВАТЕЛЯ clear all; % Input data Com_Port = 'COM9'; BR_Rate = 115200; % 9600 or 115200 % End of Input data % Device_Addr = 1; % Address of Sensor, 8 bit: 1..255 % Function = 6; % Write; % UART_Rg_Addr = 512; % First address of UART Rg (2 bytes) % Data = 0 0; % Rate 9600 bod % Data = 0 1; % Rate 115200 bod % RTU_request = [Device_Addr Function UART_Rg_Addr Data Check_sum] % RTU_request = [ 1 6 2 0 0 0 136 114]; % 9600 bod request in hex % RTU_request = [ 1 6 2 0 0 1 73 178]; % 115200 bod request in hex if BR_Rate == 9600 % 115200 s=serial(Com_Port,'Baudrate',115200); fopen (s); pause(0.1); RTU_request =[ 1 6 2 0 0 0 136 114]; else s=serial(Com_Port,'Baudrate',9600); fopen (s); pause(0.1); RTU_request = [ 1 6 2 0 0 1 73 178]; end fwrite(s, RTU_request); pause(0.004); % >=0.001s for PR-33X, for 115200 Baudrate BytesAvailable = get(s,'BytesAvailable'); if BytesAvailable > 0 Rx = fread(s,BytesAvailable)' end % close COM port fclose (s); delete (s); % End of m file 

Bibliographic list


  1. Dr. Bob Davidov. Communication with devices of industrial networks. portalnp.ru/wp-content/uploads/2013/08/12.02_Discrete-IO-unit_-MK110-_RS-485-ModBus-RTU-_ASCII-DCON-OVEN__Ed3.pdf
  2. Description of communication protocols. For pressure transducers KELLER 30th and 40th series. Class.Group = 5.20 Class.Group = 5.21. Version 3.2 (in Russian). www.izmerkon.ru .
  3. Control Center Series 30. User Guide. Für CCS30 Version 1.1. www.izmerkon.ru
  4. Dr. Bob Davidov. Computer control technologies in portalnp.ru/author/bobdavidov technical systems

Source: https://habr.com/ru/post/440966/