Ta strona używa ciasteczek (plików cookies), dzięki którym może działać lepiej. Dowiedz się więcejRozumiem i akceptuję
Kurs Raspberry Pi!Jesteś zainteresowany kursem Raspberry Pi? Wybierz najciekawsze tematy, które opiszemy »

Kurs Arduino – #5 – PWM, serwomechanizmy, biblioteki

Programowanie 12.06.2015 Damian (Treker)

ardKurs_5Poprzednia część omawiała przetwornik ADC. Tym razem pójdziemy w drugą stronę i zajmiemy się generowanie specyficznego sygnału.

Mowa o PWM – modulacji szerokości impulsu. Zagadnienie to może brzmieć skomplikowanie, jednak kilka praktycznych przykładów na pewno rozwieje wszelkie wątpliwości!

Nawigacja serii artykułów:
« poprzednia częśćnastępna część »

Kup zestaw elementów i zacznij naukę w praktyce! Przejdź do strony dystrybutora »

Czym jest sygnał PWM?

Załóżmy, że do mikrokontrolera podłączyliśmy diodę świecącą i zaczęliśmy migać nią w pętli. Dioda jest włączona przez sekundę, a przez kolejną pozostaje wyłączona i tak w koło:

Gdybyśmy narysowali wykres zmiany napięcia (od czasu) na pinie trzecim Arduino otrzymamy przebieg prostokątny:

Przebieg prostokątny generowany przez Arduino.

Przebieg prostokątny generowany przez Arduino.

Wartość zaznaczona jako x, to czas, w którym dioda świeci. Natomiast T, to okres z jakim migamy LEDem. Z kolei jego odwrotność, czyli 1/T oznacza częstotliwość. Stosunek czasu, gdy dioda świeci, do czasu gdy jest wyłączona wynosi 1:1. Innymi słowy, pozostaje ona włączona jedynie przez 50% działania programu. Fachowo parametr ten nazwiemy wypełnieniem sygnału.

Podsumowując informacje o naszym sygnale:

  1. Amplituda (maksymalna wartość): 5V
  2. Okres sygnału: 2 sekundy
  3. Częstotliwość sygnał: 1/2 = 0,5 Hz
  4. Wypełnienie sygnału: 50%

Teraz pora na podobny eksperyment. Jednak ze zmienionym wypełnieniem, przy zachowaniu poprzedniego okresu. Jak to zrealizować? Wystarczy wydłużyć czas świecenia diody jednocześnie skracając czas, gdy jest ona wyłączona. Przykładowo:

Tym razem dioda włączona jest przez około 5/6 czasu. Czyli wypełnienie wynosi około 83%. Przedstawiając sytuację na analogicznym, do poprzedniego, wykresie otrzymamy:

Większe wypełnienie sygnału.

Większe wypełnienie sygnału.

Gdy opóźnienia zamienimy miejscem otrzymamy sytuację odwrotną, czyli sygnał o wypełnieniu 17%. Ostatni już wykres:

Małe wypełnienie sygnału.

Małe wypełnienie sygnału.

Spójrz jeszcze raz na powyższe przykłady. Który z parametr zmieniał się za każdym razem? Odpowiedź jest prosta: wypełnienie. Częstotliwość przebiegów pozostawała taka sama.

Mówiąc bardziej praktycznym językiem zmieniał się tylko „procent czasu przez jaki sygnał ma potencjał wysoki„.

Teraz wyobraź sobie, że opóźnienia wstawione w powyższych programach są znacznie mniejsze, dzięki czemu częstotliwość sygnału jest znacznie większa…

Gratulacje! Właśnie zrozumiałeś w praktyce zasadę działania PWM. Czyli metodę modulacji sygnału prostokątnego poprzez regulację szerokości impulsu.

Pewnie myślisz sobie teraz: Świetnie, ale do czego to potrzebne?

Wyobraź sobie silnik sterowany przełącznikiem. Czy w momencie włączenia zasilania silnik natychmiast osiąga swoje maksymalne obroty? Nie, najpierw musi się rozpędzić. To samo tyczy się stopniowego zatrzymywania. Co stanie się, gdy zasilanie do takiego silnika będziemy co chwile włączać i wyłączać? Jeśli operacja będzie wystarczająco szybka, to powinniśmy móc osiągnąć prędkości pośrednie między zatrzymaniem, a pełnymi obrotami. Otrzymana prędkość będzie zależała od czasu przez jaki dostarczaliśmy zasilanie do silnika.

Gdy takie włączanie i wyłączanie będzie następowało dużo szybciej, to opisywany efekt będziemy mogli wykorzystać nawet przy pozornie bardzo „szybkich” elementach – diodach świecących.

Sygnał PWM generowany przez Arduino przeważnie przełączany jest 490/sekundę.

Jakiego zastosowanie ma sygnał PWM?

Otóż w technice cyfrowej sygnał ten wykorzystywany jest bardzo często. Za jego pomocą będziesz mógł sterować jasnością świecenia diody, położeniem serwomechanizmu oraz prędkością z jaką obraca się silnik! Jak łatwo zauważysz zastosowań będzie wiele zarówno w robotyce amatorskiej, jak i podczas każdego innego majsterkowania.

Sterowanie jasnością diody LED

Pora na pierwszy, praktyczny przykład wykorzystania PWM. Tym razem zajmiemy się prostym programem, którego zadaniem będzie pulsowanie diodą.

Arduino wyposażone jest w 6 kanałów sprzętowego PWM. Każde wyjście, na którym możemy uzyskać sygnał PWM zostało oznaczone na płytce znakiem tyldy „~”, a na naszej grafice pojawił się obok niego dodatkowo dopisek PWM:

ArduinoUno_pinout

Sprzętowo generowany PWM oznacza, że wytwarzanie tego sygnału nie wpływa na pracę programu (nie opóźnia go). Nie musimy również samodzielnie pisać funkcji generujących taki sygnał.

Każdy kanał PWM dostępny w Arduino UNO jest 8-bitowy. Oznacza to, że wypełnienie sygnału, które chce my otrzymać na jego wyjściu możemy określić liczbą od 0 do 255, gdzie 255 oznacza wypełnienie 100%.

W celu przeprowadzenia pierwszego ćwiczenia konieczne jest podłączenie diody do pinu 3. Nie powinieneś mieć już problemu z samodzielnym zestawieniem układu:

Pulsowanie diodą przez Arduino - PWM.

Pulsowanie diodą przez Arduino – PWM.

Pora na stworzenie programu. Naszym celem jest napisanie kilku linijek, za pomocą których dioda będzie powoli rozbłyskiwała. Inaczej mówiąc, będziemy w pętli zmieniać wypełnienie sygnału PWM, którym będzie ona sterowana.

Mam nadzieje, że wszystko jest jasne i możemy zająć się omówieniem tylko jednej, nowej funkcji. Oczywiście chodzi o analogWrite(pin, wypełnienie). Jej zadaniem jest generowanie na wybranym pinie sygnału PWM o wybranym wypełnieniu.

Zadaniem powyższego programu jest cykliczne zwiększanie wypełnienie od zera do  momentu, gdy jego wartość będzie mniejsza od 255 (100%). Gdy osiągnięte zostanie maksymalne wypełnienie dioda zostaje wyłączona (wypełnienie 0%) i proces rozświetlania diody zostaje ponowiony.

Zadanie domowe 5.1

Spróbuj uprościć powyższy program, tak aby nie trzeba było korzystać z instrukcji warunkowej if. Podpowiedź: zastanów się jaki wpływ na działanie programu ma typ zmiennej wypełnienie.

Zadanie domowe 5.2

Napisz program, który po zwiększeniu wypełnienia do 255 zacznie je stopniowo zmniejszać do zera (i tak w koło). Sprawdź przy jakim opóźnieniu w każdym obiegu pętli można zaobserwowany efekt pulsowania będzie najciekawszy.

Pora na wykorzystanie serwomechanizmu!

Pewnie nie jeden z czytelników czekał na moment, w którym omówimy i zastosujemy w praktyce serwomechanizm. Jeśli jeszcze nie wiesz o czym dokładnie mówię, to znajdź w zestawie element identyczny (lub podobny) do poniższego:

serwo-towerpro-sg-90-micro

Serwomechanizm typu micro.

Jest to serwomechanizm typu micro, czyli jeden z najmniejszych dostępnych na rynku. Jego rozmiar nie ma jednak wpływu na sposób sterowania. Gdy zrozumiesz zasadę działania będziesz mógł wykorzystywać w swoich projektach większe, mocniejsze i szybsze serwa.

Czym jest serwomechanizm?

Serwomechanizm to silnik, przekładnia oraz dedykowany sterownika zamknięty w jednej obudowie. Napędy te nie są jednak przystosowane do wykonywania pełnego obrotu. Najczęściej serwomechanizmy mogą poruszać zamontowanym ramieniem o kąt 0-180º. Co ważne, znają one swoją aktualną pozycję, więc nie musimy obawiać się np.: narastających błędów pozycji.

Serwomechanizmy wykorzystywane są głównie w modelarstwie. Np.: do odchylania lotek. W robotyce znajdują one również wiele zastosowań o czym przekonasz się w dalszych częściach kursu.

Najważniejsze dwie zasady korzystania z serwomechanizmów:

  1. Bez potrzeby nie przekręcamy ręcznie położenia wału. Może to uszkodzić stosunkowo delikatne, plastikowe koła zębate, z których zbudowano przekładne.
  2. Nie zasilamy serw bezpośrednio ze źródła, którym zasilana jest reszta układu. Każdy silnik pobiera stosunkowo duży prąd. Szczególnie na początku ruchu. Może to zakłócić pracę pozostałych układów, a w skrajnych przypadkach doprowadzić do ich uszkodzenia.

Jak działa serwomechanizm?

Skąd serwomechanizm wie, w którą pozycje ma się obrócić? Wszystko za sprawą wbudowanego sterownika. To własnie on, na podstawie dostarczonego sygnału PWM, steruje silnikiem. Przyjętym standardem jest, że do serw dostarcza się sygnał o okresie równym 20ms.  Natomiast wypełnienie sygnału interpretowane jest jako pozycja,  w którą należy przemieścić ramię serwa.

Wypełnienie generowanego sygnału powinno mieścić się w granicach 5-10%. Wartości te zostaną przekształcone na dwie skrajne pozycje serwa (maksymalnie w lewo oraz maksymalnie w prawo).

Z każdego serwomechanizmu wyprowadzone są 3 przewody:

  1. Masa (czarny, ciemnobrązowy)
  2. Zasilanie (czerwony)
  3. Sygnał sterujący (żółty/pomarańczowy)

W zależności od producenta kolory przewodów mogą się różnić. Jednak dwa na pewno będą zbliżone do czarnego i czerwonego (zasilanie). Pozostały, trzeci będzie przewodem sygnałowym.

Zasilanie serwomechanizmu

Tak jak zostało powiedziane wcześniej, nie powinno się zasilać serwomechanizmu bezpośrednio z tego samego napięcia, które zasila mikrokontroler. Po drugie, w związku z tym, że silnik może pobierać duży prąd musimy podłączyć do układu odpowiednie wydajne źródło.

Niestety port USB,
z którego zasilaliśmy do tej pory naszą płytkę może okazać się zbyt słaby!

Dlatego po raz pierwszy Arduino zasilimy przez dołączoną do zestawu baterię 9V wraz ze klipsem, który zakończony jest wtyczką pasującą do gniazda zasilania w Arduino. Dokładny schemat podłączenia znajduje się poniżej.

Serwomechanizm w praktyce

Pora na pierwszy program, który będzie poruszał ramieniem serwa. W tym celu należy połączyć układ zgodnie z poniższym schematem montażowym. Po pierwsze konieczne jest podłączenie baterii. Po drugie musimy wykorzystać stabilizator LM7805.

Jeśli nie wiesz czym jest ten element, to koniecznie zajrzyj teraz do:
8 części kursu podstaw elektroniki!

Wejście stabilizatora łączymy z pinem Vin Arduino, masę z GND, a do wyjścia podłączamy czerwony przewód serwomechanizmu. Oczywiście konieczne są również kondensatory filtrujące. Pozostałe połączenia powinny być już jasne:

