Вход

Просмотр полной версии : обмен Pc <-> Plc



IVM
01.11.2010, 11:55
Добрый день, уважаемое сообщество.

Мне необходимо посылать из PC в ПЛК (ПЛК 110) определенное количество байт данных и читать из ПЛК в PC определенное количество байт данных (ПЛК - Slave), т.е. стандартная задача. Используется интерфейс RS-485 и протокол MODBUS RTU. Для того чтобы организовать этот обмен я решил использовать функции с кодами 3 (Чтение регистров из контроллера) и 16 (Запись регистров в контроллер). В PLC Configuration ПЛК я необходимое количество байт зарезервировал. Если я пытаюсь только читать или только писать регистры то все прекрасно работает, т.е. идет нормальный обмен. Когда я пытаюсь чередовать эти команды (мне необходима двухсторонняя передача данных), то тут с откликом от контроллера творится что-то непонятное (контрольные суммы принятые и расчетные не совпадают). Я пытался использовать команду с кодом 23 (чтение/запись регистров за одну транзакцию), но ПЛК ее вообще отказывается понимать. В ответ на эту посылку ПЛК правильно возвращает свой адрес, а далее в пакете отклика все не то что надо и длина пакета не та что должна быть. Я так понял, что эту функцию ПЛК вообще не поддерживает. Может кто-то что-то посоветуете.

С уважением, Владимир Михайлович.

Gans
01.11.2010, 14:51
Попробуйте всё тоже само только по интерфейсу Ethernet. Должно получится проще и быстрее. Кстати там нет CRC :-)

IVM
02.11.2010, 08:10
Добрый день, уважаемое сообщество.

Мне необходимо посылать из PC в ПЛК (ПЛК 110) определенное количество байт данных и читать из ПЛК в PC определенное количество байт данных (ПЛК - Slave), т.е. стандартная задача. Используется интерфейс RS-485 и протокол MODBUS RTU. Для того чтобы организовать этот обмен я решил использовать функции с кодами 3 (Чтение регистров из контроллера) и 16 (Запись регистров в контроллер). В PLC Configuration ПЛК я необходимое количество байт зарезервировал. Если я пытаюсь только читать или только писать регистры то все прекрасно работает, т.е. идет нормальный обмен. Когда я пытаюсь чередовать эти команды (мне необходима двухсторонняя передача данных), то тут с откликом от контроллера творится что-то непонятное (контрольные суммы принятые и расчетные не совпадают). Я пытался использовать команду с кодом 23 (чтение/запись регистров за одну транзакцию), но ПЛК ее вообще отказывается понимать. В ответ на эту посылку ПЛК правильно возвращает свой адрес, а далее в пакете отклика все не то что надо и длина пакета не та что должна быть. Я так понял, что эту функцию ПЛК вообще не поддерживает. Может кто-то что-то посоветуете.

С уважением, Владимир Михайлович.

Все оказалось очень просто. Отрегулировал паузу между посылкой пакета в ПЛК и чтением отклика и все заработало как надо. К контроллеру притензий нет, он все делает корректно. Спасибо всем кто откликнулся.

chukandgeck
17.12.2010, 16:27
Здоровья!

Прошу помощи!
Уже неделю не могу понять что происходит,ситуация следующая:
ПЛК 150 посредством программы с использованием SysLibSockets.lib через ETHERNET передает строку символов ПК.

В сети 1 Гбит и 100 Мбит – все ОК. Все отсылается и принимается на ура.
В сети 512 Кбит(через провайдера) – ПЛК не может даже проконнектиться для посыла…, хотя и может принимать данные через SysSockSend. Пинг проходит. Загрузка файлов командой plc_io.exe тоже идет. CoDeSys тоже работает.

Наверное что-то с программой.
Очень нужен совет…

PROGRAM CLIENT
VAR
SEND_DATA_REQ: BOOL := FALSE;
STATE_SEND: INT := 0;
SOCK_OUT: DINT;
TCP_ADR_OUT:SOCKADDRESS;
PADDR_OUT: DWORD;
OUT_TON:TON;
RCV_SND_BUF: ARRAY[ 0..65 ] OF BYTE;
RES_OUT : BOOL;
SEND_BYTES: DINT;
WAS_IT_SEND: BOOL := FALSE;
L: INT;
sts: STRING;
END_VAR

(* программа *)
L := L + 1;
CASE STATE_SEND OF
0: SOCK_OUT := SysSockCreate( SOCKET_AF_INET, SOCKET_STREAM, SOCKET_IPPROTO_TCP );
TCP_ADR_OUT.sin_family := SOCKET_AF_INET;
TCP_ADR_OUT.sin_port := 5544; TCP_ADR_OUT.sin_addr := 16#C0A8C8CF; (* 192.168.200.207 *)

PADDR_OUT := ADR( TCP_ADR_OUT );
OUT_TON( IN := FALSE, PT := T#50MS ); STATE_SEND := 1;
1: RES_OUT := SysSockConnect( SOCK_OUT, PADDR_OUT, SIZEOF( PADDR_OUT) ); OUT_TON( IN := TRUE, PT := T#5S ); (* ставил до 20 сек *)
IF OUT_TON.Q THEN
STATE_SEND := 2;
END_IF
2: sts := CONCAT(INT_TO_STRING(L), '-- проверка');
SEND_BYTES := SysSockSend( SOCK_OUT, ADR(sts), 32, 0 ); IF SEND_BYTES > 0 THEN SysSockClose( SOCK_OUT ); SEND_DATA_REQ := FALSE; STATE_SEND := 0;
ELSE
SysSockClose( SOCK_OUT ); SEND_DATA_REQ := FALSE; STATE_SEND := 0;
END_IF
(* end client*)