Просмотр полной версии : ПЛК110-30-М02 нестандартный проткол к весам ВСП4
павелсиражев
23.09.2021, 10:45
Здравствуйте. Возникла задача подключить электронные весы ВСП4 с индикатором НВТ-9 к ПЛК 110-30-М02. Весы непрерывно передают данные через RS-232. Протокол данных во вложении. Использовал библиотеку SysLibCom.lib. Вот код.
PROGRAM PLC_PRG
VAR
port:COMSETTINGS:=(Port:=COM1,dwBaudRate:=2400);
portReady:BOOL;
buf:ARRAY[0..13]OF BYTE;
END_VAR
IF NOT portReady THEN(* Сразу открываем и настраиваем порт *)
portReady:=TRUE;
SysComOpen(port.Port);
SysComSetSettings(port.Port,ADR(port));
ELSE(* Работаем с открытым портом *)
SysComRead(port.Port, ADR(buf), 14, 0);
END_IF
Проблема в том, что данные в буфере buf меняются хаотично при неизменном весе. Связь плк с пк через Ethernet.
Не могу понять в чем причина. Может кто подскажет. Спасибо.
павелсиражев
24.09.2021, 11:33
А где выделение пакетов из потока байт ? Где таймауты ?
А как это сделать? Т.е. надо перед чтением последующего пакета выдержать время? А сколько? Спасибо.
павелсиражев
24.09.2021, 12:52
Добрый день. Переделал программу, добавил выдержку времени 300мс.
PROGRAM PLC_PRG
VAR
T1:=TON;
delay:TIME:=T#300ms;
port:COMSETTINGS:=(Port:=COM1,dwBaudRate:=2400);
portReady:BOOL;
buf:ARRAY[0..13]OF BYTE;
END_VAR
T1(IN:=TRUE,PT:=delay);(*запускаем таймер*)
IF NOT portReady THEN(* Сразу открываем и настраиваем порт *)
portReady:=TRUE;
SysComOpen(port.Port);
SysComSetSettings(port.Port,ADR(port));
ELSE(* Работаем с открытым портом *)
SysComRead(port.Port, ADR(buf), 14, 0);
END_IF
(*Если таймер запущен и закончил работу, то останавливаем таймер*)
IF(T1.IN=TRUE AND T1.Q=TRUE) THEN
T1(IN:=FALSE,PT:=T#0s);
END_IF
Но ничего не изменилось.
Данные из индикатора передаются в непрерывном режиме в коде ASCII в COM-порт ПЭВМ (скорость 9600, нечет, 8 бит, 1 стоп).
Сделайте выводы елки палки....
Вам надо написать код так, чтобы ловить 0x0D 0x0A и начинать хранение в буфер пакета до следующих 0x0D 0x0A
А или первые 77 6E ловить и далее до окончания.
Выдергивать строку с весом и парсить значение...
Sergey666
24.09.2021, 13:05
А где выделение пакетов из потока байт ? Где таймауты ?
Где выделение пакетов из хаотичного потока байт?
Функция чтения из порта возвращает кол-во прочитанных байт, начать прием может с какого угодно места и получить какой угодно кусок пакетов, надо сложить последовательно буффер не из 14байт а хотя-бы 28, найти байты начала строки и выцедить данные, далее чистить буффер и читать- заполнять заново
Можно читать по 1 байту и если там 0x77 дочитывать 13 оставшихся, проверять что в последних двух 0x0D 0x0A и во втором 0x6E быть уверенным что пакет полный.
Вам же уже выделили жирным текстом. Скорость весов 9600 , а установлено 2400.
Sergey666
24.09.2021, 22:41
Если что - 15 достаточно. Учитывая string удобней 16.
А если придет с середины пакета?
ужос будет простой, сколько раз ПЛК должен будет обождать, пока пакет не придет полностью ? :)
Валенок а разве ПЛК не будет успевать по одному байту и сверять его например либо с началом пакета либо с окончанием?
По идее после окончания пакета 0х0A всегда должна быть пауза у прибора, То есть мы теряем один пакет. То есть дождались 0x0A и начали чтение нового пакета.
Я так понимаю в программе же надо делать "начало измерения" то есть какая-то кнопка "Пуск" для программы, измерили, остановились, сохранили в базу или еще куда-то. Ну не читать же пустые весы постоянно.
Почему бы и нет ? Кто-то запыхается (см. п. 1) ? ну если цель стоит только отображать на HMI значение то не запыхается.
А если стоит цель что-то положили на весы, взвесить, отобразить, куда-то передать, то как бы зачем?
Ну хотя код чтения порта и разбора переменной может крутиться всегда и уже программой сверху выдергивать, не суть.
я думаю, что пауза там есть, хоть о ней и не написано, снифер покажет.
Sergey666
25.09.2021, 11:58
Вот потому, что спешить особо некуда, лучше надергать буффер 28 байт, т.е в котором будет гарантированный полный пакет, и уже парсить эту кучу, выдернув сам пакет и уже распарсив его вытащить данные искомые.
Но вариантов решения задачи может быть как минимум 3, так что кто как хочет, так этим и занимается;)
Sergey666
25.09.2021, 13:17
Для 'Wn' достаточно 15-ти, а дальше примитивная работа со строкой где выдернуть пакет не больше кода чем надергав 28.
К тому же, в отличие, не будет потери последнего вдруг пакета если он внезапно не ляжет в [14..27] ))
Скользящий разбор буффера приема? Код усложняется.
Я могу предположить их не менее 64730 на 25-09-21 12:25 - у Овена внизу написано.
И чё там у него написано?
Sergey666
25.09.2021, 15:46
Да ладно.
А давайте сравним кол-во шагов разбора Вашего буфера с данными (описанием) :
Дождались 28 байт.
..
?
По китайски прямолинейно...
1. В цикле ищем w, проверяем следующий n, если нет буффер ф топку, если да хватаем номер(i) в буффере и Return из этого цикла;
2. В цикле из буффера, начиная с (i) выбрасываем в буффер данных 7 байт, проверяем следующие в на соответствие k,g, если нет, все ф топку, если да буффер в топку и Return из этого цикла;
3. Весело верещща конвертируем буффер данных в Real;
4. Повторяем экзекуцию с заполнением буффера и ...начинаем, шило и мочало-начинай сначала.
Статистика Форум АСУ ТП. ОВЕН форум
Тем 25,307 Сообщений 324,534 Пользователи 64,730 Активные участники 2,046
Это про минимальное кол-во вариантов ))
Ну и сколько из 2,046 (щас слеза навернулась) вообще поймут о чем речь?
Sergey666
25.09.2021, 16:21
Не менее прямолинейно..
При получении любой порции данных к текущему буферу :
1. Ищу 'wn' - Если нашел выкидываю всё что до, если нет и длина = 15 буфер в топку.
2. Если длина данных >= 14 беру на проверку [2..11] на бяки для хорошо/буфер в топку
3. "Весело верещща конвертируем хорошие данные в Real" (С)
4. Из буфера удаляю первые 14 байт
Всё. Циклов - нет ))
2. Если длина данных >= 14 беру на проверку [2..11] на бяки для хорошо/буфер в топку
Это при каком размере буфера? Если 15-16, а wn обнаруживается в конце начала середины то "хороших данных" может не быть вовсе.
З.Ы Да, "при получении любой порции данных к текущему буферу" это норм, если потерь пакетов не будет
павелсиражев
27.09.2021, 07:20
Да, спасибо. Понял ошибку! Буду ловить начало пакета. Кстати, скорость обмена в настройках у весов можно менять, я просто пробовал разные скорости, остановился на минимальной, но дело не в скорости.
павелсиражев
27.09.2021, 09:40
Исправил код. Вот он.
PROGRAM PLC_PRG
VAR
portReady:BOOL;
port:COMSETTINGS:=(Port:=COM1,dwBaudRate:=2400,byS topBits:=0,byParity:=1,dwBufferSize:=28);
buf:ARRAY[0..27]OF BYTE;(*данные из весов через RS232*)
buf1:ARRAY[0..7]OF BYTE;(*массив веса*)
i:INT:=0;
i1:INT:=0;
END_VAR
IF portReady=FALSE THEN(* Сразу открываем и настраиваем порт *)
portReady:=TRUE;
SysComOpen(port.Port);
SysComSetSettings(port.Port,ADR(port));
ELSE(* Работаем с открытым портом *)
SysComRead(port.Port, ADR(buf),28,0);
END_IF
FOR i:=0 TO 27 DO
IF (buf[i]=119)AND(buf[i+1]=110) THEN
FOR i1:=0 TO 7 DO
buf1[i1]:=buf[i1+i+2];
END_FOR
END_IF
END_FOR
Прогнал по шагам. В буфере из 28 байт (buf[0..27] какие-то странные данные. Например:в десятичном коде 119,119,152,152,76,76,38,38,90,157,53,10,119,119,1 52,152,76,76,38,38,9,90,157,53,10,119,119,152
Последовательности 119,110( wn)вообще нет. Чисто числовых данных( 48-57) почти нет. И непонятно откуда там данные больше 127?
а 127 это разве для десятичного формата?
Sergey666
27.09.2021, 10:44
Чистить буфер приема надо перед чтением. И на скорости 2400 может порт некорректно работать, что хотя-бы 9600 нельзя поставить?
павелсиражев
27.09.2021, 10:54
а 127 это разве для десятичного формата?
Но в ASCII коде нет кодов больше 7F.
павелсиражев
27.09.2021, 10:55
Можно , попробую.
павелсиражев
27.09.2021, 10:56
Чистить буфер приема надо перед чтением. И на скорости 2400 может порт некорректно работать, что хотя-бы 9600 нельзя поставить?
Можно, попробую.
павелсиражев
27.09.2021, 11:05
Еще исправил код . Как только нашел код 119(w) , то сохраняю данные в другом буфере веса buf1, дальше пропускаю.
PROGRAM PLC_PRG
VAR
portReady:BOOL;
port:COMSETTINGS:=(Port:=COM1,dwBaudRate:=9600,byS topBits:=0,byParity:=1,dwBufferSize:=28);
buf:ARRAY[0..27]OF BYTE;(*данные из весов через RS232*)
buf1:ARRAY[0..7]OF BYTE;(*массив веса*)
i:INT:=0;
i1:INT:=0;
i3:INT:=0;(* индикатор наличия кода 119*)
END_VAR
IF portReady=FALSE THEN(* Сразу открываем и настраиваем порт *)
portReady:=TRUE;
SysComOpen(port.Port);
SysComSetSettings(port.Port,ADR(port));
ELSE(* Работаем с открытым портом *)
SysComRead(port.Port, ADR(buf),28,0);
END_IF
IF (i<=27)OR(i3=0) THEN
IF buf[i]=119 THEN
i3:=1;
FOR i1:=0 TO 7 DO
buf1[i1]:=buf[i+i1+2];
END_FOR
ELSE
i:=i+1;
END_IF
END_IF
i:=0;
i3:=0;
В общем ничего не меняется.
Но в ASCII коде нет кодов больше 7F.
это в режиме 7 бит данных больше нет, а по факту все 256 символов
176 dec - символ градуса по таблице
Sergey666
27.09.2021, 11:52
Вот последний код чета индокитайщиной попахивает...
Вот тут почитайте по работе с SysComRead: https://owen.ru/forum/showthread.php?t=21306
Ну и еще можно поискать
Вооот тут почитать:- https://owen.ru/forum/showthread.php?t=22498
павелсиражев
27.09.2021, 14:48
В общем, проблема в том, что исходный массив- буфер из 28 байтов, принятый по RS232 от весов уже кривой! Нет нужных символов, точки с кодом 46, символов к и g, числа с кодом 48-57 разбросаны как попало. При весе строго 0.0 весы должны выдавать где нибудь такие данные: 119,110, 48,48,48,48,48,48,46,48,107,103,13,10 . Но этого нет, все хаотично. Я уже пробовал кабель экранированный и скорости менял. Все безрезультатно.
В общем, проблема в том, что исходный массив- буфер из 28 байтов, принятый по RS232 от весов уже кривой! Нет нужных символов, точки с кодом 46, символов к и g, числа с кодом 48-57 разбросаны как попало. При весе строго 0.0 весы должны выдавать где нибудь такие данные: 119,110, 48,48,48,48,48,48,46,48,107,103,13,10 . Но этого нет, все хаотично. Я уже пробовал кабель экранированный и скорости менял. Все безрезультатно.
это встречается и у модемов, если скорости не одинаковы у компорта
павелсиражев любым ПО на прослушку порта - что дает ?
Чисто бросилось в глаза.
еще назначение i3 вызывает недоумение, видимо что то осталось от предыдущих изысканий
павелсиражев
28.09.2021, 08:16
В общем ничего не меняется, да.
При условии что это копипаста проекта - как было порно, так и осталось.
Чисто бросилось в глаза.
Валенок, я ничего не понял из Вашего комментария!
павелсиражев
28.09.2021, 08:20
еще назначение i3 вызывает недоумение, видимо что то осталось от предыдущих изысканий
Так проще. Не вижу смысла по каждому случаю применять ООП, это только усложняет код.
Так вы не написали, если подключиться к линии при помощи ПК, то какие наборы байт вы видите в посылках ?
Так проще. Не вижу смысла по каждому случаю применять ООП, это только усложняет код.
что проще? Эта переменная, кроме как присваивания ей единички с ноликом больше ни чем не занимается, это как раз избыточный код и усложненный потому что приходится тратить время чтобы понять а что она делает
И опять спрошу, не проще читать буфером в 1 байт ловя 0x0A и потом читать буфер в 14 байт с полноценным ответом и далее его разбирать, проверив и первый и второй и последние байты в уверенности целостности пакета ? Или потом читать уже постоянно по 14 байт, а в случае нарушения пакета переходить к поиску нужного байта ?
павелсиражев
28.09.2021, 09:24
Так вы не написали, если подключиться к линии при помощи ПК, то какие наборы байт вы видите в посылках ?
Например:в десятичном коде 119,119,152,152,76,76,38,38,90,157,53,10,119,119,1 52,152,76,76,38,38,9,90,157,53,10,119,119,152
почему у вас дважды идут одни и те же байты? в документации вроде такого нет ? первые 0x77 0x6E то есть 119 110 а у вас 4 раза подряд повторы
В конце 53 10 есть а должно быть 13 10 (0x0D 0x0A)
похоже что-то со скоростями не складуха или еще с чем-то. У вас там контроль четности не включен случайно ?
хотя контроль четности должен только старший бит менять, а у вас лажа какая-то
павелсиражев
28.09.2021, 09:40
Написал новый код.
PROGRAM PLC_PRG
VAR
portReady:BOOL;
port:COMSETTINGS:=(Port:=COM1,dwBaudRate:=9600,byS topBits:=0,byParity:=1,dwBufferSize:=28);
buf:ARRAY[0..27]OF BYTE;(*данные из весов через RS232*)
bufCopy:ARRAY[0..27]OF BYTE;
buf1:ARRAY[0..7]OF BYTE;(*массив веса*)
bufzero:ARRAY[0..27]OF BYTE:=28(0);
i:INT:=0;
i1:INT:=0;
i3:INT:=0;
dIW:DWORD:=0;
END_VAR
WHILE dIW<>5000000 DO
dIW:=dIW+1;
END_WHILE
dIW2:=dIW2+1;
IF portReady=FALSE THEN(* Сразу открываем и настраиваем порт *)
portReady:=TRUE;
SysComOpen(port.Port);
SysComSetSettings(port.Port,ADR(port));
SysComRead(port.Port, ADR(buf),28,0);
ELSE(* Работаем с открытым портом *)
SysComRead(port.Port, ADR(buf),28,0);
END_IF
bufCopy:=buf;
WHILE (i<=27)AND(i3=0)DO
IF bufCopy[i]=119 THEN
i3:=1;
FOR i1:=0 TO 7 DO
buf1[i1]:=bufCopy[i+i1+2];
END_FOR
END_IF
i:=i+1;
END_WHILE
i:=0;
i3:=0;
buf:=bufzero;
dIW:=0;
В нем я изменил скорость обмена на 9600, добавил обнуление буфера перед чтением данных.
Сразу принимаю 28 байт, делаю его копию и ищу код 119, затем сохраняю в массив buf1 чисто данные веса.
Еще добавил выдержку времени ( простой счетчик через WHILE, через таймер TON у меня не получилось).
Данные идут, но логики в них нет.
павелсиражев
28.09.2021, 09:47
почему у вас дважды идут одни и те же байты? в документации вроде такого нет ? первые 0x77 0x6E то есть 119 110 а у вас 4 раза подряд повторы
В конце 53 10 есть а должно быть 13 10 (0x0D 0x0A)
похоже что-то со скоростями не складуха или еще с чем-то. У вас там контроль четности не включен случайно ?
хотя контроль четности должен только старший бит менять, а у вас лажа какая-то
В том то и дело,что таких данных не должно быть.
В конфигурации ПЛК в параметрах порта Parity стоит ODD ( нечет).
Должно быть Parity - НЕТ
не ЧЕТ не НЕЧЕТ а НЕТ!!!!!!!!!!!!!!!
Сорян, в доке указан "нечет" а попробуйте НЕТ установить
павелсиражев
28.09.2021, 09:52
57186
Вот скриншот с плк.
павелсиражев
28.09.2021, 09:54
Должно быть Parity - НЕТ
не ЧЕТ не НЕЧЕТ а НЕТ!!!!!!!!!!!!!!!
Сорян, в доке указан "нечет" а попробуйте НЕТ установить
Данные из индикатора передаются в непрерывном режиме в коде ASCII в COM-порт ПЭВМ (скорость 9600, нечет, 8 бит, 1 стоп).
павелсиражев
28.09.2021, 09:57
Должно быть Parity - НЕТ
не ЧЕТ не НЕЧЕТ а НЕТ!!!!!!!!!!!!!!!
Сорян, в доке указан "нечет" а попробуйте НЕТ установить
Уже попробовал, не помогло.
павелсиражев да ,я видел. Но в той строке, что вы выкладывали в десятичном виде, явно не хватает байт между 10-ками. Точно это ПК получает такие данные ? точно порт настроен правильно, не только в программе, но и в настройках самого порта ?
павелсиражев
28.09.2021, 10:01
Вообще, я заметил, что если гонять программу по шагам, то буфер buf заполняется полностью (хотя также хаотично). Если программу запускать без остановок, то в буфер записывается только 8 байт, остальные остаются нулевыми. Выдержка времени увеличивает буфер, но все равно на сами данные это не влияет.
павелсиражев
28.09.2021, 10:17
павелсиражев да ,я видел. Но в той строке, что вы выкладывали в десятичном виде, явно не хватает байт между 10-ками. Точно это ПК получает такие данные ? точно порт настроен правильно, не только в программе, но и в настройках самого порта ?
Вроде пошли нормальные данные. Ура! Я в конфигурации ПЛК задал в параметре Parity задал NO PARITY, но еще в программе исправил строку
port:COMSETTINGS:=(Port:=COM1,dwBaudRate:=9600,byS topBits:=0,byParity:=0,dwBufferSize:=28);
павелсиражев
28.09.2021, 10:19
Порно осталось.
А что это за процедура "SysComRead" ?
ps
процедура == program (местный) == void == ...
Это из библиотеки SysLibCom функция чтения из порта.
Sergey666
28.09.2021, 10:36
Вроде пошли нормальные данные. Ура! Я в конфигурации ПЛК задал в параметре Parity задал NO PARITY, но еще в программе исправил строку
port:COMSETTINGS:=(Port:=COM1,dwBaudRate:=9600,byS topBits:=0,byParity:=0,dwBufferSize:=28);
В какой конфигурации ПЛК? Вы что этот порт еще и в конфигурации используете???
По правильной работе с портом читайте по вышеприложенным (пост#36) ссылкам, тогда понятно будет почему буфер приема заполняется не полностью.
павелсиражев
28.09.2021, 13:02
Порно осталось.
А что это за процедура "SysComRead" ?
ps
процедура == program (местный) == void == ...
Это из библиотеки SysLibCom функция чтения из порта.
павелсиражев
28.09.2021, 13:08
Вот окончательный вид рабочей программы .
PROGRAM PLC_PRG
VAR
port:COMSETTINGS:=(Port:=COM1,dwBaudRate:=9600,byS topBits:=0,byParity:=0,dwBufferSize:=28);
portReady:BOOL;
buf:ARRAY[0..27]OF BYTE;(*данные из весов через RS232*)
bufCopy:ARRAY[0..27]OF BYTE;
buf1:ARRAY[0..7]OF BYTE;(*массив веса*)
bufzero:ARRAY[0..27]OF BYTE:=28(0);
i:INT:=0;
i1:INT:=0;
i3:INT:=0;
dIW:DWORD:=0;
dIW2:DWORD:=0;
iWES: REAL:=0;
iSTEP:INT;
WES: REAL;(*чистый вес*)
iDEC: INT;
I4: BOOL := FALSE;
END_VAR
WHILE dIW<>500000 DO(*выдержка времени*)
dIW:=dIW+1;
END_WHILE
dIW2:=dIW2+1;
IF NOT portReady THEN(* Сразу открываем и настраиваем порт *)
portReady:=TRUE;
SysComOpen(port.Port);
SysComSetSettings(port.Port,ADR(port));
SysComRead(port.Port, ADR(buf),28,0);
ELSE(* Работаем с открытым портом *)
SysComRead(port.Port, ADR(buf),28, 0);
END_IF
bufCopy:=buf;
WHILE (i<=27)AND(i3=0)DO
IF bufCopy[i]=119 THEN
i3:=1;
FOR i1:=0 TO 7 DO
buf1[i1]:=bufCopy[i+i1+2];
END_FOR
END_IF
i:=i+1;
END_WHILE
FOR i:=0 TO 7 DO
IF buf1[i]= 46 THEN
I4:=TRUE;
iSTEP:=7-i;(*количество знаков после десятичной точки*)
iDEC:=i;(*положение десятичной точки*)
END_IF;
END_FOR;
IF i4=TRUE THEN
CASE iDEC-4 OF
2: buf1[iDEC]:=buf1[iDEC+1];
1: buf1[iDEC]:=buf1[iDEC+1];
buf1[iDEC+1]:=buf1[iDEC+2];
0: buf1[iDEC]:=buf1[iDEC+1];
buf1[iDEC+1]:=buf1[iDEC+2];
buf1[iDEC+2]:=buf1[iDEC+3];
END_CASE;
FOR i:=0 TO 6 DO
iWES:=iWES+(buf1[i]-48)*EXPT(10,(6-i));
END_FOR;
WES:=iWES/EXPT(10,iSTEP);
END_IF
i4:=FALSE;
iWES:=0;
i:=0;
i3:=0;
buf:=bufzero;
dIW:=0;
Сделал еще визуализацию для переменной WES.Проект во вложении.
Все отлично работает как часы! Всем спасибо!
павелсиражев
28.09.2021, 13:19
Функция ? Ничего себе. А вызываете как процедуру. Ничего не забыли ?
ps
Про чутьвышесказанное Sergey666 кстати да.
Выкладывайте сам проект а не левые кусочки.
А почему я не могу просто вызвать функцию? Если мне не нужно возвращаемое значение .
Хотя в описании библиотеки SysLibCom написано, что это функция, скорее это функциональный блок.
павелсиражев
28.09.2021, 14:58
В посте#4 я выложил программу с выдержкой времени по таймеру, но он никак не хочет считать. Не могу понять в чем причина? Хотелось бы , конечно сделать выдержку по таймеру, а не как я сделал через счетчик.
kondor3000
28.09.2021, 15:36
Добрый день. Переделал программу, добавил выдержку времени 300мс.
PROGRAM PLC_PRG
VAR
T1:=TON;
delay:TIME:=T#300ms;
port:COMSETTINGS:=(Port:=COM1,dwBaudRate:=2400);
portReady:BOOL;
buf:ARRAY[0..13]OF BYTE;
END_VAR
В посте № 4 у вас ошибка, надо равно в объявлении таймера убрать. Вот так должно быть T1:TON;
И в выложенной программе, у вас в конфигурации, так и осталось скорость 2400 и нечётный .
Sergey666
28.09.2021, 23:28
Все отлично работает как часы! Всем спасибо!
Вот ведь...а рекомендованные посты не прочитал..., #нуладно
павелсиражев
29.09.2021, 06:57
Вот ведь...а рекомендованные посты не прочитал..., #нуладно
Нет, те посты я прочитал, очень интересно ,много нового узнал.Спасибо.
Результат напоминает браконьера с гранатой на рыбалке. Нужно поесть - тонна рыбы кверху брюхом, пару рыбин на ужин и пошли дальше. Задача поесть - решена, да. И как часы само собой.
тише, тише, он знает такие слова как ООП, просто в виду примитивности задачи не желает его применять, а так бы показал нам кузькину мать
павелсиражев
29.09.2021, 08:28
В посте № 4 у вас ошибка, надо равно в объявлении таймера убрать. Вот так должно быть T1:TON;
И в выложенной программе, у вас в конфигурации, так и осталось скорость 2400 и нечётный .
Вот написал простую прогу с таймером TON.
PROGRAM PLC_PRG
VAR
T1:TON;
in1:BOOL:=FALSE;
delay:TIME:=T#10000ms;
i1:INT:=0;
END_VAR
IF in1=FALSE THEN
in1:=TRUE;
i1:=0;
T1(IN:=TRUE,PT:=delay);(*запускаем таймер*)
END_IF
IF T1.Q=TRUE THEN
in1:=FALSE;
T1(IN:=FALSE,PT:=T#0s);
ELSE
i1:=i1+1;
END_IF
Почему-то таймер не считает?
kondor3000
29.09.2021, 09:35
Вот написал простую прогу с таймером TON.
Почему-то таймер не считает?
Вставте строчку T1(); в тело программы.
Для правильной работы таймера, он должен быть вызван вне конструкции IF .... END_IF 57193
А таймер из поста #4, работает, если равно убрать.57194
И кстати там он вызван вне конструкции, почему то)))
Sergey666
29.09.2021, 09:41
Вот написал простую прогу с таймером TON.
PROGRAM PLC_PRG
VAR
T1:TON;
in1:BOOL:=FALSE;
delay:TIME:=T#10000ms;
i1:INT:=0;
END_VAR
IF in1=FALSE THEN
in1:=TRUE;
i1:=0;
T1(IN:=TRUE,PT:=delay);(*запускаем таймер*)
END_IF
IF T1.Q=TRUE THEN
in1:=FALSE;
T1(IN:=FALSE,PT:=T#0s);
ELSE
i1:=i1+1;
END_IF
Почему-то таймер не считает?
А чё он должен считать, если вызван внутри конструкции if-Then, которая false?
павелсиражев
29.09.2021, 11:07
Вставте строчку T1(); в тело программы.
Для правильной работы таймера, он должен быть вызван вне конструкции IF .... END_IF 57193
А таймер из поста #4, работает, если равно убрать.57194
И кстати там он вызван вне конструкции, почему то)))
Спасибо. Заработал. Вот не знал что таймер надо вызывать вне IF...END_IF.
Вроде про это нигде не написано?
павелсиражев
29.09.2021, 12:29
А чё он должен считать, если вызван внутри конструкции if-Then, которая false?
А почему он не работает внутри конструкции if...then?
А в другой конструкции будет работать, например FOR?
А почему он не работает внутри конструкции if...then?
Потому, что таймер не аппаратный, а программный
FUNCTION_BLOCK TON
(*
Timer on delay.
Q is TRUE, PT milliseconds after IN had a rising edge.
*)
VAR_INPUT
IN: BOOL; (* starts timer with rising edge, resets timer with falling edge *)
PT: TIME; (* time to pass, before Q is set *)
END_VAR
VAR_OUTPUT
Q: BOOL; (* is TRUE, PT seconds after IN had a rising edge *)
ET: TIME; (* elapsed time *)
END_VAR
VAR
M: BOOL; (* internal variable *)
StartTime: TIME; (* internal variable *)
END_VAR
F (IN) THEN
IF (NOT M) THEN
(* Start Timer *)
STARTTIME := TIME();
END_IF
IF (NOT Q) THEN
(* Timer is running *)
ET := TIME() - STARTTIME;
IF (ET >= PT) THEN
Q := TRUE;
ET := PT;
END_IF
END_IF
ELSE
(* Reset everything *)
Q := FALSE;
ET := t#0s;
END_IF
M := IN;
Если ты этот код не вызываешь каждый цикл ПЛК, то естественно переменные внутри кода никак не изменяются.
Sergey666
29.09.2021, 12:44
А почему он не работает внутри конструкции if...then?
А в другой конструкции будет работать, например FOR?
Вы в здравом уме? Справка по кодесису доступна? Еще и PDF руководства найти, можно даже на русском и почитать про операторы условий и циклов.
kondor3000
29.09.2021, 13:44
Спасибо. Заработал. Вот не знал что таймер надо вызывать вне IF...END_IF.
Вроде про это нигде не написано?
Ну вам ответили уже)))
Ещё пару моментов. Не надо писать IF in1=TRUE THEN, достаточно IF in1 THEN, так как IF всегда проверяет на истинность. И дважды ему этого делать не надо.
А запись IF in1=FALSE THEN, можно сделать как IF NOT in1 THEN.
павелсиражев
30.09.2021, 07:11
Ну вам ответили уже)))
Ещё пару моментов. Не надо писать IF in1=TRUE THEN, достаточно IF in1 THEN, так как IF всегда проверяет на истинность. И дважды ему этого делать не надо.
А запись IF in1=FALSE THEN, можно сделать как IF NOT in1 THEN.
Спасибо, учту.
павелсиражев
30.09.2021, 07:17
Вы в здравом уме? Справка по кодесису доступна? Еще и PDF руководства найти, можно даже на русском и почитать про операторы условий и циклов.
57215
Вот что написано в справке по кодесису, то же и в руководстве.( вложение)
павелсиражев
30.09.2021, 10:15
Потому, что таймер не аппаратный, а программный
FUNCTION_BLOCK TON
(*
Timer on delay.
Q is TRUE, PT milliseconds after IN had a rising edge.
*)
VAR_INPUT
IN: BOOL; (* starts timer with rising edge, resets timer with falling edge *)
PT: TIME; (* time to pass, before Q is set *)
END_VAR
VAR_OUTPUT
Q: BOOL; (* is TRUE, PT seconds after IN had a rising edge *)
ET: TIME; (* elapsed time *)
END_VAR
VAR
M: BOOL; (* internal variable *)
StartTime: TIME; (* internal variable *)
END_VAR
F (IN) THEN
IF (NOT M) THEN
(* Start Timer *)
STARTTIME := TIME();
END_IF
IF (NOT Q) THEN
(* Timer is running *)
ET := TIME() - STARTTIME;
IF (ET >= PT) THEN
Q := TRUE;
ET := PT;
END_IF
END_IF
ELSE
(* Reset everything *)
Q := FALSE;
ET := t#0s;
END_IF
M := IN;
Если ты этот код не вызываешь каждый цикл ПЛК, то естественно переменные внутри кода никак не изменяются.
А что то у Вас видео о кодесис на канале без звука?
павелсиражев
30.09.2021, 13:45
Что за ерунда! Не могу понять. Вчера все работало,а сегодня уже не работает! Связи с весами нет, ничего не считывает.
павелсиражев
01.10.2021, 09:21
Кто-нибудь знает , критично ли для ПЛК 110-220-30-Р (М02) если перепутать питание фазы с нулем? (L и N)
павелсиражев
01.10.2021, 09:25
батарейка у часов села?
Оказалось, что у индикатора весов НВТ-9 перестал работать порт RS 232. Другой индикатор подключил, все работает. Почему он сдох, не пойму? Я мог перепутать питание на ПЛК фазу с нулем(вилку не так подключить).
kondor3000
01.10.2021, 10:23
Оказалось, что у индикатора весов НВТ-9 перестал работать порт RS 232. Другой индикатор подключил, все работает. Почему он сдох, не пойму? Я мог перепутать питание на ПЛК фазу с нулем(вилку не так подключить).
Если просто не так вилку воткнуть, ничего бы не случилось, а если на горячую ещё и RS232 перетыкать, то может и порт сгореть. Но лучше так не делать.
при чем тут питание и порт ?
A.Simonov
01.10.2021, 16:23
Кто-нибудь знает , критично ли для ПЛК 110-220-30-Р (М02) если перепутать питание фазы с нулем? (L и N)
Для ПЛК это не критично, так как напряжение переменное ~230В 50Гц
Это значит что полярность сигнала меняется с частотой примерно 100 Гц
Однако это может быть важно, если вы монтируете щит... Где-нибудь таким образом можно и фазу на нейтраль замкнуть...
павелсиражев
21.10.2021, 12:11
Здравствуйте. Я работаю с ПЛК-110-220.30.Р-М. У него имеется 12 дискретных выходов. Но меня вводит в заблуждение то что на корпусе прибора первые четыре выхода обозначены как FDO (1-4), т.е как быстродействующие, а остальные обозначены как DO (5-12). В настройках целевой платформы у меня выбрано PLC110.30-M v2 и в конфигурации ПЛК первые 4 выхода тоже обозначены как FDO( см. скриншоты во вложении). С другой стороны в руководстве по эксплуатации re_plk110_m02__1-ru-20416-1.31.pdf в разделе технические характеристики «Дискретные выходы (контакты электромагнитных реле ПЛК110-Х.Х.Р(М02))» указано что количество релейных выходных каналов для ПЛК110-Х.30(М02) равно 12.
Помогите, пожалуйста разобраться в этой путанице.
Можно ли использовать дискретные выхода DO 1-4 (они же FDO 1-4) как обычные релейные выходы и подключать к ним нагрузку с напряжением~ 220 в? Спасибо.
kondor3000
21.10.2021, 13:41
Здравствуйте. Я работаю с ПЛК-110-220.30.Р-М. У него имеется 12 дискретных выходов. Но меня вводит в заблуждение то что на корпусе прибора первые четыре выхода обозначены как FDO (1-4), т.е как быстродействующие, а остальные обозначены как DO (5-12). В настройках целевой платформы у меня выбрано PLC110.30-M v2 и в конфигурации ПЛК первые 4 выхода тоже обозначены как FDO( см. скриншоты во вложении). С другой стороны в руководстве по эксплуатации re_plk110_m02__1-ru-20416-1.31.pdf в разделе технические характеристики «Дискретные выходы (контакты электромагнитных реле ПЛК110-Х.Х.Р(М02))» указано что количество релейных выходных каналов для ПЛК110-Х.30(М02) равно 12.
Помогите, пожалуйста разобраться в этой путанице.
Можно ли использовать дискретные выхода DO 1-4 (они же FDO 1-4) как обычные релейные выходы и подключать к ним нагрузку с напряжением~ 220 в? Спасибо.
А при чём здесь быстрые или обычные выходы? Если они вообще релейные, то можно и 220 переключать. Просто на быстрых выходах реле могут работать ещё и как ШИМ до определённой частоты.
Powered by vBulletin® Version 4.2.3 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot