Pull to refresh

Comments 37

Я прям как в универ попал снова. Спасибо за статью!

Пожалуйста. Надеюсь это поможет создать полезные устройства с энкодером.

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

Драйвер написан согласно вот этой методичке.

Архитектура Хорошо Поддерживаемого Программного Компонента
https://habr.com/ru/articles/683762/

Если коротко, то много файлов нужны для выборочной компиляции в зависимости от располагаемых в MCU ресурсами.

Ядро драйвера в файле incremental_encoder_mcal.c

20 файлов для для библиотеки работы с энкодером - не многовато ли?

Если проводить аналогию из медицины, то это как центрифугирование крови. Кровь делится на плазму, эритроциты , тромбоциты, красные кровяные тельца и прочее. Так и программный компонент тоже делится на свои фракции. Это ядро, константы, типы данных, диагностика, параметры для NVRAM, файл скрипта сборки, зависимости, конфиги, CLI и тесты. Вот как-то так.

Хз, я на pic16 обошолся всего 2мя функциями и графиком в 2D пространстве S0*S1:

/*
	rotation encoder

	10<-11
	V    ^
	00->01

	00 01 11 10 ->  10110100 0xB4

 input:  s=[ any:4   cur:2 prev:2 ]
 output:   [ trash:4 res:2 cur:2  ]

	     00 01 10 11 cur
	00   00 01 10 11    11100100 0xE4
	01   10 00 11 01    01110010 0x72
	10   01 11 00 10    10001101 0x8D
	11   11 10 01 00    00011011 0x1B
	prev
*/
enum { renc_inc=4, renc_dec=8 };
char renc_pos(char pos) { return (0xB4>>((pos&3)<<1))&3; }
char renc_upd(char s) { static const char t[4]={ 0xE4,0x72,0x8D,0x1B };
	return ((t[s&3]>>((s>>1)&6))<<2)|((s>>2)&3);
}
/* 4bits state usage:
	char pos=0, enc=(S1<<1) | S0;
	...
	enc=renc_upd( (S1<<3) | (S0<<2) | (enc&3) );
	if (enc & renc_inc) pos++;
	if (enc & renc_dec) pos--;
	code=renc_pos(pos);
*/

renc_upd просто обновляет состояние enc, у которого можно узнать увеличиваем положение или уменьшаем. если оба одновременно 1 то недопустимое значение и pos не изменяется. а renc_pos позволяет по положению генерировать S0 и S1 (это если надо эмулировать энкодер)

Я и график не понимаю зачем нужен, одной строчкой считал:

int32_t delta = pin_a_changed ^ pin_a ^ pin_b ? -1 : 1;

об этом ни статью, не методичку не напишешь! Оказывается задача решается с помощью элементарной арифметики полей Галуа.

элементарной арифметики полей Галуа.

У нас в ВУЗе нам поля Галуа не преподавали.

Да я тоже про поля тут на хабре узнал. А в этой задаче просто догадался что раз все факторы (состояние ножек, направление фронта, то какая из ножек изменилась) влияют и изменение каждого из них инвертирует результат, то надо взять от них xor.

Как заполнять переменную pin_a_changed?

если делать по прерыванию от фронта то и переменная не нужна - мы и так знаем на каком пине фронт сработал. А так - сохранять старое значение pin_a и pin_b и сравнивать с ними новые - если хоть одно изменилось то применяем формулу выше.

с отсутсвием в убогих МК barrel shifterов вот это вот 0xB4>>x будет ужОс во что скомпилировано(циклы с побитовым сдвигом), проще 16байт флэша на полную таблицу потратить.

int delta(bool a, bool b){
  static bool pa=0, pb=0;
  bool pos = a^pb, neg = b^pa, moved = pos^neg;
  pa=a; pb=b;
  return (moved&pos) - (moved&neg);
}

Во первых даже в убогих мк есть подпрограммы, которые вызываются командой call. Во вторых renc_pos нужен только для эмуляции экодера, а для определения используется только renc_upd. В третьих renc_upd может обновлять состояние и сообщать об изменении и направление поворота экодера, храня состояние в 1 байте, при желании 2 сотояния в байте. В четвёртых функция чистая (не имеет внутренних состояний) и может обрабатывать сколько угодно энкодеров. В пятых обработка опроса и фильтрации дребезга отделены от функции определения вращения. В шестых никто не мешает ограничивать диапазон допустимых положенией. И потом нафига вы пытаетесь оптимизировать раньше времения, особенно если ресурсов еще с запасом? Более того это эти экодеры не требуется опрашивать слишком быстро и когда их много они опрашиваются как клавиатура (матрица например 8*8) по последовательной шине (RST,CLK,DAT), перебирая столбцы и колонки, просто на каждый энкодер еще по 2 диода вешается.

// load S0,S1, enc, pos, pos_min, pos_max
enc=renc_upd( S1S0<<2 | (enc&3) );
if (enc & renc_inc) pos++;
if (enc & renc_dec) pos--;
// handle range
if (pos<pos_min) pos=pos_min; if (pos>pos_max) pos=pos_max;
// store enc, pos

Не всё так просто.
В драйвер энкодера еще надо заложить ограничители.
Чтобы не позволять увеличивать счетчик выше конкретного порога.
Чтобы не позволять уменьшать счетчик ниже конкретного порога.
Сами пороги прописывать в конфиг- файле.

Недавно натыкался на специализированный МК для управления мотором - Nuvoton NM1520, так у него целый отдельный периферийный модуль интерфейса экнодера оказался, фильтрует дребезг, определяет направление вращения (и его смену), отсчитывает время от сигнала нулевого положения итд, красота!

В stm32 тоже некоторые аппаратные таймеры обладают режимом энкодера.

Но что бы будете делать если надо к одному МК подключить 30 энкодеров?

Статья из серии как из простого сделать сложное. То, что вы описали, как способы применения энкодера (в данном случае фазного) :

1) Можно сделать фазовый детектор для SDR обработки сигналов. Если сигналы симфазные, то энкодер будет показывать ноль. Если A опережает по фазе B , то будет нарастать счетчик, если A отстает от B, то счетчик будет убывать.

А в чем смысл данного детектора? Что вы собрались здесь инкрементировать? Обычно вычисляется разность фаз, а не наличие того, какая фаза раньше или позже. Не понимаю целесообразность применения. Если это на СВЧ, то алгоритм конечного автомата будет работать только в теории, на практике совсем другой подход. И вряд ли он сможет показать ноль, если сигналы симфазные. У него задача определить, какая фаза была раньше. И любой программный код имеет последовательность считывания сигнала с пинов. Прерывание с одного пина в любом случае прочитается или раньше или позже, в зависимости от того, что сработало первым. Микроконтроллер - последовательная система обработки данныз. Отличие может быть в наносекундах, но оно будет. Или же вы сами будете выставлять тайминги, в которые сигналы будут считаться синфазными.

2) Регулировать громкость проигрывателей, яркость светильников.

Тут вообще все примитивно и обрабатывается банальным алгоритмом. Даже прерывания можно не трогать. И с кодом тоже нет смысла заморачиваться и соответственно тратить ресурсы микроконтроллера на сложную обработку простого решения. Даже пропуск одного такта не сыграет роли.

3) Оснащать обратной связью электрические моторы и сервоприводы.

Здесь посложнее и все зависит от того, что именно вы хотите обработать. Если сервопривод, то да, нужен очень качественный энкодер, а не то, что вы привели в пример. Я бы сказал не просто качественный, а совсем другого принципа абсолютный энкодер (оптический, магнитный, емкостный) с цифровым интерфейсом и знающий свое положение на момент включения (абсолютную позицию, угол, сдвиг и так далее) .

Если это электродвигатель, то там либо оптический, либо магнитный, либо трансформаторный (аналоговый). И ни в случае с сервоприводом ни с электродвигателем, простой фазный энкодер типа А/В ставиться не будет! И работать он там не сможет! Ну и стоит учесть, что при больших оборотах двигателя, изменение направления вращения быстрым не будет. Да, отчасти все эти энкодеры будут работать как фазовые, но на таких частотах, что длительность имнульсов будет измеряться в наносекундах. При этом магнитный энкодер эмулирует фазовый сдвиг, а оптический имеет собственную систему обработки данных. И все они передают информацию в цифровых интерфейсах.

4) Одометры, датчики скорости оборотов или измерители поступательного движения.

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

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

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

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

Автору удачи и успехов!

Конечные автоматы - дело хорошее, но необходимо рассмотреть их применение более тщательно. Мы это проходили в конце 90х и тогда это было актуально и проектировали мы это на бинарной логике.

Конечные автоматы - дело хорошее, но необходимо рассмотреть их применение более тщательно. 

Конечный автомат золотой шаблон проектирования системного ПО.
Выручал много раз при решении прикладных задач.

Декодирование BPSK Модуляции из Звука (или передача данных по воздуху) https://habr.com/ru/articles/848068/

Задача про две ёмкости для жидкости
https://habr.com/ru/articles/662561/

Запуск I2S Трансивера на Artery [часть 2] (DMA, FSM, PipeLine) https://habr.com/ru/articles/834304/

Квантование на Триггерах Шмитта
https://habr.com/ru/articles/1003262/

Конечный Aвтомат Аппаратного I2C-Трансивера
https://habr.com/ru/articles/856548/

Обзор Протокола ISO-TP [ISO 15765-2]
https://habr.com/ru/articles/798489/

