Modbus over TCP/IP
Show older comments
Hi everyone
I'm trying do implement the Modbus protocol over TCP/IP, to comunicate with the variable speed drive AVT32, manufactured by Schneider. I know there is a TCP/IP block for simulink models, and in fact, I can comunicate successfully with the AVT32. However, I need to do the same using a "m" file, and, for some reason I'm not been able to find, I could't have success yet. Please help me to figure out my mistakes.
The code I'm using is the following:
%-----------//-------------------
%configuration of TCP/IP channel
tcpip_pipe=tcpip(192.168.1.20, 502); %IP and Port of ATV32 set(tcpip_pipe, 'InputBufferSize', 512); tcpip_pipe.ByteOrder='bigEndian';
try if ~strcmp(tcpip_pipe.Status,'open') fopen(tcpip_pipe); end disp2('TCP/IP Open', handles); catch err disp2('Error: Can''t open TCP/IP', handles); end
%apparently, the channel is successfully opened.
transID = uint16(0); %16b Transaction Identifier ProtID = uint16(0); %16b Protocol ID (0 for ModBus) Lenghf = uint16(6); %16b Remaining bits (6) UnitID = uint16(0); %Unit ID (0) UnitID = bitshift(UnitID,8); FunCod = uint16(6); %Function code: write (6) UnitIDFunCod = bitor(FunCod,UnitID); %Concatenation of UnitID & FunctionCode %in one uint16 word
%According to modbus protocol, UnitID and Function code are 8bit data. In order to maintain the same data tipe in vector "message", I converted each of them to uint16, and used "bitor" to create a uint16 word when the MSB is the UnitID and the LSB is the function code
Add = uint16(8501); %16b Adress of the resister (8501) Val = uint16(value); %16b Data (5)
message = [transID ProtID Lenghf UnitIDFunCod Add Val]; disp2(message,handles); fwrite(tcpip_pipe, message);
--------------///-----------------------
after the execution of "fwrite" funcion, I'm able to verify that ATV32 doesn't receive any data, or at least in the right way.
I'll apreciate very much any help
Best Regards Justino Rodrigues
3 Comments
Miguel Gaspar
on 21 Jun 2013
Edited: Miguel Gaspar
on 21 Jun 2013
If you check
help icinterface.fwrite
you will see that by default it converts the input data to uchar. I noticed it by running echotcpip, as the returned data was truncated. Checking with a simple python echo script I confirmed that. After changing
fwrite(tcpip_pipe,message)
to
fwrite(tcpip_pipe,message,'int16')
I managed to communicate to modtools' "Modbus Slave" application on windows. This is the code I got working:
% configuration of TCP/IP channel
IPADDR='127.0.0.1';
PORT=10502; % The port should be 502, but this is previleged under linux
tcpip_pipe=tcpip(IPADDR, PORT); %IP and Port of ATV32
set(tcpip_pipe, 'InputBufferSize', 512);
tcpip_pipe.ByteOrder='bigEndian';
try
if ~strcmp(tcpip_pipe.Status,'open')
fopen(tcpip_pipe);
end
disp('TCP/IP Open');
catch err
disp('Error: Can''t open TCP/IP');
end
transID=uint16(0);
apparently, the channel is successfully opened.
transID = uint16(transID+1); % 16b Transaction Identifier
ProtID = uint16(0); % 16b Protocol ID (0 for ModBus)
Lenghf = uint16(6); % 16b Remaining bits (6)
UnitID = uint16(1); % Unit ID (0)
UnitID = bitshift(UnitID,8);
FunCod = uint16(6); % Function code: write (6)
UnitIDFunCod = bitor(FunCod,UnitID);
% Concatenation of UnitID & FunctionCode
% in one uint16 word
% According to modbus protocol, UnitID and Function code are 8bit data.
% In order to maintain the same data tipe in vector "message", I converted
% each of them to uint16, and used "bitor" to create a uint16 word when
% the MSB is the UnitID and the LSB is the function code
Add = uint16(03); % 16b Adress of the resister (8501)
Val = uint16(transID*10); % 16b Data (5)
message = [transID; ProtID; Lenghf; UnitIDFunCod; Add; Val];
disp(message);
fwrite(tcpip_pipe, message,'int16');
while ~tcpip_pipe.BytesAvailable,end
tcpip_pipe.BytesAvailable
res=fread(tcpip_pipe,tcpip_pipe.BytesAvailable)
fclose(tcpip_pipe);
Jiaqiang Yao
on 22 Mar 2018
Nice code! It works, Many thanks!
Trung Bui
on 3 Jun 2020
Add = uint16(03); % 16b Adress of the resister (8501)
How 03 in uint16 is 8501? I dont get it
Answers (2)
Tomasz
on 11 Jul 2013
0 votes
I would like to ask if somebody could bestow (give :)) some mfiles related to Modbus TCP/IP or RTU implemented in Matlab.
I will be very grateful.
I am designing and building/programming a connection between Atmega 128 and Matlab using Modbus protocol. I have programmed Atmega as Modbus Slave and also Master. Now i am looking for Matlab implementation with Modbus.
Best wishes Tom
1 Comment
Eric Wetjen
on 10 Mar 2017
MODBUS TCP/IP support was added to Instrument Control Toolbox in R2017a. See this resource page for details.
Jeff
on 22 Dec 2016
0 votes
I got communication with PLC (Automation direct P2) over Modbus TCP/IP: 1, 3, 5, 6, 15, and 16 commands. I switched from 16 bit to 8 bit commands (compared to example above) in order to handle odd bytes in 15 and 16 commands.
see attachment
Categories
Find more on Modbus Communication in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!