Страница 1 из 2
Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Ср сен 25, 2013 09:39:16
AaNnDdRrEeYy
Добрый день.
Подскажите как можно подключить 4 энкодера, но так что бы не тратить 8 ног?
Например что то вреде подключения 4 кнопок к одной ноге АЦП (знаю только эту фишку), но у энкодера надо с двух ног значения считывать а АЦП может только к одному выводу в один момент времени подключаться, выходит этот фокус тут бесполезен.
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Ср сен 25, 2013 09:47:23
s_black
А зачем четыре энкодера? Если для изменения четырёх параметров - то воспользуйтесь одним энкодером с дополнительной кнопкой, которая будет "листать" поочередно каждый из изменяемых четырёх (да хоть десяти) параметров. Понадобится всего три входа контроллера.
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Ср сен 25, 2013 09:52:05
AaNnDdRrEeYy
О, спасибо. Энкодера с кнопкой нету, но я ее отдельно привинчу. Правда не очень удобно - надо сперва по кнопке потыкать потом крутить, но ног и так уже не хватает.
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Ср сен 25, 2013 17:51:47
Eugene.Negrobov
Ну блин, энкодер сам по себе штука очень сложная в плане опроса, а ты еще и 4 штуки хочешь.
Если прямо очень-очень-очень хочется 4 энкодера и мало ножек, то можно воспользоватся любым PISO регистром с защелкой, который будет считывать состояния 8-ми ног, подключенных к энкодерам, затем пересылать полученный байт на SPI... В итоге тратится только 2 ноги, но делать это придется очень-очень быстро(т.е. высокая тактовая нужна), да и жопу порвать придется, чтобы это запрограммировать.
Лучше не морочить голову и банально поцепить 3 кнопки, одна переключает режимы, две других инкрементят или декрементят переменную. Для удобства можно добавить плавный разгон инкрементирования/декрементирования, выйдет не хуже энкодеров, а главное никакой мороки.
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Ср сен 25, 2013 18:22:23
Engineer_Keen
Eugene.Negrobov писал(а):Ну блин, энкодер сам по себе штука очень сложная в плане опроса
В каком месте она сложная? Проверка состояния одной ноги при перепаде на другой делается за одну команду, далее уже переход на обработку "+" или "-", дальше программа для энкодера не отличается от программы для 2х кнопок.
Если нужно действительно 4 ручки, можно задействовать 5 ног. На 4 ноги заводим первые каналы энкодеров, это должны быть ноги с внешними прерываниями (обычно PCINT), вторые каналы соединяем через резисторную цепочку и на АЦП, как это делают во всяких пультах дистанционного управления. Приходит прерывание PCINT - определяем какой энкодер крутили, читаем АЦП - определяем, в какую сторону.
Но я все таки сделал бы (и делаю) один энкодер с кнопкой, как сказали выше, такой штукой можно регулировать ВООБЩЕ все что угодно...
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Чт сен 26, 2013 15:26:30
vitalik_1984
Чет я не догнал каким образом можно через Ацп вообще энкодер читать.там же две "кнопки" а через Ацп как известно хорошо получается читать одновременно только одну кнопку.
Даже если придумать какую извращенную резисторную матрицу голова кругом пойдет все предусмотреть.
Как вообще будет PCINT срабатывать?
Если только делать круговой опрос Ацп с четырех каналов и оценивать четыре напряжения которые могут быть с двумя кнопками.
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Чт сен 26, 2013 15:44:50
Engineer_Keen
vitalik_1984 писал(а):Даже если придумать какую извращенную резисторную матрицу голова кругом пойдет все предусмотреть.
Да именно так, я и не говорил что это будет легко))
vitalik_1984 писал(а):
Как вообще будет PCINT срабатывать?
А куда он денется?
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Чт сен 26, 2013 17:54:04
vitalik_1984
да сам то он никуда не денется, только вот как это работать будет я себе представить не могу. получается, чтобы отследить изменение одного контакта используем прерывание, а как при этом определить в каком положении второй контакт находится? по пятой ножке? Ума не приложу как можно отследить вместе с прерыванием.
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Чт сен 26, 2013 18:25:56
Engineer_Keen
Да легко. Включить АПЦ в режиме постоянного преобразования и в его прерывании определать какая из "вторых ног" в каком состоянии, эту инфу писать в какой-нибудь регистр и в прерывании по перепаду ("первых ног энкодеров") проверять его. Да мудрено, но задача-то решаема... Ну это при условии, что энкодеры будут крутить с "человеческой" скоростью, а то АЦП перед прерыванием по перепаду будет давать неактуальную информацию.
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Чт сен 26, 2013 18:38:56
ploop
Но я все таки сделал бы (и делаю) один энкодер с кнопкой, как сказали выше, такой штукой можно регулировать ВООБЩЕ все что угодно...
Да всё можно, любой интерфейс организуется просто одной кнопкой. Даже полноценный CLI - ввод команд по кнопке, вывод светодиодом. Команды морзянкой
Но кроме того, что можно, есть то, что
удобнее. И 4 раздельных энкодера гораздо удобнее одного с кнопкой. Если позволяет корпус, детали, дизайн - я бы оставил 4 отдельных. Ну а сложности с опросом придётся решать, благо там не такие уж и сложности.
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Чт сен 26, 2013 19:14:37
vitalik_1984
Мультиплексом можно потратить 6 это понятно. Не сильно большая экономия.
Вот доперло как можно

