Страница 1 из 1

Пытаюсь настроить опрос Энкодера

Добавлено: Пн окт 09, 2017 22:00:03
alexey6522
Приветствую! Тема такая, хочу к одному МК (мега128) подключить до 5 энкодеров и опрашивать их по таймеру. Как всегда получается, что в протеусе всё норм, а на деле ничего, реакции на вращение ноль. До этого делал, но опрос был в общем цикле, при быстром вращении были проскоки. Энкодеры ставлю эти https://ru.aliexpress.com/item/5pcs-360 ... 0.0.hEFelS

Код: Выделить всё

char New;
int EncState1=0;
int EncData1=0;

//Инициализация таймера
void timer_init (void)
{
cli(); //остановка глобального прерывания
TCCR0=(1<<WGM01); // устанавливаем режим СТС (сброс по совпадению)
TIMSK |= (1<<OCIE0); // устанавливаем бит разрешения прерывания  счетчика по совпадению
OCR0 = 0b11111111; // определяем число сравнения
TCCR0|=(1<<CS00); //запуск таймера с предделителем 
sei(); // enable global interrupt
}

//опрос порта Д
void EncoderScan(void)
{
 New = PIND & 0xFF;   // Берем текущее значение
 //1-й энкодер
 if ((New != EncState1) && (EncState1 == 3))
 {
      if(New == 0b00000001) 
        EncData1++;       
      else 
        if(New == 0b00000010)                     
          EncData1--;           
 } 
 EncState1 = New;      // Записываем новое значение
}

ISR (TIMER0_COMP_vect)
{
  EncoderScan();
  if(EncData1 == 1)
  {
	EncData1=0;
	j+=1; //увеличиваем переменную на 1 + преходим в режим ожидания единиц
	if (j > 9) //так как подключено 10 светодиодов, обнуляем.
	  j = 0;
  }  
  if(EncData1 == -1)
  {
	EncData1=0;
	j-=1; //уменьшаем переменную на 1 + преходим в режим ожидания единиц 
	if (j < 0) 
	  j = 9;	
  } 
}

