Skocz do zawartości
Ważne ogłoszenie » Kliknij i sprawdź informacje o nowym forum! Czytaj dalej... ×
MarJanPol

Sterowanie serwem BEZ biblioteki

Recommended Posts

Witam, szukam informacji jak sterować serwem bez biblioteki servo.h i znalazłem kod jak poniżej - czy to będzie działać? - tzn czy ustawi standardowe serwo w maks. położeniu (nie mogę aktualnie sprawdzić):

int servoPin = 2;

void setup() {
    pinMode(servoPin, OUTPUT);

}

void loop {
    // Set the pin to high to move the motor
    digitalWrite(servoPin, HIGH);
    // Speed of the motor
    delayMicroseconds(2000);
    // Try and stop the motor
    digitalWrite(servoPin, LOW);
    // Wait 5 seconds
    delay(5000);

}

Udostępnij ten post


Link to post
Share on other sites

Zgodnie ze specyfikacją, stan wysoki powinien trwać 900-1500 mikrosekund i powtarzać się co około 20 ms. Ciężko powiedzieć jak serwo zareaguje na to co mu wysyłasz za pomocą powyższego programu. Pewnie każde inaczej.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Jamik, dziękuję za odpowiedź. Ogólnie większość przykładów kodów do pracy z serwem jakie odnajduje bazuje na bibliotece servo.h. Ja chciałbym nauczyć się sterować serwem bez używania tej biblioteki. Czy wiesz może gdzie mogę znaleźć takie informacje?

Udostępnij ten post


Link to post
Share on other sites

Ale szukasz informacji o programowym generowaniu sygnału czy raczej informacji o wykorzystaniu któregoś timera i przerwań do tego?

Udostępnij ten post


Link to post
Share on other sites

No ale przecież jedyną konieczną i wystarczjącą zarazem informację dostałeś powyżej: masz generować impuls o długości od 0.5 do 1.5ms co 20ms.

Czego jeszcze potrzebujesz, albo inaczej: czego chcesz się nauczyć konkretnie? Bo Twój kod który pokazałeś generuje już impuls, tylko ze złym okresem powtarzania. Skróć przerwę do takiej, by okres był zawsze w okolicach 20ms np. tak:

- ustaw jedynkę na wyjsciu,
- czekaj N mikrosekund (od 500 do 1500),
- ustaw zero,
- czekaj 20000-N mikrosekund

i tak w kółko.

Jeśli chcesz serwem poruszać, zmieniasz N w zadanych granicach.

A jeśli procesor ma robić jeszcze coś innego (bo w tych przykładach jedno serwo zabiera mu 100% czasu), zaprzęgnij do roboty timer i jego generator sygnałów PWM. Wymyśl może jakiś praktyczny przykład czegoś, czego nie umiesz zrobić (a próbowałeś). Opisz go i pokaż gdzie poległeś, słowem - wysil się bardziej.

Udostępnij ten post


Link to post
Share on other sites
Ale szukasz informacji o programowym generowaniu sygnału czy raczej informacji o wykorzystaniu któregoś timera i przerwań do tego?

Chciałbym się dowiedzieć jak ustawić serwo np w położeniu 45 st bez użycia biblioteki.

[ Dodano: 21-02-2018, 22:46 ]

No ale przecież jedyną konieczną i wystarczjącą zarazem informację dostałeś powyżej: masz generować impuls o długości od 0.5 do 1.5ms co 20ms.

Czego jeszcze potrzebujesz, albo inaczej: czego chcesz się nauczyć konkretnie? Bo Twój kod który pokazałeś generuje już impuls, tylko ze złym okresem powtarzania. Skróć przerwę do takiej, by okres był zawsze w okolicach 20ms np. tak:

- ustaw jedynkę na wyjsciu,
- czekaj N mikrosekund (od 500 do 1500),
- ustaw zero,
- czekaj 20000-N mikrosekund

i tak w kółko.

Jeśli chcesz serwem poruszać, zmieniasz N w zadanych granicach.

