Witam. Jak widać jest to mój pierwszy post na tym forum. Na wstępie chciałbym prosić o wyrozumiałość - jeżeli temat znalazł się w nieodpowiednim miejscu, popełniłem jakiś błąd w składni tytułu czy coś tego typy, prosiłbym moderatora o poprawkę i pouczenie jak w przyszłości uniknąć powielenia problemu.
Jestem w trakcie pisania pracy inżynierskiej dotyczącej sterowania ręką robota. Niestety moja dotychczasowa praktyka w zakresie mikrokontrolerów ogranicza się do kilku-kilkunastu godzin spędzonych na zajęciach laboratoryjnych i trochę poza nimi. Ale do rzeczy. Ruchy palców oraz przegubu kciuka są sterowane za pomocą sześciu serw modelarskich. Sterowanie ich położeniem odbywać się będzie za pomocą ATmega8515 umieszczonego w zestawie STK-500 (takie przykazanie dostałem od promotora dla ułatwienia pracy). W trakcie pracy pojawiły się dwie koncepcje sterowania, które przedatawię w oddzielnych punktach. Niestety w obu przypadkach wystąpiły problemy.
1. Jest to moja koncepcja. Polega ona na tym, że Timer0 działa w trybie CTC, generując przerwanie co 5ms. Na kanałach A oraz B Timera1 generowane są przebiegi PWM (w trybie fast PWM), również o okresie 5ms. Każdy kanał ma obsłużyć do 4 serw (stąd okres 5ms, nie zaś 20ms). W przerwaniu od CTC inkrementowana jest zmienna i oraz j. Odpowiadają one za wybór pinu (czyli serwa) na który dany impuls zostanie podany (również w przerwaniu od CTC). Podanie polega na sprawdzeniu wartości zmiennych i oraz j i zależnie od ich wartości w momencie pojawienia się impulsu na wyjściu kanału PWM (OC1A, OC1B) wystawieniu stanu wysokiego na odpowiedni pin portu B.
W pętli głównej znajduje się obsługa switch'y (port A). Dwa switch'e odpowiadają za wybór numeru serwa (przy okazji zapalająć odpowiednią LEDę na porcie C dla sygnalizacji które serwo jest teraz obsługiwane), zaś dwa inne zależnie od wartości zmiennej nr_serwa za zwiększenie albo zmniejszenie szerokości impulsu (zmienne s1, s2, s3, s4, s5, s6 oraz sx z których wartości są potem przepisywane do OCR1A albo OCR1B).
Tyle, jeżeli chodzi o ideę. W praktyce niestety wydaje się, że nic nie działa. Przy naciskaniu switch'y nie zapala się żadna LED'a. Po podłączeniu oscyloskopu pod wyjścia sprzętowego PWM (OC1A, OC1B) nie pojawiają się żadne impulsy (sygnał ciągle ma stan niski). O ile za pierwszy problem mógłbym zrzucić winę na to, że przerwania mogą odbywać się za szybko, żeby program główny coś wykonał, o tyle przecież na wyjściach OC1A/OC1B powinien być sprzętowo generowany jakikolwiek sygnał. Kod poniżej:
2. Koncepcja mojego promotora, na razie jej opracowywanie jest w toku, ale już napotkałem na problemy. Polega ona na wykorzystaniu dwóch timerów w trybie CTC - jeden o okresie 20ms, ustawiający cały port w stan wysoki (na Tim0), drugi o okresie 10us odpowiadający mniej-więcej rozdzielczości serwa (na Tim1). Idea jest taka: pierwszy timer w przerwaniu od Compare Match ustawia cały port na 1, zaś drugi w przerwaniu inkrementuje zmienną i po osiągnięciu przez nią odpowiedniej wartości odpowiadającej zadanej szerokości impulsu serującego serwem gasi odpowiedni pin.
Próbowałem napisać w miarę podstawowy program spełniający tę ideę, żeby móc go potem rozwijać. Niestety już w tym momencie napotkałem problemy. Chciałem na razie zasymulować przebieg na LED'ach, ponieważ nie posiadam w domu oscyloskopu (za każdym razem, kiedy chcę coś sprawdzić, muszę jechać na uczelnię). Zdaję sobie sprawę, że 50Hz to trochę mało, żeby zauważyć zapalanie i gaszenie diody, ale spodziewałem się, że chociaż diody, których stanu nie zmieniam będą ciągle się palić. Myślałem, że błąd jest w ustawieniach CTC, ale przeglądając dokumentację oraz różne znalezione w sieci programy błędu nie zlokalizowałem. Dlatego chciałbym prosić kogoś bardziej doświadczonego, aby rzucił na to okiem. Kod poniżej:
Z góry dziękuję za pomoc w obu przypadkach!
Pozdrowienia,
Sinsky
Jestem w trakcie pisania pracy inżynierskiej dotyczącej sterowania ręką robota. Niestety moja dotychczasowa praktyka w zakresie mikrokontrolerów ogranicza się do kilku-kilkunastu godzin spędzonych na zajęciach laboratoryjnych i trochę poza nimi. Ale do rzeczy. Ruchy palców oraz przegubu kciuka są sterowane za pomocą sześciu serw modelarskich. Sterowanie ich położeniem odbywać się będzie za pomocą ATmega8515 umieszczonego w zestawie STK-500 (takie przykazanie dostałem od promotora dla ułatwienia pracy). W trakcie pracy pojawiły się dwie koncepcje sterowania, które przedatawię w oddzielnych punktach. Niestety w obu przypadkach wystąpiły problemy.
1. Jest to moja koncepcja. Polega ona na tym, że Timer0 działa w trybie CTC, generując przerwanie co 5ms. Na kanałach A oraz B Timera1 generowane są przebiegi PWM (w trybie fast PWM), również o okresie 5ms. Każdy kanał ma obsłużyć do 4 serw (stąd okres 5ms, nie zaś 20ms). W przerwaniu od CTC inkrementowana jest zmienna i oraz j. Odpowiadają one za wybór pinu (czyli serwa) na który dany impuls zostanie podany (również w przerwaniu od CTC). Podanie polega na sprawdzeniu wartości zmiennych i oraz j i zależnie od ich wartości w momencie pojawienia się impulsu na wyjściu kanału PWM (OC1A, OC1B) wystawieniu stanu wysokiego na odpowiedni pin portu B.
W pętli głównej znajduje się obsługa switch'y (port A). Dwa switch'e odpowiadają za wybór numeru serwa (przy okazji zapalająć odpowiednią LEDę na porcie C dla sygnalizacji które serwo jest teraz obsługiwane), zaś dwa inne zależnie od wartości zmiennej nr_serwa za zwiększenie albo zmniejszenie szerokości impulsu (zmienne s1, s2, s3, s4, s5, s6 oraz sx z których wartości są potem przepisywane do OCR1A albo OCR1B).
Tyle, jeżeli chodzi o ideę. W praktyce niestety wydaje się, że nic nie działa. Przy naciskaniu switch'y nie zapala się żadna LED'a. Po podłączeniu oscyloskopu pod wyjścia sprzętowego PWM (OC1A, OC1B) nie pojawiają się żadne impulsy (sygnał ciągle ma stan niski). O ile za pierwszy problem mógłbym zrzucić winę na to, że przerwania mogą odbywać się za szybko, żeby program główny coś wykonał, o tyle przecież na wyjściach OC1A/OC1B powinien być sprzętowo generowany jakikolwiek sygnał. Kod poniżej:
Kod: C / C++
2. Koncepcja mojego promotora, na razie jej opracowywanie jest w toku, ale już napotkałem na problemy. Polega ona na wykorzystaniu dwóch timerów w trybie CTC - jeden o okresie 20ms, ustawiający cały port w stan wysoki (na Tim0), drugi o okresie 10us odpowiadający mniej-więcej rozdzielczości serwa (na Tim1). Idea jest taka: pierwszy timer w przerwaniu od Compare Match ustawia cały port na 1, zaś drugi w przerwaniu inkrementuje zmienną i po osiągnięciu przez nią odpowiedniej wartości odpowiadającej zadanej szerokości impulsu serującego serwem gasi odpowiedni pin.
Próbowałem napisać w miarę podstawowy program spełniający tę ideę, żeby móc go potem rozwijać. Niestety już w tym momencie napotkałem problemy. Chciałem na razie zasymulować przebieg na LED'ach, ponieważ nie posiadam w domu oscyloskopu (za każdym razem, kiedy chcę coś sprawdzić, muszę jechać na uczelnię). Zdaję sobie sprawę, że 50Hz to trochę mało, żeby zauważyć zapalanie i gaszenie diody, ale spodziewałem się, że chociaż diody, których stanu nie zmieniam będą ciągle się palić. Myślałem, że błąd jest w ustawieniach CTC, ale przeglądając dokumentację oraz różne znalezione w sieci programy błędu nie zlokalizowałem. Dlatego chciałbym prosić kogoś bardziej doświadczonego, aby rzucił na to okiem. Kod poniżej:
Kod: C / C++
Z góry dziękuję za pomoc w obu przypadkach!
Pozdrowienia,
Sinsky