Podłączenie serwomechanizmu do Arduino.

Podłączenie serwomechanizmu do Arduino.

Pora na program, który będzie stopniowo poruszał serwem. Na początek gotowy program, poniżej znajdziesz wyjaśnienie:

Tym razem musimy dodać nową bibliotekę, która rozszerzy możliwości naszego programu o nasze funkcje. Służy do tego polecenie:

W tym wypadku dodaliśmy plik Servo.h, który zawiera dodatkowe instrukcje dla serwomechanizów. Dzięki niej nie będziemy musieli samodzielnie kontrolować generowanego sygnału PWM. Wystarczy, że podamy pozycje (kąt) do jakiej ma obrócić się serwomechanizm.

Jeżeli chcemy sterować serwem, to musimy stworzyć dla niego obiekt:

Funkcja attach(Pin) – dla obiektu Servo – działa podobnie do pinMode – argumentem jest pin, do którego podłączony jest element. Od tego momentu na danym wyprowadzeniu (w tym przypadku 9) będzie generowany sygnał PWM.

Po uruchomieniu programu serwomechanizm powinien płynnie poruszać się z jednej skrajnej pozycji do drugiej, a następnie wracać na początek. Kluczową linijką jest:

Gdzie jako pozycję musimy wpisać kąt z zakresu 0-180º.

Zadanie domowe 5.3

Na bazie powyższego programu napisz własny, który każdy kolejny przeskok do nowej pozycji wykona po dłuższym czasie (200ms, 250ms itd).

Zadanie domowe 5.4

Napisz program, który obraca serwomechanizm do pozycji przesłanej do Arduino przez UART. Przesyłane liczby musza mieścić się w zakresie 0-180, w przeciwnym wypadku należy wyświetlić stosowny komunikat.

Zadanie domowe 5.5

Do układu podłącz potencjometr w roli dzielnika napięcia. Następnie wykorzystaj przetwornik ADC  do pomiaru napięcia ustawionego na potencjometrze. Im będzie ono większe tym serwo powinno znajdować się bliżej swojej skrajnej, prawej pozycji.

Uwaga, nie podłączaj samodzielnie silników!

W tej części kursu do Arduino podłączyliśmy bezpośrednio serwomechanizm. Było to możliwe, bo napędy te mają wewnętrzne sterowniki, które kontrolują prace gołego silnika.

Dlatego z pinu Arduino, który steruje wychyleniem serwa nie jest pobierany duży prąd.

Jeśli podłączysz do Arduino samodzielnie „goły silnik”, to pobrany prąd (>20mA) uszkodzi układ! Pamiętaj, że silniki elektryczne (nawet małe) mogą wymagać do pracy prądu 10, a nawet 100 razy większego od wydajności pinów mikrokontrolera!

Do bezpośredniego podłączenia silnika konieczny jest układ pośredni, mostek-h! Więcej informacji na jego temat znaleźć można w dalszej części kursu.

Podsumowanie

Mam nadzieję, że ta część kursu pozwoliła Ci na zrozumienie czym jest sygnał PWM oraz jak można wykorzystać go w swoich projektach.

W kolejnej, dodatkowej części, zajmiemy się omówieniem kilku przydatnych trików  związanych z transmisją przez UART. Pokaże również jak w praktyce można wykorzystać serwomechanizm w roli analogowego wskaźnika oraz zademonstruję jak wykorzystać Arduino oraz układ L293D do sterowania silnika DC!

Kup zestaw elementów i zacznij naukę w praktyce! Przejdź do strony dystrybutora »

Jak zawsze czekam na Wasze komentarze i sugestie! Powodzenia w budowie własnych urządzeń, zachęcam do eksperymentowania, koniecznie w praktyce!

Autor: Damian (Treker) Szymański
Pierwsza wersja: Sławomir Kozok

P.S. Nie chcesz przeoczyć kolejnych części naszego darmowego kursu programowania Arduino? Skorzystaj z poniższego formularza i zapisz się na powiadomienia o nowych publikacjach!

Powiadomienia o nowych, darmowych artykułach!

Komentarze

hob_bit

15:01, 13.06.2015

#1

Dzięki za kolejną ciekawą lekcję i czekam na te dodatkowe przydatne triki, a najbardziej na sterowanie silnikiem DC.

Pozdrawiam hob_bit :)

MateuszW

13:15, 14.06.2015

#2

Bardzo fajnie :) czekam na ciekawostki. Może jeszcze pojawi się temat o ciekawej funkcji arduino, która zmiana go w programator ISP.

bocian

10:12, 15.06.2015

#3

Witam. Może to tylko zbieg okoliczności, ale czy servo mogę podpiąć tylko do pinów na których generowany jest sygnał PWM czy mogę podpiąć je pod dowolny pin arduino?

MateuszW

11:59, 15.06.2015

#4

bocian

możesz podpiąć pod dowolny pin, który generuje PWM :) czyli piny: 3, 5, 6, 9, 10, 11

Treker
Autor wpisu
Administrator

17:09, 15.06.2015

#5

bocian, dałoby się sterować serwomechanizmami przez inne porty, ale byłoby to bardzo utrudnione. Każde serwo wymaga swojego sygnału PWM, a ten najłatwiej generować na wyprowadzeniach ze sprzętowym wsparciem generowania takiego sygnału :)

Treker
Autor wpisu
Administrator

12:03, 23.06.2015

#6

Harmonogram najbliższych publikacji kursu Arduino:

do 28.06 - Część dodatkowa

do 02.07 - Wyświetlacze LCD

MateuszW

18:32, 23.06.2015

#7

Czekamy, czekamy :) jest może jakiś sposób na odczytanie pozycji serwa, żeby po zadaniu obrotu nie robić delay() tylko sprawdzić czy już dotarło?

Treker
Autor wpisu
Administrator

19:10, 23.06.2015

#8

MateuszW, musiałbyś dostać się do potencjometru, który jest wewnątrz serwomechanizmu i dorobić sprzężenie zwrotne. Inna opcja, to inwestycja w bardziej zaawansowane (znacznie droższe) serwomechanizmy, z którymi można się komunikować w dwie strony.

MateuszW

21:47, 23.06.2015

#9

Tak myślałem, ale miałem nadzieję, że skoro właśnie jest już potencjometr to można jednak w jakiś prosty sposób odczytać wartość. No cóż, dzięki za odpowiedź.

Treker
Autor wpisu
Administrator

21:51, 23.06.2015

#10

No niestety serwomechanizmy mają możliwość "nasłuchiwania" PWM, nie potrafią wysyłać informacji zwrotnej.

Marcin628

10:29, 24.06.2015

#11

Witam,

Gdy już jesteśmy przy zasilaniu Arduino napięciem wyższym niż 5V mam kilka pytań (zapewne oczywistych).

- Powód, dla którego dajemy stabilizator? Czy jest to dlatego, że serwo obsługiwane jest z napięciem 5V (i zostałoby spalone) czy dlatego, że przez pin analogowy bez stabilizatora również przesłoby napięcie 9V a co za tym idzie podłączając do pinu analogowego spalimy Arduino.

- Czy podłączenie koszyku na baterię 4 x 1,5V do Arduino będzie poprawnie działać? Wyczytałem, że powinno zasilać się od 7-12V by minimalny dropout był 2V.

- Chciałem zbudować sterowanie silnikiem (jak serwem) z użyciem potencjometru. Silnik to DG01D (4.5V) gdy go podłączyłem używając Arduino tylko jako zasilanie (5V), silnik działa. Niestety gdy podłączone jest z potencjometrem, kręcąc nóżkom słychać tylko "buczenie" wewnątrz silnika nic (nic się nie kręci). Czy ma na to wpływ natężenie płynące przez piny w Arduino czy może za duże napięcie czy coś jeszcze?

Z góry dziękuję za odpowiedź!

Treker
Autor wpisu
Administrator

15:16, 25.06.2015

#12

Marcin628 napisał/a:

Powód, dla którego dajemy stabilizator? Czy jest to dlatego, że serwo obsługiwane jest z napięciem 5V (i zostałoby spalone) czy dlatego, że przez pin analogowy bez stabilizatora również przesłoby napięcie 9V a co za tym idzie podłączając do pinu analogowego spalimy Arduino.

Piny analogowe, które pracują w zakresie 0-5V nie mają tutaj niż do rzeczy. Więc sprawdź, czy dobrze rozumiesz wszystkie pojęcia. Serwomechanizm zasila silnik napięciem podanym na jego czarny (masa) oraz czerwony (Vcc) przewód.

Serwomechanizm musi być zasilany z około 5V. Czyli teoretycznie moglibyśmy podłączyć go do pinów 5V wyprowadzonych z Arduino. Niestety prąd pobierany przez silnik jest duży (szczególnie przy rozruchu), wbudowany stabilizator jest zbyt słaby, aby to obsłużyć. W związku z tym powstają zakłócenia, które resetują procesor i program nie działa poprawnie.

Postaram się w ciągu kilku tygodni rozbudować tę część kursu o demonstracje takiego zjawiska. Najpierw jednak pojawią się nowe artykuły.

Marcin628 napisał/a:

- Czy podłączenie koszyku na baterię 4 x 1,5V do Arduino będzie poprawnie działać? Wyczytałem, że powinno zasilać się od 7-12V by minimalny dropout był 2V.

Niestety 6V może okazać się zbyt niskim napięciem.

Marcin628 napisał/a:

Chciałem zbudować sterowanie silnikiem (jak serwem) z użyciem potencjometru. Silnik to DG01D (4.5V) gdy go podłączyłem używając Arduino tylko jako zasilanie (5V), silnik działa. Niestety gdy podłączone jest z potencjometrem, kręcąc nóżkom słychać tylko "buczenie" wewnątrz silnika nic (nic się nie kręci). Czy ma na to wpływ natężenie płynące przez piny w Arduino czy może za duże napięcie czy coś jeszcze?

Absolutnie NIE WOLNO podłączać silnika bezpośrednio do Arduino. Jest to najprostsza droga do jego nieodwracalnego uszkodzenia. Przykład poprawnego podłączenia silnika pojawi się w kolejnej części kursu. Radziłbym do tego czasu nie robić własnych eksperymentów z napędami! Pamiętaj, że wydajność jednego pinu Arduino to około 20mA, silnik może brać 10, albo 100 razy więcej!

Marcin628

16:02, 25.06.2015

#13

Treker, Super dzięki za wyjaśnienia!

Niestety przed eksperymentami ciężko będzie mnie powstrzymać:) Silniki na razie zostawię i poczekam na kolejny artykuł.

Jeszcze takie szybkie pytania:)

- co do stabilizatora 5V, czy w układzie nie powinny znaleźć się dwa kondensatory 100nF?

- Kupiłem wtyk DC 2.1/5.5 by móc zasilać Arduino baterią. Niestety muszę przylutować przewody do wtyku. Co do polaryzacji mam rozumieć, że + jest na "wtyku" a - na obudowie?

Mechano

19:25, 25.06.2015

#14

Dokładnie tak. Przyjmuj sobie, że zawsze masa (-) zawsze na obudowie (na zewnątrz).

MateuszW

17:21, 08.07.2015

#15

Treker napisał/a:

do 02.07 - Wyświetlacze LCD

a odcinka brak :(

Treker
Autor wpisu
Administrator

18:25, 08.07.2015

#16

MateuszW, zgadza się, brak, ale z premedytacją. Po ostatniej części kursu Arduino dotyczącej praktycznego wykorzystania serwomechanizmów oraz dodatkowych informacji o UART nie pojawiły się jeszcze żadne rozwiązania zadań domowych. Daje wszystkim czas na nadrobienie lekcji, widocznie niektórych dopadło wakacyjne lenistwo :) W międzyczasie polecam najnowszą, ostatni a już część kursu podstaw elektroniki - omawiającą przekaźniki oraz inne elementy stykowe.

Zobacz wszystkie komentarze (160) na forum

FORBOT Damian Szymański © 2006 - 2017 Zakaz kopiowania treści oraz grafik bez zgody autora. vPRsLH.