dimir 2 6 апреля, 2023 Опубликовано 6 апреля, 2023 · Жалоба В 05.04.2023 в 23:11, xvr сказал: Если у вас с энкодера приходят чистые сигналы (без дребезга), и если энкодер с стопом (т.е. у него есть устойчивые положения) и если на 1 шаг энкодера он проходит все 4 состояния, то подсчёт можно сильно упростить. На фронт (или спад - по вкусу) сигнала на одной фазе проверяем сигнал на другой. Если там 1 - инкрементриуем счётчик, иначе декрементируем (или наоборот - по вкусу). Несмотря на много 'если' вверху многие энкодеры как раз такие (за исключением 'чистых сигналов' - но дребезг можно подавить отдельно) Вот то этот вариант мне более понятен и прозрачен.Если крутишь в одну сторону то проверяешь спад или по переднему фронту проверяем сигнал на другом выводе.А так как у нас 4 состояния энкодера то на 1 шаг берётся 4 . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mitya1698 18 6 апреля, 2023 Опубликовано 6 апреля, 2023 · Жалоба В 05.04.2023 в 23:11, xvr сказал: , то подсчёт можно сильно упростить Три строки кода настолько сложны, что можно сильно упростить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xemul 0 6 апреля, 2023 Опубликовано 6 апреля, 2023 · Жалоба 8 hours ago, mitya1698 said: Три строки кода настолько сложны, что можно сильно упростить? switch() весьма неудобен в реализации и весьма компиляторозависим (особенно, в плане оптимизации). То же, что Вы написали, но чуть другими словами: tmp = (EncState ^ EncInput) & 0b11; if(tmp == 0b11) Error++; else if(tmp == 0b01)) StepD++; else if(tmp == 0b10)) StepD--; EncState = tmp; UPD прошу пардонов, писал по склерозу const uint16_t StepDir 0x1442; tmp = (EncState ^ EncInput) & 0b11; if((tmp == 0b01) || (tmp == 0b10)) { if(StepDir & (1<<(tmp | (EncState << 2)))) StepD++; else StepD--; } EncState ^= tmp; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 6 апреля, 2023 Опубликовано 6 апреля, 2023 · Жалоба 5 hours ago, mitya1698 said: Три строки кода настолько сложны, что можно сильно упростить? С пяти строк до двух- в 2.5 раза 🙂 if ((EncInput & ~EncState) & 1) Steps += (EncInput & 2) ? 1 : -1; EncState = EncInput; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xemul 0 6 апреля, 2023 Опубликовано 6 апреля, 2023 · Жалоба 2 minutes ago, xvr said: С пяти строк до двух- в 2.5 раза 🙂 if ((EncInput & ~EncState) & 1) Steps += (EncInput & 2) ? 1 : -1; EncState = EncInput; Если EncInput - какой-нить volatile прямо из порта, то ... И с ридабилитью сложно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mitya1698 18 6 апреля, 2023 Опубликовано 6 апреля, 2023 · Жалоба В 06.04.2023 в 12:30, xemul сказал: писал по склерозу Глючит на увеличении, два шага вперед, один назад. На уменьшении нормально Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xemul 0 6 апреля, 2023 Опубликовано 6 апреля, 2023 · Жалоба 33 minutes ago, mitya1698 said: Глючит на увеличении, два шага вперед, один назад. На уменьшении нормально Дык у меня кроме склероза ещё и способности к устному счёту пониженные. const uint16_t StepDir 0x2442; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nibelung 9 6 апреля, 2023 Опубликовано 6 апреля, 2023 · Жалоба Есть совсем простой код для обработки енкодера, и что интересно, он не чувствителен к дребезгу. unsigned encoder_pool (conts uint8_t faza) { static unsigned counter; static uint8_t sequence; if (0 != ((sequence ^ faza) & 3)) { sequence = 0x3F & ((sequence << 2) + (faza & 3)); if (0x12 == sequence) ++counter; if (0x21 == sequence) --counter; } return counter; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mitya1698 18 6 апреля, 2023 Опубликовано 6 апреля, 2023 · Жалоба В 06.04.2023 в 18:41, xemul сказал: способности к устному счёту пониженные. Да, так работает и меньше моего с кэйсами. В 06.04.2023 в 19:05, nibelung сказал: Есть совсем простой код для обработки енкодера, Ну так это тоже самое, только точность в 4 раза хуже. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xemul 0 6 апреля, 2023 Опубликовано 6 апреля, 2023 · Жалоба 2 hours ago, mitya1698 said: Да, так работает и меньше моего с кэйсами. if((tmp ^ (tmp>>1)) & 1) { if((StepDir >> (tmp | (EncState << 2))) & 1) должно быть ещё короче. Не могу найти старый проект. 4 энкодера (без счётчиков) вписались с антидребезгом в 4 байта ОЗУ. В #define's были EncXChY и таблица истинности для состояний энкодера. Остальные magic numbers считались препроцессором. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nibelung 9 7 апреля, 2023 Опубликовано 7 апреля, 2023 · Жалоба В 06.04.2023 в 19:54, mitya1698 сказал: только точность в 4 раза хуже. Не точность, а разрешение в 4 раза ниже, и за счет этого снижения алгоритм получается не чувствительным к дребезгу. Если нужно высокое разрешение, вот еще примерчик. Считает по каждому фронту на каждой фазе. И на вход можно подать сигналы сразу нескольких энкодеров. Спойлер unsigned encoder_poll (const uint8_t faza) { static unsigned counter; static uint8_t prior; uint8_t togle, dir; togle = prior ^ faza; dir = togle ^ (faza / 2) ^ faza; togle ^= togle / 2; prior = faza; if (1 & togle) (1 & dir) ? ++counter : --counter; //if ((1<<2) & togle) ((1<<2) & dir) ? ++counter2 : --counter2; //if ((1<<4) & togle) ((1<<4) & dir) ? ++counter3 : --counter3; //if ((1<<6) & togle) ((1<<6) & dir) ? ++counter4 : --counter4; return counter; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mitya1698 18 7 апреля, 2023 Опубликовано 7 апреля, 2023 · Жалоба В данном случае это одно и тоже. Сохраню в копилку, вдруг где несколько опросных энкодеров понадобятся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться