Энкодер
|
|
nitrometall |
Дата: Вс, 29.01.2012, 13:18 | Сообщение # 1 |
Группа:
Проверенные
Ранг:
Новенький
Сообщений:
15
Замечания:
±
На сайте с 30.10.2010
Статус:
Offline
|
привет всем! кто нибудь писал программу на бейсике для энкодера? как это сделать?
|
|
|
|
ADMIN |
Дата: Вс, 29.01.2012, 14:57 | Сообщение # 2 |
Администратор
Группа:
Администраторы
Ранг:
Специалист
Сообщений:
1086
Замечания:
±
На сайте с 20.08.2007
Статус:
Offline
|
Вот что дает поиск
|
|
|
|
nitrometall |
Дата: Вс, 29.01.2012, 20:58 | Сообщение # 3 |
Группа:
Проверенные
Ранг:
Новенький
Сообщений:
15
Замечания:
±
На сайте с 30.10.2010
Статус:
Offline
|
спасибо,но ничего он не дает! это я уже просмотрел!
|
|
|
|
ADMIN |
Дата: Пн, 30.01.2012, 03:07 | Сообщение # 4 |
Администратор
Группа:
Администраторы
Ранг:
Специалист
Сообщений:
1086
Замечания:
±
На сайте с 20.08.2007
Статус:
Offline
|
Ну, во первых, можно почитать datasheet, посмотреть диаграммы, после этого попытаться написать программу
|
|
|
|
nitrometall |
Дата: Пн, 30.01.2012, 10:56 | Сообщение # 5 |
Группа:
Проверенные
Ранг:
Новенький
Сообщений:
15
Замечания:
±
На сайте с 30.10.2010
Статус:
Offline
|
Здравствуйте ADMIN! я попробовал,вроде чет получилось,но не хочу выглядеть корявым,посмотреть бы чужие примеры!
|
|
|
|
vladh |
Дата: Пн, 30.01.2012, 14:18 | Сообщение # 6 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
258
Замечания:
±
На сайте с 15.10.2007
Статус:
Offline
|
В примерах к BascomAVR есть такой пример:
Print "Encoder test" Dim B As Byte 'we have dimmed a byte because we need to maintain the state of the encoder
Portb = &B11 ' activate pull up registers
Do B = Encoder(pinb.0 , Pinb.1 , Links , Rechts , 1) ' ---------------------------------------------------^--- 1 means wait for change which blocks programflow ' --------------------------------^--------^---------- labels which are called ' ---------------^-------^---------------------------- port PINs Print B Waitms 10 Loop End
'so while you can choose PINB0 and PINB7,they must be both member of PINB 'this works on all PIN registers
Links: Print "left rotation" Return
Rechts: Print "right rotation" Return
Может он Вас подтолкнет к дальнейшим действиям.Добавлено (30.01.2012, 14:18) --------------------------------------------- Прошу меня простить, но я как-то сразу не заметил, что у Баском для этого есть оператор. А это значит что мой пример некорректен.
Сообщение отредактировал
vladh - Пн, 30.01.2012, 13:31
|
|
|
|
marss70 |
Дата: Чт, 08.08.2013, 02:04 | Сообщение # 7 |
Группа:
Проверенные
Ранг:
Новенький
Сообщений:
17
Замечания:
±
На сайте с 20.04.2013
Статус:
Offline
|
Только в железе этот метод(B = Encoder(pinb.0 , Pinb.1 , Links , Rechts , 1)) не работает. Хорошо получается только через прерывания.
|
|
|
|
terrarus |
Дата: Пт, 09.08.2013, 16:26 | Сообщение # 8 |
Группа:
Пользователи
Ранг:
Помогаю всем
Сообщений:
451
Замечания:
±
На сайте с 21.08.2008
Статус:
Offline
|
Вот Вам рабочий пример обработки сигналов оптического инкрементального энкодера типа ЛИР-158А. Программа написана на Протоне. Давно использую такую штуку на крупногабаритных станках при измерении пройденного пути суппортом станка. Делаю сейчас на основе такой проги систему для измерения движения по 4 координатам сразу. Применяю как круговые инкрементальные энкодеры так и магнитные линейки с датчиками фирмы Gemac. С магнитными линейками длиной от 0.36 м до 12 метров точность получается 10 микрон. Линейки имеют такие же сигналы на выходе как и энкодеры.С круговыми энкодерами точность можно получить и выше но вопрос в безлюфтовых шестеренках. А вот с магнитными линейками этот вопрос отпадает.
**************************************************************** '* Name : enkoderLIR-158.BAS * '* Author : [select VIEW...EDITOR OPTIONS] * '* Notice : Copyright © 2013 [select VIEW...EDITOR OPTIONS] * '* : All Rights Reserved * '* Date : 07.08.2013 * '* Version : 1.0 * '* Notes : Программа для оптического энкодера типа ЛИР-158А * '* : Канал А энкодера подключается к RB0 а канал В к RB1* '****************************************************************
Device = 16F877A ' Используемый микроконтроллер Xtal = 20
'-------------------------------Настройки подключения ЖКИ-------------------------------- Declare LCD_Type ALPHA ' Тип ЖКИ - буквенно -цифровой Declare LCD_DTPin PORTD.4 ' Порт данных ЖКИ Declare LCD_ENPin PORTD.3 ' Цепь управления E Declare LCD_RSPin PORTD.2 ' Цепь управления RS Declare LCD_Interface 4 ' Разрядность шины данных Declare LCD_CommandUs 2000 ' Задержка перед посылкой команды Declare LCD_DataUs 50 ' Задержка перед посылкой данных Declare LCD_Lines 4 ' Количество строк ЖКИ '-----------------------------------Настройка портов------------------------------------
'------------------------------------Настройка прерываний------------------------------------
Symbol INTF = INTCON.1 ' Флаг INTF сигнализирует, произошло прерывание по сигналу на выводе RB0 или нет Symbol INTE = INTCON.4 ' Управление разрешением внешнего прерывания по изменению сигнала RB0 Symbol RBPU = OPTION_REG.7 ' Управление включением подтягивающих регистров для PORTB Symbol GIE = INTCON.7 ' Управление включением/выключением глобальных прерываний Symbol INTEDG = OPTION_REG.6 ' Бит выбора фронта прерывающего сигнала Symbol TOCS = OPTION_REG.5 ' Бит выбора источника тактового сигнала TMR0 ' 0 - таймер инкрементируется от импульсов с внутренней тактовой частотой ' Она равна частоте кварцевого генератора , деленной на 4. ' 1 - таймер инкрементируется от внешних импульсов на входе RA4/TOKI Symbol TOSE = OPTION_REG.4 ' Бит выбора фронта сигнала для TMR0, когда он тактируется внешним сигналом на входе RA4 ' 0 - таймер инкрементируется по фронту сигнал ' 1 - таймер инкрементируется по спаду сигнал Symbol PSA = OPTION_REG.3 ' Бит подключения предварительного делителя ' 0 - предварительный делитель включен на входе таймера TMP0 ' 1 - предварительный делитель включен на входе сторожевого таймера Symbol TOIE = INTCON.5 ' бит разрешения прерывания по переполнению таймера TMP0 ' 0 - запретить прерывание по переполнению таймера TMP0 ' 1 - разрешить прерывание по переполнению таймера TMP0 Symbol TOIF = INTCON.2 ' Флаг прерывания по переполнению таймера TMP0 ' 0 - не было переполнения таймера TMP0 ' 1 - было переполнение таймера TMP0
'-----------------------------------Настройка портов------------------------------------
ADCON1 =%10000000 'Сделать все разряды портов А и Е аналоговыми и включить правое выравнивание результата АЦП TRISA = %11111111 'Сделать все разряды порта А входами TRISB = %11111111 'Сделать все разряды порта В входами TRISC = %00000000 'Сделать все разряды порта С выходами TRISD = %00000000 'Сделать все разряды порта D выходами TRISE = %00000111 'Сделать все разряды порта E входами PORTD = %00000000 PORTC = %00000000 '-----------------------------------Объявление переменных--------------------------------------- Dim N_X As Dword 'Переменная для хранения кол-ва импуkьсов с энкодера на оси Х Dim X_L As Float 'Переменная для хранения текущего значения координты X в милиметрах
'--------------------------------Настройка режимов работы TMR0---------------------------------------------- 'OPTION_REG.5 = 1 ' 1 - TMR0 инкрементируется от внешних импульсов на входе RA4/TOKI 'OPTION_REG.4 = 0 ' 0 - таймер инкрементируется по спаду сигнал 'OPTION_REG.3 = 1 ' 1 - предварительный делитель отключен от входа TMR0 и подключен на входе сторожевого таймера 'TMR0 = ZN ' начальное значение регистра TMR0 при перезагрузке
'--------------------------------Настройки прерываний--------------------------------------- On_Interrupt GoTo Encoder ' При возникновении перерывания по входу RB0 немедленно перейти к метке Encoder: INTCON = %10010000 ' Разрешить глабальные прерывания, прерывание по входу RB0 INTCON.5 = 1 ' Разрешить прерывание при переполнении таймера TMR0 INTEDG = 1 ' Включить режим прерываний по фронту сигнала по входу RB0 (с учетом инерсии на оптопаре может быть следует выбрать 0) OPTION_REG.5 = 1 ' 1 - TMR0 инкрементируется от внешних импульсов на входе RA4/TOKI OPTION_REG.4 = 1 ' 0 - таймер инкрементируется по спаду сигнал OPTION_REG.3 = 1 ' 1 - предварительный делитель отключен от входа TMR0 и подключен на входе сторожевого таймера '--------------------------------Конец настроек прерываний--------------------------------------- '--------------------------------Начало инициализации---------------------------------------
Init:
N_X = 0 X_L = 0
'--------------------------------Конец инициализации--------------------------------------- '--------------------------------Начало главной программы---------------------------------------
main: If PORTD.0 = 0 Then DelayMS 200: N_X = 0 X_L = N_X / 100 Print At 1, 1, "X=" Dec2 X_L, " " DelayMS 10
GoTo main '--------------------------------Конец главной программы--------------------------------
' -----------------------Начало Подпрограммы обработки прерываний от RB0 и TMR0-----------------------
Encoder: Context Save 'If TOIF = 1 Then B0 = B0 + 1: TOIF = 0 ' Сбросить флаг прерывания по переполнению TMR0 If INTF = 1 Then If PORTB.0 = 1 And PORTB.1 = 0 Then N_X = N_X + 1 ' Вращение вперед If PORTB.0 = 1 And PORTB.1 = 1 Then N_X = N_X - 1 ' Вращение назад INTF = 0 ' Сбросить флаг прерывания по изменению уровня сигнала на RB0 Else EndIf
Context Restore Enable ' Вновь разрешить обрaботку прерываний ' Уcтановит в 1 бит глобального разрешения прерываний GIE ' (то есть разрешить все немаскированные прерывания) ' и возвратить программу в то место основной программы, откуда ' был совершен переход на подпрограмму обработки прерываний Resume
'----------------------Конец Подпрограммы обработки прерываний от RB0 и TMR0------------------------------
Если у в Вас что-то не получается, подумай, не стоит ли прочитать инструкцию...!
Сообщение отредактировал
terrarus - Пт, 09.08.2013, 16:42
|
|
|
|
terrarus |
Дата: Пн, 19.08.2013, 16:41 | Сообщение # 9 |
Группа:
Пользователи
Ранг:
Помогаю всем
Сообщений:
451
Замечания:
±
На сайте с 21.08.2008
Статус:
Offline
|
Кто-нибудь подобной темой занимался? Хотелось бы пообсуждать.
Если у в Вас что-то не получается, подумай, не стоит ли прочитать инструкцию...!
|
|
|
|
AndrF |
Дата: Пт, 04.10.2013, 11:12 | Сообщение # 10 |
Группа:
Проверенные
Ранг:
Продвинутый
Сообщений:
145
Замечания:
±
На сайте с 03.02.2012
Статус:
Offline
|
Энкодер использую, но так как движение у меня возможно лишь в одну сторону, то выход энкодера тупо завел на вход таймера контролера и далее просто читаю его значение...
|
|
|
|
terrarus |
Дата: Пт, 04.10.2013, 12:56 | Сообщение # 11 |
Группа:
Пользователи
Ранг:
Помогаю всем
Сообщений:
451
Замечания:
±
На сайте с 21.08.2008
Статус:
Offline
|
В моей программе если разкомментировать строки
'OPTION_REG.5 = 1 ' 1 - TMR0 инкрементируется от внешних импульсов на входе RA4/TOKI 'OPTION_REG.4 = 0 ' 0 - таймер инкрементируется по спаду сигнал 'OPTION_REG.3 = 1 ' 1 - предварительный делитель отключен от входа TMR0 и подключен на входе сторожевого таймера 'TMR0 = ZN ' начальное значение регистра TMR0 при перезагрузке
то можно считать импульсы от энкодера который крутитсся в одну сторону. Так я считаю количество оборотов шпинделя станка.
Да, еще нужно организовать подпрограмму SchetOborot:
ZN = TMR0 ' Присвоить переменной счетчика оборотов значение TMR0
Return
а в главной программе в нужно организовать еще и переход к этой подпрограмме
GoSub SchetOborot
Если у в Вас что-то не получается, подумай, не стоит ли прочитать инструкцию...!
Сообщение отредактировал
terrarus - Сб, 05.10.2013, 14:09
|
|
|
|
fedonin |
Дата: Пт, 02.05.2014, 14:48 | Сообщение # 12 |
Группа:
Проверенные
Ранг:
Новенький
Сообщений:
13
Замечания:
±
На сайте с 08.03.2014
Статус:
Offline
|
Добрый День Всем! А я делал вот такую обработку:
N VAR WORD LCD: LCDOUT $FE,2,DEC5 N 'Выводим значение энкодера на экран MAIN: 'Начало основного рабочего цикла IF TAKTA = 1 OR TAKTB = 1 THEN GOSUB OTHER 'Занимаемся чем-то другим, 'пока нет нужного нам совпадения выходов энкодера COUNTING: 'Здесь может быть выход из цикла энкодера, если необходимо IF TAKTA = 0 AND TAKTB = 0 THEN GOSUB COUNTING 'Ждем прекращения совпадения IF TAKTA = 1 THEN N = N + 1 'При движении в одну сторону, увеличиваем счет IF TAKTB = 1 THEN N = N - 1 'При движении в другую сторону, уменьшаем счет OTHER: 'Здесь и далее занимаетмся чем-то другим, например: GOSUB LCD 'Показываем результат на экране GOTO MAIN END
Переменная N - счетчик текущего положения энкодера, ТАКТА и ТАКТВ - выходы энкодера. Главный недостаток конструкции - "что-то другое" в цикле не должно быть длиннее, чем переход энкодера из одного состояния в другое. У меня лишних пауз не было, переменная А сравнивалась с переменной В (значение, куда нужно было передвинуть механизм), и разность выдавалась в виде ШИМ на одном из портов, как значение скорости, а знак этой разности (+ или -), на другие порты, как направление вращения двигателя. PS: Прошу прощения у модераторов, что написал немного не в тему, это PICBASIC PRO, но думаю, что важнее программная конструкция, а воплощение ее на разных языках - дело техники...
Сообщение отредактировал
fedonin - Пт, 02.05.2014, 14:58
|
|
|
|
terrarus |
Дата: Пт, 02.05.2014, 17:58 | Сообщение # 13 |
Группа:
Пользователи
Ранг:
Помогаю всем
Сообщений:
451
Замечания:
±
На сайте с 21.08.2008
Статус:
Offline
|
А если, "что-то другое в цикле занимает например 0,7 секунды? Ну например вы хотите использовать датчик температуры DS18B20? Тогда не получится! А что делать? Отказаться от температурного датчика? А если нельзя отказаться? тогда нужно снижать скорость "перехода энкодера из одного состояния в другое". А если вы используете в качестве энкодера например ЛИР-158А на 1024 импульсов на 1 оборот, который контролирет скорость вращения электродвигателя с номинальной скоростью 1500 - 3000 оборотов в минуту (25 - 50 оборотов в секунду) . в такой системе на выходе энкодера импульсы с энкодера будут следовать с частотой 25 - 50 килогерц в секунду. То есть длительноть отдельного импульса будет равна 20 - 10 микросекунд. ( Тимп. = 1/f) . это именно за такое время будет происходить " переход энкодера из одного состояния в другое". Тогда тоже не получится? А если все же нужно контролиролть с такой скоростью? Выход один: считать импульсы с энкодера в прерываниях! И наплевать сколько будет длиться цикл основной программы. Да хоть челый час!
|
|
|
|
fedonin |
Дата: Пт, 02.05.2014, 20:57 | Сообщение # 14 |
Группа:
Проверенные
Ранг:
Новенький
Сообщений:
13
Замечания:
±
На сайте с 08.03.2014
Статус:
Offline
|
Да, конечно, terrarus! Мне повезло, что вращение было сравнительно медленное, 400имп/об, через редуктор примерно 1:5, максимальная частота была не больше килогерца. Процессор 16F876A с частотой 20Mhz. И это, конечно, не вся программа, там еще была переменная, взводящаяся в начале движения, запрещающая работу кнопок, в цикле оставался только опрос концевиков, даже на индикатор на время вывешивалась надпись "ОСТОРОЖНО ДВИЖЕНИЕ!". Я привел свой пример потому, что мне он кажется простым, но почему-то никто не применяет в подобном случае простой счетчик. Хотя, конечно, не все простое гениально. В этой программе вообще не было прерываний. Забавно, программисты, работающие на других языках, в других средах, считают дурным тоном использовать прерывания, а в PICBASIC-е владение прерываниями и есть искусство... PS: terrarus, я невнимательно смотрел Ваш цикл энкодера, он похож на мой, только мой без прерываний. У Вас нет зацикливания по совпадению уровней выходов энкодера, у меня без этого счет "бежал" гораздо быстрее, чем было реальное вращение (счетчик считал машинные циклы, а не импульсы энкодера).
Сообщение отредактировал
fedonin - Пт, 02.05.2014, 21:14
|
|
|
|
terrarus |
Дата: Сб, 03.05.2014, 16:36 | Сообщение # 15 |
Группа:
Пользователи
Ранг:
Помогаю всем
Сообщений:
451
Замечания:
±
На сайте с 21.08.2008
Статус:
Offline
|
"...Забавно, программисты, работающие на других языках, в других средах, считают дурным тоном использовать прерывания, "... Думаю это не так, не зря, например, в процессорах INTEL не одна сотня прерываний, и даже встроенный контроллер прерываний. Почитайте для расширения кругозора статью "Большие потоки трафика и управление прерываниями в Linux" на сайте http://habrahabr.ru/post/108240/ . Очень интересно!
|
|
|
|