日本語 English

FinsTCP

What you can do with FINS-TCP

  • Read DM data
  • Write DM data
  • Start PLC operation
  • Stop PLC
  • Get CPU information
  • Monitor PLC status

Overview

A PC can read and write PLC memory values by sending FINS commands to the PLC via Ethernet
With FINS/TCP, the "FINS node address data send command" is sent first to obtain the FINS node addresses of the client and server
The obtained FINS node address is set in the FINS header, and a FINS-TCP header is added before the FINS frame for sending

Whole message
FINS-TCP headerFINS frame
Header LEN CMD Err FINS header FINS command
'F''I''N''S'
* FINS node address obtained with the "FINS node address data send command"

Samples

Here, DM values are read using FINS/TCP Com

PLC IP address192.168.250.1
PC IP address192.168.250.48
Contents of the send commandRead 10 words from DM100
PLC memory values
DM1000001
DM1010002
DM1020003
DM1030004
DM1040005
DM1050006
DM1060007
DM1070008
DM1080009
DM109000A

The sample code below shows synchronous communication in C#
Creating the form (placing buttons, etc.) is omitted, so place buttons and so on as needed
The sample contains no error handling; add error handling as appropriate

Synchronous communication

With synchronous communication, after sending a command it waits for the response
The receive timeout is 1000 ms, so if there is no response within 1 second it stops waiting

private void TcpFinsMessage()
{
	System.Net.Sockets.TcpClient tcp = new System.Net.Sockets.TcpClient("192.168.250.1", 9600);
	System.Net.Sockets.NetworkStream ns = tcp.GetStream();

	ns.ReadTimeout = 1000;
	ns.WriteTimeout = 1000;

	// FINS node address data send command
	byte[] FinsTcpHeader = new byte[20];
	FinsTcpHeader[0] = 0x46;       // "F"
	FinsTcpHeader[1] = 0x49;       // "I"
	FinsTcpHeader[2] = 0x4E;       // "N"
	FinsTcpHeader[3] = 0x53;       // "S"
	FinsTcpHeader[4] = 0x00;
	FinsTcpHeader[5] = 0x00;
	FinsTcpHeader[6] = 0x00;
	FinsTcpHeader[7] = 0x0C;
	FinsTcpHeader[8] = 0x00;
	FinsTcpHeader[9] = 0x00;
	FinsTcpHeader[10] = 0x00;
	FinsTcpHeader[11] = 0x00;
	FinsTcpHeader[12] = 0x00;
	FinsTcpHeader[13] = 0x00;
	FinsTcpHeader[14] = 0x00;
	FinsTcpHeader[15] = 0x00;
	FinsTcpHeader[16] = 0x00;
	FinsTcpHeader[17] = 0x00;
	FinsTcpHeader[18] = 0x00;
	FinsTcpHeader[19] = 0x00;

	ns.Write(FinsTcpHeader, 0, FinsTcpHeader.Length);

	byte[] resHeader = new byte[256];
	int resHeaderSize = ns.Read(resHeader, 0, resHeader.Length);

	if ((resHeader[8] == 0x00 && resHeader[9] == 0x00) &&
		(resHeader[10] == 0x00 && resHeader[11] == 0x01))
	{

	byte ClientNodeNo = resHeader[19];
	byte ServerNodeNo = resHeader[23];


	//Send FINS-TCP header + FINS frame
	byte[] cmd = new byte[34];
	// ----------------- FINS-TCP header
	cmd[0] = 0x46;          // "F"
	cmd[1] = 0x49;          // "I"
	cmd[2] = 0x4E;          // "N"
	cmd[3] = 0x53;          // "S"
	cmd[4] = 0x00;          // Length
	cmd[5] = 0x00;
	cmd[6] = 0x00;
	cmd[7] = 18 + 8;        // (number of bytes after Command)
	cmd[8] = 0x00;          // Command
	cmd[9] = 0x00;
	cmd[10] = 0x00;
	cmd[11] = 0x02;
	cmd[12] = 0x00;         // ErrorCode
	cmd[13] = 0x00;
	cmd[14] = 0x00;
	cmd[15] = 0x00;
	// ----------------- FINS header
	cmd[16] = 0x80;          // ICF
	cmd[17] = 0x00;          // RSV
	cmd[18] = 0x02;          // GCT
	cmd[19] = 0;             // DNA  destination network address
	cmd[20] = ServerNodeNo;  // DA1  destination node address
	cmd[21] = 0;             // DA2  destination unit address
	cmd[22] = 0;             // SNA  source network address
	cmd[23] = ClientNodeNo;  // SA1  source node address
	cmd[24] = 0;             // SA2  source unit address
	cmd[25] = 1;             // SID  identifier, any value 00-FF
	// ----------------- FINS command
	cmd[26] = 0x01;         // MRC  read command 0101
	cmd[27] = 0x01;         // SRC
	cmd[28] = 0x82;         // MemoryType = DM
	cmd[29] = 0x00;         // ReadAddress = 100CH
	cmd[30] = 0x64;
	cmd[31] = 0x00;
	cmd[32] = 0x00;         // ReadSize = 10CH
	cmd[33] = 0x0A;

	ns.Write(cmd, 0, cmd.Length);

	byte[] resCmd = new byte[2048];
	int resCmdSize = ns.Read(resCmd, 0, resCmd.Length);

	if ((resCmd[8] == 0x00 && resCmd[9] == 0x00) &&
		(resCmd[10] == 0x00 && resCmd[11] == 0x02))
	{
		byte[] rcvData = new byte[resCmdSize];
		Array.Copy(resCmd, rcvData, resCmdSize);

		textBox1.AppendText(BitConverter.ToString(rcvData) + "\r\n");
	}
}
ns.Close();
tcp.Close();

Explanation

Lines 3-4


System.Net.Sockets.TcpClient tcp = new System.Net.Sockets.TcpClient("192.168.250.1", 9600);
System.Net.Sockets.NetworkStream ns = tcp.GetStream();
	

Create a TCP client specifying the PC's IP address and TCP port number
Create the network stream used for sending and receiving data with GetStream

Lines 6-7


ns.ReadTimeout = 1000;
ns.WriteTimeout = 1000;
	

Set the read and write timeouts to 1000 ms

Lines 9-30


// FINS node address data send command
byte[] FinsTcpHeader = new byte[20];
FinsTcpHeader[0] = 0x46;       // "F"
~
FinsTcpHeader[19] = 0x00;
	

Set the FINS node address data send command in the byte array to send
With FINS/TCP, this command is sent to obtain a free FINS node address
For details, see Comparison of FINS/UDP and FINS/TCP

Line 32


ns.Write(FinsTcpHeader, 0, FinsTcpHeader.Length);
	

Send the FINS node address data send command

Lines 34-35


byte[] resHeader = new byte[256];
int resHeaderSize = ns.Read(resHeader, 0, resHeader.Length);
	

Receive the response to the FINS node address data send command

Lines 37-38


if ((resHeader[8] == 0x00 && resHeader[9] == 0x00) &&
(resHeader[10] == 0x00 && resHeader[11] == 0x01))
	

Proceed when the Command field of the FINS/TCP header in the response is 0x00000001

Lines 41-42


byte ClientNodeNo = resHeader[19];
byte ServerNodeNo = resHeader[23];
	

Store byte 19 of the response as the source (client) node number and byte 23 as the destination (server) node number

Lines 45-83


//Send FINS-TCP header + FINS frame
byte[] cmd = new byte[34];
// ----------------- FINS-TCP header
cmd[0] = 0x46;          // "F"
~
cmd[33] = 0x0A;
	

Set the FINS command including the FINS-TCP header in the byte array to send
Here a command that reads 10 words from DM100 is set
For the contents of FINS commands, see FINS Commands

Line 85


ns.Write(cmd, 0, cmd.Length);
	

Send the FINS command

Lines 87-88


byte[] resCmd = new byte[2048];
int resCmdSize = ns.Read(resCmd, 0, resCmd.Length);
	

Receive the response to the FINS command

Lines 90-97


if ((resCmd[8] == 0x00 && resCmd[9] == 0x00) &&
(resCmd[10] == 0x00 && resCmd[11] == 0x02))
{
byte[] rcvData = new byte[resCmdSize];
Array.Copy(resCmd, rcvData, resCmdSize);

textBox1.AppendText(BitConverter.ToString(rcvData) + "\r\n");
}
	

When the Command field of the FINS/TCP header in the response is 0x00000002, store the response data in rcvData and append it to the text box (txtBox1)

Lines 99-1000


ns.Close();
tcp.Close();
	

Dispose of the network stream and the TCP client instance

Related pages

Download

The source introduced here can be downloaded from GitHub

Comments