Регистрация | Вход

[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 3
  • 1
  • 2
  • 3
  • »
Модератор форума: demanik, ivan_fd  
Энкодер
nitrometall Дата: Вс, 29.01.2012, 13:18  |                                                                                                                Сообщение # 1
Группа: Проверенные
Ранг:  Новенький
Сообщений: 15
Репутация: 0   ±
Замечания:   ±
На сайте с 30.10.2010

Статус: Offline

привет всем! кто нибудь писал программу на бейсике для энкодера? как это сделать?
ЯНДЕКС Дата: 29.01.2012
ADMIN Дата: Вс, 29.01.2012, 14:57  |                                                                                                                Сообщение # 2
Администратор
Группа: Администраторы
Ранг:  Специалист
Сообщений: 1086
Репутация: 32   ±
Замечания:   ±
На сайте с 20.08.2007

Статус: Offline

Вот что дает поиск
nitrometall Дата: Вс, 29.01.2012, 20:58  |                                                                                                                Сообщение # 3
Группа: Проверенные
Ранг:  Новенький
Сообщений: 15
Репутация: 0   ±
Замечания:   ±
На сайте с 30.10.2010

Статус: Offline

спасибо,но ничего он не дает! это я уже просмотрел!
ADMIN Дата: Пн, 30.01.2012, 03:07  |                                                                                                                Сообщение # 4
Администратор
Группа: Администраторы
Ранг:  Специалист
Сообщений: 1086
Репутация: 32   ±
Замечания:   ±
На сайте с 20.08.2007

Статус: Offline

Ну, во первых, можно почитать datasheet, посмотреть диаграммы, после этого попытаться написать программу
nitrometall Дата: Пн, 30.01.2012, 10:56  |                                                                                                                Сообщение # 5
Группа: Проверенные
Ранг:  Новенький
Сообщений: 15
Репутация: 0   ±
Замечания:   ±
На сайте с 30.10.2010

Статус: Offline

Здравствуйте ADMIN! я попробовал,вроде чет получилось,но не хочу выглядеть корявым,посмотреть бы чужие примеры!
vladh Дата: Пн, 30.01.2012, 14:18  |                                                                                                                Сообщение # 6
Группа: Проверенные
Ранг:  Помогаю всем
Сообщений: 258
Репутация: 11   ±
Замечания:   ±
На сайте с 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
Репутация: 0   ±
Замечания:   ±
На сайте с 20.04.2013

Статус: Offline

Только в железе этот метод(B = Encoder(pinb.0 , Pinb.1 , Links , Rechts , 1)) не работает. Хорошо получается только через прерывания.
terrarus Дата: Пт, 09.08.2013, 16:26  |                                                                                                                Сообщение # 8
Группа: Пользователи
Ранг:  Помогаю всем
Сообщений: 451
Репутация: 17   ±
Замечания:   ±
На сайте с 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
Репутация: 17   ±
Замечания:   ±
На сайте с 21.08.2008

Статус: Offline

Кто-нибудь подобной темой занимался?
Хотелось бы пообсуждать.


Если у в Вас что-то не получается, подумай, не стоит ли прочитать инструкцию...!
AndrF Дата: Пт, 04.10.2013, 11:12  |                                                                                                                Сообщение # 10
Группа: Проверенные
Ранг:  Продвинутый
Сообщений: 145
Репутация: 3   ±
Замечания:   ±
На сайте с 03.02.2012

Статус: Offline

Энкодер использую, но так как движение у меня возможно лишь в одну сторону, то выход энкодера тупо завел на вход таймера контролера и далее просто читаю его значение...
terrarus Дата: Пт, 04.10.2013, 12:56  |                                                                                                                Сообщение # 11
Группа: Пользователи
Ранг:  Помогаю всем
Сообщений: 451
Репутация: 17   ±
Замечания:   ±
На сайте с 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
ЯНДЕКС Дата: 04.10.2013
fedonin Дата: Пт, 02.05.2014, 14:48  |                                                                                                                Сообщение # 12
Группа: Проверенные
Ранг:  Новенький
Сообщений: 13
Репутация: 0   ±
Замечания:   ±
На сайте с 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
Репутация: 17   ±
Замечания:   ±
На сайте с 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
Репутация: 0   ±
Замечания:   ±
На сайте с 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
Репутация: 17   ±
Замечания:   ±
На сайте с 21.08.2008

Статус: Offline

"...Забавно, программисты, работающие на других языках, в других средах, считают дурным тоном использовать прерывания, "...
Думаю это не так, не зря, например, в процессорах INTEL не одна сотня прерываний, и даже встроенный контроллер прерываний.
Почитайте для расширения кругозора статью "Большие потоки трафика и управление прерываниями в Linux" на сайте  http://habrahabr.ru/post/108240/     . Очень интересно!
  • Страница 1 из 3
  • 1
  • 2
  • 3
  • »
Поиск: