Pająk
Projekt robota wykorzystującego serwa (serwomechanizmy).
Spis treści
Do czego zmierzamy
Chodzi o stworzenie przykładowego robota używającego serw jako źródła siły mechanicznej. Dzięki temu można poznać sposób obsługi kolejnego typowego elementu, z którego buduje się mniejsze i większe maszyny. Zgodnie z nazwą zadaniem jest zbudowanie prostej maszyny kroczącej, czyli modelu pająka. Warto zwrócić uwagę, że nazwa dotyczy tylko trywialnego podobieństwa. Prawdziwe pająki, potrafiące konstruować wyrafinowane pajęczyny, czaić się na swoje ofiary, wykorzystywać zasadę obejścia (nie każdy pies potrafi ominąć płot chcąc się dostać do przedmiotu leżącego prawie z zasięgu pyska), posiadające nawet po kilkanaście par oczu, realizujące przeróżne rytuały godowe, są tak skomplikowane, że nazywanie pająkiem kilkunastu serw na zawiasach jest raczej pocieszne. Niemniej jednak od czegoś trzeba zacząć...
Mózgiem robota będzie Malina Zero W. Ponieważ pająk będzie miał 6 niezależnych nóg, a każda noga trzy stawy, będziemy potrzebowali 18 serw do zginania stawów. Zauważ, że staw nogi bez serwa pozwalającego ustawić ten staw pod zadanym kątem, ustawiałby się swobodnie w przypadkowych pozycjach i byłby mało przydatny. Z drugiej strony jeśli nogi mają być niezależne, każda musi posiadać swój własny zestaw serw. Dlatego będziemy potrzebowali tyle serw ile stawów będzie miał nasz stawonóg. Byłoby trudno samą Maliną wykonać sterowanie 18 serwami, o ile to w ogóle możliwe. Dlatego dodatkowym układem jaki zastosujemy będą płytki PCA9685 pozwalające wygodnie sterować 12 serwami na raz. Do komunikacji pomiędzy Maliną a płytkami sterowników serw posłuży łącze I²C. Poniższy film przedstawia ogólny schemat postępowania żeby sterować serwem z maliny z pośrednictwem układu PCA9685, co jak widać jest dziecinnie proste :)
Konstrukcja mechaniczna i zasada działania serwa modelarskiego
Mechanika serwa
Sygnał PWM — sterowanie serwem
Jak widać na filmie powyżej serwo posiada 3 kabelki do podłączenia.
Dwa z nich to masa (zwykle najciemniejszy kolor, czarny lub brązowy) i zasilanie (+ baterii, najczęściej czerwony przewód). Standardowym napięciem pracy serw modelarskich jest przedział od 4.8 do 6V (3-4 baterie po 1.5V). Nowsze serwa przewidują również zasilanie z pakietu 2S baterii litowych i dobrze pracują z napięciem 7.4V. Im wyższe napięcie tym szybciej serwo reaguje na zmiany i tym większą siłą dysponuje. Oczywiście przekraczanie dopuszczalnych napięć grozi spaleniem serwa. Pobierany prąd zależy obciążenia serwa i jego wielkości. Najwięcej prądu pobiera ono w sytuacji kiedy próbuje osiągnąć zadaną pozycję, a nie jest to możliwe z powodu zbyt dużego obciążenia (blokada). Jeśli przy normalnej pracy pobierany jest prąd 1A, to przy blokadzie można się spodziewać natężenia ponad dwa razy większego.
Trzeci przewód przeznaczony jest do określania pozycji ramienia roboczego (orczyka). Warto tutaj wyjaśnić, że sterowanie serwem nie polega na włączeniu, odczekaniu aż serwo się obróci i wyłączeniu. Serwo jest nieco bardziej wyszukanym elementem siłownikiem. Podajemy mu pozycję jaką ma przyjąć, a ono samo wykonuje potrzebny obrót. Można to porównać do obsługi windy gdzie wchodzimy i przyciskiem wskazujemy na jakim piętrze winda ma się znaleźć, i nie wnikamy w to, jak do tego dojdzie. Każde serwo ma określony zakres w jakim może się obracać. Niektóre potrafią przesuwać orczyk w zakresie 180°, inne w pełnym zakresie 360°. Dla nas ważne jest, że mamy zawsze do czynienia z pewnym zakresem, np. od 0°...180° i w tym przedziale możemy zażądać ustawienia orczyka. Pozostaje tylko wyjaśnienie co trzeba podać na kablu sterującym, żeby wybrać jakąś pozycję z dozwolonego przedziału.
Do sterowania pozycją stosuje się sygnał PWM (ang. pulse width modulation — sygnał o zmiennej szerokości impulsu). Przyjmuje się, że na wejściu sterującym podawana jest fala prostokątna (czyli mówiąc "po ludzku" na przemian włączone/wyłączone napięcie) o częstotliwości 50Hz, czyli w każdej 1/50 sekundy podajemy jakąś sekwencję włączenia/wyłączenia napięcia, która koduje w jakiej pozycji ma się ustawić serwo. Ponieważ 1/50 sekundy to 20ms musimy już tylko sprecyzować jak długo w tym czasie napięcie musi być wysokie, żeby serwo przyjęło odpowiednią pozycję. Umówiono się w ten sposób:
- jeśli przez 1ms sygnał jest wysoki, a przez pozostałe 19ms niski, serwo ustawi ramię w minimalnej pozycji (np. kąt obrotu 0°)
- jeśli przez 2ms sygnał jest wysoki, a przez pozostałe 18ms będzie niski, serwo przestawi się na maksymalną pozycję (np. kąt 180°)
- jeśli stan wysoki będzie trwał między 1ms a 2ms, serwo ustawi się odpowiednio na pozycji pomiędzy minimalną a maksymalną wartością wychylenia
Warto zwrócić uwagę, że jeśli w całym cyklu, który trwa 20ms, sygnał był wysoki przez 1ms, to stan wysoki zajął 5% cyklu. Podobnie w drugim przypadku, jeśli napięcie było włączone przez 2ms, to stan wysoki zajął 10% z całego 20ms cyklu. Można więc powiedzieć, że pozycja serwa jest zakodowana szerokością sygnału wysokiego.
W reakcji na zmiany szerokości sygnału między 5%...10% na przewodzie sygnałowym serwo ustawi ramię w pozycji między minimalnym a maksymalnym wychyleniem.
Wykorzystanie tylko 5% przedziału (od 5% do 10%) szerokości sygnału PWM do zakodowania pozycji serwa może wydawać się dziwne (dlaczego na przykład nie od 5% do 95%?), ale takie postępowanie powoduje, że sygnał jest odporny na zakłócenia. Jest to ważna cecha sygnałów sterujących. Mało kto chciałby zniszczyć model za 10 tys. dlatego, że serwo z powodu zakłóceń skierowało stery w ziemię.
UWAGA: O tym, że do sterowania serwa używany jest sygnał o częstotliwości 50Hz i tylko z modulacją szerokości od 5% do 10% trzeba pamiętać przy używaniu płytki PCA9685! Układ scalony, który nią steruje, nie był konstruowany specjalnie do sterowania serwami i pozwala wybrać dowolną częstotliwości (np. 1000Hz) jak i dowolną szerokości sygnału PWM między 0 a 100%. Pisząc program sterujący serwami przez płytkę PCA9685 należy więc koniecznie ustawić prawidłową dla serw częstotliwość pracy 50Hz, a potem przy kodowaniu pozycji serwa nie ustawiać szerokości sygnału spoza zakresu 5%..10%.
Jak szybko działa serwo?
Poglądowo prędkość reakcji serw przedstawiają filmy na tej stronie. Dokładne prędkości zależne są od konstrukcji i wysokości napięcia zasilającego. Serwa szybkie są wyraźnie droższe i około 2 razy szybsze od serw przeciętnych. Orientacyjnie można przyjąć, że serwo potrzebuje mniej więcej 2ms na wykonanie obrotu o 1°. Jeśli więc zmienimy skokowo szerokość sygnału z 5% na 10%, czyli z początkowej skrajnej pozycji przeskoczymy do skrajnej końcowej, wówczas jeśli serwo ma zasięg 180° będzie potrzebowało około 1/3 sekundy (360ms) na wykonanie tego ruchu. Ponieważ mrugnięcie oka trwa około 150ms można powiedzieć, że serwo potrzebuje mrugnięcia oka na zmianę pozycji o kąt prosty.
Łącze I²C
I²C pozwala połączyć układy cyfrowe (dwa lub więcej) dając im możliwość wymiany informacji pomiędzy sobą. Jest ono powszechnie używane we współczesnej elektronice. Na przykład w telefonach komórkowych główny procesor odczytuje informacje i steruje pracą układu scalonego z akcelerometrem przy pomocy tego połączenia. Jego zaletą jest względnie duża prędkość przesyłania danych (setki tysięcy bitów/s) oraz oszczędność ponieważ wymaga tylko dwóch przewodów: - SCL — czyli linii taktującej transmisję (ten sygnał synchronizuje układ nadawczy i odbiorczy) - SDA — czyli linii transmisji danych (tędy, w rytm linii SCL, słane są kolejne informacje)
Malina ma wyprowadzoną linię I²C na złącze 40-pinowe, ale domyślnie jego obsługa jest wyłączona. Żeby ją włączyć korzystamy z konfiguratora
sudo raspi-config
i w nim wybieramy Interfacing options, a potem I2C które włączamy i wychodzimy z programu.
Do pracy z łączem I²C przydatne nam będą również programy narzędziowe przeznaczone dla konsoli. Instalujemy je poleceniem:
sudo apt install i2c-tools
Jeśli wszystko przebiegło pomyślnie (możliwe, że będzie potrzebny restart maliny) powinniśmy być w stanie wyświetlić wszystkie urządzenia podłączone do linii I²C numer 1 poleceniem:
i2cdetect -y 1
które powinno wyświetlić następującą tabelkę:
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
Oczywiście ponieważ nie podłączaliśmy jeszcze żadnego urządzenia do linii 1 lista jest pusta. Jednak jej pojawienie się pokazuje, że obsługa I²C jest prawidłowo skonfigurowana. Teraz można zacząć z tej linii korzystać podłączając zewnętrzne urządzenia do maliny i komunikować się z nimi.
Minimum wiedzy o adresach urządzeń
Jak widać polecenie i2cdetect
wyświetla dużą tabelę zamiast po prostu poinformować czy coś jest podłączone do wyjścia I²C czy nie. Dlaczego tak się dzieje? Odpowiedź jest prosta:
Standard I²C przewiduje możliwość podłączenia do tej samej linii wielu urządzeń na raz.
Skoro na tej samej linii może być wiele urządzeń jeśli dwa z nich chcą wymieniać dane musi być jakiś sposób wskazania, dla którego urządzenia przeznaczone są posłane na linię informacje. Z tego powodu każde urządzenie na linii I²C musi mieć swój indywidualny numer, który z racji podobieństwa w sposobie użycia nazywa się adresem. Jeśli urządzenie nadające wysyła paczkę danych dodaje do niej zawsze adres urządzenia, które ma je odebrać.
Na liniach I²C dane posyła się w bajtach, czyli porcjach po 8 bitów. Z tego powodu umówiono się, że adres będzie także numerem, który da się zapisać w jednym bajcie. Ponieważ na 8 bitach da się zapisać 256 różnych kombinacji można by się było spodziewać, że na jednej linii może działać do 256 różnych urządzeń. Jednak dla uproszczenia całego protokołu transmisji zdecydowano się "poświęcić" jeden bit adresu do innego celu. Zarezerwowano go do przesłania informacji, czy wysłana pod wskazany adres porcja danych ma być po prostu zapisana w docelowym urządzeniu, czy stanowi prośbę o odesłanie jakichś informacji, na które wskazują wysłane dane (np. urządzenie 27 odeślij mi dane z rejestru mierzącego przyśpieszenia). Tym bitem określającym zapis/odczyt jest najmłodszy bit bajtu adresowego. Na czysty adres pozostaje więc 7 bitów, co daje możliwość podłączenia na jednej linii 128 rozróżnialnych urządzeń.
Dla wygody program i2cdetect
wyświetla listę urządzeń podłączonych do linii I²C w postaci tabeli — dzięki temu 128 adresów mieści się na połowie typowej konsoli a nie ciągnie przez kilka ekranów. 3 górne bity adresu numerują wiersze tej tabeli, 4 dolne numerują kolumny. Rysunek obok pokazuje ten schemat.
Urządzenia, które komunikują się po linii I²C często mają ustawiony domyślny adres, pod którym będą się zgłaszały. Często jednak zdarza się, ze chcemy dwa takie same urządzenia podłączyć do jednej linii I²C i wówczas przydatna jest opcja zmiany adresu domyślnego. Producenci urządzeń I²C mają tego świadomość i dlatego większość z nich dopuszcza taką możliwość. Podobnie jest w przypadku omawianej niżej płytki PCA9685 co również przedstawia rysunek obok.
Moduł z układem PCA9685
Opis modułu
Najbardziej kolorową i rzucającą się w oczy częścią modułu (p. niżej na zdjęcie przedstawiające połączenie maliny z płytką) jest rząd 16, w grupach po 4, potrójnych pinów do podłączania serw. Jak zwykle w przypadku serw pin czarny oznacza masę, czerwony napięcie zasilania, a żółty linię sterującą, na której podawany jest sygnał PWM. Jeśli kabelek serwa nie ma dokładnie tych samych kolorów można się zwykle kierować jasnością kolorów. Czarny bywa zastępowany brązowym, żółty białym, stosunkowo najrzadziej zmieniany jest kolor czerwony. Jeśli kabel serwa ma zupełnie inne kolory najlepiej upewnić się w jego specyfikacji jak producent rozmieścił wyjścia i ewentualnie dopasować ich rozkład do płytki PCA9685 przekładając styki we wtyczce.
Na krótszych brzegach płytka ma wyprowadzone wyjścia, którymi możemy ją połączyć z maliną oraz następnymi płytkami PCA9685:
- GND — masa zasilania
- OE — podanie stanu wysokiego, odłączy wszystkie wyjścia
- SCL i SDA — linie zegarowa i danych magistrali I2C
- VCC — zasilanie częsci logicznej 3-5V
- V+ — zasilanie serw, max 6V; nie należy przeciążać tego pinu (parz niżej)
Choć łącze na brzegu płytki posiada pin V+ przeznaczony jako źródło zasilania dla silników serw, przy dużej ilości serw, albo dla dużych serw wymagających większej mocy, żeby dostarczyć napięcie zasilania części mechanicznych lepiej skorzystać z zielonego łącza w centralnej części płytki. Pozwala ono podłączyć grubsze przewody i dobrze je przymocować przykręcanymi stykami. Dobre połączenie i grubsze przewody pozwolą uniknąć strat napięcia zasilania. W przypadku pinu V+ możemy przyjąć, że ogólny opór tego połączenia wynosi około 0.02Ω gdybyśmy więc chcieli przez nie zasilać 16 serw, każde po 1.5 A, przez pin płynąłby prąd 24A. Z prawa Ohma możemy policzyć, że w takim przypadku na tym połączeniu wystąpiłby spadek napięcia
Czyli napięcie spadłoby o prawie 10% jeśli zasilalibyśmy serwa ze źródła 6V! Żeby tego uniknąć lepiej korzystać z przeznaczonego dla dużych prądów podłączenia w środku płytki. Po jednej stronie tego łącza znajduje się napis GND oznaczający gdzie należy połączyć ujemny biegun baterii (lub innego zasilacza).
Połączenie maliny z modułem
Podłączenie jednego modułu PCA9685 do maliny nie jest skomplikowane ponieważ wszystkie niezbędne sygnały znajdują się na 40-pinowym złączu. Jedyne czego potrzebujemy to pięciożyłowy kabelek z końcówkami BLS. Po połączeniu i włączeniu maliny do zasilania na płytce PC9685 powinna się zapalić dioda wskazująca na obecność zasilania płytki. Żeby sprawdzić czy połączenie I²C również działa i możliwe jest sterowanie płytką możemy posłużyć się znanym poleceniem i2cdetect -y 1
, które tym razem powinno wykryć obecność płytki PCA9685 na linii I²C pod jej standardowym adresem 0x40:
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: 70 -- -- -- -- -- -- --
W przypadku kiedy na jednej linii I²C musimy używać więcej niż jednej płytki (np. dlatego, że mamy więcej niż 16 serw) muszą się one różnić swoim adresem. Jak zmienić w dodatkowych płytkach domyślny adres x40 na inny pisaliśmy wyżej w części o adresach urządzeń w połączeniu I²C.
Sterowanie serwem za pośrednictwem układu PCA9685 w pythonie
Do pracy z układem PCA9685 użyjemy modułu adafruit-pca9685
, który zawiera różne funkcje pozwalające wykorzystywać możliwości chipa PCA9685 bez wnikania w szczegóły jego działania z poziomu kodu zapisanego w pythonie. Moduł można zainstalować korzystając z menadżera pakietów pythona pip poleceniem:
sudo pip install adafruit-pca9685
Przykładowy kod pythona korzystający z tego modułu można zobaczyć na stronie projektu Adafruit_Python_PCA9685. Program ten przestawia serwo podłączone do kanału 0 płytki PCA9685 między dwoma pozycjami co sekundę (jego działanie widać na końcu filmu z początku strony).