PDA

Просмотр полной версии : Обработка сигнала датчика продукта на дискретный вход ПР



Антон_Б
16.01.2025, 15:32
Здравствуйте
Подскажите, пожалуйста, как реализовать следующий алгоритм:
На дискретный вход ПР200 поступает сигнал от датчика о наличии продукта, выдержка задержки по времени, и формирование выходного сигнала заданной длительности.
Дальше интереснее: Сигналы на вход поступают быстро, до отработки всего алгоритма.
Вижу решение так: чтение времени наступления события по входу, прибавление задержки по времени и в вычисленный момент времени формирование выхода.
Можно ли это реализовать на ОвенЛоджик.
Может есть более простое решение этой задачи?

kondor3000
16.01.2025, 15:45
Здравствуйте
Подскажите, пожалуйста, как реализовать следующий алгоритм:
На дискретный вход ПР200 поступает сигнал от датчика о наличии продукта, выдержка задержки по времени, и формирование выходного сигнала заданной длительности.
Дальше интереснее: Сигналы на вход поступают быстро, до отработки всего алгоритма.
Вижу решение так: чтение времени наступления события по входу, прибавление задержки по времени и в вычисленный момент времени формирование выхода.
Можно ли это реализовать на ОвенЛоджик.
Может есть более простое решение этой задачи?

Для этого существуют быстрые входы на ПР, они могут считать быстрее, чем работает алгоритм (режим подсчёта импульсов),
а в ПР вы считаете что надо, используя эти посчитанные импульсы. Лучше бы вы не темнили, а конкретно написали что надо считать.

Антон_Б
16.01.2025, 15:49
Вопрос не в том, чтобы быстро считать, а чтобы формировать импульсы на выходе, соответсвующим импульсам на входе, с задержкой.
Это отбраковка некачественной наклейки на продукцию.

melky
16.01.2025, 16:00
а че, у ПР уже выходы могут внутри цикла программы работать?
Такого нет вроде, запись выхода только в конце цикла программы.

Антон_Б
16.01.2025, 16:07
Не то пальто.
Дело в работе программных таймеров. Пока таймер считает время, он не "воспринимает" входные импульсы и они теряются. Задержка может быть до 1 сек.
Частота 3 импульса в секунду

melky
16.01.2025, 16:17
пробовали ввести 0.3 секунды для таймера?

Антон_Б
16.01.2025, 16:20
А если нужна задержка 0,5 сек

kondor3000
16.01.2025, 16:25
Не то пальто.
Дело в работе программных таймеров. Пока таймер считает время, он не "воспринимает" входные импульсы и они теряются. Задержка может быть до 1 сек.
Частота 3 импульса в секунду

Не сильно большая программа в ПР имеет цикл 5-30 мс, пусть будет 30. То есть за секунду ПР отработает 33 цикла, для ваших 3 раза в секунду, это быстро.
Таймеры можно использовать и самописные, ссылка ниже. Главное разобраться с алгоритмом. В таймере можно задавать время даже в миллисекундах и получать время таймера в мс.
https://owen.ru/forum/showthread.php?t=37203&page=9&p=429061#81

melky
16.01.2025, 16:32
Антон_Б в настройках таймера вы можете указать дробное число. Или как вариант используйте WriteToFB - он всегда в таймер пишет в мс.

Антон_Б
16.01.2025, 16:35
Вопрос в том, что таймер во время отсчёта задержки не воспринимает входные импульсы. Нужно этот момент победить

melky
16.01.2025, 16:54
напишите разумнее вопрос что ли. Входы читаются в начале цикла программы, выходы записываются в конце цикла программы. Если нет быстрых входов, то два импульса на входе внутри цикла программы будут утеряны (для понимания).
Там пофигу насколько маленькое время вы выставили таймеру.

Другой момент - таймер будет проверять свое время только на следующем цикле программы. Например цикл программы 30мс (ну это очень большая программа для ПР на самом деле), вы таймеру ставите 10 мс. таймер сработает в любом случае через 30 мс, потому что через 10 мс он еще не в курсах, что таймер отработал, так как идет цикл программы..

Антон_Б
16.01.2025, 17:28
Пока таймер формирует задержку, он не реагирует на входные импульсы

Антон_Б
16.01.2025, 17:28
А нужно, что бы задержка отсчитывалась по каждому входному импульсу

Антон_Б
16.01.2025, 18:34
Если на эту схему подавать импульсы чаще 3 сек, то на выходе будет только один импульс за три секунды.
А хотелось бы , чтобы реакция была на каждый

FPavel
16.01.2025, 18:38
Опишите:
1. Характер входов - длительность импульса, минимальная пауза между двумя импульсами
2. Какая реакция программы при приходе импульса? сначала задержка, а потом импульс на выходе - так ___П ? Каие параметры у задержки и импульса?
3. Предположим, что реакция на входной импульс по длительности превосходит минимальную паузу между двумя входными импульсами и их может поступить 2, 3...100. Как программа должна реагировать?

1exan
16.01.2025, 18:42
Если на эту схему подавать импульсы чаще 3 сек, то на выходе будет только один импульс за три секунды.
А хотелось бы , чтобы реакция была на каждый

Если вам кидать яблоки каждую секунду, а на укладку яблока в корзину у вас уходит 3 секунды - куда попадут 2 и 3 яблоки?
Вам нужно не задержку ставить, а счётчик на вход (промежуточную ёмкость для яблок): после очередного импульса счётчик увеличивается на 1, а после выполнения алгоритма (что-бы это не значило) - уменьшается на единицу.

FPavel
16.01.2025, 18:46
Есть двунаправленный универсальный счётчик - по входному импульсу увеличивайте счётчик, по выходному уменьшайте - и так до нулевого состояния.
Если CTU не подходит - сделайте на ST.

if InPulse then
Count := Count + 1;
end_if

if OutPulse then
Count := Count - 1;
end_if;

EnableOutPulse := (Count > 0);

Если есть разрешение формирования импульса EnableOutPulse, то формируйте его - задержку и выдержку - хоть при помощи Blink, хоть TON/TOF.

Антон_Б
16.01.2025, 18:47
Нужно просто сделать смещение входного импульса на заданное время. Типа СДВИГ по времени

1exan
16.01.2025, 19:02
Нужно просто сделать смещение входного импульса на заданное время. Типа СДВИГ по времени

В будущее что-ли сдвигать его? А потом назад?

kondor3000
16.01.2025, 19:05
Нужно просто сделать смещение входного импульса на заданное время. Типа СДВИГ по времени

Просто чуть изменил код таймера, теперь он сбрасывает время и начинает новый отсчёт, от каждого нового TRUE на входе.
Точно так же можно модернизировать таймер TP по импульсу.

Антон_Б
16.01.2025, 19:06
Типа сдвиг по времени пачки импульсов с входа на выход

Антон_Б
16.01.2025, 19:17
Как работает функция get_time()? Какое время она выдает?

kondor3000
16.01.2025, 19:20
Как работает функция get_time()? Какое время она выдает?

Время с начала включения ПР.
В проекте можно вывести Т3 на выход и посмотреть.

Антон_Б
16.01.2025, 19:36
В миллисек?

kondor3000
16.01.2025, 19:37
В миллисек?

Проект запустите в эмуляции, всё будет видно. В мс конечно.

Антон_Б
16.01.2025, 19:40
Спасибо за помощь

FPavel
16.01.2025, 19:42
Так вижу буферизованный генератор-повторитель-расширитель импульсов
81362

Dimensy
16.01.2025, 19:52
А почему бы вместо TP не использовать TOF (можно перед TOF поставить триггер RTRIG). Тогда пока импульсы идут выход будет активным, как только импульсы закончатся выход отключится с задержкой

Антон_Б
16.01.2025, 20:31
Хотелось бы получить, как на рисунке

FPavel
16.01.2025, 20:54
Т.е. звено чистого запаздывания.
Можно попробовать организовать битовый массив состояний входа во времени с циклической организацией записи-чтения.
Но, думаю, что это дороговато использовать ПР с такой целью.

Может быть решение исходной задачи всё же другим, менее затратным способом.

Мы уже 30+ сообщений потратили.

А какая величина запаздывания?
При машинном цикле ПР205 от 3 до 30 мс, в принципе, возможно с дискретностью 10 мс запоминать состояние входа.
Если задержка составит 1 с, то размер массива всего 100 элементов - это немного.

Антон_Б
16.01.2025, 21:06
Это ближе к телу. Делал похожим способом на ПЛК с Codesys. Вот и думал перейти на ПР. Погрешность + - 10 мс не имеет значения.