int main(void) //Основное тело программы
{
//настраиваем порты ввода-вывода
DDRA=0xFF; //установить PA как выходы     
PORTA=0x01;//Первоначально устанавливаем на всех выходах 1         
DDRD=0x00; //порт PD сконфигурировать как входы
PORTD=0x00;//Первоначально устанавливаем на всех выходах 0 
//PORTD |= (1 << PD1)|(1 << PD0); // подключаем подтягивающие резисторы        
//Инициализация внутреннего таймера и установка прерываний
timer_init();
while(1)//Бесконечный цикл
{ 
  тут будем зажигать 1 из 10-ти светодиодов по кругу, переменная j подскажет какой зажечь
}

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Пн окт 09, 2017 23:02:57
Mishany
таймер не правильно настроен
частота какая?
пробуйте так

Код: Выделить всё

TCCR0|=(1<<CS01); //запуск таймера с предделителем на 8
TIMSK |= (1<<OCIE0); // устанавливаем бит разрешения прерывания  счетчика по совпадению
OCR0 = 0b11111111; // определяем число сравнения
sei(); // enable global interrupt
код в прерывании должен выполняться быстрее чем сработает следующее прерывание

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Вт окт 10, 2017 06:12:33
alexey6522
Попробовал, уже что-то пытается обрабатывать.
кварц на 4 МГц.

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Вт окт 10, 2017 16:17:20
Mishany
понижать частоту таймера надо, делитель на 32 - будет опрос 489Гц для энкодера за глаза.
а вообще подключаем осцил, крутим энкодер, смотрим длину импульсов - подгоняе таймер на гарантированный захват импульса....

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Вт окт 10, 2017 16:55:24
Ivanoff-iv
может не совсем в тему, но енкодер удобно вешать (вместе с другими кнопками) на шину общих анодов/катодов семисегментных индикаторов (входа разделив диодами) потом собираем всё в одну кучу и получаем и энкодер и кнопки ценой одной лапки МК.

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Вт окт 10, 2017 19:41:43
alexey6522
[uquote="Mishany",url="/forum/viewtopic.php?p=3203107#p3203107"]понижать частоту таймера надо, делитель на 32 - будет опрос 489Гц для энкодера за глаза.
а вообще подключаем осцил, крутим энкодер, смотрим длину импульсов - подгоняе таймер на гарантированный захват импульса....[/uquote]

Осциллографа нет, всё на глазок и методом тыка. По поводу настройки делителя на 32, в таблице нашёл только 8, 64, 128, 256, 1024.
Как настроить асинхронный таймер/счтчик я не знаю.

Поменял значение 0xFF в строке New = PIND & 0xFF; на 0x03 и теперь хоть как-то начал обрабатывать сигналы. При вращении встречаются проскоки, на один щелчок, иногда бывает на 5 щелчков, если слишком быстро вращать, то всё зависает и перестаёт обрабатывать сигнал, а после отклика происходит сброс программы

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Ср окт 11, 2017 04:06:34
Ivanoff-iv
по идее частота опроса должна быть не меньше максимально возможной частоты переключения энкодера: вот, допустим, крутить его будешь до 5 об/с у него 20 шагов за оборот, 4 переключения за шаг, перемножаем получается 400 гц — при меньшей частоте опроса при такой скорости вращения будут пропуски. если частота опроса выше - МК просто по несколько раз промерит одно и то же состояние, это не страшно.

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Ср окт 11, 2017 06:00:11
alexey6522
Проблема в том, что кроме обработки энкодера должен ещё выполняться основной код, где имеется задержки, циклы и всё должно куда-то выводиться. Делаю развивающую игру, одну сделал, хочу ещё одну, но как-то не выходит.
По ссылке ниже, можно посмотреть предыдущий вариант игры, сама игра разделена на под игры. Имеется лабиринт, где на перекрестке мигает разными цветами светодиод, на картинке есть дорожки соответствующих цветов и в зависимости от того какой цвет зажёгся, необходимо в этот момент нажать кнопку соответствующего цвета, но если дорожка выбрана не правильна можно зайти в тупик, смысл дойти до конца. Есть ещё двоичный преобразователь, щелкая 8-ю тумблерами можно получить число, тумблер это 1 или 0. Есть ещё просто крутилка, у меня ребёнок любит на стиральной машине крутить большой круг и смотреть как лампочки по кругу бегают. Все игры пришлось разделить на части и выбирать каждую соответствующей кнопкой, одновременно не получилось сделать, так как в каждой разные задержки (паузы) для цикличного мигания и т.п. Не знаю, ясно ли объяснил.
https://youtu.be/1aMetwfHZxg

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Ср окт 11, 2017 07:32:39
Mishany
нужно менять принцип опроса, вешать на INT0...INT4 и таймер не понадобится количество ног тоже...
еще к ногам энкодера надо подключить кондеры по 0,1мкф должно улучшить их работу

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Ср окт 11, 2017 07:37:58
ARV
У DiHalt-а на сайте была статья про энкодеры с хорошим принципом опроса (автомат состояний). Немного стерлось из памяти, поэтому не ручаюсь за абсолютную точность, но по-моему этот принцип позволяет по единственному таймеру опрашивать хоть десяток энкодеров и помещать результат их опроса в переменные для дальнейшей обработки. Статья находится поиском на раз-два.

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Ср окт 11, 2017 08:30:18
trengtor
Там у дихальта небольшая ошибка есть с состояниями (что принимать, что отбрасывать). Просто для сведения.

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Ср окт 11, 2017 20:18:47
alexey6522
Можно наглядно показать как обрабатывать данные с энкодера по int0 и т.д.?
[uquote="Mishany",url="/forum/viewtopic.php?p=3203525#p3203525"]нужно менять принцип опроса, вешать на INT0...INT4[/uquote]

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Чт окт 12, 2017 03:55:34
Ivanoff-iv
самое простое: настраивай инт0 (к нему один вывод приходит) например на спад и в прерывании проверяй пин, куда второй вывод приходит — 1 - крутим вперед, 0 - назад.
но так можно качанием около одной точки его наматывать (но если енкодер явственно щелкает, то этот баг может никогда не выявиться),
правильней: инт0 на эни ченж (любое изменение), в прерывании делать исключающее или от ног энкодера и если 1 - полшага вперед, если 0 - полшага назад (или просто сравнивать их меж собой — равно-туда/неравно-сюда).
при желании можно и четверть шага ловить, но на это уже 2 прерывания понадобятся чтобы обрабатывать каждое изменение.
//странно - 2ки вместо 0ей - исправил

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Чт окт 12, 2017 06:20:13
alexey6522
Ivanoff-iv - В первом варианте вроде всё понятно, я так кнопку обычную подключал, прерывание по изменению сигнала на входе. По второму варианту сложнее понять, если можно приведите пример ?

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Чт окт 12, 2017 08:56:37
Ivanoff-iv

Код: Выделить всё

nterrupt [EXT_INT0] void ext_int0_isr(void)
{if (PIND.3==PIND.0) step++ else step--;}
при:
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
в примере D3 и D0 пины на которые подцеплены ножки энкодера (не помню на какой пин приходится инт0 у меги, у тини2313 на D3) т.е. одна из ног кроме участия в сравнении должна сменой состояния вызывать прерывание.
это в кодевижне. если так пины не адресуются можно писать и ((PIND&1<<3)^^(PIND&1<<0)) должно сработать (не проверял).

Добавлено after 22 minutes 52 seconds:
((PIND&1<<3)==(PIND&1<<0)) - точно не прокатит т.к. 1цы в разных "разрядах" появляются

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Чт окт 12, 2017 10:21:19
trengtor
alexey6522, а что – вариант с диспетчером не катит совсем?

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Чт окт 12, 2017 11:25:38
Ivanoff-iv
по поводу циклов... мне кажется частота мала и хоть [uquote="alexey6522",url="/forum/viewtopic.php?p=3202730#p3202730"]кварц на 4 МГц.[/uquote] а реальная частота может быть другая или из-за фьюзов (тактирование не с кварца) или из-за включенного какого нибудь делителя. тогда конечно будут пропуски. А остальные частотозависимые задачи правильно работают?

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Чт окт 12, 2017 19:23:15
alexey6522
[uquote="trengtor",url="/forum/viewtopic.php?p=3204421#p3204421"]alexey6522, а что – вариант с диспетчером не катит совсем?[/uquote]
Пытался прикрутить диспетчер, нашёл проект для AVR studio, для как ой версии не знаю, но он не компилируется. Я далёк ещё от всего этого. По поводу фьюзов, тактирование включено от внешнего кварца, с этим-то я уже разобрался.

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Чт окт 12, 2017 20:31:58
trengtor
Ну, не знаю тогда... Когда приперло, я под mikroPascal сам «родил» несложный диспетчер. Не рокетсайнс же.

Re: Пытаюсь настроить опрос Энкодера

Добавлено: Чт окт 12, 2017 20:33:49
alexey6522
Есть рабочий пример работы диспетчера для WinAVR?