Управление шаговым двигателем с помощью энкодера

Управление шаговым двигателем с помощью энкодера

Сообщение slav0n » 25 мар 2012, 13:31

Вот кино экспериментов. Мотор от каретки струйника, энкодер выдернут из мышевого колеса.



Сначала было 2 канала для 2-х моторов.
Вложения
схема1.GIF
схема2.GIF
while(1||!1);
slav0n
Site Admin
 
Сообщения: 4327
Зарегистрирован: 15 ноя 2009, 18:43
Благодарил (а): 24 раз.
Поблагодарили: 384 раз.

Сообщение Speys » 13 апр 2012, 22:04

Влад,добавил подтяжку по входам валкодера.Все детали правда в виде конденсаторов.
Вложения
шаг.rar
(9.01 Кб) Скачиваний: 108
111.jpg
Аватара пользователя
Speys
супермодератор
 
Сообщения: 704
Зарегистрирован: 18 ноя 2009, 02:31
Благодарил (а): 18 раз.
Поблагодарили: 25 раз.

Сообщение Speys » 12 май 2012, 08:08

Влад приветствую! Вот соорудил,все работает,правда только в горизонтальной плоскости-360градус.Вертикальной не делал,нет редуктора. (Оказалось, и так достаточно).Один нашел у себя,довольно мощный,с двигателя (шагового??? вообщем проводов было много) .Дюраль корпус,шестерни бронза,подшипники.Вместо родного,прикрутил принтерный двиг,и закрыл колпаком.Поэтому вроди большой с виду.Сам двиг,как у тебя. Вообщем просьба такая. Подкорректируй прошиву,чтоб драйвер двига включался, только когда крутиш. Перестал вращать энкодер,питание на двиг прекратилось. Причины две. Ток при удержании довольно большой,(удержание не нужно,через редуктор,руками не прокрутиш двиг) и нагреваясь микросхема драйвера,уходит в защиту...Перестает крутить,да и обмотка двига греется.. Можно управлять самим драйвером(вроди есть вывод на включение,или нужно управлять стабилизатором тока) чтоб при вращении,включался. Ток по любому ограничивать нужно.В паузе жрет 1.2А. Если это реализовать,то решено. И если можно,кнопку как у нас в Примусс,на включение самой камеры. Полевик добавлю, не хоца с фиксацией городить.
Вложения
vid1.jpg
Аватара пользователя
Speys
супермодератор
 
Сообщения: 704
Зарегистрирован: 18 ноя 2009, 02:31
Благодарил (а): 18 раз.
Поблагодарили: 25 раз.

Сообщение slav0n » 12 май 2012, 09:15

Speys писал(а): Подкорректируй прошиву,чтоб драйвер двига включался, только когда крутиш. Перестал вращать энкодер,питание на двиг прекратилось.
И если можно,кнопку как у нас в Примусс,на включение самой камеры. Полевик добавлю, не хоца с фиксацией городить.

Включение камеры будет от кнопки энкодера.
Второй канал и изменение скорости уберу.
while(1||!1);
slav0n
Site Admin
 
Сообщения: 4327
Зарегистрирован: 15 ноя 2009, 18:43
Благодарил (а): 24 раз.
Поблагодарили: 384 раз.

Сообщение Speys » 12 май 2012, 09:36

Насчет включения, придумал отлично! Все равно кнопка не задействована .Скорость остав большую,медленную не нужно,через редуктор. И напишиш изменения в схеме какие...
Аватара пользователя
Speys
супермодератор
 
Сообщения: 704
Зарегистрирован: 18 ноя 2009, 02:31
Благодарил (а): 18 раз.
Поблагодарили: 25 раз.

Сообщение slav0n » 12 май 2012, 11:02

в схеме менять практически ничего не надо.
Отключение мотора сделал программно.
Ключ питания камеры управляется ногой PB0
Фузы меги заводские (встроенный тактовый генератор 1 МГц).
Вложения
схема.GIF
main.rar
прошивка
(593 байт) Скачиваний: 79
while(1||!1);
slav0n
Site Admin
 
Сообщения: 4327
Зарегистрирован: 15 ноя 2009, 18:43
Благодарил (а): 24 раз.
Поблагодарили: 384 раз.

