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.

[ATMEGA32][WinAVR] Impulsator/enkoder - wykorzystanie timera

Tranzystor_1992 28 Lut 2010 15:03 2925 8
  • #1 28 Lut 2010 15:03
    Tranzystor_1992
    Poziom 16  

    Witam,
    piszę program pod mikrokontroler podłączony do impulsatora. Impulsator podłączony jest do pinów PA.1 i PA.2. Nie za bardzo wiem jak działa impulsator, co prawda przeglądałem kilka stron internetowych dotyczących owego tematu, próbowałem również skopiować kilka kodów, aby sprawdzić jak będą działać. Niestety, żaden nie działał w 100%, może impulsator jest uszkodzony. Impulsator zwiera piny do masy. Piny są podciągnięte do 5V za pomocą wbudowanych w mikrokontroler rezystorów.

    Między innymi próbowałem wykorzystać kod:

    Code:

    #define encoder_a ((PINC&_BV(2))>>2)
    #define encoder_b ((PINC&_BV(1))>>1)

    volatile unsigned char enc;

    void impulsator(void)
    {
    static unsigned char poprzednia_a,poprzednia_b,poprzednia_c,poprzednia_d,tab[3],roznica;



    if((poprzednia_a!=encoder_a)||(poprzednia_b!=encoder_b))   //jezeli zmini się stan na jakimkolwiek wejsciu
    {
    poprzednia_c=encoder_a;         //przechowuja stany kanałow z czasu detekcji zmiany
    poprzednia_d=encoder_b;

    _delay_ms(1);

       if((poprzednia_a!=encoder_a)||(poprzednia_b!=encoder_b))
       {

          if((poprzednia_c==1)&&(poprzednia_a==0))   //rosnace zbocze na kanale A
          {                  //numer zbocza 1
          tab[2]=tab[1];               //przepisanie numeru wczesniejszego zbocza do tab[2]
          tab[1]=1;               //wpisanie zbocza ktore nastapilo teraz do tab[1]
          poprzednia_a=1;               //stan kanalu A do zmiennej poprzednia_a
          }


          if((poprzednia_c==0)&&(poprzednia_a==1))   //opadajace zbocze na kanale A
          {                  //numer zbocza 3
          tab[2]=tab[1];
          tab[1]=3;
          poprzednia_a=0;
          }
       

          if((poprzednia_d==1)&&(poprzednia_b==0))   //rosnace zbocze na kanale B
          {                  //numer zbocza 5
          tab[2]=tab[1];
          tab[1]=5;
          poprzednia_b=1;   
          }


          if((poprzednia_d==0)&&(poprzednia_b==1))   //opadajace zbocze na kanale B
          {                  //numer zbocza 2
          tab[2]=tab[1];
          tab[1]=2;
          poprzednia_b=0;
          }




       
          roznica=(tab[2]-tab[1]);
       
          if((roznica==252)||(roznica==1))   //jezeli 2 rosnace zbocza lub 2 malejace zbocza kierunek w prawo to zwieksz enc
          {
          enc++;
          tab[2]=150;            //wpisz do tablic wartosci które nie zrobia zadnym zboczem detekci obrotu
          tab[1]=150;         }


          if((roznica==4)||(roznica==255))   //to samo tylko kieruniek w lewo
          {
          enc--;
          tab[2]=150;
          tab[1]=150;
          }




       }


    }
    }


    Niestety kod nie działa mi w pełni...
    Co jakiś czas, nie zlicza obrotu, albo zamiast wykryć obrót w prawo wykrywa w lewo i na odwrót :cry:

    0 8
  • #2 28 Lut 2010 15:42
    Pittt
    Poziom 31  

    Link, Link

    Musisz dokładnie wiedzieć jakie sygnały wystawia twoje urządzenie aby móc je prawidłowo obsłużyć.

    0
  • #3 28 Lut 2010 16:17
    Tranzystor_1992
    Poziom 16  

    Kupiony został na allegro...
    Link.
    Jest to EC11B.

    0
  • #4 28 Lut 2010 16:45
    Pittt
    Poziom 31  

    Kierunek obrotów identyfikujesz poprzez wykrywanie dowolnego zbocza dowolnego sygnału, a gdy ono się pojawi, sprawdzasz jaki poziom reprezentuje drugi sygnał. Poziom wysoki to obroty w jedną stronę, a poziom niski, w przeciwną. Wykrywanie zbocza robisz na przerwaniu.

    0
  • #5 28 Lut 2010 18:05
    Tranzystor_1992
    Poziom 16  

    Szczerze mówiąc impulsator w dalszym ciągu nie działa jak powinien :/
    Nie mogę sobie z nim poradzić :/ Co do przerwania to nie mogę obsługiwać impulsatora w przerwaniu.

    0
  • #6 28 Lut 2010 18:33
    Pittt
    Poziom 31  

    Sprawdź najpierw czy z impulsatora otrzymujesz takie przebiegi jak trzeba. Zbocza możesz wykrywać w pętli programu, ale wtedy musisz się liczyć z tym że coś się zgubi.

    0
  • #7 28 Lut 2010 23:12
    leon1313
    Poziom 14  

    Dobrze podłączyłeś impulsator? U mnie wspólny wspólny jest na środku. Można zrobić prosto zliczanie, ale trzeba się liczyć z tym, ze musisz sprawdzać stany co ok 1ms. I jak pisał Pittt, może się coś zgubić po drodze.

    0
  • #8 01 Mar 2010 07:01
    Tranzystor_1992
    Poziom 16  

    Hmm...
    Kod, który przedstawiłem w pierwszym poście działał bez zarzutów. Jedyne co mi przeszkadzało to to, że niekiedy nie liczył jednego impulsu. Zliczał go natomiast przy następnym przekręceniu. Wtedy zwiększał wartość o 2 zamiast o jeden.
    Impulsator mam dobrze podłączony. U mnie również masa ma być podłączona na środku ;)

    0
  • #9 02 Mar 2010 02:52
    leon1313
    Poziom 14  

    Chyba dokładność wykonania enkoderów mechanicznych wpływa na to.

    0