пять ног

Вес у каждой кнопки будет разный, поэтому трудно ошибиться.
Один раз откалибровать и реф взять от того же источника, что и питание для кнопок, чтобы скачки напряжения не влияли на показания.
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Чт сен 26, 2013 19:44:28
Engineer_Keen
Ну во, именно это я и имел ввиду!
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Чт сен 26, 2013 20:33:06
AVSel
Можно еще поставить на опрос энкодеров отдельный простенький МК. И соединить через UART. Нужна всего одна нога и никакого головняка в основном МК. Хоть к компу подключай.
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Чт сен 26, 2013 20:38:39
vitalik_1984
Это некошерно контроллерами разбрасываться
Вот повесть прикольная
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Чт авг 28, 2014 19:10:49
PeterHirt
Добрый день.
Я хотел для одного устройства использовать схему энкодер - кнопка, но решил что это будет в моем случае не так удобно как два энкодера.
Подключил их (пока только на схеме) к четырем ногам ATTiny24, которые с PCINT и вроде все - доволен, можно код писать.
Но подождите, в даташите написано, что прерывания PCINT обрабатываются одним обработчиком, одним и тем же для любого прерывания с любого пина PCINT, нам что, в обработчике все ноги проверять, к которым энкодеры подключены?
В общем даташит меня смутил.
Кто знает, подскажите, пожалуйста, как лучше сделать?
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Чт авг 28, 2014 20:52:29
НАПАЛМ
offtopic:
Спойлер
Впечатлило.
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Чт авг 28, 2014 21:53:13
Engineer_Keen
PeterHirt писал(а):Но подождите, в даташите написано, что прерывания PCINT обрабатываются одним обработчиком, одним и тем же для любого прерывания с любого пина PCINT, нам что, в обработчике все ноги проверять, к которым энкодеры подключены?
Да именно так, или в одном векторе проверять все задействованные ноги или раскидать их между PCINT0, PCINT1 и INT0.
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Чт авг 28, 2014 22:52:12
PeterHirt
НАПАЛМ писал(а):в одном векторе проверять все задействованные ноги
НУ в принципе оказалось не проблема в векторе отследить с какого энкодера пришло изменение.
Код: Выделить всё
uint8_t E1_thisState= (PINA & 0x03);
uint8_t E2_thisState= ((PINA & 0x0C) >> 2);
if (E1_thisState != E1_prevState)
{
//........//
E1_prevState= E1_thisState;
}
сохраняем состояние соответствующих пар битов, сравниваем с предыдущими состояниями и, при несовпадении, работаем через код грея.
Понятия не имею как это, если не затруднит - можете подсказать (как получить направление через код Грея )?
Added:
Посмотрел хедер Encoder.h из библитек тинзи, они решили проблему просто перебором чисел из таблички через switch-case =)
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Пт авг 29, 2014 09:01:52
Engineer_Keen
Если кому надо, пример для 2х энкодеров без экономии ног (задействованы 4 ноги, из них 2 обязательно на PCINT).
Ровно сотня байт кода:
Спойлер
Код: Выделить всё
;Пример обработки нескольких энкодеров через прерывание Pin Change
;!!!антидребезг не использован в целях упрощения кода, использовать в таком виде!!!
;!!!можно только в симуляторах или со схемотехническим подавлением дребезга !!!
;это вариант средней грубости - прерывания только по 1 каналу энкодера, анализ обоих фронтов
;другие возможные варианты:
;самый грубый - анализ только одного фронта, одного канала (в 2 раза меньше тактов на оборот, простейший обработчик)
;самый точный - анализ фронтов обоих каналов (в 2 раза больше тактов, но сложнее обработчик)
;(C) Engineer_Keen
.include "tn2313def.inc"
.include "macroavr.asm"
.def STR=R1 ;для сохранения SREG в прерываниях
.def OLD=R21
.equ ENC1_A=PB0 ;канал А первого энкодера
.equ ENC1_B=PB1 ;канал В первого энкодера
.equ ENC2_A=PB2 ;тоже самое для второго
.equ ENC2_B=PB3
.equ LCW1=PB4 ;индикаторы направления
.equ LCCW1=PB5 ;вращения энкодеров
.equ LCW2=PB6
.equ LCCW2=PB7
;-----------------------------------------------------------------------------
.cseg
.org 0
RJMP RESET
.org PCIaddr
RJMP ENCODERS ;обработка вращения в прерывании по PinChange
.org INT_VECTORS_SIZE
RESET: OUTI SPL,Low(RAMEND) ;инициализация стека
OUTI PORTB,(1<<ENC1_A)|(1<<ENC1_B)|(1<<ENC2_A)|(1<<ENC2_B) ;настройка портов
OUTI DDRB,(1<<LCW1)|(1<<LCCW1)|(1<<LCW2)|(1<<LCCW2)
OUTI PCMSK,(1<<ENC1_A)|(1<<ENC2_A) ;настройка прерываний
OUTI GIMSK,(1<<PCIE)
SEI
LOOP: RJMP LOOP ;вечное безделье
;-----------------------------------------------------------------------------
ENCODERS:
IN STR,SREG ;обработка прерываний от энкодеров
PUSH R16
PUSH R17
IN R16,PINB ;читаем порт
ANDI R16,(1<<ENC1_A)|(1<<ENC2_A) ;накладываем маску
MOV R17,R16 ;чтобы читать только по 1 каналу
EOR R16,OLD ;проверяем какой из энкодеров крутили
MOV OLD,R17 ;сохраняем новое значение
;-----------------------------------------------------------------------------
SBRS R16,ENC1_A ;если крутили не первый
RJMP ENC2 ;пропускаем его проверки
SBIC PINB,ENC1_A ;проверяем первый энкодер
RJMP RISEA1
FALLA1: SBIC PINB,ENC1_B ;задний фронт, если второй канал=1
RJMP CCW1 ;то переход на метку "против часовой стрелки"
RJMP CW1 ;иначе "по часовой"
RISEA1: SBIC PINB,ENC1_B ;передний фронт, наоборот
RJMP CW1 ;если второй канал=1, то "по часовой"
;если 0, по "против часовой" (переход на следующую строку)
CCW1: ;тут действия при вращении против часовой
SBI PINB,LCCW1 ;например мигаем диодом
RJMP ENC2
CW1: ;тут при вращении по часовой
SBI PINB,LCW1 ;например мигаем другим диодом
;-----------------------------------------------------------------------------
ENC2: SBRS R16,ENC2_A ;теперь аналогичным образом проверяем
RJMP ENC3 ;второй энкодер
SBIC PINB,ENC2_A
RJMP RISEA2
FALLA2: SBIC PINB,ENC2_B
RJMP CCW2
RJMP CW2
RISEA2: SBIC PINB,ENC2_B
RJMP CW2
CCW2:
SBI PINB,LCCW2
RJMP ENC3
CW2:
SBI PINB,LCW2
;-----------------------------------------------------------------------------
ENC3: ;следующие энкодеры, если надо
POP R17
POP R16
OUT SREG,STR
RETI
Вариант с макросом:
Спойлер
Код: Выделить всё
;Пример обработки нескольких энкодеров через прерывание Pin Change
;!!!антидребезг не использован в целях упрощения кода, использовать в таком виде!!!
;!!!можно только в симуляторах или со схемотехническим подавлением дребезга !!!
;это вариант средней грубости - прерывания только по 1 каналу энкодера, анализ обоих фронтов
;другие возможные варианты:
;самый грубый - анализ только одного фронта, одного канала (в 2 раза меньше тактов на оборот, простейший обработчик)
;самый точный - анализ фронтов обоих каналов (в 2 раза больше тактов, но сложнее обработчик)
;(C) Engineer_Keen
.include "tn2313def.inc"
.include "macroavr.asm"
.def STR=R1 ;для сохранения SREG в прерываниях
.def OLD=R21
.equ ENC1_A=PB0 ;канал А первого энкодера
.equ ENC1_B=PB1 ;канал В первого энкодера
.equ ENC2_A=PB2 ;тоже самое для второго
.equ ENC2_B=PB3
.equ LCW1=PB4 ;индикаторы направления
.equ LCCW1=PB5 ;вращения энкодеров
.equ LCW2=PB6
.equ LCCW2=PB7
;-----------------------------------------------------------------------------
;макрос проверки энкодера, использование:
;DefineDirection канал_А,канал_В, метка по часовой, метка против часовой, метка для следющего энкодера
.macro DefineDirection
SBRS R16,@0 ;если крутили не его
RJMP @4 ;пропускаем его проверки
SBIC PINB,@0 ;проверяем этот энкодер
RJMP PC+4
SBIC PINB,@1 ;задний фронт, если второй канал=1
RJMP @3 ;то переход на метку "против часовой стрелки"
RJMP @2 ;иначе "по часовой"
SBIC PINB,@1 ;передний фронт, наоборот
RJMP @2 ;если второй канал=1, то "по часовой"
.endm
;-----------------------------------------------------------------------------
.cseg
.org 0
RJMP RESET
.org PCIaddr
RJMP ENCODERS ;обработка вращения в прерывании по PinChange
.org INT_VECTORS_SIZE
RESET: OUTI SPL,Low(RAMEND) ;инициализация стека
OUTI PORTB,(1<<ENC1_A)|(1<<ENC1_B)|(1<<ENC2_A)|(1<<ENC2_B) ;настройка портов
OUTI DDRB,(1<<LCW1)|(1<<LCCW1)|(1<<LCW2)|(1<<LCCW2)
OUTI PCMSK,(1<<ENC1_A)|(1<<ENC2_A) ;настройка прерываний
OUTI GIMSK,(1<<PCIE)
SEI
LOOP: RJMP LOOP ;вечное безделье
;-----------------------------------------------------------------------------
ENCODERS:
IN STR,SREG ;обработка прерываний от энкодеров
PUSH R16
PUSH R17
IN R16,PINB ;читаем порт
ANDI R16,(1<<ENC1_A)|(1<<ENC2_A) ;накладываем маску
MOV R17,R16 ;чтобы читать только по 1 каналу
EOR R16,OLD ;проверяем какой из энкодеров крутили
MOV OLD,R17 ;сохраняем новое значение
;-----------------------------------------------------------------------------
ENC1: DefineDirection ENC1_A,ENC1_B,CW1,CCW1,ENC2 ;проверка первого энкодера
CCW1: ;тут действия при вращении против часовой
SBI PINB,LCCW1 ;например мигаем диодом
RJMP ENC2
CW1: ;тут при вращении по часовой
SBI PINB,LCW1 ;например мигаем другим диодом
;-----------------------------------------------------------------------------
ENC2: DefineDirection ENC2_A,ENC2_B,CW2,CCW2,ENC3 ;второго
CCW2:
SBI PINB,LCCW2
RJMP ENC3
CW2:
SBI PINB,LCW2
;-----------------------------------------------------------------------------
ENC3: ;следующие энкодеры, если надо
POP R17
POP R16
OUT SREG,STR
RETI
Re: Как подключить 4 энкодера но не тратить 8 ног?
Добавлено: Вс авг 31, 2014 22:38:30
PeterHirt
Engineer_Keen писал(а):Ровно сотня байт кода:
Очень сложно понять как использовать этот код в своем приложении без знания асма.
На C у меня обработчик прерывания PCINT выполняется 78 циклов. Это нормально? Или не очень?