Pull to refresh

Comments 102

Сам сделал. Кольцо ws2812 на 45 светодиодов

UFO just landed and posted this here

Если в мышь установить потенциометр вместо энкодера, то он умрет через 1 неделю интенсивного использования.
Для исключения дребезга контактов программно нужна задержка и немного дополнительного кода. И это все равно не избавит от ошибок.
Слишком Вы упрощаете. Если посмотреть на библиотеку analogRead повнимательней, да еще добавить обработку всех считанных показаний потенциометра, то быстрее не получится. Тем более при каждом чтении на АЦП программно выдерживается пауза, для того что бы входной конденсатор разрядился

UFO just landed and posted this here

На видео настольная лампа электронщика с энкодером. В течении 1 недели смонтирую видео про него и выложу

UFO just landed and posted this here

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

UFO just landed and posted this here

Вы не сделали еще одну важную деталь - изменение скорости прокрутки. Допустим вам надо регулировать от 0 до 100. И каждый щелчок увеличивает переменную на 1. И если крутить просто по программе то надо сделать 100 щелчков. А в нормальной аппаратуре количество прибавления зависит от скорости вращения энкодера. Медленно вращаем - приращивается на 1, быстрее - на 2, еще быстрее на 3 и т.д.

Допустим, вам надо регулировать условную яркость из двух мест одновременно.

Конечно, есть моторизованные потенциометры, но программно синхронизировать уставку параметра, пришедшую "извне" со с переменной, привязанной к энкодеру - проще.

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

analogWrite(9, readEncoder() );

Вот и весь код.

На ардуиновской функции analogRead() свет клином не сошелся. Вполне можно работать с АЦП в фоновом режиме по прерываниям, а в основном цикле использовать готовые результаты измерения. Получится примерно так же, как Вы поступаете в своей программе с энкодером.
Вроде бы и крутишь, но часть щелчков фейковые.
Это известная проблема. Из описания Transistor Tester: "The figure 2.8 shows a rotary pulse encoder, which has not only bouncing contacts, but also has a unstable state of one of the switches at the indexed position (detent)".

А Вы сначала сравните мой код с гайверовским, а потом напишите результат. Я проверял его код, работает крайне нестабильно

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

Начнем с твоего плагиаторства, ты украл мой проект (2011г.) и выложил в своем видео блоге(2017г.) от своего имени и еще добавил, что ты сам разработал ))))). Хотя даже код не изменил для неузнаваемости. Ровно как и большинство твоих видео, это проекты других людей, выложенные тобой как от супер-гениального разработчика.
По поводу твоей библиотеки, я считаю ниже своего достоинства использовать в своих проектах, твои г..но библиотеки и все остальное, что как то связано с твоим ником или именем.

ахахах, это тебя пришлось забанить в группе за идиотию и клевету? Отвечу здесь ещё раз, мне не сложно:

  • Я ничего никогда ни у кого не крал. Код был взят с форума arduino.ru, он был там в свободном доступе. И я не выдавал его за свой.

  • По этой же причине я не менял код и взял твою библиотеку, не изменяя исходник. Как я делаю во всех проектах, чтобы зритель мог скачать архив и не собирать файлы по всему интернету. Кому интересно - всегда может выйти на твой репозиторий. Опять же, я не выдавал библиотеку за свою, я не совсем конченый в отличие от некоторых.

  • А вот плату разработал я, на чём сделан акцент в видео, схема там - классическая для симистора и детектора нуля, находится в гугле по запросу arduino dimmer.

Библиотеки не используй, никто не заставляет, но абсолютно беспричинно поливать говном человека и его работу это как то низко, даже если это зависть или хз что там в голове. Всего хорошего, береги достоинство =)

Не крал говоришь? Смотрим здесь https://youtu.be/jPbptVGZisc?t=438

Твоя фраза в видео - "Мой алгоритм" )))

Если ты взял в интернете, то при публичном использовании ты обязан сослаться на первоисточник. Но ты вместо этого говоришь "Мой алгоритм" при этом показываешь мой код.
Схема нарисована мной в нулевых годах, я реализовал ее тогда на pic контроллере и выложил на форум Микрочипа. В те времена ардуино еще не родился. Потом в 2010г. реализовал на ардуино. Так, что схема тоже впервые нарисована мной.
Если ты взял проект в интернете, то в этом нет ничего плохого, но вот если ты используешь его в публичном доступе и говоришь, что это твое, то ты "Плагиатор".

Про достоинство: Как вообще у тебя язык повернулся говорить про достоинство в твоей ситуации? Если оно у тебя еще осталось, то удали видео и пожмем руки.

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

Давай так - извиняешься за фонтан говна и ничем не обоснованной клеветы в мою сторону в отношении остальных проектов (мы это обсуждали года два назад, я подробно расписывал какие проекты были лично мои, а какие - ДОРАБОТАНЫ и об этом по-русски сказано в видео, а ты ни ничего не смог на это ответить) - и я прямо сейчас убираю видео про диммер, вообще без проблем, и также приношу свои извинения.

Глянул конец - я уже предлагал мирно решить этот вопрос, добавив любые ссылки и нужную тебе информацию в описание под видео.

Я не помню такого, если предлагал то извини за невнимательность, это решает наш вопрос и ссылки будет достаточно. Хотя форум уже полумертвый, но тем не менее. Если разместишь ссылку на оригинал http://cyber-place.ru/showthread.php?t=525 , то все претензии снимаются. После чего дашь ссылки на то, что нужно мне удалить я удалю без проблем и извинюсь

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

Спасибо! Извини за нападки я все таки был неправ о достоинстве. Ссылка на мой канал в ютуб, это был жест твоей доброй воли и ставит меня в неловкое положение, за мои высказывания. Удалять видео не нужно, я снимаю все претензии и приношу извинения за слишком резкую и чрезмерную реакцию.

UFO just landed and posted this here

Вдруг кому пригодится информация (кто не в "теме").

Есть еще абсолютные энкодеры, которые "запоминают" свое положение.

Например: EAW0J-B24-AE0128L

Они дороже конечно, но не намного. Энкодер выше, стоит в чип-дип 1240р.

1240 это примерно в 10 раз дороже инкрементальника из статьи. Очень намного.

А ещё есть микросхема AS5600, которая представляет собой абсолютный энкодер на 4096 отсчётов. И вот она стоит 200 рублей. Радиально намагниченный магнит к ней - ещё 68 рублей. Работает изумительно. На температуру почти не реагирует, +- 2 отсчёта на 60 градусов.

Спасибо за инфу, буду иметь ввиду.

Так то мне нужен энкодер с разрешением 1градус (поворотное устройство для антенны придумываю). Вот на всякий и прикупил такой для "разминки".

Нудык 12 бит - это разрешение меньше 0,1 градуса, и ошибка будет не более 0,3. Такие энкодеры продаются на алиэкспрессе и применяются в ЧПУ станочках для контроля шагового двигателя - что он шаги не пропускает. Стоят ещё дешевле, чем я написал - первый же линк из поиска али - 130 рублей.

Такая штука имеет смысл, когда обороты под 20000 и есть специальная микросхема-обработчик энкодера, ну либо магнитные помехи просто ОМГ. Во всех остальных случаях сейчас нет большого резона применять оптический энкодер.

UFO just landed and posted this here

Кстати говоря, для больших оборотов и минимальных задержек есть синуснокосинусные преобразователи. Это такой сенсор, внутри которого два магниторезистивных моста, причём они сдвинуты по фазе на 90°. Один выдаёт синус угла поворота, а другой - косинус. Таким образом, обрабатывая сигнал с обоих мостов, мы можем рассчитать точное значение угла поворота. Такие штуки бывают как со встроенным обработчиком и цифровым интерфейсом, так и чисто мосты "без никто". Например, TLE5501

А этой AS5600 надолго хватит, если я ее следить за направлением ветра в метеостанцию поставлю? Сейчас стоит последовательность из 16 герконов и резисторов разных номиналов.

Она бесконтактная. Будет работать, пока питание подано. Лет на 10 точно хватит, а может и больше. Магниту тоже ничего от времени не будет, плюс у AS-ки довольно большой запас по напряжённости магнитного поля и АРУ.

Кстати, для метеостанции там есть режимы энергосбережения с пониженной частотой опроса. 1.5мА при частоте опроса 100 мс. Ну или выключать-включать.

AS5600 на I2C и нельзя менять адрес. То есть, если надо парочку, то это не очень удобно.

Есть вариант AS5048 на SPI, но они уже намного дороже. Есть ещё недорогие варианты типа такого, но что бы можно было без проблем больше одного подключить?

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

Варианты, конечно, есть - поставить мультиплексор порта, например, но это какие-то адовые костыли, которых бы не было, если бы, например, у микрухи была нога "ENABLE".

Ага, именно так. Видимо, расчёт на то, что обычно нужна одна такая.

С мультиплексором, конечно, перебор. Проще поставить AS5048, это явно проще и дешевле будет на фоне продукта.

А мне как раз надо на оба колеса для робота такие поставить.

Если на оба колеса - то, как по мне, проще найти камень с двумя аппаратными I2C или сделать софтовый. Ну или, например, выводить ШИМ и его измерять - тупо, но работает. А ШИМ AS5600 делать точно умеет.

Камень тут не я выбираю, к сожалению. Это просто начальное требование.

С ШИМом вроде говорят, что не так надёжно получается на этих датчиках. К сожалению, не помню подробностей -- может помехоустойчивость не очень или ещё что.

P.S. хммм... только сейчас понял, что у меня как раз есть два железных I2C на камне. Не знаю куда я смотрел до этого, но зато я точно знаю, что на улице за окном ровно 12 ворон летает.

Правда, проводов будет чуть больше. Но этот вариант уже есть смысл рассмотреть.

UFO just landed and posted this here

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

очень приятно пользоваться устройствами с отзывчивым управлением
но энкодеры, подвержены износу, и даже конденсаторы не спасают :(
пользуюсь решением от DI HALT опрос по таймеру 1-5 мс
если же необходимо по прерыванию: великолепное железное решение — MC14490 -аппаратный подавитель дребезга

Все подвержено износу. Но вот колесики на мышках годами живут, а там инкрементальный энкодер

Часто в мышках энкодер делают на основе оптопары.

Это с шариками мышки так делали, а колесо на оптических мышках обычно на инкрементном энкодере

Так на оптопарах он тоже инкрементный... Но я не помню в мышках чаще оптический или механический на колесе (вот x/y на мышках с шариком точно оптические были).

UFO just landed and posted this here

Ну да, я забыл ты же писатель, а не читатель. Специально для тебя https://yandex.ru/images/search?from=tabbar&text=%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%B0%D1%8F%20%D0%BC%D1%8B%D1%88%D1%8C

Только вот на многочисленных фото оптических энкодеров я не нашел, даже на старых мышках установлены механические, инкрементальные энкодеры

Давно не разбирал мышей, но
потрудитесь обьяснить
image

Фото всей платы можно?

У моей мышки Logitech



Ну это Logitech, а остальные предпочитают экономить.
Часто в мышках энкодер делают на основе оптопары.

Уже давно — редко.
UFO just landed and posted this here
Это так. Но полагаю, что обработка состояния энкодера в них сделана по таймеру, или аппаратно, с защелкиванием по тактовым импульсам на частоте опроса. Вешать 3 дребезжащих контакта на прерывание, это верный путь к проблемам.
энкодеры, подвержены износу
От конкретного энкодера зависит. Не знаю, какой энкодер установлен в MP3-ресивере Pioneer, но работает он без единого нарекания вот уже 18-й год. И это с учетом колебаний температуры и влажности в салоне автомобиля!

Конденсаторы можно уменьшить до 0.01мкФ. Номинал подтягивающих резисторов к +питания?

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

Определение нажатия на кнопку энкодера лучше сделать в void loop()

Много раз порывался поставить энкодер в свои поделия, и каждый раз приходил к тому, что он прекрасно заменяется тремя кнопками: ▲,▼ и ●. Количество пинов - то же, количество кода - в 100 раз меньше, кнопка подтверждения - есть. Единственное отличие - требуется три дырки, и нет красивой и приятной тактильно крутилки. Тут да, крутилка - это другое ощущение.

Крутилка гораздо удобнее, особенно когда надо вводить большие интервалы.

Спасибо за инфу.

Видео длиннее и не надо: коротко и по делу

Код обработки длинного и короткого нажатия кнопки без библиотек на чистом С

//****************************************************************************
void ScanKeyboardTast(void)
{
static DWORD Tdl_key=0; 								// штамп времени
static BOOL Key_Up;
static BOOL Key_Down;
static BOOL LongPres=0;
static BOOL Key_Sost=1;
static BOOL Key_OldSost=1;
static BYTE Status_Input; 								// Состояние входа

		Status_Input=Status_Input<<1;
		if (BXOD1 == 1)	Status_Input=Status_Input | 0x01; else Status_Input=Status_Input & 0xFE;
		if 		(Status_Input== 0xFF) Key_Sost=0; 
		else if (Status_Input== 0x00) Key_Sost=1;

//	Если не нужна защита от дребезга то нужна всего одна строка
		Key_Sost=BXOD1;									// Кнопка замыкает подтянутый к +питания вход на землю

		if	((Key_Sost ==0) && (Key_OldSost ==1)) 		// Кнопка нажата ?
			{
			Key_Down=1;									// Установили флаг нажатия
			Tdl_key = TickGet();						// сделали штамп времени
			}

		if	((Key_Sost ==1) && (Key_OldSost ==0)) 		// Если кнопка отжата ?	
			{
			if	(LongPres==1) 							// Проверяем было ли длинное нажатие
				{
				LongPres=0;
				// {.....}								// Действие по длинному нажатию
				}
			Key_Down=0;
			// {.....}									// Действие по короткому нажатию нажатию
			}
	
		if (Key_Down==1)								// если было нажатие
			{
			if (TickGet() - Tdl_key > Time_long_press)	// проверяем вдруг будет длинное нажатие
				{
				LongPres=1;								// зафиксировали длинное нажатие
				}
			}
		Key_OldSost=Key_Sost;							// запомнили предыдущее состояние кнопки
}
//****************************************************************************
// Примечание функция TickGet() очень похожа на функцию millis() в Ардуино
// BXOD1  - вход подключения кнопки

У меня в прерывании обрабатывается вот так:

   if (comb == 7 && lastcomb == 3 && btn_press) //Если было отпускание кнопки, то проверяем ее предыдущее состояние 
   {
    if (millis() - timer > btn_long_push)         // проверяем сколько прошло миллисекунд
    {
      enc_state=4;                              // было длинное нажатие 
    } else {
             enc_state=3;                    // было нажатие 
            }
      btn_press=0;                           //обнулить статус кнопки
    }

Можно так же добавить обработку очень длинных нажатий

UFO just landed and posted this here

Поэтому в нормальной программе если используется глобальная переменная как enc_state и в обработчике, и в основном теле программы, то код, который изменяет значение переменной в основной части лупа (обнуляет) должен быть закрыт DISABLE_INT() / ENABLE_INT() в противном случае даже в такой простой программе, все может легко сбиваться. То, что работает - подозреваю дело времени.

Так для этого есть специальный тип переменных volatile. Про swich вообще жесть, Вы похоже не в курсе как он работает и стоит ли его применять в этом случие. Прежде чем судить о правильности кода, лучше почитайте основы програмирования

UFO just landed and posted this here
volatile всего лишь предписывает компилятору не делать никаких предположений о значении переменной при оптимизации, а вовсе не обеспечивает синхронизации. В Вашем случае используется переменная байтовой длины, поэтому проблем не возникает, так как установка и считывание значения переменной происходит атомарно. Если бы переменная была длиннее, то она бы уже не была атомарной и были бы возможны проблемы, о которых и написал Gromushka.
UFO just landed and posted this here
Согласен. По хорошему, если время обработки события в основном цикле много больше, чем возможный темп возникновения событий, то необходимо организовывать очередь, иначе возможен пропуск событий. А при организации очереди необходимо позаботиться о синхронизации операций записи и извлечения.

Еще решением может быть отключением прерывания и последующим включением после полной обработки. Например так:

ISR (PCINT1_vect) //Обработчик прерывания от пинов A1, A2, A3

{

uint8_t comb = bitRead(PINC, 3) << 2 | bitRead( PINC, 2)<<1 | bitRead(PINC, 1);

PCICR = 0b00000000; // PCICR |= (1<<PCIE1); Выключить прерывание PCINT1

INTstate=1;

}

UFO just landed and posted this here

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

а enc_rotation не байтовая.

по этому если мы начинаем читать на 8-битном контроллере 0x01FF считали старший байт, в середине присвоения вызвалось прерывание которое инкрементировало значение до 0x0200, затем мы считали младший байт и получили на выходе 0x100.

По этому или запрет прерываний на время присваивания или двойная буферизация в прерывании и флаг запрета обновления в прерывании. Или любой другой механизм (который как правило сводится к этим двум).

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

А расскажите, чем вас не устроил коммент про swith? А то я вот смотрю на 4 одинаковых куска вида:

if(enc_state==1) // Если энкодер вращался без нажатия

{

Serial.print("Вращение без нажатия ");

Serial.println(enc_rotation);

enc_state=0; //обнуляем статус энкодера

}

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

Нужно же было писать в какой функции Вы хотели вставить switch. Я то подумал, что Вы предлагаете в прерывании его вставить. В главном цикле loop этот кусок кода всего лишь демонстрация, он потом выбрасывается от туда

Это не я его предлагал вставить, другой комментатор, но и в прерывании правильное структурирование кода тоже никак бы не помешало, там вся логика завязана на 4 значения comb. Конечно - это все идеализм, особенно, если говорить про прототипы, но раз уж отреагировали так резко - будьте готовы объясниться.

Во первых это многословность и громоздкость самой конструкции, только взгляните — switch, case, break и default

Вы бы написали свой пример обработки на switch, потом мы бы порассуждали, что лучше и компактнее

Я писал про структурированность кода, а не про компактность, странно, что это надо объяснять. Компактно вы можете хоть "a = 3 - a;" написать по мотивам легенд из прошлого века "как заменить 1 на 2 и наоборот". Но даже если это не вспоминать, у нас еще в 98-м на лабах универа снижали оценки за лишние бессмысленные if, жрущие производительность.

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

Я Вам предложил написать такой же код на switch, что бы потом сравнить его размер после компиляции и производительность. Напишите , а потом поговорим.

UFO just landed and posted this here
if (enc_state !=0)
{
func(enc_state);
enc_state=0;
}

Когда вижу простыню if-ов, рука сама тянется к пистолету ;)

