PDA

Просмотр полной версии : измерение скважности входного шим сигнала



svr007
05.11.2018, 22:30
Добрый вечер. Есть плк 110-60р и насосы которые отдают обратную связь шим сигналом при фиксированной частоте 75 гц., аварии и мощность передаются через скважность(процент заполнения).Подскажите пожалуйста алгоритм подсчета скважности в Codesys 2.3.

Ryzhij
06.11.2018, 07:45
Соберите RC-цепочку для усреднения ШИМ-сигнала и просто измеряйте напряжение.
Про мощность через ШИМ ещё понятно, а вот про аварии )))
Может, там просто дискретный сигнал?

svr007
06.11.2018, 08:20
Без АЦП никак? У ПЛК на борту нет аналоговых входов,только дискретные, покупать отдельно модуль не хочется. Насос до 70% заполнения отдает мощность, а дальше процент заполнения - аварии и предупреждения,100% заполнения- насос остановлен.

Ryzhij
06.11.2018, 08:43
Модуль быстрого ввода с такой функцией обойдётся Вам ничуть не дешевле, а цикл ПЛК слишком велик для такой задачи.

petera
06.11.2018, 09:55
Модуль быстрого ввода с такой функцией обойдётся Вам ничуть не дешевле, а цикл ПЛК слишком велик для такой задачи.

Если время цикла ПЛК укладывается в 1 мс, то на обычных входах можно измерять длительность сигнала 2 мс и более. Период входного сигнала = 1/75 = 13,33 мс. По этому минимальный коэффициент заполнения (D=dT/T), который можно измерить 0,15 (15%).
Если время цикла ПЛК больше, то и погрешность будет больше.
Если ПЛК - М2, то использование быстрого входа и прерывания 20 мкс, помогут измерить скважность без дополнительных модулей.

svr007
06.11.2018, 10:03
Если время цикла ПЛК укладывается в 1 мс, то на обычных входах можно измерять длительность сигнала 2 мс и более. Период входного сигнала = 1/75 = 13,33 мс. По этому минимальный коэффициент заполнения (D=dT/T), который можно измерить 0,15 (15%).
Если время цикла ПЛК больше, то и погрешность будет больше.
Если ПЛК - М2, то использование быстрого входа и прерывания 20 мкс, помогут измерить скважность без дополнительных модулей.

Добрый день. ПЛК М2 на борту 4 быстрых входа, подскажите приблизительный алгоритм.

Sulfur
06.11.2018, 10:34
svr007
Читайте про инструмент HardellaIDE, с ним можно на ПЛК110[M2] работать с быстрыми входами с циклом до 1 мкс.

svr007
06.11.2018, 11:18
HardellaIDE и быстрые входа вроде больше как для энкодеров, на ум приходит алгоритм:
1.запускать прерывание по фронту сигнала
2.в прерывание запускать таймер, в следующем прерывании считать и обнулить
3.мерить время между импульсами сигнала, зная время периода вычислять процент заполнения.
У меня будет 4 входа шим, ПЛК не загнется такова количества? хочется более правильный алгоритм.

Sulfur
06.11.2018, 12:11
В ПЛК[М2] быстрые входа и выхода обслуживаются физически другим сопроцессором, который обменивается с основным процессором через область обмена. Харделла позволяет писать алгоритм именно для сопроцессора быстрых входов\выходов.
Только вот таймеров там нет, придется писать самостоятельно, используя время цикла сопроцессора как квант отсчета.

Ryzhij
06.11.2018, 13:13
Добро бы речь шла о крупносерийном или хотя бы серийном изделии...
Дополнительные затраты на программирование кто-нибудь посчитает? ;)

petera
06.11.2018, 13:31
Добро бы речь шла о крупносерийном или хотя бы серийном изделии...
Дополнительные затраты на программирование кто-нибудь посчитает? ;)
Мы тут что делаем? Контроллеры программируем!
Какие затраты на программирование, Вы о чем?

petera
06.11.2018, 13:41
HardellaIDE и быстрые входа вроде больше как для энкодеров, на ум приходит алгоритм:
1.запускать прерывание по фронту сигнала
2.в прерывание запускать таймер, в следующем прерывании считать и обнулить
3.мерить время между импульсами сигнала, зная время периода вычислять процент заполнения.
У меня будет 4 входа шим, ПЛК не загнется такова количества? хочется более правильный алгоритм.

Зачем Вам HardellaIDE?
Используйте библиотеки Timer и SysLibPorts
только прерывания будут не не по фронту сигнала а от 20мкс таймера.
Внутри POU обработки прерывания от таймера можно напрямую анализировать состояние быстрых дискретных входов
Пример работы с быстрыми входами есть на диске
39664


