2012-03-14 2 views
6

Я пытаюсь отправить команды FINS через UDP с ПК (C# .NET) в модуль Ethernet Ethernet (Omron), но не получает ответа от ПЛК и не имеет понятия, где я может начать устранение неполадок.Отправить команду FINS с C# на PLC

PLC имеет очень простую релейную логику, следующим образом: Если DM100 имеет значение #0001, а затем вызвать на выходе 101.00. (Здесь, «Trigger» просто имя символа для области памяти D100 и «Выход» является символом для выхода 101.00) enter image description here

Тогда я написал кусок C#, который выполняет команду плавников «Область памяти Write» который имеет код команды 01 02, за которым следует начальный адрес, количество элементов для записи и данные. Код C# должен записать значение # 0001 в область ПЛК для запуска ВКЛ на 101.00.

[удален код, который не работает] ..

Выход 101.00 не получил сработал, и не получаю никаких исключений. я убедился в следующем:

  1. порт, узел и адрес настроен правильно, как подтверждено «Work Online» в CX-Programmer. Я также пинговал каждый IP, чтобы убедиться, что узлы подключены.
  2. Код UdpClient действителен, так как я написал очень простой код сервера/клиента, который успешно отправляет и принимает пакеты.
  3. Лестничная логика не имеет проблем. Я перенесла лестницу на ПЛК и проверила работу Online в режиме монитора и установила значение D100 вручную.

Я подозреваю, что в массиве fins_cmnd есть ошибка, но, как видно из моего кода, я прокомментировал как можно более подробную информацию о каждом значении; Я ничего не могу найти. Я подозреваю, что не могу правильно разобрать шестнадцатеричный код, но опять же, у меня нет исключения для руководства.

Я понятия не имею, где и как я могу устранить неполадки. Надеюсь, что кто-то здесь с FINS программированием или опытом ПЛК может мне помочь.

[ОТВЕТ]
Благодаря Porge за ссылку - что у меня обнаружили проблему. После пары троп, наконец, заставить его работать. См. Ниже рабочий код.

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(); 

ответ

6

Ни одна из этих строк не будет обрабатываться как шестнадцатеричная. NumberStyles.AllowHexSpecifierразрешает шестнадцатеричный префикс «0x», но не анализирует его число как hex, если оно не присутствует.

Так что вы хотите (char)Int16.Parse("0x64", NumberStyles.AllowHexSpecifier).

Однако числовые литералы в C# могут быть шестнадцатеричными, поэтому вместо того, чтобы делать все, что вы можете просто написать 0x64.

Я только что просмотрел протокол 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 байта каждый. Они не соответствуют тому, что у вас есть, поэтому я расширил этот раздел.

+0

Память, да, 4 байта, поэтому у меня есть два элемента массива 0x00 и 0x64 вместе 4 байта. потому что каждый «раздел» принимает только 16 бит. – KMC

+0

@KMC: Я расширил часть данных, основываясь на том, что, на мой взгляд, должно выглядеть как на данной странице. Помогает ли это? – porges

Смежные вопросы