Опсь, сорян, с этого же и началось ;)

Чукча не читатель, чукча писатель! Я же писал выше, что этот кусок кода не обязательный, вставлен только для демонстрации работы и да я согласился, что его лучше поменять. Речь же шла о замене if() в прерывании

UFO just landed and posted this here
if (enc_state == 1) func(1);
if (enc_state == 2) func(2);  
if (enc_state == 3) func(3);
 enc_state = 0; 

сравнивайте

switch (enc_status)
{
case 1: 
   func(1);
break;
case 2:
    func(2);
 break;
 case 3: 
    func(3)
  break;
}
enc_state = 0;
Дело вкуса. Если в вариант с if-ами добавить else (чтобы не гонять лишние проверки) и скобки (если вдруг вздумается делать что-то еще кроме func()) — никакой разницы.
ЗЫ: волшебные константы нехорошо в любом случае.
К сожалению, привычка всегда окружать блок кода внутри if фигурными скобками, даже если это одиночное выражение, приходит только после набития некоторого числа шишек. А до этого превалируют рассуждения о краткости, лаконичности и т.д.
Справедливости ради, можно и в однострочной записи окружить скобками. Поправьте, если ошибаюсь, но можно же всю программу на си написать в одну строку.
Можно, конечно и в одну строчку (чтобы строки экономить), и все переменные длиной в 1 букву (чтобы символы экономить) ;)
Поправляю: с директивами препроцессора будут проблемы — со всякими #define и т.д.
UFO just landed and posted this here

