Send FINS command from C # to PLC

I am trying to send FINS commands via UDP from a PC (C # .NET) to an Ethernet Ethernet module (Omron), but does not receive a response from the PLC and has no idea where I can start troubleshooting.

The PLC has a very simple ladder logic: If the DM100 has the value #0001 , then output 101.00 . (Here, β€œTrigger” is just the symbol name for the D100 memory area, and β€œExit” is the output symbol 101.00 ) enter image description here

Then I wrote a C # snippet that runs the FINS "Write Area Memory" command, which has a command code of 01 02 , followed by the start address, the number of items to write, and data. The C # code must write the value # 0001 to the PLC area D100 in order to enable ON at 101.00 .

[remote code that does not work].

Exit 101.00 does not work, and I get no exceptions. I made sure of the following:

  • The port, node and address are configured correctly, as confirmed in "Work Online" in the CX-Programmer. I also check each IP to make sure that the nodes are connected.
  • The UdpClient code UdpClient valid since I wrote a very simple server / client code that successfully sends and receives packets.
  • Ladder logic has no problems. I moved the ladder to the PLC and checked Work Online in monitor mode and set the value to D100 manually.

I suspect that there is an error in the fins_cmnd array, but as can be seen from my code, I commented on as much as possible detailed information about each value; I can’t find anything. I suspect that I cannot parse the hex code correctly, but then again, I have no exception for the manual.

I have no idea where or how I can troubleshoot. Hope someone here with FINS programming or PLC experience can help me.

[ANSWER]
Thanks to Porge for the link - it made me deal with the problem. After a couple of trails, finally make it work. Below is the working code.

 string SERV_IP_ADDR = "192.168.250.1"; const int FINS_UDP_PORT = 9600; byte[] sendPacket = new byte[] { // Full UDP packet: 80 00 02 00 00 00 00 05 00 19 01 02 82 00 64 00 00 01 00 01 // Header 0x80, //0.(ICF) Display frame information: 1000 0001 0x00, //1.(RSV) Reserved by system: (hex)00 0x02, //2.(GCT) Permissible number of gateways: (hex)02 0x00, //3.(DNA) Destination network address: (hex)00, local network 0x00, //4.(DA1) Destination node address: (hex)00, local PLC unit 0x00, //5.(DA2) Destination unit address: (hex)00, PLC 0x00, //6.(SNA) Source network address: (hex)00, local network 0x05, //7.(SA1) Source node address: (hex)05, PC IP is 192.168.250.5 0x00, //8.(SA2) Source unit address: (hex)00, PC only has one ethernet 0x19, //9.(SID) Service ID: just give a random number 19 // Command 0x01, //10.(MRC) Main request code: 01, memory area write 0x02, //11.(SRC) Sub-request code: 02, memory area write // PLC Memory Area 0x82, //12.Memory area code (1 byte): 82(DM) // Address information 0x00, //13.Write start address (2 bytes): D100 0x64, 0x00, //15.Bit address (1 byte): Default 0 0x00, //16.No. of items (2 bytes): only one address which is D100 0x01, // Write Data 0x00, //18.Data to write (2 bytes): value is 1 0x01, }; UdpClient client = new UdpClient(); //create a UdpClient instance try { client.Send(sendPacket, sendPacket.Length, SERV_IP_ADDR, FINS_UDP_PORT); } catch (SocketException se) { Console.WriteLine(se.ErrorCode + ": " + se.Message); } client.Close(); 
+6
source share
1 answer

None of these lines will be treated as hexadecimal. NumberStyles.AllowHexSpecifier allows the hexadecimal prefix "0x", but does not parse the number as hex if it is not present.

So you need (char)Int16.Parse("0x64", NumberStyles.AllowHexSpecifier) .

However, numeric literals in C # can be hexadecimal, so instead of doing everything you can just write 0x64 .

I just looked at this page as a reference for the protocol, and it would be better to create the message directly as bytes instead of specifying Unicode code points and decoding them in bytes as ASCII. You can also use the array specification syntax to remove a lot of interference:

 var message = new byte[] { // header 0x80, //(ICF) Display frame information: 1000 0001 0x00, //(RSV) Reserved by system: (hex)00 0x02, //(GCT) Permissible number of gateways: (hex)02 0x00, //(DNA) Destination network address: (hex)00, local network 0x00, //(DA1) Destination node address: (hex)00, local PLC unit 0x00, //(DA2) Destination unit address: (hex)00, PLC 0x00, //(SNA) Source network address: (hex)00, local network 0x05, //(SA1) Source node address: (hex)05, PC IP is 192.168.250.5 0x00, //(SA2) Source unit address: (hex)00, PC only has one ethernet 0x19, //(SID) Service ID: just give a random number 19 // command 0x01, //(MRC) Main request code: 01, memory area write 0x02, //(SRC) Sub-request code: 02, memory area write // data 0x82, //Memory area code, 2 bytes: 82(DM) 0x00, //Write start address DM100 0x64, 0x00, 0x00, //Word write: only one address 0x01, 0x00, //Write value of 1 to address DM100 (0000 0000 0000 0001) 0x01, // - this value is 0xaabbccdd -> cc dd aa bb 0x00, 0x00, }; 

It also looks like there are some problems with your data section - according to the linked document, the memory address should be 4 bytes, the record length is 2 bytes and the values ​​are 4 bytes each. They do not match what you have, so I expanded this section.

+6
source

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


All Articles