PDA

Просмотр полной версии : ПЛК-63м



Oleg77
13.09.2018, 17:56
Ребята ! А кто подскажет почему ПЛК-63м виснет и перегружается самопроизвольно ? Это связано с неправильно написанной программой? Может кто сталкивался с такой проблемой ?

melky
14.09.2018, 09:05
Залейте голый проект и проверьте.

Филоненко Владислав
14.09.2018, 09:09
В сервисном меню есть коды последних ошибок, можно понять почему

Oleg77
14.09.2018, 11:36
Залейте голый проект и проверьте.

Спасибо ! Попробуем !

Голый не перегружает.

Oleg77
14.09.2018, 11:39
В сервисном меню есть коды последних ошибок, можно понять почему

Разобрались. Пишет код ошибки 3.
Произошла перезагрузка сторожевым таймером, обусловленная зависанием.
Проверить программу CoDeSys на наличие ошибок.

Спасибо !

Oleg77
14.09.2018, 13:58
Наверное лучше описать поставленную задачу. Пытаемся связать ПЛК-63м с амперметром через RS-485 ModBus RTU. Берём готовый пример c пластинки, подставляем в него свои данные и запускаем программу. ПЛК работает, пакеты бегают и вдруг писк и перезагрузка. По времени нет определённой системности. Может перегрузиться через 3 секунды, может через 7, или 15 и т.п. Потом опять начинает работать. Через некоторое время опять писк и перезагрузка.

Oleg77
14.09.2018, 14:14
В ходе мониторинга было определено, что зависание происходило после принятие пакета от Амперметра. Мониторинг пакетов проводили программой MODSIM32 в режиме Show traffic.
38747

[008][003][000][015][000][001][180][144] - это запрос

[008] - адрес амперметра
[003] - код функции чтения регистра
[000][015] - первый регистр для чтения (0FH)
[000][001] - количество регистров
[180][144] - контрольная сумма

[008][003][002][000][000][100][069] - это ответ

[008] - адрес амперметра
[003] - код функции чтения регистра
[002] - количество байт
[000][000] - данные
[100][069] - контрольная сумма

всё как бы в порядке ! запрос и ответ как по феншую !

Опять писк и перезагрузка. Последний пакет [008][003][002][000][000][100][069].

melky
14.09.2018, 14:20
может у вас таймаут ожидания ответа есть и он как-то в прогамме влияет на ватчдог ?
Типа амперметр задумался с ответом и в этот момент срабатывает ватчдог

Oleg77
15.09.2018, 15:12
может у вас таймаут ожидания ответа есть и он как-то в прогамме влияет на ватчдог ?
Типа амперметр задумался с ответом и в этот момент срабатывает ватчдог

От амперметра ответ пришёл: [008][003][002][000][000][100][069].

Тут в программе есть таймаут T#50ms. Мы его меняли на больший, результат не изменился. Зависание и перезагрузка.

Из одного сообщения на форуме http://www.owen.ru/forum/showthread.php?t=28500 пользователя aRRma99 узнаём, что в библиотеке модбаса есть ошибка. Вот что он пишет:

Еще следует помнить что в библиотеке модбаса есть ошибка из-за которой через пачку в порт мусор идет. Для ее починки следует сделать следующее
(*
В БИБЛИОТЕКЕ OWEN MODBUS.LIB В ФБ MB_UNI_IO ЗАМЕНЯЕМ СТРОКУ 7 НА
WHILE SysComRead(ComHandle, ADR(DataBuf)+DataSize, SIZEOF(DataBuf)-DataSize, 0) <> 0 DO;
инче в случае получения ошибки таймаута FF в след пачке пойдем мусор.
Также для скорости 9600 необходимо установить значение таймера T_FRTU = ~5ms
*)

Тоже попробовали сделать. Всё равно зависает.

Oleg77
16.09.2018, 00:53
Ну и чего хочешь услышать ? Творение выкладывай

Не вопрос !:)

Пример взят с пластинки, которая пришла с ПЛК.

38772

Вот его листинг:



PROGRAM PLC_PRG
VAR
get1_modbus: MB_RD_HOLD_REGS;
get2_modbus: MB_RD_INP_REGS;
get3_modbus: MB_RD_HOLD_REGS;