A jeśli procesor ma robić jeszcze coś innego (bo w tych przykładach jedno serwo zabiera mu 100% czasu), zaprzęgnij do roboty timer i jego generator sygnałów PWM. Wymyśl może jakiś praktyczny przykład czegoś, czego nie umiesz zrobić (a próbowałeś). Opisz go i pokaż gdzie poległeś, słowem - wysil się bardziej.

Super. Dziękuję!

Udostępnij ten post


Link to post
Share on other sites

Jak już pisał marek1707, trzeba wystawić na porcie sterującym stan wysoki przez około 1250 mikrosekund i powtarzać to co około 20 milisekund. Jeśli chcesz przy tym wykonywać jeszcze coś, to obawiam się, że nie obejdzie się bez przerwań/timerów.

A można spytać, w czym przeszkadza Ci gotowa biblioteka? Czy to tylko takie eksperymenty?

Udostępnij ten post


Link to post
Share on other sites

Pracując z serwami modelarskimi tj. sterowanymi sygnałem PWM 0.5-1.5ms/50Hz masz dwa problemy:

- nie wiesz jaki jest zakres kątów wychyleń,
- musisz sygnał nadawać ciągle.

Pierwsze skutkuje tym, że w zasadzie dla każdego typu serwa musisz sobie zrobić kalibrację, czyli wysłać najpierw sygnał 0.5ms a potem 1.5ms i zobaczyć gdzie znalazł się wał serwa. Możesz - ale to już na własną odpowiedzialność - przekroczyć podane granice i wyjechać np. do 0.3ms w jedną i 2ms w drugą stronę. Jeżeli będziesz miał szczęście, serwo się nie spali a Ty dostaniesz "darmowy" trochę szerszy zakres wychyleń. W zasadzie serwa nie muszą wychylać się więcej jak o ±60-70° od tzw. neutrum, bo szersze zakresy są w modelarstwie bezużyteczne. Tak więc po wysłaniu dwóch skrajnych wartości dostajesz dwa skrajne wychylenia i od tej pory musisz przeliczać żądany kąt (jeśli znasz go z góry) na długość impulsu. Nie jest możliwe powiedzenie z góry, że 45° od położenia centralnego to impuls o długości tyle a tyle µs.

Drugie jest o tyle ważne, że nie można powiedzieć o jednorazowym ustawieniu serwa w jakieś położenie. Ono zawsze podąża za Twoimi impulsami i nie może ich nie być. Zawsze od włączenia zasilania do jego wyłączenia musisz wysyłać informację (impulsy) o aktualnym ustawieniu wału wyjściowego.

----------------

EDIT: A jeśli już zrozumiesz jak można to fajnie zrobić i przeniesiesz kod (w sensie sposobu generacji sygnału PWM) z biblioteki do swojego programu, to będzie z biblioteką czy bez?

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites
Zawsze od włączenia zasilania do jego wyłączenia musisz wysyłać informację (impulsy) o aktualnym ustawieniu wału wyjściowego.

W większości przypadków jest to prawda, ale:

* Niektóre serwa cyfrowe nie wymagają ciągłego impulsu i "pamiętają" ostatni. W końcu mają na pokładzie nie prymitywny komparator, a normalny mikrokontroler i mogą tam mieć zaprogramowane cokolwiek. Natknąłem się już na takie i zepsuły mi projekt, bo akurat chciałem wykorzystać tę cechę serw, bo:

* Można to wykorzystać do oszczędzenia prądu/zmniejszenia hałasu/zmniejszenia zużycia, wysyłając do serwa sygnał tylko wtedy, gdy chcemy by się ruszało i/lub trzymało pozycję. Przykładowo w moich robotach przestaję nadawać sygnał do serw gdy wykryję niski stan baterii — robot wtedy "siada", ale przynajmniej bateria się nie rozładuje za bardzo aż robota wyłączę. Użyłem tego także w moim projekcie mechatronicznych uszu, które się poruszają gdy ruszamy głową — ciągłe brzęczenie serw byłoby irytujące, a uszy są na tyle lekkie, że serwo trzyma pozycję samymi oporami przekładni.

Udostępnij ten post


Link to post
Share on other sites

A można spytać, w czym przeszkadza Ci gotowa biblioteka? Czy to tylko takie eksperymenty?

No właśnie eksperymenty :)

[ Dodano: 21-02-2018, 23:25 ]

Pracując z serwami modelarskimi tj. sterowanymi sygnałem PWM 0.5-1.5ms/50Hz masz dwa problemy:

- nie wiesz jaki jest zakres kątów wychyleń,
- musisz sygnał nadawać ciągle.

Pierwsze skutkuje tym, że w zasadzie dla każdego typu serwa musisz sobie zrobić kalibrację, czyli wysłać najpierw sygnał 0.5ms a potem 1.5ms i zobaczyć gdzie znalazł się wał serwa. Możesz - ale to już na własną odpowiedzialność - przekroczyć podane granice i wyjechać np. do 0.3ms w jedną i 2ms w drugą stronę. Jeżeli będziesz miał szczęście, serwo się nie spali a Ty dostaniesz "darmowy" trochę szerszy zakres wychyleń. W zasadzie serwa nie muszą wychylać się więcej jak o ±60-70° od tzw. neutrum, bo szersze zakresy są w modelarstwie bezużyteczne. Tak więc po wysłaniu dwóch skrajnych wartości dostajesz dwa skrajne wychylenia i od tej pory musisz przeliczać żądany kąt (jeśli znasz go z góry) na długość impulsu. Nie jest możliwe powiedzenie z góry, że 45° od położenia centralnego to impuls o długości tyle a tyle µs.

Drugie jest o tyle ważne, że nie można powiedzieć o jednorazowym ustawieniu serwa w jakieś położenie. Ono zawsze podąża za Twoimi impulsami i nie może ich nie być. Zawsze od włączenia zasilania do jego wyłączenia musisz wysyłać informację (impulsy) o aktualnym ustawieniu wału wyjściowego.

----------------

EDIT: A jeśli już zrozumiesz jak można to fajnie zrobić i przeniesiesz kod (w sensie sposobu generacji sygnału PWM) z biblioteki do swojego programu, to będzie z biblioteką czy bez?

Badzo Ci dziękuję za szczegółowe wyjaśnienia!

Ps. Będzie chyba z biblioteką bo ogólnie lubię upraszczać rzeczy :)

[ Dodano: 21-02-2018, 23:28 ]

Zawsze od włączenia zasilania do jego wyłączenia musisz wysyłać informację (impulsy) o aktualnym ustawieniu wału wyjściowego.

* Można to wykorzystać do oszczędzenia prądu/zmniejszenia hałasu/zmniejszenia zużycia, wysyłając do serwa sygnał tylko wtedy, gdy chcemy by się ruszało i/lub trzymało pozycję. Przykładowo w moich robotach przestaję nadawać sygnał do serw gdy wykryję niski stan baterii — robot wtedy "siada", ale przynajmniej bateria się nie rozładuje za bardzo aż robota wyłączę. Użyłem tego także w moim projekcie mechatronicznych uszu, które się poruszają gdy ruszamy głową — ciągłe brzęczenie serw byłoby irytujące, a uszy są na tyle lekkie, że serwo trzyma pozycję samymi oporami przekładni.

Ciekawe spostrzeżenia. Dziękuję! :)

Udostępnij ten post


Link to post
Share on other sites

To nawiązując do tego co pisał marek1707 dodam, że najczęściej bawię się z SG90 i MG90 i do robota kroczącego zmuszony byłem stworzyć tablicę poprawek przeliczających moje kąty na to jak te kąty "wyobrażało" sobie serwo. Zwłaszcza najtańszy import z Kraju Środka może wykazywać dziwne zachowania ;).

Mam też mikroserwo przeznaczone do poruszania chwytakiem które ma kąt maksymalny 90 stopni. O mało go nie spaliłem :).

Udostępnij ten post


Link to post
Share on other sites

Faktycznie generowanie odpowiedniego PWM do sterowania serwem za pomocą delay jest bardzo proste ale rozumiem też dlaczego jest mało praktyczne. Próbuję więc zrozumieć o co chodzi z tymi timerami, żeby nauczyć się zmieniać odpowiednio częstotliwość i okres sygnału PWM. Niezłe wprowadzenie jest tutaj https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM ale i tak chętnie poczytałbym coś dla bardziej opornych ;-)

Czy któryś z kolegów mógłby wyjaśnić jak zmodyfikować konkretnie timer żeby uzyskać jedynkę przez 15us przy okresie 20ms? Konkretnie:

1. Który pin i który timer najlepiej wybrać i dlaczego?

2. Który z 4 trybów PWM będzie właściwy i dlaczego? Np fast PWM czy inny?

3. Jak wyliczyć prescaler value żeby uzyskać pożądaną częstotliwość i okres?

...no a jakby któremuś z kolegów chciało się napisać na koniec przykładowy kod realizujący powyższe to od razu stawiam sześciopak :-D

Udostępnij ten post


Link to post
Share on other sites

Gdyby było rozwiązanie "naj", to nikt nie stosowałby innych :). Wszystko zależy od tego co chcesz zrobić. Moim zdaniem, warto zacząć od analizy rozwiązania zastosowanego w oryginalnej bibliotece sterującej serwem servo.h. Jest proste i skuteczne. Zabawa z modyfikacjami PWM w Arduino by sterować serwem skazana jest na męki, jeśli nie na porażkę.

Udostępnij ten post


Link to post
Share on other sites
Gdyby było rozwiązanie "naj", to nikt nie stosowałby innych :). Wszystko zależy od tego co chcesz zrobić.

- ale ja napisałem - chciałbym uzyskać jedynkę przez 15us przy okresie 20ms

Moim zdaniem, warto zacząć od analizy rozwiązania zastosowanego w oryginalnej bibliotece sterującej serwem servo.h. Jest proste i skuteczne. Zabawa z modyfikacjami PWM w Arduino by sterować serwem skazana jest na męki, jeśli nie na porażkę.

- ponieważ co jakiś czas przy różnych okazjach wraca temat timerów, przerwań i innych tego typu wynalazków więc postanowiłem "przerwać" mój aktualny proces zabawy robotem i spróbować zrozumieć o czym mowa. Uznałem (być może błędnie), że niezłym początkiem będzie właśnie modyfikacja PWM. Tak czy inaczej czasami dopada mnie potrzeba zrozumienia "o co chodzi" i tak jest właśnie z tym tematem. Tak więc nawet jeśli modyfikowanie PWM by sterować serwem jest drogą przez mękę to chętnie ją podejmę w celach szkoleniowych :) - no chyba, że lepiej zacząć naukę timerów od czegoś innego - to wtedy będę wdzięczny za sugestie.

Udostępnij ten post


Link to post
Share on other sites
- ale ja napisałem - chciałbym uzyskać jedynkę przez 15us przy okresie 20ms

Na to masz już rozwiązanie z delay. Pytanie brzmi, co więcej chcesz uzyskać. Do testera serwomechanizmów powyższe rozwiązanie wystarczy. Do robota machającego kilkoma serwami równolegle z silnikami, czujnikami i jeszcze co tam wymyślisz już nie. I wtedy trzeba sięgnąć do innych rozwiązań. Dlatego pytam, co chcesz zrobić.

Z oryginalnym PWM-em Arduino jest ten problem, że wypełnienie określa się liczbą 8 bitową. Gdybyś nawet uzyskał okres równy 20ms, to rozdzielczość wyniosłaby 20ms/256 czyli skok co około 78us. A to, jeśli dobrze liczę, dałoby Ci dokładność ustawienia serwa około 14 stopni. Myślę, że to Cię nie satysfakcjonuje.

Na początek poczytaj w nocie katalogowej o tym jakie timery masz do dyspozycji. Poczytaj też o przerwaniach wewnętrznych. Jak to będziesz wiedział, to spróbujemy zrobić kolejny krok.

Udostępnij ten post


Link to post
Share on other sites

Bądź aktywny! Zaloguj się lub utwórz konto

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto

Zarejestruj nowe konto, to proste!

Zarejestruj nowe konto

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się

×