Сравниваю: код с if выполняет всегда 3 проверки, вне зависимости от того, которая сработала. И сколько бы вы не лепили в одну строчку, такое отношение к производительности непозволительно даже джунам.

а что сравнивать то ? по идее switch намного лучше... и в том числе по производительности...

о чем спор то ?!

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

Нужно это чтобы прерывания были настолько атомарными, насколько возможно (если так можно сказать). А это нужно чтобы максимально исключить возможность прихода других прерываний во время обработки текущего. В крутилке для лампы это, конечно, не важно, но в сложных задачах с кучей переферии может быть критичным. Также это может быть важным в системах требовательных к таймингам разного рода (например, если есть софтварный bitbang генератор [например, для той же ws2812 ленты] и тд) — очевидно, что длинные обработчики прерываний будут сбивать тайминги, а очередь событий позволит нивелировать эффект, обрабатывая логику «между кадрами».

Состояний не 4, а 16 (важны не только текущие значения пинов, но и предыдущие), из них 4 – стояние на месте (биты не поменялись), 4 – вращение в одну сторону, 4 – в другую и ещё 4 – некорректные (слишком быстрое вращение или ещё что, имеет смысл игнорировать).

Ну и по целой функции на состояние – жирно, достаточно значения +1, 0 или -1. Табличка на 16 signed char. Можно, конечно, поиграться с логическими операциями и избавиться от неё (кто тут умеет в карты Карно?), но смысла нет.

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

Проще и надежней использовать керамические конденсаторы.

RC фитр и вход в режиме триггера Шмитта, тогда уж.

И совсем не стоит коротить энкодером конденсаторы достаточно приличной емкости.

Алекс(ей/андр?), вас не затруднит на ваш скетч нарисовать подробный алгоритм? Это позволит начинающим портировать код на другие языки. Если вы планируете несколько статей, то приведение в начале рисунка алгоритма было бы здорово.

я кроме конденсаторов еще и 100Ом по общему проводу поставил

идея с вращением при нажатии понравилась, дажэ сходу понял где мне это надо.

UFO just landed and posted this here

Вопрос автору. А не стоит ли всю логику из обработчика убрать, и в нем лишь фиксировать значения в некоторой очереди фиксированной длины? А саму логику вызывать в теле основной функции непосредственно перед использованием? Из плюсов, думаю, ускорится обработка прерывания и можно будет пропускать "дребезг" программно усреднением соседних значений в очереди?

Хм. Давно на авр не кодил, но в свое время программно ловил фронт одного канала по таймеру (период то ли 1мс то ли 100мкс) и в зависимости от состояния соседнего канала инкрементировал/декрементировал положение вала (так называемая одинарная точность, есть еще двойная - ловится фронт/спад одного канала и четверная - фронт/спад обоих каналов).

На современных мк (вроде стм32) квадратурный энкодер встроен в переферию и таких заморочек не нужно.

Sign up to leave a comment.

Articles