Общение

russian-robots@conference.jabber.ru - Чат, в котором можно поболтать об электронике, создании роботов и программировании.
Как мне зайти в чат?

 Обсуждение

Не стесняйтесь оставлять комментарии, мне интересно и важно ваше мнение!
  • Wadimka: Подскажу где взять недорого строчники, идете/едите в любую контору которая ...
  • Vladimir: Об этом датчике я тоже знаю, хотелось с чегото начать изучать МК, а не слеп ...
  • Vladimir: Спсиба
  • Евгений: Стоит поставить инфракрасный датчик движения и не городить ничего :) Литера ...
  • Vladimir: Добрый день Евгений. Это мне для дома в кладовку. При входе на двери стоит ...
  • Евгений: Фотобарьер? По подробнее расскажите.
  • Vladimir: Добрый день. Прошу вас помочь в реализации пректа фотобарер на Tiny45, со с ...
  • Евгений: С таким кодом даже http://caxapa.ru/codebook/?search=BLSH ничего не находит ...
  • Икрементальный энкодер и подсчет импульсов по прерыванию (Win AVR, atmega32)

    10th Июль 2011 | Метки: , ,

    Энкодер в этой статье – это устройство для измерения числа оборотов вала моторредуктора.

    Для чего нужно считать обороты? Применений этому несколько:

    • Для увеличения точности перемещений. Заказал сделать 3.5 оборота – энкодер отсчитал нужное колличество импульсов и микроконтроллер (как пример) выключил двигатель.
    • Стабилизация скорости вращения двигателя.
    • Определение направления вращения.

    Третий вариант нам не нужен, так как всегда известно в какую сторону вращается вал двигателя. Мы используем энкодер только для подсчета импульсов, точнее для измерения пройденного пути.

    Как устроен энкодер?

    Простейший энкодер для подсчета импульсов состоит из диска с отверстиями (1), инфракрасного светодиода (не обязательно инфракрасного) и фототранзистора (или фотодиода). Диск расположен между светодиодом и фототранзистором. При вращении излучение от светодиода проходит через отверстия в диске и попадает на фототранзистор.  В итоге сопротивления фототранзистора то стремительно возрастает, то также стремительно убывает, из-за этого на резисторе R появляются импульсы. Подсчитав их можно судить о пройденном расстоянии или частоте вращения вала двигателя.

    Подсчитывать импульсы будем при помощи микроконтроллера atmega32, по внешнему прерыванию INT0 по перепаду уровня. Тем самым количество импульсов на оборот будет = количество отверстий в диске умножить на 2.

    Программа

    Её я писал на Си в Win AVR (AVR GCC), для управления двигателем я использовал встроенный в контроллер Minibot 2.1 драйвер двигателей. Внимание! Mega32 питается от 5 вольт!

    Поскольку один канал драйвера двигателей я спалил :( , то приведу пример для одного энкодера, для второго не сложно будет доработать по аналогии.

    // http://cdxp.zx6.ru/
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #define F_CPU 7372800L
    #include <util/delay.h>
     
    #define LED_ON() PORTC|=(1<<4)
    #define LED_OFF() PORTC&=~(1<<4)
    #define M1 PINC2
    #define M2 PINC3
    #define E1 PIND4
    #define E2 PIND5
    #define MOTOR1 PORTC
    #define MOTOR2 PORTC
    #define PWM_FREQ 25000
    #define TOP F_CPU/(1*1*PWM_FREQ)
    #define MCORRECT 10
    #define WHEEL_RADIUS_CM 3
    #define PULSES_PER_TURN 48
    #define DIST(x) ((PULSES_PER_TURN/(3.14*WHEEL_RADIUS_CM))*x)
     
    unsigned int i=0;
    ISR(INT0_vect)
    {
    	//Увеличиваем счетчик срабатываний энкодера
    	i++;
    }
     
    void motors(int mo1, int mo2)
    {
    	if(mo1<0)
    	{
    		OCR1BL = (unsigned char)(-mo1);
    		MOTOR1 &= ~(1<<M1);
    	}
    	else
    	if(mo1>=0)
    	{
    		OCR1BL = (unsigned char) mo1;
    		MOTOR1 |= (1<<M1);
    	}
     
    	if(mo2<0)
    	{
    		OCR1AL = (unsigned char) (-mo2);
    		MOTOR2 &= ~(1<<M2);
    	}
    	else
    	if(mo2>=0)
    	{
    		OCR1AL = (unsigned char) mo2;
    		MOTOR2 |= (1<<M2);
    	}
    }
     
    void go(int d,int m1speed,int m2speed)
    {
    	d=DIST(d);
    	cli();
    	i=0;
        	motors(m1speed,m2speed);
    	sei();
    	while(i<d-MCORRECT);
    	motors(0,0);
    }
     
    void intettupt_init(void)
    {
    	//INT0 enabled, any change
    	MCUCR |= (1<<ISC00);
    	MCUCSR = 0x00;
    	GICR |= (1<<INT0);
    	GIFR |= (1<<INT0);
    }
     
    void ports_init(void)
    {
    	PORTB |= (1<<6);
    	DDRC |= (1<<M1)|(1<<M2)|(1<<4);
    	DDRD |= (1<<E1)|(1<<E2);
    	PORTD = 1<<3;
    }
     
    void timer1_init(void)
    {
    	TCCR1A |= (1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);
    	TCCR1B |= (1<<CS10)|(1<<WGM12)|(1<<WGM13);
    	OCR1AH=0xFF;
    	OCR1BH=0xFF;
    	ICR1 = TOP;
    	TCNT1 = 0x0000;
    }
     
    int main(void)
    {
        	intettupt_init();
        	ports_init();
        	timer1_init();
        	go(5,0,255); //Проехать 5 сантиметров
        	while(1)
        	{
            //TODO:: Please write your application code
        	}
    }

    В прерывании постоянно увеличиваем переменную i, которая является счетчиком импульсов с энкодера. Чтобы проехать определенное расстояние, надо отсчитать N импульсов. Как это сделать? Обнуляем счетчик, включаем двигатель, разрешаем прерывания и висим в цикле пока энкодер не провернется N раз. После этого выключаем двигатель. (см. функцию go() )

    Теперь разберём define’s:

    PULSES_PER_TURN – количество импульсов на один оборот диска энкодера

    MCORRECT – калибровочная константа, двигатель останавливается не мгновенно и после его выключения энкодер еще несколько раз щелкает. Если нужна точность, то стоит подобрать эту константу, если не нужна – поставить ноль.

    WHEEL_RADIUS_CM – радиус колеса на валу моторредуктора в сантиметрах.

    PWM_FREQ – частота ШИМа в герцах, при помощи которого регулируем скорость вращения двигателей.

    DIST(x) – этот макрос переводит сантиметры в количество импульсов.

    И функции:

    go(int d, int m1speed, int m2speed) - При помощи этой функции можно задать расстояние, которое нужно проехать.

    motors(int m1speed,int m2speed) -  Моя любимая реализация функции для управления драйвером 2-х двигателей, если скорость отрицательна – двигатель крутится в обратную сторону. Максимальная скорость +-255, минимальная 0.

    PS: Как отремонтирую драйвер двигателей, выложу вариант для 2-х энкодеров.

     

    Понравилась статья? Нажмите на любую из кнопок:

    0
    Пока комментариев нет.

    :D :-) :( :o 8O :? 8) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: