Просмотр полной версии : Обработка сигнала датчика продукта на дискретный вход ПР
Здравствуйте
Подскажите, пожалуйста, как реализовать следующий алгоритм:
На дискретный вход ПР200 поступает сигнал от датчика о наличии продукта, выдержка задержки по времени, и формирование выходного сигнала заданной длительности.
Дальше интереснее: Сигналы на вход поступают быстро, до отработки всего алгоритма.
Вижу решение так: чтение времени наступления события по входу, прибавление задержки по времени и в вычисленный момент времени формирование выхода.
Можно ли это реализовать на ОвенЛоджик.
Может есть более простое решение этой задачи?
kondor3000
16.01.2025, 15:45
Здравствуйте
Подскажите, пожалуйста, как реализовать следующий алгоритм:
На дискретный вход ПР200 поступает сигнал от датчика о наличии продукта, выдержка задержки по времени, и формирование выходного сигнала заданной длительности.
Дальше интереснее: Сигналы на вход поступают быстро, до отработки всего алгоритма.
Вижу решение так: чтение времени наступления события по входу, прибавление задержки по времени и в вычисленный момент времени формирование выхода.
Можно ли это реализовать на ОвенЛоджик.
Может есть более простое решение этой задачи?
Для этого существуют быстрые входы на ПР, они могут считать быстрее, чем работает алгоритм (режим подсчёта импульсов),
а в ПР вы считаете что надо, используя эти посчитанные импульсы. Лучше бы вы не темнили, а конкретно написали что надо считать.
Вопрос не в том, чтобы быстро считать, а чтобы формировать импульсы на выходе, соответсвующим импульсам на входе, с задержкой.
Это отбраковка некачественной наклейки на продукцию.
а че, у ПР уже выходы могут внутри цикла программы работать?
Такого нет вроде, запись выхода только в конце цикла программы.
Не то пальто.
Дело в работе программных таймеров. Пока таймер считает время, он не "воспринимает" входные импульсы и они теряются. Задержка может быть до 1 сек.
Частота 3 импульса в секунду
пробовали ввести 0.3 секунды для таймера?
А если нужна задержка 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
Антон_Б в настройках таймера вы можете указать дробное число. Или как вариант используйте WriteToFB - он всегда в таймер пишет в мс.
Вопрос в том, что таймер во время отсчёта задержки не воспринимает входные импульсы. Нужно этот момент победить
напишите разумнее вопрос что ли. Входы читаются в начале цикла программы, выходы записываются в конце цикла программы. Если нет быстрых входов, то два импульса на входе внутри цикла программы будут утеряны (для понимания).
Там пофигу насколько маленькое время вы выставили таймеру.
Другой момент - таймер будет проверять свое время только на следующем цикле программы. Например цикл программы 30мс (ну это очень большая программа для ПР на самом деле), вы таймеру ставите 10 мс. таймер сработает в любом случае через 30 мс, потому что через 10 мс он еще не в курсах, что таймер отработал, так как идет цикл программы..
Пока таймер формирует задержку, он не реагирует на входные импульсы
А нужно, что бы задержка отсчитывалась по каждому входному импульсу
Если на эту схему подавать импульсы чаще 3 сек, то на выходе будет только один импульс за три секунды.
А хотелось бы , чтобы реакция была на каждый
Опишите:
1. Характер входов - длительность импульса, минимальная пауза между двумя импульсами
2. Какая реакция программы при приходе импульса? сначала задержка, а потом импульс на выходе - так ___П ? Каие параметры у задержки и импульса?
3. Предположим, что реакция на входной импульс по длительности превосходит минимальную паузу между двумя входными импульсами и их может поступить 2, 3...100. Как программа должна реагировать?
Если на эту схему подавать импульсы чаще 3 сек, то на выходе будет только один импульс за три секунды.
А хотелось бы , чтобы реакция была на каждый
Если вам кидать яблоки каждую секунду, а на укладку яблока в корзину у вас уходит 3 секунды - куда попадут 2 и 3 яблоки?
Вам нужно не задержку ставить, а счётчик на вход (промежуточную ёмкость для яблок): после очередного импульса счётчик увеличивается на 1, а после выполнения алгоритма (что-бы это не значило) - уменьшается на единицу.
Есть двунаправленный универсальный счётчик - по входному импульсу увеличивайте счётчик, по выходному уменьшайте - и так до нулевого состояния.
Если 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.
Нужно просто сделать смещение входного импульса на заданное время. Типа СДВИГ по времени
Нужно просто сделать смещение входного импульса на заданное время. Типа СДВИГ по времени
В будущее что-ли сдвигать его? А потом назад?
kondor3000
16.01.2025, 19:05
Нужно просто сделать смещение входного импульса на заданное время. Типа СДВИГ по времени
Просто чуть изменил код таймера, теперь он сбрасывает время и начинает новый отсчёт, от каждого нового TRUE на входе.
Точно так же можно модернизировать таймер TP по импульсу.
Типа сдвиг по времени пачки импульсов с входа на выход
Как работает функция get_time()? Какое время она выдает?
kondor3000
16.01.2025, 19:20
Как работает функция get_time()? Какое время она выдает?
Время с начала включения ПР.
В проекте можно вывести Т3 на выход и посмотреть.
kondor3000
16.01.2025, 19:37
В миллисек?
Проект запустите в эмуляции, всё будет видно. В мс конечно.
Так вижу буферизованный генератор-повторитель-расширитель импульсов
81362
А почему бы вместо TP не использовать TOF (можно перед TOF поставить триггер RTRIG). Тогда пока импульсы идут выход будет активным, как только импульсы закончатся выход отключится с задержкой
Хотелось бы получить, как на рисунке
Т.е. звено чистого запаздывания.
Можно попробовать организовать битовый массив состояний входа во времени с циклической организацией записи-чтения.
Но, думаю, что это дороговато использовать ПР с такой целью.
Может быть решение исходной задачи всё же другим, менее затратным способом.
Мы уже 30+ сообщений потратили.
А какая величина запаздывания?
При машинном цикле ПР205 от 3 до 30 мс, в принципе, возможно с дискретностью 10 мс запоминать состояние входа.
Если задержка составит 1 с, то размер массива всего 100 элементов - это немного.
Это ближе к телу. Делал похожим способом на ПЛК с Codesys. Вот и думал перейти на ПР. Погрешность + - 10 мс не имеет значения.
Период следования импульсов от 300 мсек
Тогда и ST в руки.
Массив bool, два индекса на запись и на чтение, тактирование при помощи BLINK и RTrig.
Столь простые вещи не буду делать - неинтересно, и подозреваю, что исходная задача решается не через звено чистого запаздывания.
Сергей0308
16.01.2025, 21:19
Так это же проще пареной репы, вот когда-то очень давно кому-то помогал на форуме, в смысле, делал задержку почти на 2000 тактов:
81366
Задержку можно настраивать!
Тогда и ST в руки.
Массив bool, два индекса на запись и на чтение, тактирование при помощи BLINK и RTrig.
Столь простые вещи не буду делать - неинтересно, и подозреваю, что исходная задача решается не через звено чистого запаздывания.
Типа FIFO буфера. Только что в него заносить? Метки времени прихода импульса на входе.
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 мс).
Мне не нужено масштабирование входного импульса, просто по восходящему фронту выдать импульс с задержкой
Немогу понять как работает выше проведённый код. Что такое In и Out. Типа состояние входа и выхода?
Сначала идёт блок Blink, а затем Rtrig?
Типа змейки, которая непрерывно бегает и ловит вход
℅-/
Гениально
Рогов Алексей
17.01.2025, 07:39
Преобразуем Ваш импульс в целое число: целое умножаем, делим,,, записываем полученное в таймер ТР или TOF - так может?
Антон_Б почему змейки? Blink дает половину выставленного периода 1 а половину 0, если время Th, Tl равны. А для работы вашего или иного макроса нужен импульс, а не удержание 1 Н-ное время. вот RTrig и дает этот самый импульс, длительностью в 1 цикл программы.
У меня как-то так получилось и даже, вроде, работает
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
Спасибо, всем сочуствующим, буду пробовать
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
У меня как-то так получилось и даже, вроде, работает
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
ГОДНЫЙ ВАРИАНТ, ТО ЧТО НУЖНО, СПАСИБО ЗА ПОМОЩЬ
ГОДНЫЙ ВАРИАНТ, ТО ЧТО НУЖНО, СПАСИБО ЗА ПОМОЩЬ
Упустил нюанс с переполнением. От греха подальше, лучше поправить две строчки
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
В этом примере длительность выходного импульса равна 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, но хотел принцип реализации задержки показать.
Powered by vBulletin® Version 4.2.3 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot