Forum elektroda.pl

Regulamin  | Punkty  | Dodaj...  | Ostatnie  | Szukaj  | Rejestracja  | Zaloguj

Ta strona używa cookie. Dowiedz się więcej o celu ich używania i zmianie ustawień cookie w przeglądarce.
Korzystając ze strony wyrażasz zgodę na używanie cookie, zgodnie z aktualnymi ustawieniami przeglądarki.

AVR + enkoder obrotowy. Program w C


Napisz nowy temat  Odpowiedz do tematu      Strona Główna -> Forum elektroda.pl -> Mikrokontrolery Ogólne -> Mikrokontrolery AVR -> AVR + enkoder obrotowy. Program w C
Autor
Wiadomość
elektroziom
Poziom 16
Poziom 16


Dołączył: 07 Mar 2006
Posty: 316
Miasto: Tarnów/Kraków

Post#1 Post autora tematu 28 Paź 2010 21:34   

AVR + enkoder obrotowy


Witam serdecznie :)

Mam za zadanie obsłużyć enkoder obrotowy i już drugi dzień nie mogę sobie z nim poradzić :/

enkoder taki jak w projekcie elektrodowicza mirley:

http://www.elektroda.pl/rtvforum/viewtopic.php?t=1369283&highlight=enkoder+audio&sid=257b88886d9ea0d1f8c64228853b95a1

Miałby ktoś może z was gotowy programik do takiego enkodera i mógł go mi udostępnić? :/

założenia:

-program napisany w C/C++
- obrót w prawo inkrementuje zmienną, obrót w lewo dekrementuje tą samą zmienną..
- enkoder podłączony do dwóch pinów portu (zwiera do masy).
-procesor ATmega 32 + kwarc 16MHz

bardzo prosze o waszą pomoc.. pozdrawiam :)
Powrót do góry
   
Google


Google Adsense


Post# 28 Paź 2010 21:34   





Powrót do góry
   
hotdog
Poziom 20
Poziom 20


Dołączył: 19 Mar 2005
Posty: 1067
Miasto: Zielna Góra (okolice)

Post#2 28 Paź 2010 22:08   

Re: AVR + enkoder obrotowy


A w czym masz problem? Rozumiesz jak on działa?

Pozdrawiam
Powrót do góry
   
tmf
Moderator
Moderator


Dołączył: 12 Sie 2009
Posty: 7542
Miasto: Katowice

Post#3 28 Paź 2010 22:32   

Re: AVR + enkoder obrotowy


Kod:

 unsigned char i=0;
    
    if((PINC & _BV(PC0))==0) i++;
    if((PINE & _BV(PE7))==0) i^=3; // convert gray to binary
    
    unsigned char enc_last=EncoderState & 3;
   i-=enc_last;
    enc_last+=i;
        EncoderState&=0xFC;
    EncoderState|=enc_last;
    
    if(i & 1)
    { // bit 0 = value (1)
    if(i & 2) NoOfPulses--; // bit 1 = direction (+/-)
    else NoOfPulses++;
    }


Debouncing to już sobie sam dodaj :)
Powrót do góry
   
elektroziom
Poziom 16
Poziom 16


Dołączył: 07 Mar 2006
Posty: 316
Miasto: Tarnów/Kraków

Post#4 Post autora tematu 30 Paź 2010 15:31   

Re: AVR + enkoder obrotowy


Mógłby mi ktoś wytłumaczyć działanie kodu w poście elektrodowicza tmf ? ;/ pisałem do niego na priv ale niestety nie odpowiada :/ pierwsze 3 linijki to sprawa oczywista ale reszta niestety dla mnie nie ;/

Sprawdziłem dokładnie działanie mojego enkodera:
Generuje on przebieg w kodzie Graya, ale stany spoczynkowe to na zmianę 11 (3) i 00 (0), a w momencie przejścia generuje na zmianę 10 (2) i 01 (1).

Obsłużyłem go za pomocą dwóch przerwań od INT0 (PIND.2) i INT1 (PIND.3):

Kod:

volatile int licznik = 0;

int main(void)
{
    //inicjalizacje

}

SIGNAL (INT0_vect) //obsługa przerwania INT0
{
   if((!(PIND & 1<<2)) != (!(PIND & 1<<3)))
   ++licznik;
   else
   --licznik;
}

SIGNAL (INT1_vect) //obsługa przerwania INT1
{
   if((!(PIND & 1<<2)) != (!(PIND & 1<<3)))
   --licznik;
   else
   ++licznik;
}


INT0 reaguje na zbocze opadające a INT1 na zbocze narastające. Wszystko śmiga łądnie tylko niestety zajmuje aż dwa przerwania zewnętrzne :( chciałbym to samo zrobić na zwykłych pinach portu bo w sumie potrzebuje podłączyć 3 takie enkodery :(

Może programowo sprawdzać czy nastąpiło zbocze opadające i narastajśce na odpowiednich pinach tak jak robiłem to przerwaniami i w obsłudze sprawdzać czy te dwa piny od encodera są różne od siebie żeby ominąc stany spoczynkowe 11 i 00 ? :/

Próbowałem już zrobić programowo reakcje na zbocza ale bez skutecznie :(

Na koniec zamieszczam schemat ideowy podłączenia enkodera do ATmega32:

AVR + enkoder obrotowy. Program w C
Powrót do góry
   
tmf
Moderator
Moderator


Dołączył: 12 Sie 2009
Posty: 7542
Miasto: Katowice

Post#5 30 Paź 2010 15:55   

Re: AVR + enkoder obrotowy


Generalnie nie odpowiadam na PW, chyba, że z jakiegoś powodu mnie zainteresują :)
Co do enkodera - mylisz się, generuje on kod Graya, zmiana następuje przy każdym przejściu. Stany 00, 01,11,10 są stabilne, nie ma czegoś takiego jak stany przejściowe. Mój kod po prostu konwertuje kod Graya na kod binarny, z zachowaniem informacji o kierunku. Zmienna NoOfPulses jest inkrementowana/dekrementowana w zależności od kierunku obrotu.
Co do twojej obsługi - można to zrobić bez przerwań (tak jak w moim kodzie), ale trzeba zastosować wtedy pooling, czyli najlepiej w przerwaniu sprawdzać stan enkodera. W dodatku trzeba to robić na tyle często, żeby wyłapywać każdy obrót, inaczej przy szybkim przekręcaniu enkodera robi się problem z odczytem kierunku. Tobie to nie zadziałało, bo żeby określić kierunek obrotu oprócz bieżącego staniu potrzebny jest poprzedni - właśnie po to, żeby wiedzieć jaka zmiana zaszła.
Powrót do góry
   
elektroziom
Poziom 16
Poziom 16


Dołączył: 07 Mar 2006
Posty: 316
Miasto: Tarnów/Kraków

Post#6 Post autora tematu 31 Paź 2010 11:49   

Re: AVR + enkoder obrotowy


Może opiszesz dokładniej poszczególne linie kodu? :)

dodam komentarze do Twojego kodu co rozumie a czego nie rozumie :)

Kod:

unsigned char enc_last=EncoderState & 3;


tutaj maskujesz 2 najmłodsze bity prawda? zmienną EncoderState deklarowałeś jako zmienna globalna unsigned char? czy poprostu lokalną wewnątrz ciała jakiejś petli?

Kod:

 i-=enc_last;
    enc_last+=i;


tutaj najpierw odejmujesz wartość zmiennej i od zmiennej enc_last a potem dodajesz dlaczego?

Kod:

  EncoderState&=0xFC;
    EncoderState|=enc_last;


tutaj maskujesz 3ci najmłodszy bit i sumujesz zawartośc stanów poprzedniego i następnego? do czego to służy ? sory za takie pytania ale chciałbym "poczuć" ten kod a nie lubie jak coś robie a tego nie rozumie :P
Powrót do góry
   
asembler
Poziom 22
Poziom 22


Dołączył: 16 Wrz 2007
Posty: 2122

Post#7 31 Paź 2010 14:00   

Re: AVR + enkoder obrotowy


