我尝试通过UDP从PC(C#.NET)将 FINS 命令发送到PC以太网模块(Omron),但没有从PLC得到任何响应,也不清楚我从哪里可以开始进行故障排除。
PLC具有非常简单的梯形图逻辑,如下所示:
如果DM100
的值为#0001
,则在输出101.00
上触发。 (在这里,“触发器”只是存储区D100
的符号名,而“输出”是输出101.00
的符号)
然后,我编写了一段C#,它执行“Memory Area Write”的FINS命令,该命令的命令代码为01 02
,后跟开始地址,要写入的项目数以及数据。 C#代码应将#0001
的值写入PLC的D100
区域,以在101.00
上触发ON。
[删除的代码无效]。
输出101.00
没有被触发,我也没有收到任何异常。
我确保以下几点:
UdpClient
代码有效,因为我编写了一个非常简单的服务器/客户端代码,可以成功发送和接收数据包。 D100
一个值。 我怀疑
fins_cmnd
数组中有错误,但是从我的代码中可以看出,我对每个值都尽可能详细地进行了注释。我可能找不到任何东西。我怀疑我可能无法正确解析十六进制,但是同样,我也没有异常(exception)来指导我。我不知道在哪里以及如何进行故障排除。希望这里有
FINS
编程或PLC经验的人能为我提供帮助。[ANSWER]
感谢链接porg -这使我发现了问题。经过几番尝试后,终于可以正常工作了。参见下面的工作代码。
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's 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();
最佳答案
这些字符串都不会被解析为十六进制。 NumberStyles.AllowHexSpecifier
允许使用十六进制前缀“0x”,但除非存在该数字,否则不会将其解析为十六进制。
因此,您需要(char)Int16.Parse("0x64", NumberStyles.AllowHexSpecifier)
。
但是,C#中的数字文字可以是十六进制的,因此您可以只编写0x64
而不是做所有的事情。
我刚刚查看了协议(protocol)的this page as a reference,并且直接将消息创建为字节而不是指定Unicode代码点并将其解码为ASCII也是更好的选择。您还可以使用数组规范语法来消除很多困惑情况:
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's 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,
};
您的数据部分似乎也有问题-根据链接的文档,内存地址应为4个字节,写入长度为2个字节,值分别为4个字节。这些与您所拥有的不匹配,因此我在该部分进行了扩展。
关于c# - 从C#发送FINS命令到PLC,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9695639/