Некоторые контроллеры ОВЕН ПЛК имеют встроенный таймер, по прерыванию которого может быть
вызван отдельная программа (POU), не связанная с выполнением основной программы ПЛК. Минимальный
период вызовов прерываний таймера составляет 20мкс и может быть увеличен при вызове функции
инициализации. Период должен быть кратен 20мкс. В POU, вызываемому по этому прерыванию, могут
обрабатываться состояния "быстрых" входов и выходов ПЛК. Такой режим обработки может потребоваться
для задач, время обработки которых должно быть существенно меньше времени цикла ПЛК или для
автоматизации объектов, критичных ко времени реакции на определенные события.
К "быстрым" входам и выходам относятся несколько первых входов и выходов на ПЛК110. Подробно о
количестве "быстрых" входов и выходов смотри руководство по эксплуатации на контроллер.

Ryzhij
06.11.2018, 19:21
Мы тут что делаем? Контроллеры программируем!
Какие затраты на программирование, Вы о чем?
При всем уважении, тут мы трепемся, а программируем в другом месте.
Пока одни костыли...
Сможете добиться стабильности и повторяемости результатов на разных экземплярах ПЛК без подстройки программы?
А на разных сериях ПЛК? ;)
Этим и отличается "колхоз" от "промышленных решений" - повторяемостью результатов и ремонтопригодностью.

svr007
13.11.2018, 08:59
Накидал алгоритм, если честно мне не нравится,думаю можно сделать красивее, но работает точно.
Вся обработка идет в прерываниях системного таймера каждые 60 мкс. Осциллограф подтвердил что все точно обрабатывается.
39754

svr007
13.11.2018, 09:02
Тут полная схема
39755

petera
13.11.2018, 11:21
Мой вариант
39766

Прерывания таймера - 40мкс.


PROGRAM PWM_meter
VAR
count: DWORD; (*счетчик прерываний таймера*)
in: BYTE;
start1: DWORD;
State1: INT;
start2: DWORD;
State2: INT;
start3: DWORD;
State3: INT;
start4: DWORD;
State4: INT;
END_VAR
В обработчике прерываний подсчитывается длительность входных импульса - dT в единицах прерывания для каждого входа


count:= count + 1;
in:= SysPortIn(0);

(*--- Первый вход ПЛК ---*)
CASE State1 OF
0:
IF in.0 THEN
start1:= count;
State1:= 1;
END_IF
1:
IF NOT in.0 THEN
dT1_cycle:= count - start1;
State1:= 0;
END_IF
END_CASE

(*--- Второй вход ПЛК ---*)
CASE State2 OF
0:
IF in.1 THEN
start2:= count;
State2:= 1;
END_IF
1:
IF NOT in.0 THEN
dT2_cycle:= count - start2;
State2:= 0;
END_IF
END_CASE


Полученные значения передаются в PLC_PRG через глобальные переменные

VAR_GLOBAL
dT1_cycle: DWORD;
dT2_cycle: DWORD;
dT3_cycle: DWORD;
dT4_cycle: DWORD;
END_VAR

Коэффициенты заполнения рассчитываются в PLC_PRG

PROGRAM PLC_PRG
VAR
init:BOOL:=TRUE; (* Переменная для инициализации прерывания таймера при запуске основной программы *)
F: REAL := 75.0; (*Частота ШИМ в Гц*)
D1: REAL; (* коэфф. заполнения 1 в %*)
D2: REAL; (* коэфф. заполнения 2 в %*)
D3: REAL; (* коэфф. заполнения 3 в %*)
D4: REAL; (* коэфф. заполнения 4 в %*)
END_VAR

(*Инициализируем обработчик прерывания таймера и настраиваем период срабатывания таймерного прерывания*)
IF (init=TRUE) THEN
SetIRQ(40); (*Период задается в мкс, должен быть кратен 20*)
(*ВНИМАНИЕ! Включенный обработчик прерывания работает даже после останове программы,
если необходимо его отключать и повторно включать, то делайте это в обработчике событий "Stop" и "Start"*)
init:=FALSE; (*Обнуление переменной инициализации, чтобы она не происходила на втором и последующих циклах ПЛК*)
END_IF

(*коэффициент заполнения D= dT/T= dT * F *)
D1:= DWORD_TO_REAL(dT1_cycle) * 40 * F / 10000; (* коэфф. заполнения в %*)
D2:= DWORD_TO_REAL(dT2_cycle) * 40 * F / 10000;
D3:= DWORD_TO_REAL(dT3_cycle) * 40 * F / 10000;
D4:= DWORD_TO_REAL(dT4_cycle) * 40 * F / 10000;

svr007
13.11.2018, 11:43
Мой вариант
39766

Прерывания таймера - 40мкс.
В обработчике прерываний подсчитывается длительность входных импульсов - dT в единицах прерывания, для каждого входа


PROGRAM PWM_meter
VAR
count: DWORD; (*счетчик прерываний таймера*)
in: BYTE;
start1: DWORD;
State1: INT;
start2: DWORD;
State2: INT;
start3: DWORD;
State3: INT;
start4: DWORD;
State4: INT;
END_VAR
В обработчике прерываний подсчитывается длительность входных импульса - dT в единицах прерывания для каждого входа


count:= count + 1;
in:= SysPortIn(0);

(*--- Первый вход ПЛК ---*)
CASE State1 OF
0:
IF in.0 THEN
start1:= count;
State1:= 1;
END_IF
1:
IF NOT in.0 THEN
dT1_cycle:= count - start1;
State1:= 0;
END_IF
END_CASE

(*--- Второй вход ПЛК ---*)
CASE State2 OF
0:
IF in.1 THEN
start2:= count;
State2:= 1;
END_IF
1:
IF NOT in.0 THEN
dT2_cycle:= count - start2;
State2:= 0;
END_IF
END_CASE


Полученные значения передаются в PLC_PRG через глобальные переменные

VAR_GLOBAL
dT1_cycle: DWORD;
dT2_cycle: DWORD;
dT3_cycle: DWORD;
dT4_cycle: DWORD;
END_VAR

Коэффициенты заполнения рассчитываются в PLC_PRG

PROGRAM PLC_PRG
VAR
init:BOOL:=TRUE; (* Переменная для инициализации прерывания таймера при запуске основной программы *)
F: REAL := 75.0; (*Частота ШИМ в Гц*)
D1: REAL; (* коэфф. заполнения 1 в %*)
D2: REAL; (* коэфф. заполнения 2 в %*)
D3: REAL; (* коэфф. заполнения 3 в %*)
D4: REAL; (* коэфф. заполнения 4 в %*)
END_VAR

(*Инициализируем обработчик прерывания таймера и настраиваем период срабатывания таймерного прерывания*)
IF (init=TRUE) THEN
SetIRQ(40); (*Период задается в мкс, должен быть кратен 20*)
(*ВНИМАНИЕ! Включенный обработчик прерывания работает даже после останове программы,
если необходимо его отключать и повторно включать, то делайте это в обработчике событий "Stop" и "Start"*)
init:=FALSE; (*Обнуление переменной инициализации, чтобы она не происходила на втором и последующих циклах ПЛК*)
END_IF

(*коэффициент заполнения D= dT/T= dT * F *)
D1:= DWORD_TO_REAL(dT1_cycle) * 40 * F / 10000; (* коэфф. заполнения в %*)
D2:= DWORD_TO_REAL(dT2_cycle) * 40 * F / 10000;
D3:= DWORD_TO_REAL(dT3_cycle) * 40 * F / 10000;
D4:= DWORD_TO_REAL(dT4_cycle) * 40 * F / 10000;


Спасибо большое за подсказку, буду тестировать. А чем обусловлен выбор 40 мкс? повышением точности?. Я выбирал 60 чтоб меньше грузить ПЛК,точность устраивает.

petera
13.11.2018, 11:49
Спасибо большое за подсказку, буду тестировать. А чем обусловлен выбор 40 мкс? повышением точности?. Я выбирал 60 чтоб меньше грузить ПЛК,точность устраивает.
Ничем не обусловлен.

Пусть будет 60, только изменить
SetIRQ(60); (*Период задается в мкс, должен быть кратен 20*)
формулу поправить
D1:= DWORD_TO_REAL(dT1_cycle) * 60 * F / 10000; (* коэфф. заполнения в %*)

svr007
13.11.2018, 12:19
Я понял. С точки зрения ресурсов ПЛК это тяжело ему? В основной программе будет обмен с модулями,облако и панель оператора.
Ну и в догонку какой колхоз пришлось на подопытным сделать что бы отладить прогу
39768
Генератора сигнала нету,пришлось на быстые выхода вместо реле прикрутить оптопару TLP620,все работает фронты четкие.

svr007
13.11.2018, 13:26
Petera еще раз спасибо большое, проверил все работает. Направление понял, код поправлю( не учитывается 0 и 100%).

Филоненко Владислав
13.11.2018, 18:18
Для таких высокоскоростных задач есть PRU и ПО для его программирования