Są dwa typy taki enkoderów z tego co sie praktycznie dowiedziałem.
Pierwszy nazywany przeze mnie normalnie zwartym a drugi normalnie rozwartym.
Różnią się one wewnętrzną budową a dokładnie szerokością zastosowanych styków. O ile program nie zostanie napisany na oba typy uwzględniając ich budowę można napisać program który bedzie działał tylko z jednym z nich.
Powrót do góry
   
manekinen
Poziom 22
Poziom 22


Dołączył: 12 Kwi 2006
Posty: 1646
Miasto: Kętrzyn

Post#8 31 Paź 2010 17:20   

Re: AVR + enkoder obrotowy


elektroziom - przede wszystkim poszukaj pdf-a do swojego enkodera i upewnij się jak działa - zaoszczędzi Ci to wiele problemów. To wspólne wyprowadzenie nie koniecznie musi być po środku, a wtedy całość będzie działała - lecz niepoprawnie a Ty będziesz szukał błędu w kodzie.

Co do samej obsługi, ja to robię tak: Jedno wyprowadzenie na przerwaniu zewnętrznym a drugie na zwykłym pinie. Obydwa podciągnięte wewnętrznie - nie trzeba żadnych dodatkowych rezystorów. Dodatkowo do masy kondensatory 10nF - drgania styków mogą wszystko zepsuć. Obojętnie w którą stronę pokręcę, wyzwolone zostaje przerwanie a w jego obsłudze czekam jakieś 10us i sprawdzam co się dzieje na drugim pinie... jeśli jest stan niski to znaczy że pokręcono np. w lewo, jeśli wysoki to np. w prawo. Jego stan można sobie przepisać do flagi i już później w wolnej chwili zwiększać/zmniejszać licznik.

asembler - a bawiłeś się enkoderem z myszy pc? Tam co krok masz raz zwarty a raz rozwarty, i za każdym razem trzeba przekonfigurować jakim zboczem będzie wyzwalane następne przerwanie. Dodam że taki enkoder wspólne wyprowadzenie ma właśnie po boku :)
Powrót do góry
   
asembler
Poziom 22
Poziom 22


Dołączył: 16 Wrz 2007
Posty: 2122

Post#9 31 Paź 2010 19:04   

Re: AVR + enkoder obrotowy


Prosty programik na enkoder to 22 bajty kodu lecz trzeba wiedzieć z jakim sprzętem mamy do czynienia. Sprawa się komplikuje gdy chcemy zastosowac dowolny enkoder pod ten sam program wtedy program ma ponad 400 bajtów ale dodatkow enkoder moze być 'nieprawny' czyli troszkę brudny.
Taka uwaga do autora tematu: Przed przystąpieniem dopisania softu dobrze jest taki enkoder rozebrac i przciści bo podejrzewam ze to sprzet z trzeciej ręki.
Nie bawiłem sie myszkami ale z tegoco piszesz to taki enkoder podpada pod normalnie rozwarty wg. mojego nazewnictwa.
Powrót do góry
   
Google


Google Adsense


Post# 31 Paź 2010 19:04   





Powrót do góry
   
Bobekmaster
Poziom 20
Poziom 20


Dołączył: 20 Sty 2006
Posty: 874
Miasto: Wrocław

Post#10 23 Gru 2010 22:22   

Re: AVR + enkoder obrotowy


tmf napisał:
Kod:

 unsigned char i=0;
    
    if((PINC & _BV(PC0))==0) i++;
    if((PINE & _BV(PE7))==0) i^=3; // convert gray to binary
    
    unsigned char enc_last=EncoderState & 3;
   i-=enc_last;
    enc_last+=i;
        EncoderState&=0xFC;
    EncoderState|=enc_last;
    
    if(i & 1)
    { // bit 0 = value (1)
    if(i & 2) NoOfPulses--; // bit 1 = direction (+/-)
    else NoOfPulses++;
    }


Debouncing to już sobie sam dodaj :)


Mam pytanie czy deboucing jest potrzebny do obsługi enkodera? Z tego co rozumiem ma on niwelować zakłócenia związane z drżeniem styków.
Skorzystałem z Twojego programu i działa dobrze bez debouncingu.

Pozdrawiam
Powrót do góry
   
tmf
Moderator
Moderator


Dołączył: 12 Sie 2009
Posty: 7542
Miasto: Katowice

Post#11 23 Gru 2010 22:45   

Re: AVR + enkoder obrotowy. Program w C


Nie jest konieczny, ale to zależy od okoliczności. Musisz się liczyć z tym, że bez debouncingu przy kręceniu stan może przejściowo oscylować +/-1, aż się ustabilizuje na nowej wartości. W zależności od kodu to może być problem (jeśli każda zmiana generuje zdarzenie), lub nie.
Przy okazji, trzeba też pamiętać, że są różne enkodery - niektóre pomiędzy stabilnymi pozycjami generuja 1 impuls, ale są takie, które generują 2 lub 4. W takich sytuacjach NoOfPulses należy podzielić przez 2 lub 4.
Powrót do góry
   
Google


Google Adsense


Post# 23 Gru 2010 22:45   





Powrót do góry
   
Bobekmaster
Poziom 20
Poziom 20


Dołączył: 20 Sty 2006
Posty: 874
Miasto: Wrocław

Post#12 23 Gru 2010 22:50   

Re: AVR + enkoder obrotowy. Program w C


Mój enkoder wysyła 4 impulsy i wynik dziele przez 4.
Impulsy nie skaczą i zliczają się poprawnie.
Funkcja jest wyzwalana przerwaniem zegarowym a nie zewnętrznym.

Tak więc nie będę robił deboucingu.

Pozdrawiam i dziękuję za odpowiedź.
Powrót do góry
   
Fredy
Poziom 19
Poziom 19


Dołączył: 05 Paź 2003
Posty: 781

Post#13 24 Gru 2010 16:20   

Re: AVR + enkoder obrotowy. Program w C


tmf napisał:
Nie jest konieczny, ale to zależy od okoliczności. Musisz się liczyć z tym, że bez debouncingu przy kręceniu stan może przejściowo oscylować +/-1, aż się ustabilizuje na nowej wartości. W zależności od kodu to może być problem (jeśli każda zmiana generuje zdarzenie), lub nie.
Przy okazji, trzeba też pamiętać, że są różne enkodery - niektóre pomiędzy stabilnymi pozycjami generuja 1 impuls, ale są takie, które generują 2 lub 4. W takich sytuacjach NoOfPulses należy podzielić przez 2 lub 4.


Zauważ że na wejściu schematu wyżej są kondensatory 100n więc drgań tu nie będzie napewno - tym bardziej że enkodery są zwykle oparte o układy optyczne a nie mechaniczne.
Powrót do góry
   
tmf
Moderator
Moderator


Dołączył: 12 Sie 2009
Posty: 7542
Miasto: Katowice

Post#14 24 Gru 2010 17:10   

Re: AVR + enkoder obrotowy. Program w C


Zauważ, że nie rozmawiamy o powyższym schemacie, to czy 100nF wystarczy zależy od pullupa i stałej RC, a enkodery o których tu mowa to zwykłe enkodery obrotowe, mechaniczne, a nie optyczne. Raczej nikt przy zdrowych zmysłach nie wrzuciłby do sterowania menu enkodera optycznego za kilkaset zł :)
Wesołych Świąt.
Powrót do góry
   
Fredy
Poziom 19
Poziom 19


Dołączył: 05 Paź 2003
Posty: 781

Post#15 27 Gru 2010 10:15   

Re: AVR + enkoder obrotowy. Program w C


Ja obsługę takich enkoderów wykonuje zawsze na jednym przerwaniu. Jeden z impulsów wywołuje przerwanie, w obsłudze przerwania sprawdzam tylko stan drugiego kanału. Jeśli jest wysoki to ++licznik, jeśli jest niski to --licznik.
Powrót do góry
   
tmf
Moderator
Moderator


Dołączył: 12 Sie 2009
Posty: 7542
Miasto: Katowice

Post#16 27 Gru 2010 11:57   

Re: AVR + enkoder obrotowy. Program w C


Moim zdaniem jest to kepski pomysł. Ew. drgania styków wywołują serię przerwań, dzięki czemu procesor niepotrzebnie jest zajęty. IMHO lepiej to robić na zasadzie poolingu z przerwania timera. Wtedy cały program działa w sposób bardziej deterministyczny.
Powrót do góry
   
Fredy
Poziom 19
Poziom 19


Dołączył: 05 Paź 2003
Posty: 781

Post#17 27 Gru 2010 23:50   

Re: AVR + enkoder obrotowy. Program w C


tmf napisał:
Moim zdaniem jest to kepski pomysł. Ew. drgania styków wywołują serię przerwań, dzięki czemu procesor niepotrzebnie jest zajęty. IMHO lepiej to robić na zasadzie poolingu z przerwania timera. Wtedy cały program działa w sposób bardziej deterministyczny.


A tak nie będzie procesor zajęty ? To dopiero będzie masakra.
No chyba że będziesz odpytywać raz na sekundę ......
Powrót do góry
   
tmf
Moderator
Moderator


Dołączył: 12 Sie 2009
Posty: 7542
Miasto: Katowice

Post#18 28 Gru 2010 00:40   

Re: AVR + enkoder obrotowy. Program w C


Będzie, ale w sposób przewidywalny. W dodatku odpowiedni dobór czasu pomiędzy kolejnymi wyzwoleniami przerwania załatwia automatycznie debouncing. Przy przerwaniach z kolei, dopóki nie kręcisz jest ok, ale jak zaczniesz to masz nagle przerwanie za przerwaniem. W efekcie program jest małodeterministyczny, a policzenie czasu reakcji staje się niemożliwe. A w wielu sytuacjach maksymalny czas reakcji programu warto znać, chociażby żeby wiedzieć z jakim opóźnieniem wchodzisz w przerwania krytyczne czasowo.
Powrót do góry
   
Fredy
Poziom 19
Poziom 19


Dołączył: 05 Paź 2003
Posty: 781

Post#19 28 Gru 2010 00:51   

Re: AVR + enkoder obrotowy. Program w C


Nie zgadzam się z Tobą.

Wyobraź sobie sytuację - kręcisz dość szybko. Pojawia się impuls na kanale A. Wtedy musisz natychmiast sprawdzić stan kanału B. Jeśli zrobisz to zbyt późno to możesz zinterpretować ruch jako odwrotny a to jest totalny error.
Przy szybkim kręceniu enkodera stan przejściowe trwają bardzo krótko, a tak naprawdę miarodajne są zbocza tych sygnałów.
Także gwarantuje ci że Twoje rozwiązanie słabo zda egzamin.
No chyba że będziesz testować co 0,1ms. Ale wtedy to procek to mocno odczuje - dużo więcej aniżeli w przerwaniach.
Powrót do góry
   
tmf
Moderator
Moderator


Dołączył: 12 Sie 2009
Posty: 7542
Miasto: Katowice

Post#20 28 Gru 2010 11:53   

Re: AVR + enkoder obrotowy. Program w C


Nie masz racji. Szybsze kręcenie wcale nie skraca okresów niestabilności. Łatwo się o tym przekonać na oscyloskopie. Stąd też enkoder mechaniczny po prostu ma górną ilość impulsów jakie można wykręcić, przekroczenie tej wartości uniemożliwia wiarygodny odczyt. Zresztą tak jak piszę się po prostu robi, nawet Atmel w mikrokontrolerach mających sprzętową obsługę enkodera korzysta z czegoś w rodzaju timerów. Zbocza się nie nadają do interpretacji bo na jeden przeskok enkodera jeden z sygnałów będzie generował wiele przejść. Program więc musiałby reagować na kaźde z nich, co prowadziłoby do błędów.
Powrót do góry
   
Google


Google Adsense


Post# 28 Gru 2010 11:53   





Powrót do góry
   
LordBlick
Zasłużony dla elektroda
Zasłużony dla elektroda