Антон_Б
16.01.2025, 21:10
Период следования импульсов от 300 мсек

FPavel
16.01.2025, 21:11
Тогда и ST в руки.
Массив bool, два индекса на запись и на чтение, тактирование при помощи BLINK и RTrig.

Столь простые вещи не буду делать - неинтересно, и подозреваю, что исходная задача решается не через звено чистого запаздывания.

Сергей0308
16.01.2025, 21:19
Так это же проще пареной репы, вот когда-то очень давно кому-то помогал на форуме, в смысле, делал задержку почти на 2000 тактов:

81366

Задержку можно настраивать!

Антон_Б
16.01.2025, 21:24
Тогда и ST в руки.
Массив bool, два индекса на запись и на чтение, тактирование при помощи BLINK и RTrig.

Столь простые вещи не буду делать - неинтересно, и подозреваю, что исходная задача решается не через звено чистого запаздывания.

Типа FIFO буфера. Только что в него заносить? Метки времени прихода импульса на входе.

FPavel
16.01.2025, 21:40
A: array [0..999] of bool; // буфер на 1000 * 10 мс = 10 с
InIndx: udint;
OutIndx: udint;

if CLK then // если на тактовом входе true - выполнить пересчёт
A[InIndx] := In;
OutIndx := InIndx + 123; // 123 * 10 ms = 1 s 23 ms - задержка при такте 10 ms
if OutIndx > 999 then
OutIndx := OutIndx - 1000; //минус длина массива
end_if
Out := A[OutIndx]; // значение выхода
InIndx := InIndx + 1;
if InIndx > 999 then
InIndx := InIndx - 1000; //минус длина массива
end_if
end_if
На вход CLK подать выход связки BLINK+RTrig с полным периодом 10 мс (5+5 мс).

Антон_Б
16.01.2025, 21:54
Мне не нужено масштабирование входного импульса, просто по восходящему фронту выдать импульс с задержкой

Антон_Б
16.01.2025, 22:03
Немогу понять как работает выше проведённый код. Что такое In и Out. Типа состояние входа и выхода?
Сначала идёт блок Blink, а затем Rtrig?
Типа змейки, которая непрерывно бегает и ловит вход
℅-/
Гениально

Рогов Алексей
17.01.2025, 07:39
Преобразуем Ваш импульс в целое число: целое умножаем, делим,,, записываем полученное в таймер ТР или TOF - так может?

melky
17.01.2025, 09:13
Антон_Б почему змейки? Blink дает половину выставленного периода 1 а половину 0, если время Th, Tl равны. А для работы вашего или иного макроса нужен импульс, а не удержание 1 Н-ное время. вот RTrig и дает этот самый импульс, длительностью в 1 цикл программы.

Dimensy
17.01.2025, 09:54
У меня как-то так получилось и даже, вроде, работает

function_block Impuls

var_input //объявление входных переменных
U : bool;
Delay : udint; //Длительность задержки импульса, мс
Imp : udint; //Длительность выходного импульса, мс
end_var

var_output //объявление выходных переменных
Q : bool;
end_var

var //объявление локальных переменных
CurTime : udint;
RTrig : SYS.RTRIG;
TOF : SYS.TOF;
MasDel : array[0..9] of udint;
MasImp : array[0..9] of bool;
nWrite, nRead : udint := 0;
flag : bool;
end_var

TOF.T := udint_to_time(Imp);
CurTime := time_to_udint(get_time());
RTrig(I := U);
if RTrig.Q then
MasDel[nWrite] := CurTime + Delay;
MasImp[nWrite] := true;
nWrite := (nWrite + 1) mod 10;
end_if
flag := MasImp[nRead] and CurTime >= MasDel[nRead];
if flag then
MasImp[nRead] := false;
nRead := (nRead + 1) mod 10;
end_if
TOF(I := flag, Q => Q);

end_function_block

Антон_Б
17.01.2025, 10:50
Спасибо, всем сочуствующим, буду пробовать

Антон_Б
17.01.2025, 12:28
A: array [0..999] of bool; // буфер на 1000 * 10 мс = 10 с
InIndx: udint;
OutIndx: udint;

if CLK then // если на тактовом входе true - выполнить пересчёт
A[InIndx] := In;
OutIndx := InIndx + 123; // 123 * 10 ms = 1 s 23 ms - задержка при такте 10 ms
if OutIndx > 999 then
OutIndx := OutIndx - 1000; //минус длина массива
end_if
Out := A[OutIndx]; // значение выхода
InIndx := InIndx + 1;
if InIndx > 999 then
InIndx := InIndx - 1000; //минус длина массива
end_if
end_if
На вход CLK подать выход связки BLINK+RTrig с полным периодом 10 мс (5+5 мс).

В этом примере длительность выходного импульса равна 5 мс. А можно ли ее задавать?
Время не корректно выадерживает. МОжет связано с BLINKom

Антон_Б
17.01.2025, 12:34
У меня как-то так получилось и даже, вроде, работает

function_block Impuls

var_input //объявление входных переменных
U : bool;
Delay : udint; //Длительность задержки импульса, мс
Imp : udint; //Длительность выходного импульса, мс
end_var

var_output //объявление выходных переменных
Q : bool;
end_var

var //объявление локальных переменных
CurTime : udint;
RTrig : SYS.RTRIG;
TOF : SYS.TOF;
MasDel : array[0..9] of udint;
MasImp : array[0..9] of bool;
nWrite, nRead : udint := 0;
flag : bool;
end_var

TOF.T := udint_to_time(Imp);
CurTime := time_to_udint(get_time());
RTrig(I := U);
if RTrig.Q then
MasDel[nWrite] := CurTime + Delay;
MasImp[nWrite] := true;
nWrite := (nWrite + 1) mod 10;
end_if
flag := MasImp[nRead] and CurTime >= MasDel[nRead];
if flag then
MasImp[nRead] := false;
nRead := (nRead + 1) mod 10;
end_if
TOF(I := flag, Q => Q);

end_function_block

ГОДНЫЙ ВАРИАНТ, ТО ЧТО НУЖНО, СПАСИБО ЗА ПОМОЩЬ

Dimensy
17.01.2025, 18:42
ГОДНЫЙ ВАРИАНТ, ТО ЧТО НУЖНО, СПАСИБО ЗА ПОМОЩЬ

Упустил нюанс с переполнением. От греха подальше, лучше поправить две строчки

function_block Impuls

var_input //объявление входных переменных
U : bool;
Delay : udint; //Длительность задержки импульса, мс
Imp : udint; //Длительность выходного импульса, мс
end_var

var_output //объявление выходных переменных
Q : bool;
end_var

var //объявление локальных переменных
CurTime : udint;
RTrig : SYS.RTRIG;
TOF : SYS.TOF;
MasDel : array[0..9] of udint;
MasImp : array[0..9] of bool;
nWrite, nRead : udint := 0;
flag : bool;
end_var

TOF.T := udint_to_time(Imp);
CurTime := time_to_udint(get_time());
RTrig(I := U);
if RTrig.Q then
MasDel[nWrite] := CurTime;
MasImp[nWrite] := true;
nWrite := (nWrite + 1) mod 10;
end_if
flag := MasImp[nRead] and CurTime - MasDel[nRead] >= Delay;
if flag then
MasImp[nRead] := false;
nRead := (nRead + 1) mod 10;
end_if
TOF(I := flag, Q => Q);

end_function_block

FPavel
17.01.2025, 19:00
В этом примере длительность выходного импульса равна 5 мс. А можно ли ее задавать?
Время не корректно выадерживает. МОжет связано с BLINKom
Странно, вроде бы, выдерживает


function_block Delay

var_input
In: bool;
Clk: bool;
end_var

var_output
Out: bool;
end_var

var
A: array [0..999] of bool; // буфер на 1000 * 10 мс = 10 с
InIndx: udint;
OutIndx: udint;
end_var

if CLK then // если на тактовом входе true - выполнить пересчёт
A[InIndx] := In;
OutIndx := InIndx + 123; // 123 * 10 ms = 1 s 23 ms - задержка при такте 10 ms
if OutIndx > 999 then
OutIndx := OutIndx - 1000; //минус длина массива
end_if
Out := A[OutIndx]; // значение выхода
InIndx := InIndx + 1;
if InIndx > 999 then
InIndx := InIndx - 1000; //минус длина массива
end_if
end_if
end_function_block

81384

Ничего не менял в коде...

По хорошему, BLINK и RTrig реализовать бы на ST, но хотел принцип реализации задержки показать.