Skocz do zawartości

Sterowanie serwem BEZ biblioteki


Pomocna odpowiedź

Napisano

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);

}

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

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?

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

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.

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ę!

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?

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
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.

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ę! 🙂

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 🙂.

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 😃

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ę.

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.

- 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.

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

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

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...