Сообщение Speys » 12 май 2012, 14:35

Ок. Проверил,все как должно, работает. Двиг запитал от 5 вольт,без ограничения по току.При вращении жрет прим 650 мА.Остановка практически 0. Осталось ключ на включение допаять и в корпусок маленький. У меня схема в доме,управление и питание подаю по витой паре (4 пары жил),БП на чердаке. Для этого и просил откл самой камеры.СПАСИБО!
Аватара пользователя
Speys
супермодератор
 
Сообщения: 704
Зарегистрирован: 18 ноя 2009, 02:31
Благодарил (а): 18 раз.
Поблагодарили: 25 раз.

Сообщение slav0n » 23 авг 2014, 17:36

по просьбам читателей выкладываю код

Код: Выделить всё

#include <avr/io.h>
#include <avr/interrupt.h>

#define u8 unsigned char
#define s8   signed char
#define u16 unsigned int


//порт и выводы к которым подключен энкодер
#define PORT_Enc    PORTC    
#define PIN_Enc    PINC
#define DDR_Enc    DDRC
#define Pin1_Enc    0
#define Pin2_Enc    1
/*
//1
#define A0 0b0001
#define B0 0b0010
#define A1 0b0100
#define B1 0b1000
*/
//2
#define A0 0b0010
#define B0 0b0001
#define A1 0b0100
#define B1 0b1000
/*
//3
#define A0 0b0100
#define B0 0b0001
#define A1 0b0010
#define B1 0b1000

//4
#define A0 0b1000
#define B0 0b0001
#define A1 0b0010
#define B1 0b0100

//5
#define A0 0b1000
#define B0 0b0010
#define A1 0b0001
#define B1 0b0100

//6
#define A0 0b1000
#define B0 0b0100
#define A1 0b0001
#define B1 0b0010

//7
#define A0 0b0100
#define B0 0b1000
#define A1 0b0001
#define B1 0b0010

//8
#define A0 0b0100
#define B0 0b1000
#define A1 0b0010
#define B1 0b0001

//9
#define A0 0b0010
#define B0 0b1000
#define A1 0b0100
#define B1 0b0001

//10
#define A0 0b0010
#define B0 0b0100
#define A1 0b1000
#define B1 0b0001

//11
#define A0 0b0001
#define B0 0b0100
#define A1 0b1000
#define B1 0b0010

//12
#define A0 0b0001
#define B0 0b0010
#define A1 0b1000
#define B1 0b0100
*/

volatile u16 timer;
volatile u16 timer1;
volatile u8 cmd =0;

#define speed 1
#define kanal 2

//const u8 WaveDriv[4] ={A0, B0, A1, B1};

const u8 FullStep[4] =
{
   A0|B0,
      B0|A1,
         A1|B1,
            B1|A0
};

const u8 HalfStep[8] =
{
   A0|B0,
      B0,
      B0|A1,
        A1,
        A1|B1,
          B1,
          B1|A0,
            A0
};


//##############
ISR(SIG_OVERFLOW0)
{   
   timer++;
   timer1++;
   
   static u8 stateEnc;
   u8 currentState = 0;
   
   if(PIN_Enc & (1<<Pin1_Enc)) currentState |=2;
   if(PIN_Enc & (1<<Pin2_Enc)) currentState |=1;

   //если состояние энкодера не изменилось выходим
   if(currentState == (stateEnc & 0b00000011)) return;
   
   timer1 = 0;

   stateEnc <<=2;
   stateEnc |= currentState;
   
   static u8 tick;
   
   if(stateEnc == 0b11100001) tick++;
   if(stateEnc == 0b11010010) tick--;
   
   PORTD = FullStep[tick % 4];
/*   
   u8 out;

   if(cmd & speed)out = HalfStep[tick % 8];
   else           out = FullStep[tick % 4];
   
   if(cmd & kanal)out <<=4;
   PORTD = out;
   
   for(u8 i=0;i<8;i++)
   {
      PORTB &=~((1<<PB0)|(1<<PB1));
      
      if(out & 1)PORTB |= (1<<PB0); //data
      
      PORTB |= (1<<PB1);            //clk
      out >>=1;      
   }
*/   
}

//##############
int __attribute__((naked)) main(void)
{
   //вкл подтягивающий резистор
   PORT_Enc = (1<<Pin1_Enc)|(1<<Pin2_Enc)|(1<<PC2);   
   DDRD = 0xff;
   DDRB = (1<<PB0);
   
   TIMSK = (1<<TOIE0);
   
   TCCR0 = 0b000001;
   sei();
   
   while(1)
   {   
      if(timer1 > 3000) PORTD = 0;
      
      static u8 flag;
      
      if((PINC & (1 << PC2))==0)  //проверяем кнопку
      {
         if(timer > 300 && flag == 0)
         {
            PORTB ^= 1;
            flag = -1;
         }
      }
      else
      {
         timer =0;
         flag = 0;
      }
      
   /*
      static u8 flags;
      
      if((PINC & (1 << PC2))==0) //проверяем кнопку
      {   
         if(timer >  200 && (flags & speed) ==0)
         {
            cmd ^= speed;
            flags |= speed;
         }
            
         if(timer > 3000 && (flags & kanal) ==0)
         {
            cmd ^= kanal;
            flags |= kanal;
         }
      }
      else
      {
         timer =0;
         flags =0;
      }
   */
      
   //   PORTB &=~((1<<PB2)|(1<<PB3));
   //   if(cmd & kanal)PORTB |= (1<<PB2);
   };
}
while(1||!1);
slav0n
Site Admin
 
Сообщения: 4327
Зарегистрирован: 15 ноя 2009, 18:43
Благодарил (а): 24 раз.
Поблагодарили: 384 раз.

Re: Управление шаговым двигателем с помощью энкодера

Сообщение intruderok » 23 авг 2014, 20:01

на ардуино бы замутить
intruderok
 
Сообщения: 1
Зарегистрирован: 20 авг 2014, 15:32
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: Управление шаговым двигателем с помощью энкодера

Сообщение slav0n » 23 авг 2014, 20:43

intruderok писал(а):на ардуино бы замутить

мути, кто мешает?
Написано на Си. Всего кода фиг-да-нифига.

Вот например если оставить чистый код управления шаговиком от энкодера на полной скорости, то там не на что смотреть.
Код: Выделить всё

#include <avr/io.h>
#include <avr/interrupt.h>

#define u8 unsigned char

//порт и выводы к которым подключен энкодер
#define PORT_Enc    PORTC    
#define PIN_Enc    PINC
#define DDR_Enc    DDRC
#define Pin1_Enc    0
#define Pin2_Enc    1
//ноги управления мотором
#define A0 0b0001
#define B0 0b0010
#define A1 0b0100
#define B1 0b1000

const u8 FullStep[4] =
{
   A0|B0,
      B0|A1,
         A1|B1,
            B1|A0
};
//прерывание где всё шаманство происходит
ISR(SIG_OVERFLOW0)
{   
   static u8 stateEnc;
   u8 currentState = 0;   
   if(PIN_Enc & (1<<Pin1_Enc)) currentState |=2;
   if(PIN_Enc & (1<<Pin2_Enc)) currentState |=1;

   //если состояние энкодера не изменилось выходим
   if(currentState == (stateEnc & 0b00000011)) return;

   stateEnc <<=2;
   stateEnc |= currentState;
   
   static u8 tick;
   if(stateEnc == 0b11100001) tick++;
   if(stateEnc == 0b11010010) tick--;
   
   PORTD = FullStep[tick % 4];
}

int __attribute__((naked)) main(void)
{
   //вкл подтягивающий резистор
   PORT_Enc = (1<<Pin1_Enc)|(1<<Pin2_Enc);
   DDRD = 0xff;
   TIMSK = (1<<TOIE0);
   TCCR0 = 0b000001;
   sei();   
   while(1 || !1);
}
while(1||!1);
slav0n
Site Admin
 
Сообщения: 4327
Зарегистрирован: 15 ноя 2009, 18:43
Благодарил (а): 24 раз.
Поблагодарили: 384 раз.


Вернуться в Самодельные электронные устройства

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1