Skocz do zawartości

Enkodery optyczne Pololu, gubienie kroków


Matusso

Pomocna odpowiedź

Siema

Ostatnio dokonałem zakupu napędów Pololu HP 50:1 z obustronnym wałem oraz enkoderów. Wszystko złożem do kupy tak jak jest opisane na stronie, przylutowałem odpowiednio do płytki. Po pierwszych testach wszystko było ok, zasilanie silników działało, sygnały enkoderów również.

Problemy zaczęły się gdy chciałem dokładnie sterować silnikami z użyciem enkoderów, okazało się że czujniki enkodera gubią obroty łopatek. Przykładowo dla 3 łopatek pełny obrót dla przełożenia 50:1 powinien wykonać się po 150 przejściach łopatek koło czujnika, wykonywał się on po około 120(+/-10). Im większa prędkość silników tym większe błędy.

Czujniki podłączyłem do zwykłych portów atmegi8 a sygnały traktowałem jak naciśniecie przycisku.

Dodaje ogólny zarys programu:

        if(bit_is_set(PINB, 5)  && flaga==1)
	{
		i++;
		flaga=0;
	}
	if(bit_is_clear(PINB, 5)  && flaga==0)
	{
		flaga=1;
	}
	if(a>=50)
	{
		pokaz_wynik(i);
		_delay_ms(200);
		i=0;
		a=0;
	}

W tym przypadku uruchamiam silnik na określony czas(zmienna a zwiększa się w przerwaniu timera) by sprawdzić czy wyniki będą powtarzalne. Niestety nie są.

Wyjście A podłączone jest do PB4, B do PB5. Zmienna "i" zlicza ilość przejść łopaty wirnika koło czujnika B.

Próbowałem już kilku rozwiązań programowych np. gdzie oba czujniki rejestrowały przejście łopatki, zmieniałem również odległość wirnika do czujników ale ciągle są podobne błędy.

Sam już nie wiem gdzie może być problem.

Mam nadzieje ze dobrze wyjaśniłem problem.

Prosze o sugestie jak mógłbym to rozwiązać.

Pozdrawiam

Link do komentarza
Share on other sites

A może próbujesz rozwiązać problem którego nie ma? Przecież w rzeczywistości do enkodery będą raportowały ile obrotów zrobił silnik i właśnie dlatego ich potrzebujemy, bo silnik obraca się różnie. Może odwróć test i zamiast włączać silnik na określony czas (co niczego nie gwarantuje i moim zdaniem błąd rzędu 10% jest możliwy), kręć zadaną liczbę impulsów z enkodera i policz ile obrotów zrobiło koło. Dobierz tak liczbę zliczanych impulsów, by było to np. 10 pełnych obrotów koła. Niech silniki kręcą się na tyle wolno - przecież możesz tym sterować - byś zdążył policzyć obroty koła. Możesz nakleić coś na koła i puścić test np. 50000 impulsów z pełną prędkością. Zrób profilowanie prędkości kół tak, by wyhamowywały przed osiągnięciem zadanej liczby kroków albo nawet niech wracają gdy "przejechały". Wtedy sprawdzisz poprawność działania enkoderów nawet przy dużych prędkościach, bo przecież przekładnia zębata chyba się nie myli?

Link do komentarza
Share on other sites

Robiłem testy po przez ręczne obracanie kołem. Przy wolnym obracaniu(mniej więcej jeden obrót na 15s) wychodziło 150 impulsów czyli tyle ile powinno przy szybszym obracaniu wyniki były nawet niższe od 100 impulsów na obrót.

Link do komentarza
Share on other sites

Te czujniki są analogowe a doprowadzasz je do wejść cyfrowych procka. Trzeba by najpier jakoś to na cyfrową postać przerobić dajać na jakiś komparator, bramkę schmitta czy nawet jakiś prosty wzmacniacz operacyjny.

Zmierz miernikiem jak zmienia się sygnał z wyjść tych czujników (czyli na we procka)

1obr/15 to tragicznie mało.

ja bez problemu mierze takim czujnikiem prędkość 2500 obr/min przy 10 łapatkach czyli ponad 400 impulsów/s na 2 silniakach i to w wolnym bascomie.

Pokaż ponadto cały program.

Nie wiem co to jest ta zmienna "a". może ona wczesnej osiąga wartość 50 i przestaje liczyć a powinno dalej.

1obr/15s to na pewno musi być jakiś poważny błąd software'owy lub hardware'owy.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Faktycznie na wyjściu jest około 3V a nawet mniej wiec nie dziwota ze gubi kroki.

Jeśli chodzi o program to zmienna "a" zwiększała się w przerwaniu programu i chodziło ogólnie o to żeby wykonywało pomiar co około 2s, wstawiłem w ta pętle diodę LED żeby sprawdzić czy działa tak jak chce i było ok.

Czyli jeśli dodam układ jak na załączonym obrazku powinno już działać ok?

Link do komentarza
Share on other sites

Powinno działać.

Skoro masz mniej niż 3V na wyjściu tych czujników to za jasno tam masz. Zasłoń ręką wszystko i zobacz czy będzie wyższe napięcie. Może kontrast zwiększ przez zamalowanie czarnym flamastrem.

Link do komentarza
Share on other sites

Po zakryciu ręka faktycznie większe napięcie, nawet momentami do 5V. Zamalowałem czarnym flamastrem wyniki nadal były błędne. Mam nadzieje ze dodanie komparatorów rozwiąże sprawę ostatecznie.

Link do komentarza
Share on other sites

Dodałem wiec taki układ do enkoderów:

I zauważyłem ze wyniki są podobne lub takie same jak wcześniej

Do testów stosuje program jak poniżej i ręcznie obracam kołem.

while(1)
{
	//enkoder_2B PINB, 7
	pokaz_wynik(i);
	if(bit_is_set(PINB, 7) && flaga==1)
	{
		i++;
		flaga=0;
	}

	if(bit_is_clear(PINB, 7) && flaga==0)
	{
		flaga=1;
	}

	//zerowanie licznika po wciśnięciu przycisku
	if(bit_is_set(PIND, 3) && flaga==0)
	{
		flaga=1;
           i=0;
	}
}

Sam już nie wiem co robię źle.

Link do komentarza
Share on other sites

No właśnie, na każdego przychodzi kiedyś taki moment, że zgadywanie przestaje wystarczać.

Najpierw założyłeś sobie, że własnoręcznie zbudowany czujnik będzie dawał idealny sygnał i podłączyłeś go wprost do portu procesora. Nieważne, że czytałeś o zboczach, że powinny być strome, o poziomach napięć, że powinny trzymać się z daleka od progu przełączania - ech, jakoś to będzie. Choć masz detektor kwadraturowy (jak sądzę z nazw sygnałów na schemacie) czyli dwa czujniki na jedną tarczę, napisałeś dziwnie prosty program z analizą jednego tylko wejścia - co tam, przecież to nie apteka. Nie zadziałało, hm, to co by tu jeszcze? Może by tak obejrzeć sygnał? Z czym tak naprawdę walczę? Zastanowić się nad działaniem kodu? Pożyczyć oscyloskop? Jechać na uczelnię? A może nawet zrobić go sobie z ADC? Policzyć czas wykonywania funkcji pokaz_wynik()?

Nie.. Przecież jesteśmy w średniowieczu, po co nam mikroskop albo posiewy do oglądania jakichś bakterii - które jak wiadomo nie istnieją - wystarczy liść łopianu. Tak! Weźmy komparatory! Panaceum na wszelkie kłopoty. Jak ich używać? No przecież, podłączamy do wejścia sygnał i już. Nieważne, że są reguły mówiące o histerezie, o ograniczonym zakresie napięć wejsciowych itd, i że tylko wtedy ma sens ich stosowanie, gdy pracują z dodatnim sprzężenim zwrotnym bo inaczej działają dokładnie tak jak porty procesora. Może by w tej sytuacji zmienić konfigurację czujników na odwrotną, bo inaczej przekroczysz 3V na wejściu?

Gdzie tam. Można pisać do upadłego, pokazywać schematy, eeech, przecież to jakieś naukowe wymysły, ludzie od pokoleń okładali chorego liśćmi i grali na fujarce i jakoś się goiło albo.. umierali - też prawda, ale wtedy to widocznie tak miało być i już. No to komparatory nie pomogły, motyla noga, to już koniec możliwości człowieka. Rocket science zawiodła, jesteśmy ugotowani.

No i teraz pewnie oczekujesz jakiejś złotej poroady typu: zrób tak i tak a będziesz zdrowy i bogaty, bo przecież zrobiłeś wszystko co mogłeś. A ja Ci mówię: nic nie zrobiłeś, macałeś ściany po ciemku jak dziecko w piwnicy. Ani nie wiesz jaki masz sygnał, jak wyglądają jego zbocza ani jak wygląda to co wychodzi z komparatorów, ani (chyba) nie wiesz jak obsługiwać enkodery kwadraturowe (albo nie pokazałeś całego kodu) ani też nie wziąłeś sobie do serca żadnych zasad stosowania komparatorów. Nic. Idąc dalej tym tropem, na Twoim miejscu zmieniłbym procesor na 32-bitowy. Nadal nie będziesz wiedział co się dzieje, bo po co sięgać po narzędzia, ale przynajmniej będzie się działo przynajmniej 10 razy szybciej. Jaki postęp.

Link do komentarza
Share on other sites

Witam po przerwie

Koledze marek1707 dziękuje ze wyczerpujący post aczkolwiek wystarczyły proste wskazówki co robić dalej w tym temacie 🙂

Postanowiłem wykorzystać sugestie na temat użycia oscyloskopu i udało mi się załatwić do niego dostęp. Poniżej są wyniki:

Pomiar dla dwóch czujników enkodera A i B.

Sygnał wydaje się być w porządku.

Poniżej znajduje się program z którego korzystam.

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

//UART
#define FOSC 8000000// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

volatile int flaga=1;
volatile int i=0;
volatile int a=0;
volatile char tab[5];  //tab to zamiast wyswietl_wynik bo krotsze
volatile char *wsk;



void TIMER_init(int OCR); 
int16_t pomiar(uint8_t kanal); 

//UART
void USART_Transmit( unsigned char data);
void USART_Init( unsigned int ubrr);
void pokaz_wynik(int pm);
void PWM_init(void);

int main(void)
{
sei();	//aktywacja globalnych przerwan


 //tryb CTC, TOP=OCR2
//porty sterujące

DDRD &=~((1<<PD7) |(1<<PD6));	//porty enkoderów 
  	PORTD |= (1<<PD7) |(1<<PD6);

DDRB |= (1<<PB1);

USART_Init(MYUBRR);
PWM_init();
TIMER_init(1);
  	OCR1A=150;
OCR1B=0;

while(1)
{
	if(bit_is_set(PIND, 7) && flaga==1)
	{
		i++;
		flaga=0;
	}

	if(bit_is_clear(PIND, 7)  && flaga==0)
	{
		flaga=1;
	}

	if(i>=150)
	{
		OCR1A=0;	//silnik STOP
             pokaz_wynik(a);
       	_delay_ms(500);
       	flaga=1;
          i=0;
		a=0;
		OCR1A=150;	//silnik start
	}

}
}

void TIMER_init(int OCR)
{
//Timer 8-bitowy
TCCR2 |= (1<<WGM21);	//tryb CTC, TOP=OCR2
TCCR2 |= (1<<CS22) | (1<<CS21) | (1<<CS20); //prescaler= 1024
TIMSK |= (1<<OCIE2);	//aktywacja przerwania co (8Mh/presc=78/OCR2=1024)=100Hz
OCR2=OCR;
}


void PWM_init(void)
{
//PWM 16-bit
TCCR1A |= (1<<COM1A1) | (1<<COM1B1);	//fast PWM nie odwracający(clear at compare match)

//Fast PWM, 8-bit
TCCR1B |= (1<<WGM12);
TCCR1A |= (1<<WGM10);

TCCR1B |= (1<<CS10) | (1<<CS11); //preskaler=1, brak skalowania

}


//UART
void USART_Init( unsigned int ubrr) //to na początku inicjujesz
{
wsk=&tab[0];

UBRRH = (unsigned char)(ubrr>>8);
UBRRL = (unsigned char)ubrr;

UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
//OSCCAL=170;
UCSRC |= (1 << URSEL) |(1 << UCSZ1) | (1 << UCSZ0);//|(1<<UPM1);

}


void USART_Transmit( unsigned char data )
{
while ( !( UCSRA & (1<<UDRE)) );
UDR = data;
}


void pokaz_wynik(int pm)
{

itoa(pm,wsk,10);

USART_Transmit(tab[0]);
USART_Transmit(tab[1]);
USART_Transmit(tab[2]);
USART_Transmit(tab[3]);
USART_Transmit(tab[4]);
USART_Transmit(0x0a);
USART_Transmit(0x0d);
}


//////PRZERWANIA///////
ISR(TIMER2_COMP_vect)
{
a++;
}

W powyższym programie obserwowałem po jakim czasie(zmienna "a") występuje zliczenie 150 impulsów (dla jednego tylko kanału) czyli pełen obrót. Wyniki były rożne i po samej obserwacji koła widać było że nie wykonywało pełnego obrotu.

Proszę o dalsze wskazówki i sugestie co może być nie tak.

Pozdrawiam

Link do komentarza
Share on other sites

Nie, nie, oscyloskopu nie powinieneś używać po to by udowodnić nam, że wszystko jest OK a ten uparty układ na złość nie działa, tylko do znalezienia błędu. Mając takie narzędzie nie pisz "sygnał wydaje się w porządku" bo jak mam to rozumieć? Jeśli Tobie - który siedzisz przy ekranie i mierzysz - tylko "wydaje się", to jak jest naprawdę?

