Kręć, się kręć czyli serwo HXT900 z continuous rotation
Serwomechanizmy takie jak mały HXT 900 są sterowane szerokością impulsu PWM. Czyli podłączamy zasilanie, masę i wyjście cyfrowe PWM do serwa i jeżeli skorzystamy z biblioteki Servo wchodzącej w skład Arduino IDE wystarczy napisać do serwa wartość od 0 do 180 określającą jak daleko ma się wychylić.
Dzięki niewielkiej przeróbce HXT900 można zmienić w silniczek którego prędkość obrotową można regulować w prosty sposób przez bibliotekę Servo, bez konieczności korzystania z układów elektronicznych do zasilania i sterowania silnikiem. Nazywane to jest continuous rotation.
Zacznijmy od demontażu serwa, przy okazji zobaczymy jak serwo działa. Najpierw – co będzie potrzebne do tej operacji?
Czyli – mały śrubokręt, gwóźdź do poszerzenia na gorąco otworu na ośkę (może być śrubka o odpowiedniej średnicy), pilnik do metalu (podejrzewam, że papier ścierny w zupełności też wystarczy), szczypce boczne, lutownica i topnik.
Bierzemy serwo i odkręcamy śrubki na dole obudowy:
Następnie zdejmujemy górną i dolną część obudowy:
W dolnej części widać silnik oraz elektronikę sterującą całością, w górnej oś potencjometru, na której wraz z pomocniczą ośką osadzone są cztery kółka zębate:
Jak właściwie działa serwo?
Teraz można łatwo zrozumieć jak działa taki serwomechanizm. Ośka w złotym kolorze (ta z prawej na zdjęciu) jest jednocześnie osią potencjometru. Koło najwyżej na tej osi jest osadzone bez luzów i gdy obraca się razem z nim kręci się oś potencjometru. Zmieniające się napięcie na potencjometrze odczytuje sterownik na dole serwa. Porównując odczyt z zadaną wartością (poprzez szerokość impulsu PWM) steruje obrotami i kierunkiem pracy silnika, tak aby potencjometr przyjął odpowiednią pozycję.
Ostatnie koło zębate (to przymocowane na sztywno do ośki potencjometru) jednocześnie wystaje na zewnątrz obudowy i mocuje się do niego orczyki, które są w zestawie. Dzięki temu serwo 'wie’ jak daleko jest wychylone i jak ma się zachować w zależności od sygnału sterującego.
Jeżeli teraz ogłupimy serwo, tak, że będzie myślało, że potencjometr jest w pozycji połowa wychylenia a zmiana położenia orczyku nie będzie dawała informacji do sterownika to przy zmieniającym się sygnale sterującym silnik serwa będzie kręcić się w jedną lub drugą stronę z prędkością tym większą im większa będzie odległość zadanego wychylenia od odczytu (nieruchomego) potencjometru.
Zaczynamy od demontażu całego mechanizmu. Uwaga – zaznacz, zapamiętaj które koło zębate jest w którym miejscu, bo potem musisz całość złożyć! Ponadto wewnątrz mechanizmu znajduje się smar, więc trzeba to robić na jakiejś podkładce aby nie pobrudzić podłoża.
Metalowa, pomocnicza ośka jest wsadzona luźno w otwór w obudowie, więc nie ma problemu z jej wyjęciem, potencjometr wyjmujemy na siłę, ciągnąc za najwyższe koło – uwaga – nie szarpnij zbyt mocno bo możesz urwać kable przylutowane do potencjometru.
W tym celu musimy pozwolić kręcić się swobodnie ostatniemu kołu zębatemu (temu osadzonemu na sztywno na osi potencjometru). I tutaj pojawia się pierwsza rzecz którą musimy zmienić:
Jak widać koło ma blokadę mechaniczną, zapobiegającą zbyt dalekiemu wychyleniu – trzeba szczypcami bocznymi obciąć wystającą część plastiku – prosta sprawa.
Po demontażu kół potrzebujemy znaleźć pozycję 90. W tym celu podłączamy do Arduino serwomechanizm – czerwona żyłka do zasilania (5V), żółta do wyjścia cyfrowego 9 a brązowa do masy. W Arduino wpisujemy następujący szkic:
#include <Servo.h> Servo s; void setup(){ s.attach(9); } void loop() { s.write(90); };
Ma on za zadanie ustawić serwomechanizm w pozycję środkową. Jednak nie ma sprzężenia zwrotnego z potencjometru, więc silnik będzie pracował ze stałą prędkością. Jak teraz pokręcicie potencjometrem, zobaczycie jak w okolicy zadanej przez szkic pozycji prędkość silnika zmniejszy się aż wreszcie stanie. Szukamy właśnie tej pozycji – gdy silnik nie pracuje (i nie rusza się przez dłuższą chwilę, bo przy wartościach brzegowych może lekko zacząć się ruszać) unieruchamiamy ośkę potencjometru. Można użyć kleju, ja jednak preferuję cynę (kleje typu Kropelka mogą być naprawdę niebezpieczne, zwłaszcza jak masz w domu małe dzieci) i zalutować oś, tak aby nie mogła się kręcić:
Widać wyraźnie co się dzieje, gdy za mocno szarpniemy potencjometrem ;)
Teraz ostatnie sprawa – ostatnie koło zębate jest osadzone bardzo ciasno na osi potencjometru – tak aby nie było poślizgu i potencjometr się obracał razem z orczykiem serwa. Musimy teraz pozwolić się kołu obracać swobodnie.
W tym celu najpierw cienkim śrubokrętem oraz nożem hobby poszerzyłem lekko otwór w kole zębatym, następnie nad kuchenką gazową rozgrzałem mały gwóźdź o średnicy zbliżonej do osi potencjometru i poszerzyłem dalej otwór. Jeżeli zrezygnujesz z mechanicznego poszerzania na rzecz tylko rozgrzanego gwoździa – to trzeba uważać, aby nie skrzywić osi otworu. Jeżeli to zrobisz wówczas koło nie będzie się obracało równomiernie i całość może się po prostu zaciąć.
Aby zapewnić swobodny obrót koła trzeba też lekko zeszlifować oś (chyba że gwóźdź był wyraźnie szerszy od osi potencjometru). Użyłem pilnika do metalu, choć oś jest wykonana z miękkiego metalu, więc podejrzewam, że nie będzie problemu jeśli użyje się papieru ściernego:
Teraz pozostaje złożyć całość:
Co dalej?
Trzeba sprawdzić czy dobrze ustawiliśmy potencjometr i czy działa zgodnie z naszym oczekiwaniem. Wgrywamy prosty szkic, ja użyłem Nettigo Keypada, ale można zrobić prostą klawiaturę z dwóch przycisków. Po naciśnięciu przycisku zmienia się wychylenie serwa, czyli prędkość i kierunek obrotów.
Szkic na starcie ustawia serwo w pozycji 90. Jeżeli nasz potencjometr był dobrze ustawiony podczas lutowania, wówczas serwo nie powinno pracować. Przyciski góra/dół zmieniają ustawienie serwa o jedną pozycję. W pętli sprawdzamy czy jest wciśnięty klawisz, jeżeli tak to zmieniamy wartość na jaką serwo zostanie ustawione.
Jak to wygląda w rzeczywistości? A na przykład tak:
Jak widać serwo ma tylko kilka stopni prędkości, ale do prostych zastosowań się nadaje.
Jeżeli nie przeprowadzimy pozycjonowania potencjometru a tylko ustawimy go „na oko„, wówczas może się okazać, że pozycja stop wypada np nie przy 90 a przy 70. Na dodatek może się okazać, że pozycji zero nie ma :) i że jeżeli miało być to 90 to okaże się że silnik minimalnie kręci się w jedną stronę przy 89 a w drugą przy 90 (zero wypada gdzieś pomiędzy 89 a 90).
Jeżeli możesz sprawdzić serwo i sobie to ustawić pozycję zero we własnym szkicu – nie ma problemu, można zrezygnować z pozycjonowania potencjometru.
Jeszcze sam szkic użyty w tym przykładzie do odnalezienia pozycji stop:
#include <NettigoKeypad.h> #include <Servo.h> Servo s; NG_Keypad k; int deg = 90; void setup(){ s.attach(9); Serial.begin(9600); k.register_handler(NG_Keypad::UP, up); k.register_handler(NG_Keypad::DOWN, down); }; void up(){ deg += 1; if (deg >180) { deg = 180; } Serial.println(deg); }; void down(){ deg -= 1; if (deg <0) { deg =0; } Serial.println(deg); }; void loop() { k.check_handlers(analogRead(0)); s.write(deg); delay(100); }
Używana tutaj jest biblioteka NettigoKeypad. Jej stan na chwilę obecną (IV 2011) to używalna beta.
Funkcja register_handlers
przypisuje funkcję która zostanie wywołana do klawiszy. W check_handlers
sprawdzany jest stan wejścia analogowego i jeżeli jest wciśnięty klawisz to wywoływana jest odpowiednia funkcja up()
lub down()
. Biblioteka musi się dorobić jeszcze debouncingu i kontrolowania powtarzania klawiszy. Poza tym można już jej z powodzeniem używać.
Co można z takim serwem zrobić? To już opiszę innym razem.
O, ciekawe:) Takiego rozwiązania nie widziałem jeszcze :) Zwykle w internecie jest opisane o przeróbce serwa polegającej na wywaleniu całej elektroniki i sterowaniu bezpośrednio silnikiem poprzez mostek H ;) No ale nie powiem, z tym zablokowaniem potencjometru to całkiem niezły pomysł!
tak małego serwa jeszcze nie rozbierałem, ale nie prościej jest wywalić (odłączyć elektrycznie nie koniecznie fizycznie) potencjometr i wlutować dwa rezystory z założenia trafiając w 90°?
@Kamil – po co? :) wszystko jest na miejscu :) Żeby było jasne – nie jest to moja autorska idea – pomysł pochodzi z http://letsmakerobots.com/node/4873?page=1 ale trochę trzeba było zmodyfikować, bo tam inne nieco servo było.
@wariat
Nie wiem czy prościej. Po pierwsze mało miejsca w środku,a potencjometr musi zostać, bo jego ośka jest osią serva też. Po drugie – nie wiem na ile jest tam czuła elektronika i jak bardzo dokładnie ma być 50%. I czy na pewno – może jest w fabryce kalibrowane na ustawienie 90 stopni? I każde servo może mieć nieco inną wartość podziału napięcia.
Zresztą – niech to będą 2% rezystory – jeśli trafi się najgorszy wypadek to dostaniesz 98/(98+102)= 49% [bo 100 +- 2]. Dla 5% rezystorów najgorszy przypadek to 47.5%. I teraz tylko to zależy od kontrolera w servie jaka to będzie wartość wychylenia dla napięcia.
Wszystko co piszesz to prawda, jednocześnie kiedyś kombinowałem z kolegą i właśnie tak przerobiliśmy serwo, tam też oś potencjometru była używana jako oś zębatek, ale to niczego nie utrudnia. Tylko serwo było ochanście razy większe i rezystorki się spokojnie zmieściły. Ale nie twierdzę, że to lepsza metoda, po prostu jest to metoda alternatywna ;-)
Co do rozbieżności przy 2% tolerancji … warto może użyć multimetru i problem znika ;-)
Pomysł dobry i znany lecz zobacz jak się grzeje elektronika która nie jest przystosowana do ciągłego ruchu
Witam! Może ktoś tu mi odpowie na moje pytanie:
przerobiłem serwo TowerPro SG-5010 wyjmując czarny kawałek plastiku który łączył potencjometr z zębatką. Bez niego może ona się swobodnie obracać. Jednak gdy chciałem przywrócić normalne funkcje serwa to włożyłem ten plastik ale gdy zasiliłem serwo zaczęło ono wariować (max prędkość silnika). Próbowałem wysyłać do serwa komendę obrócenia się do 90stopni ale po wysłaniu np. 91 stopni zaczęło wariować. Co mam robić?
@greenmagic
Z tego co napisałeś wynika, że potencjometr nie jest dobrze skalibrowany. Gdy włożyłeś ponownie plastik służący za blokadę, pozycja potencjometru była taka, że po wychyleniu ponad 90 stopni wartość odczytana z potencjometru wychodzi poza skalę na jaką servo było przygotowane i elektronika serva głupieje.
Może spróbuj ponownie ustawić pozycję potencjometru – nie wiem jak to servo wygląda. Spróbuj przekręcić trochę potenc. w jedną stronę i założyć plastik znowu – zobacz czy teraz 'zwariuje’ przy mniejszym czy większym wychyleniu. Jeżeli przy większym, to przekręć potencjometr znowu w tą stronę aż do poprawnego działania w całym 0-180. Jeżeli wcześniej to trzeba kręcić w drugą stronę.
Chyba jest błąd w opisie kabelków. Jest tak:”…brązowa żyłka do zasilania (5V), czerwona do wyjścia cyfrowego 9 a żółta do masy. A powinno być (tak przynajmniej jest w moim egzemplarzu i w opisach, znalezionych w necie):czerwona żyłka do zasilania (5V), żółta do wyjścia cyfrowego, brązowa do masy. W nowszej wersji tego serwa potencjometr jest plastykowy i nie daje się „usztywnić” przez lutowanie.
@Daniel
Racja. Nie wiem jak ja to napisałem. Poprawione, dzięki za zwrócenie uwagi.
Co do plastikowej ośki – zostaje tylko jakiś super glue lub inna kropelka…
Witam. Netmaniac świetny artykuł, pomógł mi przerobić Hextronika’a HX5010 tylko napotkałem na problem. Serwo działa jak ma działać, problem jest gdy serwo się zatrzyma (na 90*) po kilku minutach przeskoczy sobie o „ząbek” i tak co kilka minut przeskakuje. Czy ktoś spotkał się z takim problemem ?
Jeśli mamy dwa serva jak napisać program?
Serwa mają być podłączone do wyjść z PWMem i tworzysz dwa obiekty
Servo s1, s2
, potems1.attach(PIN_Z_PWM_GDZIE_PODPIETO_SERVO1)
i podobnie dla s2 i gotowe.Przepraszam, ale dziś serwa mogą być podłączone do dowolnego wyjścia w Arduino. Przynajmniej jeśli chodzi o standardową bibliotekę Servo.h :)
Właśnie przerobiłem 2 serwa opierając się na powyższym przykładzie. Przy 90 oba są nieruchome. Przy 91 jeden zaczyna się poruszać ale drugi dalej stoi. Przy 92 oba powoli się kręcą. Oczywiście przy tej samej wartości mają różne (niewiele ale jednak) prędkości. Chciałem zrobić coś jeżdżącego więc będzie mi robot skręcał. Jak najprościej je skalibrować? Czy pozostaje jedynie opcja rozebrania i dokładniejszego ustawienia potencjometru?
Niektórzy podłączają zamiast potencjometru 2 takie same rezystory, ale nie wiem czy to idealne rozwiązanie.
Możesz spróbować skalibrować potencjometry za pomocą jakiegoś multimetru do takich samych wartości.
Na koniec, możesz użyć dokładniejszej funkcji obsługi serwa writeMicroseconds() http://arduino.cc/en/Reference/ServoWriteMicroseconds
Tylko uważaj na podawane wartości. Z reguły 1500 odpowiada kątowi 90 stopni.
Na koniec możesz pomyśleć o jakiejś automatycznej kalibracji ruchu za pomocą czujników.
Mam takie pytanie: czy można podłączyć serwo do PCF8574?
Potrzebuje kupić takie serwo przerobione. Bęądź zlecić przerobienie na zlecenie. Oferuję 100zł