Buffer: ARRAY[0..255] OF BYTE;
cmpl: BOOL;
port_opened: BYTE := 0;
Init: BOOL;
Settings:COMSETTINGS;
com_num: PORTS:=0;
enabl: BOOL;
err: INT
TimeOut: TIME:=T#50ms;
Exception: BYTE;
DataSize: WORD;
master1: BYTE:= 1;

t: DWORD;
A: WORD := 0;
x: WORD;
x1: WORD;
x2: WORD;
x3: WORD;
d: REAL;
ptr_D:POINTER TO BYTE;

COM_SERVICE1: COM_SERVICE;
END_VAR



t:=t+1;
IF (t MOD 1000)=0 THEN
A := A + 1;
IF A > 9999 THEN
A := 0;
END_IF
END_IF


IF port_opened=0 THEN
Settings.Port:=com_num;
Settings.dwBaudRate:=115200;
Settings.byParity:=0;
Settings.dwTimeout:=0;
Settings.byStopBits:=0;
Settings.dwBufferSize:=0;
Settings.dwScan:=0;
END_IF

COM_SERVICE1(Enable:=(port_opened=0) , Settings:=Settings , Task:=OPEN_TSK );

IF COM_SERVICE1.ready THEN
port_opened:=2;
END_IF

IF port_opened=2 THEN

CASE master1 OF

0:

get1_modbus(
Enable:=enabl ,
Mode:=MB_ASCII ,
DevAddr:=2 ,
FirstAddr:=8 ,
Quantity:=1,
ComHandle:=Settings.Port ,
TimeOut:=TimeOut ,
Buffer:=Buffer ,
Complete=>cmpl ,
Exception=>err ,
ByteCnt=>DataSize );

IF cmpl THEN
IF err=0 THEN
x:=BYTE_TO_WORD(BUFFER[1]) OR SHL(BYTE_TO_WORD(BUFFER[0]),8);
END_IF
master1:=1;
END_IF

1:

get3_modbus(
Enable:=enabl ,
Mode:=MB_ASCII ,
DevAddr:=2 ,
FirstAddr:=10 ,
Quantity:=2,
ComHandle:=Settings.Port ,
TimeOut:=TimeOut ,
Buffer:=Buffer ,
Complete=>cmpl ,
Exception=>err ,
ByteCnt=>DataSize );

IF cmpl THEN
master1:=2;
IF err=0 THEN
ptr_D:=ADR(d);
ptr_D^:=buffer[1];
ptr_D:=ptr_D+1;
ptr_D^:=buffer[0];
ptr_D:=ptr_D+1;
ptr_D^:=buffer[3];
ptr_D:=ptr_D+1;
ptr_D^:=buffer[2];
END_IF
END_IF

2:

get2_modbus(
Enable:= enabl,
Mode:=MB_ASCII ,
DevAddr:=2 ,
FirstAddr:=12 ,
Quantity:=6 ,
ComHandle:= Settings.Port,
TimeOut:=TimeOut ,
Buffer:=Buffer ,
Complete=>cmpl ,
Exception=>err ,
ByteCnt=> DataSize);

IF cmpl THEN
IF err=0 THEN
x1:=BYTE_TO_WORD(BUFFER[1]) OR SHL(BYTE_TO_WORD(BUFFER[0]),8);
x2:=BYTE_TO_WORD(BUFFER[5]) OR SHL(BYTE_TO_WORD(BUFFER[4]),8);
x3:=BYTE_TO_WORD(BUFFER[9]) OR SHL(BYTE_TO_WORD(BUFFER[8]),8);
END_IF
master1:=0;
END_IF
END_CASE

IF enabl = FALSE THEN
enabl := TRUE;
END_IF

IF err <> 0 THEN
enabl := FALSE;
END_IF

END_IF



Коменты убрал чтобы не мешали иероглифы.
Вписываю сюда свои данные. Беру только нулевой блок для эксперимента. Хотя и со вторым и третьим вместе, все пакеты запросов и ответов проходят. Остальное рэмю.

Получается приблизительно как то вот так:



PROGRAM PLC_PRG
VAR
get1_modbus: MB_RD_HOLD_REGS;
(* get2_modbus: MB_RD_INP_REGS;
get3_modbus: MB_RD_HOLD_REGS;
*)
Buffer: ARRAY[0..255] OF BYTE;
cmpl: BOOL;
port_opened: BYTE := 0;
Init: BOOL;
Settings:COMSETTINGS;
com_num: PORTS:=0;
enabl: BOOL;
err: INT
TimeOut: TIME:=T#50ms;
Exception: BYTE;
DataSize: WORD;
master1: BYTE:= 0; (*Нулевой блок*)