Co sprawdziłeś? Czy oglądałeś impulsy przy podstawie czasu takiej, by mieć pewność, że procesor nie zauważy podwójnych zboczy obok siebie? Czy skorzystałeś z możliwości wyzwalania impulsami krótszymi niż cośtam? Przecież jeżeli podczas prostego jednego obrotu koła zliczasz za dużo impulsów to kiedyś musisz to robić. Oscyloskopem masz sprawdzić kiedy. Przy jego pomocy masz wyszukać i zrozumieć problem a nie udowadniać sobie, że wszystko jest OK - bo nie jest. Zakładam oczywiście, że wiesz co robisz i zliczanie dwóch zboczy jednego sygnału z enkodera powinno doprowadzić do liczby 150 po jednym pełnym obrocie koła.

Zacznij od podejrzenia sygnału (obu zboczy) przy podstawie rzędu 1us/dz. Czy zbocza są monotoniczne? Czy nie ma jakichś zafalowań, szczególnie w obszarze połowy zasilania? To Ty musisz wiedzieć, jaki sygnał jest akceptowalny a jaki już nie. Oscyloskop Ci tego nie powie. Zastanów się co musiałoby się stać, że by procesor pracujący z zegarem xMHz zaliczył dwie inkrementacje na jednym zboczu sygnału. Jak musiałoby ono być zniekształcone? Czy widzisz coś takiego? Jeżeli masz tryb wyzwalania runt sprawdż, czy pojawiają się impulsy o niepełnej amplitudzie, np. opuszczające bezpieczny obszar 0V, jadące do góry i przekraczające 2.5V ale nie dochodzące np. do 5V tylko wracające z powrotem. I odwrotnie: w dół od 5V tylko do np. 2V i z powrotem w górę. Jeśli masz wyzwalanie od szybkości zbocza (slope) zasadź się na prędkość wg Ciebie nieakceptowalną i znajdź zbocze zbyt wolne by mogło być przez procesor uznane za pojedyncze. To wszystko może nowoczesny oscyloskop cyfrowy. To potężne narzędzie a jego tryby wyzwalania to klucz do sprawnego separowania milionów normalnych sytuacji od tej jednej, błędnej, która jako najważniejsza powinna zostać złapana i wyświetlona. Tego nie ma żadna zabawka za 200zł, żaden oscyloskop analogowy ani nawet najlepsza karta dźwiękowa. Ustaw trigger na wyzwalanie impulsami krótszymi niż np. 1ms. Czy znajdują się takie podczas normalnej pracy silników? To dobrze? A 100us są? Też OK?

Zasilanie? Czy silniki nie psują szyn zasilania? Gdzie miałeś podłączone masy sond? Jak wygląda płytka? Jakie pasmo ma ten oscyloskop? Czy włączyłeś ograniczenie pasma analogowego w którymś kanale? Jak sprzężony jest z wejściem kanał triggera? Czy akwizycja pracuje w trybie Normal czy PeakDetect? Czy gdy obracasz koło ręką to zjawisko błędów zliczania też występuje? Jak jest jego skala? Czy jest lepiej niż z silnikami czy podobnie? Czy badałeś sygnały z enkodera z poziomem wyzwalania ustawionym w pobliżu poziomów stabilnych 0-5V? Czy tam coś się pojawia podczas pracy silnika?

Jeśli będziesz absolutnie pewien, że sygnał i zasilania są OK, dopiero wtedy zacznij grzebać w programie. Zrób proste ustawianie i zerowanie linii jakiegoś portu w chwili inkrementacji - nich procesor generuje impuls gdy zwiększa licznik np. tylko w jednej sytuacji, powiedzmy przy zboczu narastającym. Wyzwól się od tego impulsu i sprawdź jak późno po zboczu procesor je widzi? Czy wystarczająco szybko? Czy impulsy inkrementacji licznika pojawiają się wyłącznie po odpowiednim zboczu sygnału wejściowego czy zdarzają się także na przeciwnym? Wywal zliczanie do 150, niech silniki kręcą ile bateria dała, będziesz miał dużo czasu na pomiary. Ustaw trigger na odstęp czasu (długość impulsu) mniejszą niż spodziewany minimalny okres sygnału z enkodera. Czy nastąpiło choć jedno wyzwolenie? Ustaw tryb akwizycji na SINGLE i poczekaj aż coś się złapie. Jak to wygląda? Dlaczego oscyloskop się wyzwolił i co spowodowało, że okres między inkrementacjami był krótszy niż okres sygnału wejściowego? itd. itd.. To Ty musisz być najbardziej podejrzliwym gościem w okolicy bo to Ty szukasz błędu. Nie znajdziesz go prowadząc pomiary w celu udowodnienia sobie, że jest dobrze. Wykorzystaj narzędzie jakim dysponujesz i pokaż nam zrzut ekranu w sytuacji gdy procesor zliczył dwa razy a powinien był tylko raz - to jest interesujące, reszta to biadolenie.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.