Elektroda.pl
Elektroda.pl
X
BotlandBotland
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Sterowanie serwomechanizmem z wykorzystaniem atmegi32 [C]

14 Kwi 2013 14:06 5922 41
  • Poziom 11  
    Mam problem ze sterowaniem serowmechanizmu tower pro mg90s. Chodzi mi o to, że serwomechanizm ma zbyt dużą prędkość obrotową. Wyczytałem, że aby regulować prędkość serwomechanizmu, należy zmieniać długość impulsu sterującego.
    Napisałem taki program:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Troszkę mało czytelny ten mój kod, ale mam nadzieję, że zrozumiecie o co w nim chodzi. Z góry mówię, że wolałbym to zrobić na funkcji delay niż kombinować z timerami i przerwaniami, ponieważ jeszcze nie posiadłem dostatecznej wiedzy na ten temat, a z uruchomieniem serwa trochę mi się śpieszy. Problemem jest, że serwo kręci się wolniej, lecz po pewnym czasie zaczyna zwalniać, w końcu się zatrzymuje. Ma ktoś pomysł co może być tego powodem?
  • BotlandBotland
  • Pomocny post
    Specjalista - Mikrokontrolery
    Jednak zrób to z timerami.

    Twój procesor wykonuje jedną instrukcjŁ an ogół w jedną mikrosekundę. Pętla, w której odliczasz jednomikrosekundowe opóźnienia samy wykonuje się kilka mikrosekund - tak zrobione opóźnienia są trudne do określenia, w każdym razie niewiele mają wspólnego z tym, co chcesz uzyskać.
    Do sterowania serwem (zwłaszcza płynnego) potrzebujesz timera w trybie PWM i programowej zmiany wypełnienia w procedurze obsługi przerwania tego timera.
  • Poziom 11  
    Jeżeli by mi się to udało, to sygnał PWM mógłby być podawany na obojętnie który pin atmegi? Czy muszę i mam możliwość odbierania go jedynie z pinów OC1B i OC1A?
  • Pomocny post
    Specjalista - Mikrokontrolery
    Sprzętowo tylko na wyjściach OC. Przy tej częstotliwości można sterować dowolnymi wyjściami programowo, obsługując wszystkie przerwania timera.
  • BotlandBotland
  • Poziom 11  
    Tylko nie bardzo mogę pojąć jak to rozwiązać na timerach. Ja to bym widział tak: Sygnał podawany na serwo musi mieć długość impulsu 1ms lub 2ms(zależy w którą stronę ma się kręcić serwo), timer0 liczy sobie impulsy i jak zrobić aby przerwanie zostało wywołane dopiero, gdy na pewnym pinie atmegi pojawi się sygnał? I jak zrealizować zmianę długości impulsu? Zastanawia mnie także jak długo ten impuls ma się zmieniać ;/
  • Specjalista - Mikrokontrolery
    Sprzętowo: zaprogramuj timer w tryb PWM, ustaw okres 20 ms, a rejestr OC na wartość, która da długość impulsu taką , jak trzeba, np. 1.5 ms.

    To, jak wolno ma się zmieniać impuls, zależy od tego, jak szybko chcesz kręcić serwem. Najpierw napisz zwykłą obsługę serwa, potem dołożysz powolną zmianę.
  • Poziom 11  
    Na stronie http://www.robotyka.net.pl/sterowanie-serwomechanizmem/ znalazłem coś takiego:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Mam kilka pytań a mianowicie:

    1. Po co tutaj ustawiany jest port DDRA?
    2. Rejestr ICR1 jest 16 bitowy?
    3. Czy dobry jest mój tok myślenia:
    W rejestrze TCCR1A oraz w rejestrze TCCR1B ustawiamy bity WGM11, WGM12, WMG13 po to, aby timer pracował w trybie Fast PWM, czyli zlicza do wartości podanej w rejestrze (w naszym przypadku OCR1A) i gdy zliczy zmienia wartość na przeciwną (czyli jeżeli od początku był stan wysoki to zmienia na niski). Po osiągnięciu wartości TOP czyli w naszym przypadku podanej w rejestrze ICR1 licznik się resetuje i sekwencja się powtarza.

    4. Jeżeli chciałbym sterować kierunkami obrotu serwomechanizmu to wystarczy zmieniać wartość rejestru OCR1A na wartości 2000 lub 1000?

    5. Mam problem ze zrozumieniem, w jaki sposób włączać i wyłączać PWM na portach. Chodzi mi to taki przypadek: Jeżeli na np. PIN0 portu A pojawi się stan wysoki, zaczyna się sekwencja PWM, jeżeli na PIN0 portu A pojawi się stan niski, sekwencja PWM zostaje wyłączona. Domyślam się, że należy zmieniać stan bitów WGM11,WGM12,WGM13, ale to tylko domyślenia i chciałbym poznać wasze zdanie na ten temat.

    6. Aby zmniejszyć prędkość obracania się serwomechanizmu należy zwiększać wartość rejestru OCR1A a zmniejszać ICR1? Jeśli tak to lepiej jest zmienić dla przykładu 5 razy długość sygnału i powtórzyć to 300 razy czy zmienić 300 razy długość sygnału i powtórzyć ten proces 5 razy (nie wiem czy zachowałem proporcje ale mam nadzieję, że wiadomo o co chodzi).
  • Pomocny post
    Poziom 11  
    AD1.
    Jeżeli chodzi o Atmegę32 nie potrzebne ustawienie portów. Chyba że autor kodu miał inny cel na myśli :-)

    Obsługa timerów ma miejsce tylko na:
    OC0 - PINB3
    OC1A - PIND5
    OC1B - PIND6
    OC2 - PIND7

    Tak mi się wydaje z tego co z noty przeczytałem.

    AD2.
    Tak ICR1 jest 16-sto bitowy. Nota strona 111.

    AD3.
    Tak.

    AD4.

    Nie.

    Z tego co mi wiadomo to kierunek obrotu zależy od podpięcia/zmianę zasilania i masy a za to odpowiada np. scalony mostek H.
    Ma on za zadanie zmianę kierunku na liniach zasilania. W tej kwestii niech wypowiedzą się bieglejsi.

    AD5.

    Sterowanie serwomechanizmem z wykorzystaniem atmegi32 [C]

    Wyzerowanie COM1A1/COM1B1 oraz COM1A0/COM1B0 wyłączy timer.

    AD6.

    Zwiększasz OCR1A czas między impulsami - to będzie chyba też wypełnienie.
    Jak chcesz szybko to zmniejszasz czas między impulsami (zagęszczasz). Jak chcesz wolniej to zwiększasz czas (rozrzedzasz).


    Niech się wypowiedzą bardziej doświadczeni.
  • Pomocny post
    Poziom 40  
    Cytat:
    AD1.

    Dla poprawnego działania pinu wyjściowego OCnxx należy ustawić DDR jako wyjście. Oczywiście w przypadku A32 ma to być DDRD (PD4, PD5) a nie DDRA.
  • Poziom 11  
    kazzik87 napisał:
    AD1.

    AD4.

    Nie.

    Z tego co mi wiadomo to kierunek obrotu zależy od podpięcia/zmianę zasilania i masy a za to odpowiada np. scalony mostek H.
    Ma on za zadanie zmianę kierunku na liniach zasilania. W tej kwestii niech wypowiedzą się bieglejsi.


    Na tej stronce: http://www.forbot.pl/forum/topics20/mechanika...-w-robotyce-amatorskiej-kompendium-vt3902.htm przeczytałem, że kierunek obrotu serwa zależy od długości podawanego impulsu sterującego (od 1ms do 2ms), ale wolałbym żeby ktoś to potwierdził.
  • Pomocny post
    Poziom 40  
    Kierunek zależy od różnicy aktualnej pozycji a tej którą wysyłasz. Można założyć że długość impulsu który wysyłasz to jakaś pozycja. Patrz tutaj:
    http://www.pitt.edu/~sorc/robotics/handbook/ServoControl.htm
    Jeśli aktualna pozycja jest większa od tej którą wysyłasz to serwo będzie wracać a jeśli odwrotnie to jechać w drugą stronę. Im większa różnica między pozycją wysyłaną a aktualną pozycją serwa tym szybciej będzie się ono obracać w danym kierunku.
  • Poziom 11  
    O i ja się czegoś ciekawego dowiedziałem.

    Do tej pory pracowałem z silnikami krokowymi (bi i unipolarnymi). Stąd też to nawiązanie do scalonych mostków Hala :-p


    PS.:
    Czy na tym schemacie w linku nie ma przypadkiem scalonych mostków H - "BAL6686 H-Bridge" podpiętych do linii zasilania Serwem :-)
    Tak wiem sterowane są przez BAL6688 :-)
  • Poziom 11  
    Fajnie to excray wytłumaczyłeś. Jeszcze mam takie pytanko, czy serwo ma stały punkt neutralny? Czy on się zmienia z każdym przesunięciem? Jeżeli np mam w pozycji neutralnej, i chciałbym aby wolno się kręcił w kółko to tak: czas trwania impulsu jest puki co równy 1.5ms i następnie mam zwiększać tą wartość np. co 0.05 ms do momentu uzyskania czasu impulsu 2.0ms, następnie ustawić czas trwania impulsu 1ms i zwiększać do 1.5ms i tak w kółko?
  • Poziom 11  
    skyline11 napisał:
    ..., czy serwo ma stały punkt neutralny? ...


    Nie wiem co rozumiesz pod pojęciem "neutralny"?

    Jak ustawisz 1,5 ms to serwo stoi.
    Jak ustawisz 1 ms to będzie kręcił w lewo maksymalnie.
    Jak ustawisz 2 ms to będzie kręcił w prawo maksymalnie.

    Jak chcesz przyśpieszać w lewo to zmniejszasz wartość do 1 ms np o 0,05 ms :-)
    Jak chcesz przyśpieszać w prawo to zwiększasz wartość do 2 ms np. o 0,05 ms :-)

    Jak chcesz wrócić do pozycji "0" to musisz liczyć impulsy. A następnie cofnąć serwo w przeciwnym kierunku o tę samą wartość :-)

    Nie wiem czy o to Ci chodziło?
  • Pomocny post
    Poziom 40  
    skyline11 napisał:
    Jeszcze mam takie pytanko, czy serwo ma stały punkt neutralny? Czy on się zmienia z każdym przesunięciem?

    Zazwyczaj serwo ma określony zakres obrotu - najczęściej 0-180*. W celu określenia czy serwo osiągnęło położenie wysyłane przez mikroprocesor w serwie do ramienia podczepiony jest potencjometr który mówi dla wbudowanego w serwo sterownika jaka jest aktualna pozycja ramienia. Takie serwa nie potrafią obracać się o kąt większy jak 180* Jeśli Ty masz takie serwo które "kręci się w kółko" to oznacza prawdopodobnie że ktoś w Twoim serwie odłączył mechanicznie ten potencjometr od ramienia (tak czasami robią modelarze aby uzyskać serwo które może wykonać wiele obrotów) i ustawiają ten potek w pozycji środkowej. Trudno jest w takim serwie trafić w środek ustawienia tego potka i najczęściej takie serwo zawsze się lekko obraca w jedną bądź inną stronę. Coś za coś. Za to w takim serwie można regulować kierunkiem i prędkością. Im bardziej pozycja którą wysyłasz różni się od tej na stałe ustalonej na potencjometrze tym szybciej się kręci. A kierunek tak samo jak w zwykłym serwie czyli pozycja większa niż obecna bądź mniejsza niż obecna. Jak wspominałem w tak zmodyfikowanym serwie trudno jest uzyskać taką pozycję kiedy serwo się całkowicie zatrzyma.

    EDIT> To znaczy da się je zatrzymać - trzeba przestać wysyłać do niego impulsy z informacją o pozycji. Niemniej trudno jest dobrać taką długość impulsów aby pomimo ich wysyłania serwo nie obracało się.
  • Poziom 11  
    @kazzik87 - chodzi mi o to, aby po prostu kręcił się wolniej, a nie zwalniał albo przyśpieszał.
  • Pomocny post
    Specjalista - Mikrokontrolery
    Szerokość impulsu wysyłanego do serwa określa pozycję, jaką serwo ma przyjąć. Przyjmie ją zawsze najszybciej, jak potrafi, czyli typowo poniżej sekundy. Jeśli chcesz zmieniać powoli pozycję serwa, to kolejno wysyłaj mu impulsy o szerokościach zmienianych co pewien krok - w ten sposób po każdym impulsie serwo przesunie się trochę, a cały czas przesuwania może trwać np. 10 sekund.
  • Poziom 11  
    Napisałem coś takiego, niestety nie działa. Gdzie popełniam błąd?

    Kod: c
    Zaloguj się, aby zobaczyć kod
  • Specjalista - Mikrokontrolery
    Wszędzie. Pod każdym if masz prawie to samo. Jedyne, co masz zmieniać - to wypełnienie. Zaprogramuj timer raz, a dobrze. Potem napisz prosty program, który zmienia wypełnienie w kółko od 1000 do 2000, w przerwaniu timera. Kiedy zadziała - zacznij kombinować ze sterowaniem.
  • Poziom 11  
    Moje wypełnienie określa rejestr OCR1A, i za każdym razem gdy warunek zostanie spełniony wartość tego rejestru powinna się zwiększać, więc nadal nie wiem gdzie popełniam błąd. Dodam jeszcze, bo zapomniałem wcześniej napisać, że serwomechanizm nie kręci się w kółko - przepraszam za wprowadzenie w błąd.
  • Poziom 11  
    Ja się już pogubiłem w tym co chcesz uzyskać.

    Napisz dokładnie co chcesz uzyskać.

    Rozpocznij od podstaw!
    Najpierw dobrze ustaw timer, potem przerwanie do tego timera. Zrób tak żeby serwo ruszyło - przynajmniej w jedną stronę. Potem zacznij bawić się prędkością serwa - w jedną stronę. A następnie dodaj drugi kierunek. Na koniec możesz dodać sterowanie.

    Zerknij tutaj:
    Link1
    Link2
    Link3
    Link4
  • Poziom 11  
    Napisałem timer raz a dobrze, czyli w programie umieściłem tylko to:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Teoretycznie powinien pozostać w pozycji środkowej, a serwo wychyliło się w lewo. Zmiana rejestru OCR1A na wartość 1400 też nic nie pomogła. Serwomechanizm siedzi w chwytaku, chwytak bez względu czy podam mu długość impulsu 1,4ms czy 1,5 i tak wychyla się maksymalnie ;/ Czy według waszego założenia serwo powinno wychylić się powiedzmy o 1 stopień i się zatrzymać, potem zmieniam długość impulsu (zmieniając wartość rejestru OCR1A), i małą wartość i znowu obraca się o 1 stopień i znowu zmieniam i znowu się obraca i tak w kółko? Bo jeżeli tak to moje serwo tak się nie zachowuje...[/code]
  • Specjalista - Mikrokontrolery
    Pokaż cały kod. Mam tu przed sobą na biurku serwo, i właśnie wczoraj uruchamiałem kod, który nim wolno kręcie w jedną i drugą stronę - to raczej musi działać.
  • Poziom 11  
    Kod: c
    Zaloguj się, aby zobaczyć kod
  • Specjalista - Mikrokontrolery
    Zapomniałeś o pustej pętli na końcu.
  • Poziom 11  
    Dodałem, bez zmian...
  • Specjalista - Mikrokontrolery
    A jaką masz ustawioną częstotliwość w procesorze?
  • Poziom 11  
    1Mhz, sprawdzałem w AVR studio, też mam ustawione 1Mhz. Tak przy okazji, przy podaniu krótszego impulsu niż 1,5ms serwo powinno obrócić się o dany kąt i się zatrzymać?
  • Specjalista - Mikrokontrolery
    Przy podawaniu ciągu impulsów o stałej szerokości serwo powinno stań po osiągnięciu zadanego kąta. Stawiam na źle ustawioną częstotliwość procesora w bajtach konfiguracji. Spróbuj np. odliczać po 50 przerwań timera i migać diodą - powinna zmieniać stan co sekundę.