Elektroda.pl
Elektroda.pl
X
SterControl
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

atmega - sterowanie pojazdem z silnikiem krokowym

baracuda2 17 Lut 2013 14:59 1509 5
  • #1 17 Lut 2013 14:59
    baracuda2
    Poziom 13  

    Witam

    Chciałbym zbudować pojazd napędzany dwoma silnikami krokowymi. Na chwilę obecną mam zbudowane podwozie z zamontowanymi silnikami. Na początek ma być sterowane podczerwienią. Dla jednego silnika działa, zwykły program zmieniający stany co 3ms dla sterowania pół-krokowego ( silnik unipolarny 6 przewodów). Problem jest z sterowaniem 2 silników, kroki są gubione, jak się domyślam trzeba zapewne użyć przerwań aby móc sterować dwoma sinikami. Proszę o jakieś przykłady, programiki w C które były by pomocne w tym projekcie.

    Układ oparty o projekt z linku:
    Link

    Początkowe funkcje jakie chciałbym uzyskać:
    jazda do przodu - dwa silniki uruchomione
    jazda do tyłu
    skręt
    zmiana prędkości - zmiana odstępu miedzy krokami

    Pozdrawiam

    programik który miałem do 1 silnika

    Code:
    #include <avr/io.h>
    
    #include <avr/interrupt.h>
    #include <util/delay.h>
     

    int speed = 3;
    volatile int cod = 0;
    typedef unsigned char  u8;
     

    //prawy przod
    void start_Pprzod (int v)
    {
       //1//
       PORTC |= 1 << PC4;
       //PORTD |= 1 << PD5;
       _delay_ms(v);
       PORTC &= ~(1 << PC3);
       //PORTD &= ~(1 << PD6);
             
       //2//
       PORTC |= 1 << PC5;
       //PORTB |= 1 << PB0;
       _delay_ms(v);
       PORTC &= ~(1 << PC4);
       //PORTD &= ~(1 << PD5);
       
       //3//
       PORTC |= 1 << PC2;
       //PORTD |= 1 << PD7;
       _delay_ms(v);
       PORTC &= ~(1 << PC5);
       //PORTB &= ~(1 << PB0);
             
       //4//
       PORTC |= 1 << PC3;
       //PORTD |= 1 << PD6;
       _delay_ms(v);
       PORTC &= ~(1 << PC2);
       //PORTD &= ~(1 << PD7);
    }

    //lewy przod
    void start_Lprzod (int v)
    {
       //1//
       PORTD |= 1 << PD5;
       _delay_ms(v);
       PORTD &= ~(1 << PD6);
             
       //2//
       PORTB |= 1 << PB0;
       _delay_ms(v);
       PORTD &= ~(1 << PD5);
       
       //3//




       PORTD |= 1 << PD7;
       _delay_ms(v);
       PORTB &= ~(1 << PB0);
             
       //4//
       PORTD |= 1 << PD6;
       _delay_ms(v);
       PORTD &= ~(1 << PD7);
    }

    void stop_prawy()
    {
       PORTC &= ~(1 << PC1);
       PORTC &= ~(1 << PC2);
       PORTC &= ~(1 << PC3);
       PORTC &= ~(1 << PC4);
    }

    void stop_lewy()
    {
       PORTB &= ~(1 << PB0);
       PORTD &= ~(1 << PD5);
       PORTD &= ~(1 << PD6);
       PORTD &= ~(1 << PD7);
    }
       
    //-----------------------------------------------------------------------------
    int main(void)
    {
       //silnik 1
       DDRC |= _BV(5);  //A+
       DDRC |= _BV(4);  //B+
       DDRC |= _BV(3);  //A-
       DDRC |= _BV(2);  //B-

       //silnik 2
       DDRB |= _BV(0);  //A+
       DDRD |= _BV(5);  //B+
       DDRD |= _BV(6);  //A-
       DDRD |= _BV(7);  //B-
       
       int v = speed;
       u8 out;
       
       DDRD  &= ~(1<<PD2);
        PORTD &= ~(1<<PD2);
        //
        MCUCR |= (1<<ISC01); // opadajace zbocze
        GICR  |= (1<<INT0);   
        //
        TCCR0 = (1<<CS02); // prescaler 256
        TIFR |= (1<<TOV0);   

        sei();
       
       
        while(1)
       {
       
          if(cod != 0)
          {
             v = speed;
          
             out = cod & (1<< 11);
             out |= cod & 0x3f;
             
             if(out == 2)
             {
                start_Pprzod(v);
             }/*
             if(out == 8)
             {
                start_Lprzod(v);
             }
    */
             if(out == 5)
             {
                stop_prawy();
                stop_prawy();
                cod = 0;
             }/*
             if(out == 9)
             {
                speed--;
                cod = 0;
             }
             if(out == 3)
             {
                speed++;
                cod = 0;
             }
             */
          }
       
       }
       return 0;
     }

    0 5
  • SterControl
  • #2 17 Lut 2013 15:18
    tmf
    Moderator Mikrokontrolery Projektowanie

    Nie wiem czy do napędu akurat silniki krokowe to najlepszy pomysł. Ale skoro tak wymyśliłeś... Nie, przerwań nie potrzebujesz, chociaż są pomocne. Pokaż jak sterujesz tym krokowcem to będzie można powiedzieć coś więcej. Na razie powiem tak - skoro do krokowca i tak potrzebujesz mostek H, to kup sobie scalony mostek H ze zintegrowanym sterownikiem. I problem z głowy.

    0
  • SterControl
  • #3 17 Lut 2013 15:19
    piotrva
    Moderator na urlopie...

    Musisz wykorzystać jeden z timerów do generowania równych odstępów czasowych. I potem w zależności od kierunku obrotu i prędkości w każdym lub co którymś przerwaniu ustawiać na danym silniku kolejny/poprzedni krok. Kroki polecam zapisać w tablicy i potem tylko wywoływać jej określony element.

    0
  • #4 27 Lut 2013 11:39
    baracuda2
    Poziom 13  

    Zastanawiam się na chwile obecną z sugestia zapisania kroków w tablicy. Czy to ma wyglądać
    tak że mamy (np. dla sterowania pełnokrokowego) tablice 8 - elementową z czterema krokami dla silnika 1 i 4 krokami dla silnika 2? Tablica z intami i zapisane w niej stany portów binarnie.

    0
  • #5 27 Lut 2013 12:09
    BlueDraco
    Specjalista - Mikrokontrolery

    Wystarczą tablice ze stanami linii portów dla poszczególnych kroków, czyli bajtowe:

    const uint8_t step[] = {0b0011, 0b0110, 0b1100, 0b1001};

    A potem dodasz atrybut PROGMEM i odwołania przez prog_read_byte().

    0
  • #6 13 Lis 2013 20:31
    baracuda2
    Poziom 13  

    Wykorzystanie timera do odliczanie czasu impulsów. Tablica z z wszystkimi krokami silnika, zmieniany indeks tablicy po przepełnieniu licznika.

    0