t: DWORD;
A: WORD := 0;
x:WORD;
x1: WORD;
x2: WORD;
x3: WORD;
d: REAL;
ptr_D:POINTER TO BYTE;

COM_SERVICE1: COM_SERVICE;
END_VAR



t:=t+1;
IF (t MOD 1000)=0 THEN
A := A + 1;
IF A > 9999 THEN
A := 0;
END_IF
END_IF


IF port_opened=0 THEN
Settings.Port:=com_num;(*Можно и 0 поставить*)
Settings.dwBaudRate:=9600; (*Скорость*)
Settings.byParity:=0;
Settings.dwTimeout:=0;
Settings.byStopBits:=2;(*Стоп биты*)
Settings.dwBufferSize:=0;
Settings.dwScan:=0;
END_IF

COM_SERVICE1(Enable:=(port_opened=0) , Settings:=Settings , Task:=OPEN_TSK );

IF COM_SERVICE1.ready THEN
port_opened:=2;
END_IF

IF port_opened=2 THEN

CASE master1 OF

0:

get1_modbus(
Enable:=enabl ,
Mode:=MB_RTU , (*Можно и 0 поставить*)
DevAddr:=8 ,(*Адрес 8*)
FirstAddr:=15 ,(*Регистр для считывания (0FH)*)
Quantity:=1,(*Один регистр*)
ComHandle:=Settings.Port ,
TimeOut:=TimeOut ,
Buffer:=Buffer ,
Complete=>cmpl ,
Exception=>err ,
ByteCnt=>DataSize );

IF cmpl THEN
IF err=0 THEN

(*Убрал обработку буфера когда пытались определить момент при котором происходит зависание*)
(* x:=BYTE_TO_WORD(BUFFER[1]) OR SHL(BYTE_TO_WORD(BUFFER[0]),8);
так, что остались в работе только FB ModBus*)

END_IF
(* master1:=1;*)
END_IF


(*Отсюда последние два блока отключил, хотя и с ними все запросы и ответы пролетают*)
(*
1:

get3_modbus(
Enable:=enabl ,
Mode:=MB_RTU ,
DevAddr:=8 ,
FirstAddr:=15 ,
Quantity:=2,
ComHandle:=Settings.Port ,
TimeOut:=TimeOut ,
Buffer:=Buffer ,
Complete=>cmpl ,
Exception=>err ,
ByteCnt=>DataSize );

IF cmpl THEN
master1:=2;
IF err=0 THEN
ptr_D:=ADR(d);
ptr_D^:=buffer[1];
ptr_D:=ptr_D+1;
ptr_D^:=buffer[0];
ptr_D:=ptr_D+1;
ptr_D^:=buffer[3];
ptr_D:=ptr_D+1;
ptr_D^:=buffer[2];
END_IF
END_IF

2:

get2_modbus(
Enable:= enabl,
Mode:=MB_RTU ,
DevAddr:=8 ,
FirstAddr:=15 ,
Quantity:=6 ,
ComHandle:= Settings.Port,
TimeOut:=TimeOut ,
Buffer:=Buffer ,
Complete=>cmpl ,
Exception=>err ,
ByteCnt=> DataSize);

IF cmpl THEN
IF err=0 THEN
x1:=BYTE_TO_WORD(BUFFER[1]) OR SHL(BYTE_TO_WORD(BUFFER[0]),8);
x2:=BYTE_TO_WORD(BUFFER[5]) OR SHL(BYTE_TO_WORD(BUFFER[4]),8);
x3:=BYTE_TO_WORD(BUFFER[9]) OR SHL(BYTE_TO_WORD(BUFFER[8]),8);
END_IF
master1:=0;
END_IF

До этого места*)




END_CASE

IF enabl = FALSE THEN
enabl := TRUE;
END_IF

IF err <> 0 THEN
enabl := FALSE;
END_IF

END_IF



Окончательного варианта программы пока нет. Там ещё много чего надо будет написать, а пока экспериментируем и пытаемся понять почему происходит зависание и перезагрузка.

ASo
16.09.2018, 07:35
Аааа, ну в этом примере известная ошибка.