Dołączył: 31 Sie 2004
Posty: 5476
Miasto: Słupsk

Post#21 28 Gru 2010 19:39   

Re: AVR + enkoder obrotowy. Program w C


Osobiście używam własnej procedury na zboczach i nie odczuwam z tym żadnej niedogodności. Przerwanie na zboczu opadającym musi być potwierdzone na zboczu narastającym, ot cały debouncing. Obsługa przerwania to mikrosekundy i jest niczym w porównaniu z namiętnie stosowanym przez niektóre przypadki waitms() ;).
Powrót do góry
   
tmf
Moderator
Moderator


Dołączył: 12 Sie 2009
Posty: 7542
Miasto: Katowice

Post#22 28 Gru 2010 19:57   

Re: AVR + enkoder obrotowy. Program w C


To żaden debouncjing, przecież jak drgają styki to masz naprzemienne zbocza narastające/opadające, inaczej byłby to stabilny stan logiczny :)
Oczywiście w większości przypadków to nie przeszkadza i można sobie robić na przerwaniach. Problem pojawia się w sytuacji, kiedy inne procedury wymagają niskiego, albo chociażby przewidywalnego czasu reakcji na przerwanie. Aby to zapewnić, przerwania o niskich priorytetach robi się jako ISR_NAKED, bo większość AVRów nie ma priorytetów przerwań. No i tu właśnie rodzi się problem - takiego przerwania, gdzie masz nieprzewidywalne drgania nie można zrobić naked, bo go przerwie kolejne i dojdzie do zagnieżdżenia stosu wywołań. To samo w sobie też nie jest problemem, chyba, że... jesteś krucho z pamięcią. IMHO umieszczanie enkodera na przerwaniach INT nie ma właściwie zalet, a w pewnych sytuacjach ma wady. Ponieważ obsługa enkodera to jest coś co zrobiłem raz w życiu i kopiuje istniejący kod do innych układów, więc lepiej to zrobić raz i bezproblemowo, niż tworzyć rozwiązania, które są dobe, ale czasami.
Powrót do góry
   
LordBlick
Zasłużony dla elektroda
Zasłużony dla elektroda


Dołączył: 31 Sie 2004
Posty: 5476
Miasto: Słupsk

Post#23 28 Gru 2010 23:45   

Re: AVR + enkoder obrotowy. Program w C


Hmmm... do tej pory żyłem z przeświadczeniem, że standardowo w AVR przerwania nie da się przerwać innym przerwaniem... Ale ja rzeźbię w asm i też kopiuję istniejący kod... ;)
Powrót do góry
   
tmf
Moderator
Moderator


Dołączył: 12 Sie 2009
Posty: 7542
Miasto: Katowice

Post#24 29 Gru 2010 00:02   

Re: AVR + enkoder obrotowy. Program w C


Standardowo tak jest, ale nic nie stoi na przeszkodzie, żeby pierwszą instrukcją obsługi przerwania było sei. W AVR-libc załatwia to atrybut ISR_NOBLOCK. W poprzednim poście błędnie napisałem ISR_NAKED, coś mi jakieś nagości widać chodzą po głowie :)
Powrót do góry
   
Napisz nowy temat  Odpowiedz do tematu      Strona Główna -> Forum elektroda.pl -> Mikrokontrolery Ogólne -> Mikrokontrolery AVR -> AVR + enkoder obrotowy. Program w C
Strona 1 z 1
Podobne tematy
Enkoder obrotowy. (2)
AVR, Enkoder, Delphi Odczyt pozycji przez RS. (33)
Program do avr. Atmega8. Odliczanie czasu, program zawiesza się. (4)
[AVR][ATTiny2313]SD + program na AVR (6)
Program AVR (1)
pomocy !!! program na avr (4)
avr-program konfigurowalny (3)
porty 90s8515 program AVR (4)
atmel avr i pamiec na program (7)
program w AVR,blagam o pomoc!! (11)


Administrator || Moderatorzy || Regulamin forum || Regulamin ogólny || Informacja o cookies || Reklama || Kontakt

Page generation time: 0.063 seconds

elektroda.pl temat RSS