LINUX.ORG.RU
решено ФорумTalks

энкодер плохо работает

 , , , ,


0

1

Вот что интересно. Раньше использовал atmega328 и у меня энкодер работал без всякого debouncing. Работало тупо: смотрел на состояние второго пина при falling edge на первом (энкодер коротит pullUp пины на землю). Ну, всё как у всех.

А вот stm32F411re с тем же энкодером тупо не работает. Значения скачут очень рандомно (т.е. повернул ручку на одно деление, а в программе счётчик увеличивается сразу на 2-30). Причём, в лучшем случае удаётся читать показания при вращении в одну сторону, но не другую.

С чем может быть связано такое различие? Я вот подумал что питание и наводки вряд ли могут оказать какое-то влияение. Может, разница в частоте сказывается? Атмега на 8Mhz работала, а эта плата на 100MHz.

★★★★★

Последнее исправление: true_admin (всего исправлений: 1)
Ответ на: комментарий от pitman

изолирует или защитит от статики все органы управления.

Это как? У меня будут пластиковые ручки на энкодере, этого достаточно?

проскакивает в МК выжигая входные порты и включая БП на максимум

Не выйдет, МК только крутилки обрабатывает и дисплей обслуживает. Образцовое напряжение идёт с i2c DAC.

Я вот единственное переживаю как делать защиту от перегруза. В оригинальной схеме там была аппаратная защита. Но уж больно много деталей. Я вот думаю над двумя вещами: софтовая реализация и полуаппаратная. С софтовой всё понятно, с полуаппаратной несколько интересней. Я думаю снимать напряжение с шунта, дальше на op amp и потом на компаратор. С компаратора нога идёт на reference voltage DAC у которого есть kill switch.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от prischeyadro

В обратном направлении вращение появилось?

Оно появилось, но дребезжит. Я хотел ради прикола понизить clock frequency, но лёг спать :). Завтра попробую понизить частоту опроса пинов до 2MHz, просто ради прикола. Но я надеюсь что софтовое решение решит все проблемы, ведь на avr всё каким-то образом достаточно хорошо работало вообще без заморочек.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

Завтра попробую понизить частоту опроса пинов до 2MHz,

Погоди. А зачем ты пины опрашиваешь? У тебя разве не по прерываниям срабатывает?

Zubok ★★★★★
()
Ответ на: комментарий от true_admin

Завтра попробую понизить частоту опроса пинов до 2MHz, просто ради прикола

Я правильно сейчас понимаю, что это входы обычные, которые не касаются энкодера? Еще обрати внимание на приоритеты прерываний и просто на те прерывания, которые используется в mbed, не происходит ли чего-нибудь более приоритетного с большой частотой? Не оставляй болтаться в воздухе пины, которые генерируют прерывания (external interrupts) и которые разрешены. А также обрати внимание, не загоняешь ли ты процессор в какой-нибудь режим малого потребления, что он в результате не отрабатывает у тебя прерывания. Проверь настройки mbed.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Хм, может я что и напутал... Но, в общем, разные части микроконтроллера работают с разной скоростью: http://waijung.aimagin.com/stm32f41x_block_diagram.png (если не открывается то google://stm32f4+block+diagram)

В общем, я так понимаю, внешние прерывания работают путём опроса пинов, только это сделано аппаратно. Вот частоту опроса можно менять. Может всё и не так работает, может я с чем-то путаю. Но мне казалось что, например, у avr именно так работают прерывания на тех ногах которые поддерживают edge triggering.

С удовольствием узнаю как это работает на самом деле.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

Нет. Смотри стр. 256 даташита. Там устройство External Interrupt. Никакого такого опроса ножек там нет. Есть контроллер прерываний NVIC, куда поступают запросы на прерывания. Фронты определяются Edge Detect Circuit, а дальше в соответсвии с настройками (какие ножки выбраны для external interrupts) идут в этот NVIC.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Эм, наверно я нагнал про опрос пинов. Просто сбили с толку синхронные и асинхронные прерывания. Хотя, всё равно интересно как оно внутри работает.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

