logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Problem z wysterowaniem impulsatora

Przemo_2014 06 Cze 2010 14:33 1715 12
REKLAMA
  • #1 8161230
    Przemo_2014
    Poziom 19  
    Witam,

    Na wyjściu impulsatora występują dwa przebiegi prostokątne przesunięte w fazie o 90 stopni. Program który napisałem działa na na zasadzie że kiedy na jednym przebiegu występuje zmiana stanu z L na H sprawdzam jaki jest stan na drugim wyjściu i na podstawie tego rozpoznaje kierunek obrotu. Niby wszystko powinno działać odpowiednio ale w nie których momentach wartość liczbowa zamiast się zmniejszać wzrasta. Co jest przeciwne z logiką napisanego programu. Czy miał ktoś podobny problem ?

    Pozdrawiam
  • REKLAMA
  • #2 8161277
    tmf
    VIP Zasłużony dla elektroda
    Jest to perfekcyjnie zgodne z logika :) Kluczem jest hasło - kod Graya. Impulsator właśnie taki daje. Zobacz co się stanie jeśli zgubisz jeden impuls...
    Kolejny problem - jeśli to impulsator mechaniczny, a nie optyczny, to możesz mieć problem z drganiem styków, trzeba to wyeliminować, bo będą cuda się działy.
  • REKLAMA
  • #3 8161329
    utak3r
    Poziom 25  
    Zobacz, to jest sprawdzony kod, co prawda dla PICa, ale sobie spokojnie przerobisz. Kluczem do sukcesu jest fakt, że impulsator zwraca... 3 stany, nie dwa:

    
    enum e_encoder { WAITING, LEFT, RIGHT };
    typedef enum e_encoder rotate;
    rotate stan_enkodera;
    
    rotate checkEncoder()
    {
      static rotate stan = WAITING;
      static unsigned char waitcount = 0;
    
      if (PORTA.B2 == 1)
        {
        if (PORTA.B3 == 1)
        {
          if ( stan != RIGHT )         // debouncing
          waitcount++;
          stan = RIGHT;
        }
        else {
          if (stan != LEFT)                // debouncing
          waitcount++;
          stan = LEFT;
        }
      }
      else
      {
        stan = WAITING;
        waitcount = 0;
      }
    
      if (waitcount > 1) // kierunek zwracamy tylko po przejściu stanu oczekiwania
      {
        waitcount = 0;
        return stan;
      }
      else
        return WAITING;
    }
    
    .........................
            stan_enkodera = checkEncoder();
            if (stan_enkodera == RIGHT)
    ........................
    
  • #4 8161343
    Przemo_2014
    Poziom 19  
    Jest to impulsator mechaniczny. Jeśli chodzi o stany to są wystawiane w kolejności (00)(10)(11)(01) wszystko to rozumiem tylko tak jak właśnie napisałeś impulsator ten gubi w pewnych chwilach jeden z impulsów co skutkuje złą zmianą wartości. Przejżałem rozwiązania jakie są na elektrodzie ale żadne z nich nie dawało poprawnej obsługi impulsatora. Próbowałem też wyeliminować momenty w których są gubione kroki ale w tedy impulsator nie działa płynnie. Wie ktoś może jak uzyskać poprawną prace impulsatora ?
  • #5 8161381
    utak3r
    Poziom 25  
    Przemo_2014 napisał:
    Wie ktoś może


    Rozumiem, że już wypróbowałeś mój kod, prawda?.... :|
  • #6 8161394
    asembler
    Poziom 32  
    Obsługa w przerwaniu załatwia sprawę raz na jutro jeżeli chodzi o gubienie impulsów.
    Buforowanie załatwia sprawe płynnosci.
  • REKLAMA
  • #7 8161416
    utak3r
    Poziom 25  
    Też nie przesadzajmy... ile ten impulsator daje impulsów na obrót? 12? Więcej?... Odstęp między impulsami jest ogromny. Co oczywiście nie zmienia faktu, że tak się powinno robić, jednak zwracam uwagę na fakt, że problem jest w kodzie, nie gubieniu. Błędna obsługa impulsatora prowadzi właśnie do efektu "to w lewo, to w prawo".
  • #8 8161447
    asembler
    Poziom 32  
    utak3r napisał:
    Też nie przesadzajmy... ile ten impulsator daje impulsów na obrót? 12? Więcej?... Odstęp między impulsami jest ogromny. Co oczywiście nie zmienia faktu, że tak się powinno robić, jednak zwracam uwagę na fakt, że problem jest w kodzie, nie gubieniu. Błędna obsługa impulsatora prowadzi właśnie do efektu "to w lewo, to w prawo".


    W sumie racja jezeli napiszemy program głowny którego petla bedzie sie wykonywac powiedzmy 30 razy na sekunde to bez przerwan tez sie da zrobic.
  • #9 8161840
    Przemo_2014
    Poziom 19  
    utak3r (skąd taka nazwa?) przetestowałem twój kod ale nie usunął on wyżej przeze mnie opisanych skutków złego działania impulsatora. Jakich ty używasz impulsatorów ? Podejrzewam więc że pozostaje użycie jeszcze zewnętrznych kondensatorów które usuną zakłócenia powstające na stykach impulsatora. Czy związku z tym wystarczą do tego zwykle kondensatory ceramiczne podpięte pomiędzy nóżki impulsatora czy raczej stosuje się inne rozwiązania ?
  • REKLAMA
  • #11 8162442
    m.bartczak
    Poziom 16  
    Hej

    Używam dokładnie takich samych impulsatorów.

    Ten kod działa u mnie na przerwaniach:

    
    #define ENCODER_PIN0_DIR	DDRB
    #define ENCODER_PIN0_PORT	PORTB
    #define ENCODER_PIN0		(1<<PB0)
    #define ENCODER_PIN0_READ   PINB
    
    #define ENCODER_PIN1_DIR	DDRB
    #define ENCODER_PIN1_PORT	PORTB
    #define ENCODER_PIN1		(1<<PB1)
    #define ENCODER_PIN1_READ   PINB
    
    
    /**
     * 0 2 3 1
     */
    struct Encoder {
    	u08 last; // Last read of encoder
    	u08 current; // Current state of encoder
    	int value;
    };
    
    volatile struct Encoder encoder;
    
    void encoderCheck(void)
    {
    	u08 v = 0;
    	if(ENCODER_PIN0_READ & ENCODER_PIN0)
    	{
    		v = v + 1;
    	}
    	if(ENCODER_PIN1_READ & ENCODER_PIN1)
    	{
    		v = v + 2;
    	}
    	encoder.current = v;
    	switch(encoder.last)
    	{
    		case 0:
    		{
    			if(v==1)
    			{
    				encoder.value--;
    			}
    			if(v==2)
    			{
    				encoder.value++;
    			}
    		}
    		break;
    		case 1:
    		{
    			if(v==3)
    			{
    				encoder.value--;
    			}
    			if(v==0)
    			{
    				encoder.value++;
    			}
    		}
    		case 2:
    		{
    			if(v==0)
    			{
    				encoder.value--;
    			}
    			if(v==3)
    			{
    				encoder.value++;
    			}
    		}
    		break;
    		case 3:
    		{
    			if(v==2)
    			{
    				encoder.value--;
    			}
    			if(v==1)
    			{
    				encoder.value++;
    			}
    		}
    		break;
    	}
    	encoder.last = encoder.current;
    }
    


    Pamiętaj o debouncerze!!! Można użyć bramki shmitta, np 74HC7541
  • #12 8226340
    asembler
    Poziom 32  
    Problem moze byc w samym impulsatorze. Moze zrobisz wstawke w ASM? podporgram zajmuje chyba 20 bajtów.

    Proszę poprawić pisownię.
    Robak
REKLAMA