ПасТильда: ещё одна прошивка
https://habr.com/ru/articles/706470/

Передача и прием данных по лазерному лучу (SDR декодирование BPSK в реальном времени)
https://habr.com/ru/articles/1023062/

Принцип Определения Дальности Между UWB Трансиверами (Конечный Автомат Для DS-TWR)
https://habr.com/ru/articles/723822/

Протокол TBFP
https://habr.com/ru/articles/969948/

Пуск Беспроводной CLI на Микроконтроллере
https://habr.com/ru/articles/929086/

Синтаксический разбор CSV строчек
https://habr.com/ru/articles/765066/

Теория управления шаговым двигателем (или как вертеть PTZ камеру) https://habr.com/ru/articles/709500/

Техникум: Конечный Aвтомат Обработки Сигнала с Кнопки https://habr.com/ru/articles/760088/

Техникум: Распознавание Вещественного Числа из Строчки https://habr.com/ru/articles/757122/

Cross-Detect для Проверки Качества Пайки в Электронных Цепях https://habr.com/ru/articles/762142/

H-мост: Load Detect (или как выявлять вандализм)
https://habr.com/ru/articles/709374/

Load-Detect для Проверки Качества Пайки
https://habr.com/ru/articles/756572/

При разработке электронных устройств порой надо подключить инкрементный энкодер.

Может все таки НЕ надо - энкодеры помоему худшее что могло произойти с железными интерфейсами...

Приходиться... еще можно понять и простить старые полулюбительский вещи только с 1 энкодером...

 - энкодеры помоему худшее что могло произойти с железными интерфейсами

Почему тогда осциллографы и блоки питания все еще настраиваются энкодерами?

Взрослые БП клавиатура или клавиатура+энкодер, в осликах энкодеры заменили только переключатели/переменники каждый под конкретную функцию. В этом направлении к счастью только самый ширпотреб пытается на 1 энкодере собрать миллион функции которыми невозможно пользоваться.

Скрытый текст

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

И многие дорогие приборы. Хотя видел в очень дорогой промштуковине имитацию: бульб, имитирующий крутилку, и в торце уложено сенсорное колечко - по нему палец по кругу водишь, и он как крутилка плавно меняет параметр. А кнопки, которые перемещают по многуровневому меню, ужасны. Хуже только сенсорный экран с многуровневым меню.

В любом mcu есть куча таймеров, и несколько из них аппаратно поддерживают энкодеры

В любом mcu есть куча таймеров, и несколько из них аппаратно поддерживают энкодеры

А как быть если нужен не просто энкодер, а энкодер с ограничением?
Чтобы упершись в максимум можно было крутить только назад CCW.
И напротив, упершись в минимум, можно было крутить только вперед CW.
Вернее крутить можно всегда, а софт должен программно накладывать пределы.
Ведь это основа любого HMI.

обработать сответствующее прерывание

Настоящее "искусство" начинается там, где надо устанавливать энкодером довольно большой интервал значений, скажем в случае рентгеновской трубки с максимальным напряжением 450 кВ мы можем устанавливать инкремент один вольт, но заставлять юзера накручивать четыреста пятьдесят тысяч инкрементов - ну, такое, жестоко как минимум, так что приращение должно зависеть от скорости вращения колёсика, а вкупе с тем, что частота опроса ограничена, кроме того подключённое устройство несколько инерционно, всё это приводит к тому, что код приходится обложить кучей условий, чтобы всё это заставить работать комфортно для пользователя, и все ещё и крутят с разной скоростью.

Настоящее "искусство" начинается там, где надо устанавливать энкодером довольно большой интервал значений, 

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

По крайней мере так сделано на лабораторных блоках питания (AC-DC).

В механических микроскопах мне нравится как сделано - там две крутилки (с разным передаточным числом) и одна внутри другой, как пирамидка. Очень удобно. Если электронно такое реализовать, вообще будет хорошо

В рентген аппарате изменение напряжения с точностью в десятые доли процента практически никак на качестве контроля не скажется. В данном конкретном случае это избыточная точность. Это если предположить, что высоковольтный генератор может такую точность обеспечить. Скорее всего, у вас точность один вольт будет только на экране, а на трубку пойдет хорошо если +/- 5 кВ, да еще и с дрейфом в процессе излучения.

Стопитсоттысячная реализация... Зачем?

Сделано по iso26262

и по методичке. Мне кажется самое интересное вы прячете в методичке!

Интересно:

В целом в стандарте ISO-26262 не всё понятно, но полезные советы для себя обнаружить можно.

как же вы определяете соответствие тому, что пока не полностью понятно?

Что понятно, то и делаю. Что не понятно - пропускаю.

Sign up to leave a comment.

Articles