В даташите все написано. стр 256, 10.2.4 описывает, как это происходит. И я не знаю, в каком режиме твой процессор. Может, он все время «спит», когда ничего не происходит, а прерывания ему wake-up делают (или не делают, а он просыпается по другим событиям), поэтому там не пойми что происходит. Там почитай, там есть такой способ их конфигурации. Если процессор спит, а снаружи что-то произошло и его разбудить надо (стр. 256, 10.2.3). И также смотри на то, как у тебя сконфигурирован.

Или у тебя какие-то другие прерывания все время происходят. Может, они не запрещены и процессор где-то время проводит. Надо смотреть на настройки mbed еще.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)

Проверь, m_position у тебя как volatile int объявлена? Надо именно так.

Zubok ★★★★★
()

И еще проверь, а нет ли у тебя проблем с запаздыванием индикации. То есть вот у тебя в циклы вывод на дисплей счетчика. Проверь холостым счетчиком. Может, у тебя частые последовательные обновления информации в цикле не хотят проходить?

Zubok ★★★★★
()
Ответ на: комментарий от true_admin

Защита от статики. Сопротивление от энкодера к ножкам МК + два диода Шотке встречно включенные на питание и массу. Если что, разряд пойдет через них. Диоды со стороны энкодера, перед сопротивлением. Самый простой вариант. Либо использовать спец.микруху есть такие. Изолировать через оптрон или энкодер с оптическим выходом. Вариантов масса.

Надо быть параноиком - софт всегда глючит. Только аппаратный вариант.

pitman
()
Ответ на: комментарий от Zubok

Ребята, спасибо, почти заработало. Код от prischeyadro достаточно хорошо переключает m_position из нуля в единицу и обратно (проблемы когда ручку крутишь медленно или когда из промежуточной позиции крутишь обратно, что логично). Я думаю я разберусь как заставить всё вместе работать.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

Рад, что смог помочь, но странно, что ещё какие-то проблемы остаются. FSM - это совершенно железобетонное решение, с запасом по надёжности от дребезга, возвращения из промежуточных состояний, вспышек на солнце и нашествия марсиан. Скажи, есть ли накопленная ошибка? Ну то есть если энкодер на два полных оборота прокрутить в одну сторону, потом на два полных в обратную, m_position в ноль вернётся? Да, не знаю, обратил ли ты внимание, в моём варианте m_position меняется на 4 за один период сигнала, а в твоём изначальном - на 1 за период.

prischeyadro ★★★☆☆
()
Ответ на: комментарий от true_admin

Я думаю я разберусь как заставить всё вместе работать.

Я все-таки считаю, что у тебя есть проблема в другом месте. По идее все должно работать с любым кодом. С твоим прежним (только с раскомментированными участками), с автоматом, разумеется, тоже.

Дребезг как таковой все приведенные решения не подавляют, а просто счетчик на помеху делает +1, а потом -1.

проблемы когда ручку крутишь медленно

А какие проблемы? Симптомы? Ты не уточнил, твой энкодер какое разрешение имеет? Суммарное значение счетчика при повороте на 360 градусов выдает значение, похожее на правду? Уменьшается ли он в 0, когда возвращаешь назад?

Zubok ★★★★★
()
Ответ на: комментарий от prischeyadro

Да, не знаю, обратил ли ты внимание, в моём варианте m_position меняется на 4 за один период сигнала, а в твоём изначальном - на 1 за период.

Небольшая поправочка, если можно: не 1 за период, а 2, один на arise при B=0, другой — на afall при B=1. Это, разумеется, если раскомментировать то, что закомментировано. Изначальный же, закомментированный вариант подвержен подсчету дребезга и просто никуда не годится. Он, да, на 1 увеличивает.

UPD. В принципе, использование того или иного варианта вытекает из компромисса между требуемой точностью и временем, в котором процессор проводит в прерывании (1 vs 2 vs 4 прерывания за период). Да, и плюс к тому: я бы не дал гарантии, что смешение A и B ровно четверть периода. Исполнение может быть другим. Да и duty cycle может быть не 50%. Поэтому надежнее всего в программе с автоматом делить на счетчик на 4.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 3)
Ответ на: комментарий от Zubok

Да, и плюс к тому: я бы не дал гарантии, что смешение A и B ровно четверть периода. Исполнение может быть другим. Да и duty cycle может быть не 50%.

Хотя для quadrature encoder это гарантируется.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Разумно, да. Тем более, если это энкодер, который вращается ступенчато и в промежуточном положении не остаётся, счётчик и так будет меняться шагами по 4.

prischeyadro ★★★☆☆
()
Ответ на: комментарий от prischeyadro

Так, разобрался. Всё работает, спасибо большое.

Выявленные новые проблемы:

а) одна из новых ног МК была не пригодна для внешних прерываний (либо я плохо прочитал мануал).

б) оказалось что выводы нового энкодера не совпадают со старым. Вот уж не ожидал подставы. Китайцы соединили крайние ноги вместе, но зачем?? (http://www.ebay.co.uk/itm/181598483028?_trksid=p2059210.m2749.l2649&ssPag...

К сожалению, провозился долго т.к. долго не мог въехать как твой алгоритм работает и не понимал как отлаживать. Потом дошло что состояния меняются либо 0-1-2-3-0, либо 0-3-2-1-0 (по крайней мере в текущем коде, я его немного разворотил пока отлаживал). Очень помог вывод состояния на экран на ряду со счётчиком. В конце руками закорачивал пины и понял что энкодер у меня работает совсем не так как я думаю.

Zubok, тебе тоже большое спасибо. Перечитывая свои посты я понимаю что я тупил :(.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

а) одна из новых ног МК была не пригодна для внешних прерываний (либо я плохо прочитал мануал).

Скорее это либо, но с оговоркой (оговорка после цитаты). Стр. 193 даташита.

7.3.8 External interrupt/wakeup lines

All ports have external interrupt capability. To use external interrupt lines, the port must be configured in input mode, refer to Section 10.2: External interrupt/event controller (EXTI) and Section 10.2.3: Wakeup event management.

Оговорка. mbed как низлежащая платформа вполне может запретить использовать какие-то ноги для external interrupt, так как, может, использует их для каких-то определенных вещей. Но тогда это должно быть явно описано в документации mbed, на какие ноги это распространяется. Диаграмма на стр. 258 даташита явно показывает 16 линий прерывания, на которые мультиплексируются порты от PA до PI. Твои D6 и D7 будут подключены на EXTI6 и EXTI7 соответственно.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от true_admin

б) оказалось что выводы нового энкодера не совпадают со старым. Вот уж не ожидал подставы. Китайцы соединили крайние ноги вместе, но зачем??

А откуда ты знаешь, что там даташит вообще от твоего? На твоем модель написана? А то их знаешь сколько безымянных.

Zubok ★★★★★
()
Ответ на: комментарий от true_admin

Китайцы соединили крайние ноги вместе, но зачем??

Какие именно? A и B по чертежу? Или D и E? А то как-то я не очень понимаю, что же получится, если две ноги соединены. Что-то непонятное говоришь.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

А откуда ты знаешь, что там даташит вообще от твоего?

Название модели не фигурирует ни в «даташите» ни на энкодере. Я ошибся на счёт того что А и C замкнуты (не распарсил чёртёж на ночь глядя). Там просто средний вывод (тот что на землю кидают) оказался крайним справа.

По поводу ног, я похоже, разобрался: «IMPORTANT: You can not use two pins on one line simultaneously». Я использовал ноги A3 и A5. Так вот, на самом деле их нормальные названия PB_0 и PC_0 и они используют interrupt line0. По крайней мере я так понимаю инфу на http://stm32f4-discovery.com/2014/08/stm32f4-external-interrupts-tutorial/ .

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

Название модели не фигурирует ни в «даташите» ни на энкодере. Я ошибся на счёт того что А и C замкнуты (не распарсил чёртёж на ночь глядя). Там просто средний вывод (тот что на землю кидают) оказался крайним справа.

Даташит переписан тем, кто выставил их на продажу. Фирма, из которого взят даташит, вот: http://www.ljv.cn/en/ProductClass-29-1.html . Производитель и даташиты на картинке их. Только понять, в какой тыкать у китайцев трудно. В каждом энкодере в отдельном файле справочные данные и отдельно - чертеж с рапиновкой. См. боковое меню, ищи свой. Один экодер может иметь разные исполнения shaft и размеры - смотри чертежи. Но вроде там одна и та же распиновка. На самом энкодере никаких знаков опознавательных? Ты его на ebay и купил?

Так вот, на самом деле их нормальные названия PB_0 и PC_0 и они используют interrupt line0.

Все верно. Они на EXTI0 заведены, а мультиплексор может выбрать только одну. Также в даташите диаграмма этот момент показывает на стр. 258.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 2)
Ответ на: комментарий от true_admin

http://www.ljv.cn/en/Product-319.html

Совпадает. И на ebay A - B - C. Но вроде все правильно. Канал A, Канал B и общий. C на землю и кидают. Вроде все правильно написано. Это ты не разобрался с нумерацией просто.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 3)
Ответ на: комментарий от Zubok

В даташите даже временные диаграммы даны A - C и B - C. Очевидно же, что C - общий.

Zubok ★★★★★
()
Ответ на: комментарий от true_admin

И еще по ходу пьесы. Ток, проходящий через ножки каналов, по даташиту должен быть не выше 5мА. Если ты случайно сделаешь программную ошибку и сконфигурируешь входы как выходы и подашь HIGH на них, то через энкодер ты их просадишь на землю (а энкодер - это просто контакт) и у тебя ток большой попрет через контакты энкодера, а это разогрев. Да и можно порты пожечь - ток не ограничен ничем. Разумно ограничить ток, подключив A и B через резисторы, а подтягивать к питанию не внутренним pull-up, а внешним, то есть до резисторов (иначе делитель напряжения образуется). Еще можно конденсаторы на землю от A и B. R = 10кОм будет ок.

                       Encoder

Vcc   --[   R   ]--+             +--[   R   ]--   Vcc
                   |  A   C   B  |
MCU_A --[   R   ]--+--o   o   o--+--[   R   ]--   MCU_B
                          |
                         ___
Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 4)
Ответ на: комментарий от Zubok

Ну а если нет риска, что сконфигурируешь не так, то внутренний pull-up без навеса вполне годится. Там достаточно большое внутри сопротивление, меньше миллиампера через энкодер потечет.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Да, софтварные ошибки меня больше всего пугают. Особенно когда перевешиваешь энкод с одной ноги на другую не дай бог повернуть ручку когда прошивка ещё старая или же когда прошивка новая, а энкодер ещё не перевесил. Но мне главное чтобы порт целиком не сгорел, а ног пока хватает :).

Чорт, я вместо reference manual читал datasheet :(.

Спасибо большое за твоё время, я много понял в этой жизни :)

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

Да, софтварные ошибки меня больше всего пугают. Особенно когда перевешиваешь энкод с одной ноги на другую не дай бог повернуть ручку когда прошивка ещё старая или же когда прошивка новая, а энкодер ещё не перевесил. Но мне главное чтобы порт целиком не сгорел, а ног пока хватает :).

Ну, дело не только в защите. Внутренние pull-up не очень нормированы и довольно высоки. Если ты захочешь повесить конденсатор на вход для подавления дребезга, то характеристика low-pass фильтра не поймешь какая. Подсоединил к одному контроллеру - одно, к другому-другое. Поэтому есть смысл отказаться от внутренних pull-up и сделать схемку с известными сопротивлениями, как выше, но только еще небольшие кондерчики повесить для подавления дребезга. Тогда можно прикинуть частоту отсечки такого фильтра.

http://www.bourns.com/data/global/pdfs/Bourns_enc_sgnl_cond_technote.pdf

https://ccrma.stanford.edu/wiki/More_Sensors

Можно, конечно, подавлять дребезг и программно. Я у кнопок дребезг всегда программно давлю, а энкодеры просто у меня оптические, а там нет дребезга в принципе.

Zubok ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.