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

Enkoder-C przerwania a sterowanie silnikiem jak zrealizować

Rysiek_XL 05 Sty 2008 15:58 1452 2
  • #1 05 Sty 2008 15:58
    Rysiek_XL
    Poziom 14  

    Witam. Mam maleńką prośbę. Czy mógłby ktoś z bardziej doświadczonych kolegów podpowiedzieć mi w następującej sprawie??
    Mianowicie zliczam impulsy (na zew. przerwaniach) z enkodera i teraz chciałbym ruszyć silnikiem o ileś impulsów i aby ten samoczynnie sie zatrzymał. Problem w tym, że kod na pewno działa poprawnie ale niestety silnik ignoruje moj warunek i "kręci sie nadal"

    Moj wykrojony kod:

    Code:


    void start(void)
    {

          //ustaw linie PD5 jako wyjście
       sbi(DDRD,PD5);
          //Preskaler F_CPU/64
       timer1SetPrescaler(3);
          //PWM 10Bit
       timer1PWMInit(10);
          // PWM kHz
       timer1PWMInitICR(287);
          // Od 0->1023 :)
       timer1PWMAOn();
          //wypełnienie 50%
       timer1PWMASet(512);
       
    }

    void stop(void)
    {
       cbi(TCCR1A,COM1A1);
        cbi(TCCR1A,COM1A0);
       outb(PORTD,0xFF);
    }


    void SetPos(void)
    {
    s32 posOld=20;

    s32 pos;
    pos=(EncoderState[0].position/1006);

       if (posOld == pos)
       {
          stop();
       }
          else
       {
          start();   

          }

    Dziekuje .

    0 2
  • #2 05 Sty 2008 16:20
    MirekCz
    Poziom 35  

    Prawdopodobnie błąd tkwi w warunku posOld==pos

    Silnik ma pewną bezwładność i w momencie jak uzyskasz odpowiednią pozycję wywołana zostanie funkcja stop, po czym silnik obróci się o kawałek obrotu, enkoder uzyska już inną pozycję (nie spełniającą warunku posOld==pos) i silnik zostanie załączony ponownie.

    Jeżeli zależy Tobie na uzyskaniu dokładnie ustalonej pozycji to musisz dodać płynne sterowanie prędkością silnika i zastosować jakiś regulator (np. typu PID), który zacznie zwalniać obroty jeszcze zanim silnik dojdzie do oczekiwanej pozycji.

    Uproszczona wersja to dodać jakąś zmienną i zrobić to na zasadzie:

    Code:

    s32 stop=0;//zmienna globalna

     if (posOld == pos)
       {
          stop=1;
       }
    if (stop==0) start();
    else stop();



    PS.Potencjalny inny problem jest taki, że zczytujesz zbyt wolno enkoder i pomiędzy odczytami pozycja przeskakuje o więcej niż 1.
    Wtedy musisz zastosować jakiś "obszar martwy" w którym silnik się wyłączy. Ten problem oczywiście nie wystąpi przy dobrze zaimplementowanej płynnej regulacji obrotów silnika.
    Przykładowy kod:

    Code:

    if (((posOld+10)>pos) && ((posOld-10)<pos)))
    {
      stop=1;
    }

    10 to przykładowa zmienna, w praktyce jest zależna od dokładności enkodera/maksymalnej prędkości silnika/częstotliwości odczytywania położenia enkodera.

    0
  • #3 07 Sty 2008 20:05
    Rysiek_XL
    Poziom 14  

    Dzięki. Probowałem tak i nadal nic. Po prostu zachowuje sie tak jakby po uruchomieniu silnika program ignorował cały warunek.
    Czy ma ktoś jakiś pomysł?

    pozdrawiam

    0
  Szukaj w 5mln produktów