PDA

Просмотр полной версии : Расчет подключаемого энкодера



AlekseyK
19.03.2016, 11:45
Всем добрый день.

Знаю, что тема энкодеров и продукции Овен поднималась ни раз, и перед тем как задать вопрос, пару дней перечитывал форум.

Задача состоит в измерении позиции объекта, посредством подсчета импульсов с энкодера.
Для работы на станке выбран ПЛК110-60[М02]. К нему подключен инкрементный энкодер 2000 им/об. Ожидается, что данная связка обеспечит корректный подсчет перемещения объекта при вращении энкодера со скоростью до 5 об/сек. Расчет велся сходя из следующих соображений.

5 об/сек*2000 им/об=10 000 им/сек. То есть получается всего 10 кГц, с чем ПЛК110[M02] должен легко справляться.
Длительность одного периода сигнала получается 100 мкс.

В онлайн курсе по работе с новым ПЛК110 (http://www.owen.ru/uploads/chast_10.html) предлагается анализировать состояние быстрых входов по внутреннему таймеру 20мкс, таким образом на каждый период сигнала энкодера должно приходиться 5 измерений состояния входов. Чего как я понимаю более чем достаточно, чтобы не терять количество импульсы.
23231

На практике не всё так красиво, как на бумаге.
Сделан тестовый проект для проверки корректности счета (в приложении).

Смысл его в следующем. На энкодере ставится метка между корпусом и валом. Они сводятся вместе. Данная позиция принимается нулевой. На визуализации проекта значения энкодера обнуляются.
Далее вращаем энкодер n-ое количество раз. На станке пробег объекта от одной конечной точки до другой будет в несколько десятков оборота энкодера. Далее мы снова сводим метки вала и корпуса. В индикаторе "Позиция" должно отобразиться "0", в индикаторе "Кол-во оборотов" соответственно сколько раз мы крутанули энкодер в прямом направлении. Если в "Позиции" значения отличаются от нулевого (с учетом погрешности, конечно, так как при таком разрешении энкодера точно свести две метки тяжело) значит ПЛК потерял часть импульсов.

Так вот. Энкодер на станок пока не устанавливал, кручу его руками. И если честно, сомневаюсь что делаю это быстрее чем 5 об/сек. Но после двадцати оборотов, при сведении меток получаю значение около 1500, то есть расхождение на четверть оборота энкодера.

Отсюда вопрос к бывалым и опытным товарищам.
Может при выборе энкодера допущена ошибка? Или в проекте есть какой-то подводный камень, который я упускаю?

Поделитесь своим мнением пожалуйста.

lara197a
19.03.2016, 12:08
У Васв цикле обрабатывается значение энкодера.
Программа не правильная.
примерно так

AlekseyK
19.03.2016, 14:38
не обрабатывается, а формируется.
В вашем примере реализован счетчик, в моем энкодер, так как объект может двигаться как вперед, так и назад. К тому же я не увидел принципиального отличия наших обработчиков. Как и у вас, у меня используется чтение быстрых входов через функцию SysPortIn(0). Только вы анализируете весь получаемый байт, а я отдельно два первых бита, чтобы понять, в плюс идет текущий импульс или в минус. Или всё дело в количестве операций в прерывании?

Вольд
19.03.2016, 15:03
Когда вы пальцами крутите вал энкодера, то, возможно, вращение в основном направлении сопровождаются не большими откатами в обратном направлении. Возможно программа не корректно отрабатывает смену направления вращения вала, что и приводит к появлению ошибки.

lara197a
19.03.2016, 15:13
когда дали инженерный образец ПЛК 110, то
крутил сервопривод, с обратной связью,
для проверки работы счетчика
все работало правильно.
Вот такие не хитрые програмки писал

AlekseyK
19.03.2016, 15:22
Когда вы пальцами крутите вал энкодера, то, возможно, вращение в основном направлении сопровождаются не большими откатами в обратном направлении. Возможно программа не корректно отрабатывает смену направления вращения вала, что и приводит к появлению ошибки.

Обратите внимание на обработчик прерывания.




in:=SysPortIn(0);
IF in.0<>Old_in THEN
IF in.0=TRUE THEN
IF in.1=TRUE THEN
Enc:=Enc+1;
ELSE
Enc:=Enc-1;
END_IF;
END_IF;
END_IF;

Old_in:=in.0;

IF (Enc=Razr_Enc) THEN
Enc:=0; (*Переход через ноль в прямом направлении*)
Oborot:=Oborot+1;
END_IF;

IF Enc=INT_TO_DWORD(-1) THEN
Enc:=Razr_Enc-1; (*Переход через ноль в обратном направлении*)
Oborot:=Oborot-1;
END_IF;

IF Sbros THEN
Enc:=0;
Oborot:=0;
END_IF;


Счет импульсов реализован как в прямом, так и в обратном направлении. То есть небольшие откаты должны учитываться при подсчете.

AlekseyK
20.03.2016, 01:57
Кажется нашел решение своей проблемы. При объявлении скоростных входов как "Fast encoder" позиция энкодера не теряется.

С моим разрешением энкодера (2000 имп/об) можно делать до 32 оборотов в одном направлении, не переполняя регистр энкодера. Если в одну сторону крутить его максимально быстро, а в обратную медленно, то в первом случае (при объявлении быстрых входов как "direct control") появлялась ошибка, так как в прямом направлении происходила потеря импульсов. И при сведении метки на валу подсчитанное положение отличалось от нуля.

Если же мы берем объявление как "Fast encoder", то импульсы не теряются. Но появляются две другие проблемы. На 33-м обороте будет переполнение регистра энкодера и как следствие потеря позиции объекта. То есть необходимо увеличить разрядность регистра энкодера до 32бит.

Для этого выполняем следующий код:



IF ((Old_enc-Enc) > 25000) OR ((Enc-Old_Enc) > 25000) THEN (*Резкое изменение значение регистра означает переполнение в плюс или минус*)
IF (Enc < Old_Enc) THEN (*Enc - значение регистра "Fast Encoder"*)
Kol_Oborotov:=Kol_Oborotov+1;
ELSE
Kol_Oborotov:=Kol_Oborotov-1;
END_IF;
END_IF;

Enc32:=Kol_Oborotov*65535+Enc; (*Enc32 - положение энкодера в DWORD*)
Old_Enc:=Enc;


Вторая проблема в том, что нельзя задать разрешение подключенного энкодера (в старом ПЛК110 это опция присутствовала), в новом счет идет жестко от 0 до 65535. Но она опять же решается, если по переменной Enc32 сделать операцию MOD 2000 - получим угловую позицию энкодера 2000 имп/об без ограничения на 32 оборота.

Код можно размещать в основном цикле программы, так как сравниваются значения регистра энкодера на предыдущем цикле и на текущем. Все промежуточные значения всё равно не могут быть обработаны из-за длины цикла программы. Если хотим чтобы ПЛК максимально часто "присматривался" к позиции энкодера, то размещаем код в прерывание 20 мкс. Анализировать позицию (и реагировать на нее) быстрее чем там, всё равно не получится.

Думаю что добавлю к этому коду еще инициализацию на нулевую точку и оформлю всё в виде функционального блока, чтобы обработка была целостной.
Если кому интересно - результат выложу в данной теме.

Остается только одно непонятно. Зачем ОВЕН в своем онлайн-курсе предлагает реализовывать обработку энкодера через "direct control"? Ведь даже видео-пример про это сняли. Или есть какие-то нюансы, которые я упускаю?

Ну и вопрос к документации. Вот открываем Руководство пользователя, которое хоть на веб-страничке нового ПЛК110, хоть на диске, который вместе с ним приходит, и видим на странице 71 описание модуля Fast Encoder. А в нем описание параметра "Range of encoder 1" и нигде ни слова о том, что данный параметр актуален только для старого ПЛК. В результате вместо спокойной работы с документацией начинаются недоумения "а куда пропал параметр? А не кривой-ли у меня таргет? А может на моем ПЛК прошивка старая?" и изучение постов форума. Деталь, мелочь, но думаю многие заходят на форум с вопросами как раз из-за таких деталей.

lara197a
20.03.2016, 11:14
можно проще, если считать в DWORD
Суммирование значения счетчика из регистра счета:
C:dword;
оттуда, M:word;

C:=C + ((оттуда - M) and 65535);
M:=оттуда;
C:=C + (abs(word_to_int(оттуда - M)) mod 16#10000); - для энкодера

Newcomer
20.03.2016, 12:32
Кажется нашел решение своей проблемы. При объявлении скоростных входов как "Fast encoder" позиция энкодера не теряется.

С моим разрешением энкодера (2000 имп/об) можно делать до 32 оборотов в одном направлении, не переполняя регистр энкодера. Если в одну сторону крутить его максимально быстро, а в обратную медленно, то в первом случае (при объявлении быстрых входов как "direct control") появлялась ошибка, так как в прямом направлении происходила потеря импульсов. И при сведении метки на валу подсчитанное положение отличалось от нуля.

Если же мы берем объявление как "Fast encoder", то импульсы не теряются. Но появляются две другие проблемы. На 33-м обороте будет переполнение регистра энкодера и как следствие потеря позиции объекта. То есть необходимо увеличить разрядность регистра энкодера до 32бит.

Для этого выполняем следующий код:



IF ((Old_enc-Enc) > 25000) OR ((Enc-Old_Enc) > 25000) THEN (*Резкое изменение значение регистра означает переполнение в плюс или минус*)
IF (Enc < Old_Enc) THEN (*Enc - значение регистра "Fast Encoder"*)
Kol_Oborotov:=Kol_Oborotov+1;
ELSE
Kol_Oborotov:=Kol_Oborotov-1;
END_IF;
END_IF;

Enc32:=Kol_Oborotov*65535+Enc; (*Enc32 - положение энкодера в DWORD*)
Old_Enc:=Enc;


Вторая проблема в том, что нельзя задать разрешение подключенного энкодера (в старом ПЛК110 это опция присутствовала), в новом счет идет жестко от 0 до 65535. Но она опять же решается, если по переменной Enc32 сделать операцию MOD 2000 - получим угловую позицию энкодера 2000 имп/об без ограничения на 32 оборота.

Код можно размещать в основном цикле программы, так как сравниваются значения регистра энкодера на предыдущем цикле и на текущем. Все промежуточные значения всё равно не могут быть обработаны из-за длины цикла программы. Если хотим чтобы ПЛК максимально часто "присматривался" к позиции энкодера, то размещаем код в прерывание 20 мкс. Анализировать позицию (и реагировать на нее) быстрее чем там, всё равно не получится.

Думаю что добавлю к этому коду еще инициализацию на нулевую точку и оформлю всё в виде функционального блока, чтобы обработка была целостной.
Если кому интересно - результат выложу в данной теме.

Остается только одно непонятно. Зачем ОВЕН в своем онлайн-курсе предлагает реализовывать обработку энкодера через "direct control"? Ведь даже видео-пример про это сняли. Или есть какие-то нюансы, которые я упускаю?

Ну и вопрос к документации. Вот открываем Руководство пользователя, которое хоть на веб-страничке нового ПЛК110, хоть на диске, который вместе с ним приходит, и видим на странице 71 описание модуля Fast Encoder. А в нем описание параметра "Range of encoder 1" и нигде ни слова о том, что данный параметр актуален только для старого ПЛК. В результате вместо спокойной работы с документацией начинаются недоумения "а куда пропал параметр? А не кривой-ли у меня таргет? А может на моем ПЛК прошивка старая?" и изучение постов форума. Деталь, мелочь, но думаю многие заходят на форум с вопросами как раз из-за таких деталей.

А вы пост #55 из этой темы читали: http://www.owen.ru/forum/showthread.php?t=23600&page=6

Читать состояние регистра энкодера из прерывания по таймеру 20 мкс бесполезно.

При частоте следования импульсов 10 кГц получается 10 импульсов за 1 мс. Это не много. При длительности цикла основной программы ПЛК 2 мс абсолютная погрешность будет не больше 20 импульсов на интервал измерения длины.

capzap
20.03.2016, 12:44
А вы пост #55 из этой темы читали: http://www.owen.ru/forum/showthread.php?t=23600&page=6

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

AlekseyK
20.03.2016, 12:50
C:=C + ((оттуда - M) and 65535);

Первый вариант считает только в прямом направлении, в случае легкого отката энкодера назад - в переменой С уже каша.

Например возврат с 30-го импульса на 27-й:

С:=30+((27-30) and 65535);
C:=30+((-3) and 65535); где -3 будет рассматриваться как dword, то есть = FFFFFFFD и ее результат с and 65535 даст FFFD=65533;
C:=30+65533;
С:=65563; а не 27 как положено.



Второй вариант перемещения в минус засчитывает в плюс.
Тот же вариант возврат от 30-го импульса к 27-му:

C:=C + (abs(word_to_int(оттуда - M)) mod 16#10000);
С:=30+(abs(word_to_int(27-30)) mod 16#10000);
C:=30+(abs(-3) mod 16#10000); вот тут, из-за abs() мы потеряли направление движения
C:=30+(3 mod 65536); ; немного не понял зачем тут MOD, ведь разность значений регистра "оттуда" не может быть больше 65535 вообще никак.
C:=30+3;

Если MOD в конце операции подсчета стоит для приведения положения энкодера к его разрядности, то очевидно что данный вариант работать не будет. Так как операция MOD должна применяться к абсолютному положению энкодера подсчитанному в DWORD, это следует из того, что при переполнения регистра "оттуда" положение энкодера резко сбрасывается в ноль со значения [65535 MOD "разрядность энкодера"]. И при каждом переполнении эти значения будут складываться. То же самое и при обратном переходе через ноль. В регистре "отттуда" был ноль, стало резко [65535 MOD "разрядность энкодера"].

Если я в чем-то ошибаюсь или не понял вашу мысль, прошу не ругать. Потому как обе приведенные формулы проверил на ПЛК с подключенным энкодером и говорю только о том, что наблюдаю в отладчике.

capzap
20.03.2016, 12:56
C:=30+((-3) and 65535); где -3 будет рассматриваться как dword, то есть = FFFFFFFD и ее результат с and 65535 даст FFFD=65533;
почему DWORD, обе переменные объявлены как word значит и результат будет ворд, для страховки можете добавить DWORD_TO_WORD

AlekseyK
20.03.2016, 13:15
А вы пост #55 из этой темы читали: http://www.owen.ru/forum/showthread.php?t=23600&page=6


Да, читал. Но ведь получается как.
При входе в прерывание 20мкс уже сформировано значение регистра энкодера (модуля "Fast encoder", не "direct control"). Да, возможно на предыдущем заходе в прерывание (или в основном цикле программы) там было 125, а сейчас 130. Да, я не могу отреагировать на 126 импульс. Но главное, что эти импульсы не потеряны. Допустим я вернусь к нему, уменьшив скорость объекта. Тогда и точность увеличится.

Это всё вопросы точности позиционирования. И на сколько я знаю ОВЕН не заявлял что обеспечивает точное позиционирование с частотой входного сигнала 100 кГц. Заявлено, что есть поддержка входного сигнала 100кГц, это выполняется.

Сейчас я со всей дури кручу в руках энкодер на 2000 имп/об и при сведении нулевой метки оказываюсь на том же инкременте откуда начал движение. Меня это вполне устраивает. Как это будет выглядеть на конечном станке - увижу чуть позже.

Newcomer
20.03.2016, 13:17
не задумывались, что здесь люди конфигурируют входа и сами в таймере20мкс создают собственный енкодер, а не то что Вы думаете

capzap, посты в теме надо читать все и внимательно, а не через один.

AlekseyK
20.03.2016, 13:19
почему DWORD, обе переменные объявлены как word значит и результат будет ворд, для страховки можете добавить DWORD_TO_WORD

"С" объявлена как DWORD. Как я понимаю тут будет работать неявное приведение WORD-значения (оттуда - M) к DWORD. Иначе операция AND 65535 теряет смысл, а так lara197a "зачищает" верхнее слово перед сложением.

Владимир Ситников
20.03.2016, 13:20
AlekseyK, попробуйте так:
m : WORD; (* текущее значение fast encoder *)
ottuda : WORD; (* прошлое показание encoder'а *)
c: DINT; (* абсолютное положение encoder'а, без проблем с 65535 *)

c := c + WORD_TO_INT(m - ottuda);
ottuda := m;

capzap
20.03.2016, 13:23
"С" объявлена как DWORD. Как я понимаю тут будет работать неявное приведение WORD-значения (оттуда - M) к DWORD. Иначе операция AND 65535 теряет смысл, а так lara197a "зачищает" верхнее слово перед сложением.

а то что там куча скобок Вам ни о чем не говорит?

Newcomer
20.03.2016, 13:24
Да, читал. Но ведь получается как.
При входе в прерывание 20мкс уже сформировано значение регистра энкодера (модуля "Fast encoder", не "direct control"). Да, возможно на предыдущем заходе в прерывание (или в основном цикле программы) там было 125, а сейчас 130. Да, я не могу отреагировать на 126 импульс. Но главное, что эти импульсы не потеряны. Допустим я вернусь к нему, уменьшив скорость объекта. Тогда и точность увеличится.

Это всё вопросы точности позиционирования. И на сколько я знаю ОВЕН не заявлял что обеспечивает точное позиционирование с частотой входного сигнала 100 кГц. Заявлено, что есть поддержка входного сигнала 100кГц, это выполняется.

Сейчас я со всей дури кручу в руках энкодер на 2000 имп/об и при сведении нулевой метки оказываюсь на том же инкременте откуда начал движение. Меня это вполне устраивает. Как это будет выглядеть на конечном станке - увижу чуть позже.

Разработчики фирмы "ОВЕН" решили вопрос с максимальной частотой, которую можно подавать на вход энкодера и быстрого счетчика. Для этого они ввели в схему ПЛК аппаратный счетчик. Но пока не решен вопрос с оперативным опросом этого счетчика. Была анонсирована технология PRU, которая решает эту проблему, но до ее полной реализации еще далеко.

AlekseyK
20.03.2016, 13:27
Почему же, говорит.
Говорит что сначала будет выполняться вычитание, затем к его результату применят AND, а затем уже результат битового "И" добавят к аккумулятору "С".
Или я что-то путаю?

AlekseyK
20.03.2016, 13:30
AlekseyK, попробуйте так:
m : WORD; (* текущее значение fast encoder *)
ottuda : WORD; (* прошлое показание encoder'а *)
c: DINT; (* абсолютное положение encoder'а, без проблем с 65535 *)

c := c + WORD_TO_INT(m - ottuda);
ottuda := m;


Почти хорошо. )) После перехода через максимальное значение регистра энкодера появляется один лишний такт в "С".

Владимир Ситников
20.03.2016, 13:31
Это всё вопросы точности позиционирования. И на сколько я знаю ОВЕН не заявлял что обеспечивает точное позиционирование с частотой входного сигнала 100 кГц.
Давайте так: а зачем вы вообще заморачиваетесь с 20мкс таймером?
Почему бы не поместить работу с fastencoder'ами в простой ПЛК цикл (PLC_PRG)?



Сейчас я со всей дури кручу в руках энкодер на 2000 имп/об и при сведении нулевой метки оказываюсь на том же инкременте откуда начал движение. Меня это вполне устраивает. Как это будет выглядеть на конечном станке - увижу чуть позже.
Поздравляю вас, но в этом вам никак не помогает 20мкс таймер.
Попробуйте перенести работу в PLC_PRG -- наверняка всё то же самое будет.

Newcomer
20.03.2016, 13:32
В этой теме: http://www.owen.ru/forum/showthread.php?t=16666&page=2 пост #19 почитайте.

Владимир Ситников
20.03.2016, 13:34
Почти хорошо. )) После перехода через максимальное значение регистра энкодера появляется один лишний такт в "С".

Это как? На каких входных данных не работает-то?

Максимальное значение регистра -- 65535. Верно?
Следующее значение -- 0. Верно?

В моём эмуляторе такое работает как и ожидается:
ottuda := 65535;
m := 0;
c := 0;
c := c + WORD_TO_INT(m - ottuda); (* оказывается равным 1 *)

capzap
20.03.2016, 13:35
capzap, посты в теме надо читать все и внимательно, а не через один.
AlekseyK хотя бы на практике проверяет свои идеи, а Вы пытаетесь свои измышления довести до окружающих ни чем/ни кем не подтвержденные. Работа по прерываниям ни чем не отличается от отдельной задачи, которая бы считала результат энкодера из конфигуратора в свободном цикле например
Поиграется с энкодером, вернется на прямое управление, Ваши посты ему ни как не помогут, они просто не в тему, да он уже и высказался

AlekseyK
20.03.2016, 13:39
А я и не говорю, что буду работать с ними в 20 мск. Может в дальнейшем он и будет реализован, но только для быстрой остановки объекта. К прерывания меня завел онлайн-курс по работе с ПЛК[M02] - http://www.owen.ru/uploads/chast_10.html . Где предлагается работать с энкодерами именно через модуль "direct conntrol" и таймер 20 мск. Я уже возмущался этим в посте #7

Владимир Ситников
20.03.2016, 13:42
AlekseyK хотя бы на практике проверяет свои идеи, а Вы пытаетесь свои измышления довести до окружающих ни чем/ни кем не подтвержденные

Во-первых Newcomer ссылается на "подтверждение Владислава Филоненко".
Во-вторых, Newcomer правильно подметил, что AlekseyK упускает из виду, что "использование 20мкс таймера реально бесполезно". Текущий проект будет работать с тем же качеством из простого PLC_PRG.

В третьих, судя по экспериментам AlekseyK, слова Владислава, похоже, подтверждаются: попытка обработать fast inputs из 20мкс таймера пропускает сигналы. По крайней мере, исходная программа выглядит логично, и на ум приходит только то, что реально fastcounters нельзя читать из таймера.
Хотя, конечно, странно это, особенно, учитывая, что именно так рекомендуют делать в "видео от ОВЕН".

AlekseyK
20.03.2016, 13:42
Это как? На каких входных данных не работает-то?


До 65535 всё работает, согласен. Но мне мало 32 оборотов моего энкодера, когда идет переполнение регистра "fast encoder". Поэтому в 7 посте я описал метод, как расширить счет на 32бита и уйти от этого ограничения.

Владимир Ситников
20.03.2016, 13:47
До 65535 всё работает, согласен. Но мне мало 32 оборотов моего энкодера, когда идет переполнение регистра "fast encoder". Поэтому в 7 посте я описал метод, как расширить счет на 32бита и уйти от этого ограничения.

Ой, да приведите же значения на которых "ломается".

Как себя ведёт это самое "переполнение fast encoder"?
Какие значения принимает этот самый регистр?

AlekseyK
20.03.2016, 13:47
В этой теме: http://www.owen.ru/forum/showthread.php?t=16666&page=2 пост #19 почитайте.

Прочитал, и пример посмотрел. При активации строки "Назад" переменная C растет. Разве так должно быть?

AlekseyK
20.03.2016, 13:57
Прошу прощения, это не у вас лишний такт появляется, а у меня не учитывается такт при переходе от 65535 к 0. Ваш вариант работает. Энкодер точный, тяжело выставить два соседних положения.
Вот тут была ошибка:
Enc32:=Kol_Oborotov*65536+Enc; а не 65535

Newcomer
20.03.2016, 14:02
AlekseyK хотя бы на практике проверяет свои идеи, а Вы пытаетесь свои измышления довести до окружающих ни чем/ни кем не подтвержденные. Работа по прерываниям ни чем не отличается от отдельной задачи, которая бы считала результат энкодера из конфигуратора в свободном цикле например
Поиграется с энкодером, вернется на прямое управление, Ваши посты ему ни как не помогут, они просто не в тему, да он уже и высказался

А вы место и время не перепутали ? Тут не армия, где все делается на ать-два. ;)

Newcomer
20.03.2016, 14:12
Прочитал, и пример посмотрел. При активации строки "Назад" переменная C растет. Разве так должно быть?

Направление вращения автоматически не определяется, тут надо подумать как выбирать расчетную формулу.

Главная ценность формулы в том, что она защищает от переполнения.

AlekseyK
20.03.2016, 14:15
Во-вторых, Newcomer правильно подметил, что AlekseyK упускает из виду, что "использование 20мкс таймера реально бесполезно". Текущий проект будет работать с тем же качеством из простого PLC_PRG.




Код можно размещать в основном цикле программы, так как сравниваются значения регистра энкодера на предыдущем цикле и на текущем. Все промежуточные значения всё равно не могут быть обработаны из-за длины цикла программы. Если хотим чтобы ПЛК максимально часто "присматривался" к позиции энкодера, то размещаем код в прерывание 20 мкс. Анализировать позицию (и реагировать на нее) быстрее чем там, всё равно не получится.

То что данный код будет одинаково работать и в таймере и в основном цикле я написал сразу как его выложил. Поэтому относительно возможностей таймера 20 мкс иллюзий нет.

AlekseyK
20.03.2016, 14:17
Направление вращения автоматически не определяется, тут надо подумать как выбирать расчетную формулу.

Главная ценность формулы в том, что она защищает от переполнения.

А вот формула от vladimirisitnikov учитывает и направление и защищена от переполнения. Ну и просто логичней.

Newcomer
20.03.2016, 14:21
А вот формула от vladimirisitnikov учитывает и направление и защищена от переполнения. Ну и просто логичней.

Приведите эту формулу в окончательном виде, я ее проверю и засундучу. ;)

AlekseyK
20.03.2016, 14:25
m : WORD; (* текущее значение fast encoder *)
ottuda : WORD; (* прошлое показание encoder'а *)
c: DINT; (* абсолютное положение encoder'а, без проблем с 65535 *)

c := c + WORD_TO_INT(m - ottuda);
ottuda := m;

Проверил на железе, у меня вопросов нет.

capzap
20.03.2016, 14:55
Во-первых Newcomer ссылается на "подтверждение Владислава Филоненко".
Во-вторых, Newcomer правильно подметил, что AlekseyK упускает из виду, что "использование 20мкс таймера реально бесполезно". Текущий проект будет работать с тем же качеством из простого PLC_PRG.

В третьих, судя по экспериментам AlekseyK, слова Владислава, похоже, подтверждаются: попытка обработать fast inputs из 20мкс таймера пропускает сигналы. По крайней мере, исходная программа выглядит логично, и на ум приходит только то, что реально fastcounters нельзя читать из таймера.
Хотя, конечно, странно это, особенно, учитывая, что именно так рекомендуют делать в "видео от ОВЕН".

во первых (#55) - в правом верхнем углу есть тоже ссылка, не обязательно указывать страницу и говорить какой пост прочитать
во вторых, ни какого подтверждения там нет, есть просьба что то подтвердить или опровергнуть (докопаляся до какой то ерунды)
в третьих и я обозначил что так с энкодером можно работать в отддельной задача или в главном цикле, не важно
в четвертых по мне так подход в исходной программе не совсем логичный, за основу берется условие состояния одного из входов и внутри этого условия анализируется состояние второго входа, хоть и правильно всё но в железе мало ли могут быть ошибки из-за дребезгов и т.п. Я бы анализировал что пришел импульс по поднятию обоих входов, а направление учитывал, кто из входов в предыдущей итерации был false

Newcomer
20.03.2016, 16:28
m : WORD; (* текущее значение fast encoder *)
ottuda : WORD; (* прошлое показание encoder'а *)
c: DINT; (* абсолютное положение encoder'а, без проблем с 65535 *)

c := c + WORD_TO_INT(m - ottuda);
ottuda := m;

Проверил на железе, у меня вопросов нет.

У меня то же. Спасибо автору.

AlekseyK
20.03.2016, 16:29
а как вы отличите полезный сигнал от дребезга? Если на первом высокий уровень, на втором тоже высокий но от дребезга, то по условию, что на втором в предыдущей итерации был 0 надо засчитывать движение в одну из сторон. Алгоритм получается абсолютно такой же, только момент засчитывание такта сместиться на четверть периода вперед.

capzap
20.03.2016, 16:48
а как вы отличите полезный сигнал от дребезга? Если на первом высокий уровень, на втором тоже высокий но от дребезга, то по условию, что на втором в предыдущей итерации был 0 надо засчитывать движение в одну из сторон. Алгоритм получается абсолютно такой же, только момент засчитывание такта сместиться на четверть периода вперед.
с дребезгом может и погорячился, хотя есть фильтрация, но от неё может быть больше вред чем польза
только Вы от сигнала берете передний фронт, в это единичный момент времени на входах может произойти всё что угодно, просело напряжения и вместо логической единицы получили логический ноль, вот и произошло неверное трактование сигнала и как следствие неверный подсчет импульсов, не трудно же написать что то подобное

IF in.0 AND in.1<>oldIn1 THEN
ELSIF in.1 AND in.0<>oldIn0 THEN

или (но с дополнительным отдельным учетом обработки направления)

foo:=in.0 AND in.1;
IF foo<>oldFoo THEN

AlekseyK
20.03.2016, 17:03
Вы анализируете тот же самый фронт. Только в моей программе счет шел по фронтам и спадам первого сигнала, а у вас только по фронтам, но обоих сигналов. Тут тоже можно дребезг словить, допустим если внезапно просело напряжение на первом сигнале, пока ждем установку второго.

capzap
20.03.2016, 17:40
Вы анализируете тот же самый фронт. Только в моей программе счет шел по фронтам и спадам первого сигнала, а у вас только по фронтам, но обоих сигналов. Тут тоже можно дребезг словить, допустим если внезапно просело напряжение на первом сигнале, пока ждем установку второго.

где у меня по двум фронтам, во первых я пример привел а не готовое решение, во вторых фронт у меня один если вход другого уже TRUE это как бы не большая, но разница с Вашим кодом

lara197a
20.03.2016, 19:02
AlekseyK
Вам привели вполне себе рабочие примеры.
если у вас не тривиальная, ответственная задача,
то проще ее решить на любом другом ПЛК,
где имеются готовые 2-х фазные счетчики и прерывания, для работы с ними.
или
специальные счетные модули.
Примеры приводить не буду.
если нужно, то пишите в личку.

AlekseyK
20.03.2016, 20:45
где у меня по двум фронтам, во первых я пример привел а не готовое решение, во вторых фронт у меня один если вход другого уже TRUE это как бы не большая, но разница с Вашим кодом

Ну смотрите. Вы предлагаете засчитывать импульс, когда оба сигнала прочитаны как единицы (оператор AND). При этом +1 или -1 зависит от того, на каком канале до этого был 0. То есть получается, что на текущем проходе у вас на обоих каналах единицы, а на предыдущем по одному из них был ноль (на картинке на первом). Но это же и есть детектирование фронта сигнала!
Получается, что если приходит фронт на первом канале, когда на втором уже единица, то +1. Если приходит фронт на втором канале, когда на первом единица, то -1.


23257


Тут у нас видимо небольшое недопонимание друг друга вышло. Конечно же и у вас и у меня при каждом такте счета только один фронт. Но во время этого фронта и у вас и у меня на другом канале уже установленное значение. Только у вас это всегда TRUE, а у меня TRUE или FALSE. Думаю мы уже поняли друг друга и топчемся на месте, так что пора заканчивать, к тому же решение по созданной теме найдено.



AlekseyK
Вам привели вполне себе рабочие примеры.
если у вас не тривиальная, ответственная задача,
то проще ее решить на любом другом ПЛК,
где имеются готовые 2-х фазные счетчики и прерывания, для работы с ними.
или
специальные счетные модули.
Примеры приводить не буду.
если нужно, то пишите в личку.

Да, за примеры всем спасибо. Как вы заметили я ни одного не пропустил и сделал разбор каждого. Указав на особенности их применения. Самым правильным и лаконичным было решение от vladimirisitnikov, ему отдельная благодарность.

А задача хоть и ответственная, но вполне тривиальная и по силам ПЛК110[M02].

capzap
20.03.2016, 21:41
вроде бы vladimirisitnikov предложил вариант оптимизации со встроенным энкодером,а не обработке входов при прямом управлении и здесь на самом деле маска не нужна, потому что не будет ни какого переполнения ворда, он сам продолжит счет с другого конца диапазона

В последнем посте нарисованы эпюры по которым можно теорию объяснять преподавателю, а в реале импульсы не такие прямоугольные, поэтому вероятность больше когда условие проверяется на наличие двух логических единиц от двух сигналов, по другому это будет как байт сравнивать с 3 и следить какое значение до этого было 1 или 2

AlekseyK
20.03.2016, 23:01
Совершенно верно. А задача и стояла получить позицию объекта по оборотам энкодера. Вариант с прямым управлением входами с заданной частотой вращения не справился, об этом я писал еще в посте #7. И маски у vladimirisitnikov никакой нет. Переход от переменной типа Word в регистре "fast encoder" к переменной типа DINT сделано с той целью, чтобы уйти от ограничения максимального количество подсчитанных импульсов равного 65535. Так как энкодер 2000 имп/об и при измерении позиции объекта вращается более чем на 32 оборота. Об этом сказано в том же посту.

А про эпюры это конечно да, но вырисовывать еще и правильные фронты/спады наверное было лишним, мы с вами и так знаем, что там не всё идеально. ))

Алексей Дмитриев
23.03.2016, 15:22
Ну не работает техника овен (никакая) с энкодерами корректно - это не раз проверенный факт! Чего перья-то ломать?
Даже счетчик СИ8, предназначенный только считать и то не работает!

Вольд
23.03.2016, 16:04
Ну не работает техника овен (никакая) с энкодерами корректно - это не раз проверенный факт! Чего перья-то ломать?
Даже счетчик СИ8, предназначенный только считать и то не работает!

Кончай народ пугать. ;)

Алексей Дмитриев
23.03.2016, 16:46
Вот, например, прямо из коробки.:mad:

Вольд
23.03.2016, 17:35
Вот, например, прямо из коробки.:mad:

Зачем обобщать ?

Вольд
23.03.2016, 17:36
Вот, например, прямо из коробки.:mad:

Зачем обобщать ? Обратитесь в СЦ.

Алексей Дмитриев
23.03.2016, 19:30
1. Потому что два счетчика, купленные в разное время ведут себя одинаково.
2. Потому что уже не в первый раз.
Проблема, похоже, системная и с длинной бородой.

Вольд
24.03.2016, 10:59
1. Потому что два счетчика, купленные в разное время ведут себя одинаково.
2. Потому что уже не в первый раз.
Проблема, похоже, системная и с длинной бородой.

То, что с фирмой "ОВЕН" надо держать ухо востро давно известно.

Филоненко Владислав
24.03.2016, 12:13
Вот, например, прямо из коробки.:mad:
Отличное видео про то, как не надо читать РЭ при выборе прибора. И к чему это приводит.
Итак, суперэнкодер DFS60B-S4MA10000
Maximum output frequency: 600 kHz
И Си8
Максимальная частота входных импульсов: 8000 Гц

И почему же, если палец крутит чуть быстрее, он не считает? Даже затрудняюсь предположить :D

Вольд
24.03.2016, 12:43
То, что энкодер способен выдавать 600 кГц говорит о том, что вал может вращаться с высокой скоростью.
Тут важно сколько импульсов на оборот имеет энкодер. Вот тогда можно делать окончательный вывод можно этот энкодер подключать к СИ 8 или нет при рабочей частоте вращения вала.

Алексей Дмитриев
24.03.2016, 14:51
Отличное видео про то, как не надо читать РЭ при выборе прибора. И к чему это приводит.
Итак, суперэнкодер DFS60B-S4MA10000
Maximum output frequency: 600 kHz
И Си8:
Максимальная частота входных импульсов: 8000 Гц
И почему же, если палец крутит чуть быстрее, он не считает? Даже затрудняюсь предположить
Если Вы, уважаемый, внимательно читали и смотрели, то что написано в руководствах, то:
1. Этот энкодер программируемый, конкретно зашито 3000 имп на оборот.
2. На реальном техпроцессе частота следования импульсов не превышает 1 кГц.
3. Крутил не быстро, примерно оборот за секунду, то есть не более 3 кГц.
4. Перестает считать совсем, с любой частотой, а не пропускает импульсы из-за недостатка быстродействия.
Кстати, открыл тему про СИ8, но ни одного ответа не увидел.
http://www.owen.ru/forum/showthread.php?t=23671

Maximus
25.03.2016, 15:34
А почему не СИ30? В нем как раз для энкодеров режим есть. И частота до 20к. 8к СИ8 в режиме определения направления вращения по состоянию др. входа не дотягивает... К сожалению это так. В СИ30 таких проблем нет.

Алексей Дмитриев
26.03.2016, 16:43
Проект построен на базе давнишнего проекта, раньше работало, правда там частота была на порядок ниже. Здесь же нужно еще и тахометр на тот же энкодер, потому частоту увеличил до 1 кГц. Думал, раз заявлено 8 кГц, то на 1-то точно потянет.

Филоненко Владислав
28.03.2016, 08:03
Ну так при работе с энкодером надо фазу мерить, т.е. число отсчётов как минимум в 2 раза выше, чем частота сигналов на входах А и В. Это для энкодера 1х. Для 2х и 4х ещё 2 раза больше. Вот от 8 кГц и ничего не осталось.

Алексей Дмитриев
28.03.2016, 22:41
Ну так при работе с энкодером надо фазу мерить, т.е. число отсчётов как минимум в 2 раза выше, чем частота сигналов на входах А и В. Это для энкодера 1х. Для 2х и 4х ещё 2 раза больше. Вот от 8 кГц и ничего не осталось.

Причем здесь удвоение, учетверение и т.п.? В режиме 4 СИ8 считает вход 1 фронт 01, по входу 2 в момент прихода фронта на вход 1 стоит потенциал либо 0 либо 1 для определения того, что нужно сделать +1 или -1. Чего уж проще-то? Не работает даже с низкой частотой, порядка 50 Гц.

Филоненко Владислав
29.03.2016, 08:49
Э, на видео работал, пока слишком быстро не начали крутить. Или я что-то не понимаю?

Алексей Дмитриев
29.03.2016, 09:56
Э, на видео работал, пока слишком быстро не начали крутить. Или я что-то не понимаю?

От скорости не зависит, может вообще стоять. По истечении некоторого времени даже не начинает считать.

Владимир Ситников
29.03.2016, 20:55
От скорости не зависит, может вообще стоять. По истечении некоторого времени даже не начинает считать.

А сам СИ8 у вас на какой коэффициент делит импульсы?
Похоже, за один оборот СИ показывает 30 (я не учитываю десятичный разделитель на самом СИ), т.е. показания табло умножаем на 100 и получаем "количество импульсов" (если реально 3000 имп/оборот)

Если так, то вначале оно зависло на скорости 4300 имп/сек, а потом при 3800 имп/сек.
https://docs.google.com/spreadsheets/d/1idRmiGIn9BJxyUP3XkhHkHJZSeHcpK66sflFQTVFjkM/edit?usp=sharing

"для пущего" можете явно проверить как СИ будет реагировать на быстрое кручение?
Точно так же замирать будет? Или просто пропускать импульсы?
Как минимум, будет остальным наука.

Филоненко Владислав
30.03.2016, 13:38
4300 и 3800 имп/сек это выше 8Кгц. Т.к. 8 КГц - в режиме счёта импульсов, а не энкодера, где всё надо делить на 4

Алексей Дмитриев
31.03.2016, 01:22
4300 и 3800 имп/сек это выше 8Кгц. Т.к. 8 КГц - в режиме счёта импульсов, а не энкодера, где всё надо делить на 4
Почему надо на 4 делить? Частота на входе не более 3 кГц была. Я же говорю, что можно чуть повернуть и остановиться. После того, как постоит минуты 2-3 вообще не продолжает считать. Потом, как я понимаю, не должен он подвисать при высокой частоте. Максимум пропускать импульсы.

Алексей Дмитриев
31.03.2016, 01:24
А сам СИ8 у вас на какой коэффициент делит импульсы?
Похоже, за один оборот СИ показывает 30 (я не учитываю десятичный разделитель на самом СИ), т.е. показания табло умножаем на 100 и получаем "количество импульсов" (если реально 3000 имп/оборот)

Если так, то вначале оно зависло на скорости 4300 имп/сек, а потом при 3800 имп/сек.
https://docs.google.com/spreadsheets/d/1idRmiGIn9BJxyUP3XkhHkHJZSeHcpK66sflFQTVFjkM/edit?usp=sharing

"для пущего" можете явно проверить как СИ будет реагировать на быстрое кручение?
Точно так же замирать будет? Или просто пропускать импульсы?
Как минимум, будет остальным наука.
Именно предделитель 100. Далее два знака после запятой.

Linan
04.04.2016, 18:37
Была похожая проблема, нужно было расчитать, спасибо)