Connecting KELLER sensors to MATLAB
Introduction
KELLER manufactures high-precision sensors with digital output, which are connected 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 work, using the PR-33X high-precision pressure sensor as an example, we show the connection of KELLER sensors to the MATLAB integrated environment, originally developed for the analysis and synthesis of control systems, which has powerful tools for processing and displaying signal data.
Brief specification of pressure transmitter KELLER PR 33X
Standard pressure range (VPI), bar 30
Accuracy of pressure measurement, total (10 ... 40 ° C) 0.025% VPI
Output signal RS 485
Baud rate 9600 or 115200 baud
Supply voltage (U) 8 ... 28 V
Service life 10 million cycles 0 ... 100% VPI
The pressure transmitter also contains an integrated temperature sensor.
Interface
All KELLER products with index X have a digital interface (RS485 half duplex) that supports MODBUS RTU and Keller Bus protocols.
Connection to a PC is carried out via RS485-USB converter. For best compatibility, the company recommends using the Keller converter K-114.
Software
To configure and record sensor readings, free CCS30 software is used, the interface of which is shown in Figure 1.

Figure 1. Accumulation and display of graphical and tabular data by CCS30 [3].
PC connection
The PR-33X pressure sensor was connected to a PC using a USB to RS-232/422/485 MOXA USB Serial Port

converter as shown in
Figure 2. Figure 2. Connection diagram of the PR-33X pressure transmitter to a PC and a 12 V power supply. When powered Below 5.69 V (up to 4.95 V), the sensor readings increase. When powered 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



Figure 3. Configuring the MOXA converter to the RS-485 2W interface.
Transmission Formats
Data exchange between the computer (control device) and the sensor (slave device) is carried out according to the Modbus protocol messages containing the following fields [2].

First, the computer sends a request message to the sensor, then the sensor in response sends its own message with its own checksum when the requested action is successful, or sends a function with code 1 if 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 sent to the sensor contains one of the following function codes.


Figure 4. Format of transmitted and received messages according to the Modbus RTU standard [1].
Addresses of used sensor registers PR-33X

Examples of Modbus messages (reading of the integrated pressure and temperature sensor) [2]

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

Figure 5. Rules for converting four-byte sensor readings into a floating-point number.
MATLAB program for reading and displaying pressure and temperature sensors PR-33X
The PR-33X sensor reading and display program includes a main module and three subroutines. The converter operates at 115200 baud. Pressure and temperature data are read out upon request.
The program input data is the COM port address of your device (Com_Port = variable) and the address of your converter. If only one converter is connected, then, as a rule, Device_Addr = 1. The
number of readings is set by the Loop constant (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
Modbus RTU request generation routine
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
Modbus RTU sequence checksum calculation routine
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 readings to a floating point number
% 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 display of pressure and temperature of the PR-33X converter read by the above program are shown in Figure 6.

Figure 6. Output data of the PR-33X converter obtained by the program developed in MATLAB. The program reads 1000 pressure readings at 115200 baud in 9 seconds. The program reads 1000 pressure readings and 1000 temperature readings (separately) at 115200 baud in 17 seconds.
MATLAB program switching data transfer speed of the converter
To switch to a new frequency, it is necessary in the program to set the COM port address of your device (Com_Port = variable) and the required frequency of the converter (BR_Rate = 9600; or BR_Rate = 115200;)
ATTENTION. To switch to a new data transmission frequency after setting the zero bit of the register of the UART converter, it is necessary to 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
- Dr. Bob Davidov. Communication with industrial network devices. portalnp.ru/wp-content/uploads/2013/08/12.02_Discrete-IO-unit_-MK110-_RS-485-ModBus-RTU-_-ASCII-DCON-OVEN__Ed3.pdf
- Description of communication protocols. For KELLER 30 and 40 series pressure transmitters. Class.Group = 5.20 Class.Group = 5.21. Version 3.2 (in Russian). www.izmerkon.ru .
- Control Center Series 30. User Guide. Für CCS30 Version 1.1. www.izmerkon.ru
- Dr. Bob Davidov. Computer control technologies in technical systems portalnp.ru/author/bobdavidov