{"id":1068,"date":"2018-01-23T19:08:05","date_gmt":"2018-01-23T19:08:05","guid":{"rendered":"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/?p=1068"},"modified":"2018-01-29T08:33:40","modified_gmt":"2018-01-29T08:33:40","slug":"sterowanie-serwem-za-pomoca-joysticka","status":"publish","type":"post","link":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/?p=1068","title":{"rendered":"Sterowanie serwem za pomoc\u0105 joysticka"},"content":{"rendered":"<p>Na zaj\u0119ciach sterowali\u015bmy serwomechanizmami za pomoc\u0105 <strong>joysticka<\/strong>. Na pocz\u0105tku u\u017cywali\u015bmy niewielkiego modu\u0142u z joystickiem pod\u0142\u0105czanego bezpo\u015brednio do Arduino. W drugiej cz\u0119\u015bci u\u017cyli\u015bmy nak\u0142adki (<strong>shield<\/strong>) na Arduino z joystickiem oraz czterema przyciskami (podobnie jak na gamepadach).<\/p>\n<h1>Modu\u0142 z joystickiem<\/h1>\n<p>Modu\u0142 posiada pi\u0119\u0107 pin\u00f3w. GND oraz 5V pod\u0142\u0105czamy do Arduino. VRx i VRy to piny steruj\u0105ce odpowiednio osi\u0105 OX (czyli lewo-prawo) oraz OY (czyli g\u00f3ra-d\u00f3\u0142). Pod\u0142\u0105czamy je do pin\u00f3w analogowych. Ostatni pin odpowiada za przycisk, jednak nie u\u017cywali\u015bmy go w tym zadaniu.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-1071\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/thumbjoystick-300x225.jpg\" alt=\"\" width=\"300\" height=\"225\" srcset=\"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/thumbjoystick-300x225.jpg 300w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/thumbjoystick-768x576.jpg 768w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/thumbjoystick.jpg 1000w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Prosty program wy\u015bwietlaj\u0105cy po\u0142o\u017cenie joystika<\/p>\n<pre class=\"lang:arduino decode:true\" title=\"Odczytywanie wychylenia joy-a\">void setup(){\r\n  Serial.begin(9600);\r\n}\r\nint x,y;\r\nvoid loop(){\r\n   x = analogRead(A0);\r\n   y = analogRead(A1);\r\n   Serial.print(\"x=\");\r\n   Serial.print(x);\r\n   Serial.print(\", y=\");\r\n   Serial.println(y);  \r\n  }<\/pre>\n<p>Po\u0142o\u017cenie na osi OX (tak\u017ce OY) to liczby z zakresu 0..1023. Po\u0142o\u017cenie spoczynkowe powinno odpowiada\u0107 warto\u015bci 511 (liczby 0..510 to wychylenie w lewo, liczby 512..1023 to wychylenie w prawo). U\u017cycie tego programu pozwoli\u0142o nam sprawdzi\u0107, \u017ce tak jednak nie jest &#8211; u nas joy w po\u0142o\u017ceniu spoczynkowym mia\u0142 warto\u015bci 514, 517 (o\u015b OX i OY).<\/p>\n<p>Podczas dzia\u0142ania tego programu mo\u017cemy postawi\u0107 sobie nast\u0119puj\u0105ce zadanie: ustawi\u0107 pozycj\u0119 joy-a w takim po\u0142o\u017ceniu, aby odczyty by\u0142y x=800 y=200. Okazuje si\u0119 to jednak bardzo trudne! Widzimy wi\u0119c, \u017ce sterowanie joy-em nie jest \u0142atwe i wymaga sporo wprawy.<\/p>\n<h1>Wie\u017cyczka<\/h1>\n<p>U\u017cywana przez nas wie\u017cyczka (do kt\u00f3rej mo\u017cna przyczepi\u0107, np. kamerk\u0119 internetow\u0105 by ni\u0105 sterowa\u0107) sk\u0142ada\u0142a si\u0119 z dw\u00f3ch serw na podstawce. Umo\u017cliwia to poruszanie si\u0119 mechanizmu na boki oraz w g\u00f3r\u0119 i d\u00f3\u0142.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1088\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/DSC_4378-1024x576.jpg\" alt=\"\" width=\"640\" height=\"360\" srcset=\"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/DSC_4378-1024x576.jpg 1024w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/DSC_4378-300x169.jpg 300w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/DSC_4378-768x432.jpg 768w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<p>Wszystkie potrzebne elementy po\u0142\u0105czyli\u015bmy za pomoc\u0105 p\u0142ytki prototypowej. Zamiast zasilania z Arduino u\u017cyli\u015bmy zewn\u0119trznego koszyka na 4 baterie o \u0142\u0105cznym napi\u0119ciu 5V. Dlaczego tak zrobili\u015bmy? Chodzi\u0142o nam o oddzielne zasilanie silnik\u00f3w aby <strong>nie przeci\u0105\u017cy\u0107<\/strong> p\u0142ytki Arduino &#8211; pojedyncze serwo mo\u017ce pobra\u0107 nawet 200mA pr\u0105du (co sprawdzali\u015bmy na <a href=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-admin\/post.php?post=1020&amp;action=edit\">poprzednich zaj\u0119ciach<\/a>), a wydajno\u015b\u0107 pr\u0105dowa Arduino UNO to <a href=\"https:\/\/playground.arduino.cc\/Main\/ArduinoPinCurrentLimitations\">oko\u0142o 200-400 mA<\/a>. Dlatego dwa takie serwa mog\u0105 uszkodzi\u0107 nasz\u0105 p\u0142ytk\u0119. My u\u017cyli\u015bmy <strong>oddzielnego zasilania silnik\u00f3w<\/strong> aby temu zapobiec. WA\u017bNE: w przypadku u\u017cywania kilku \u017ar\u00f3de\u0142 zasilania (u nas Arduino 5V i 4x baterie AAA) <strong>musimy uwsp\u00f3lnili\u0107 masy<\/strong> (GDN z Arduino, &#8222;minus&#8221; z bateryjki).<\/p>\n<p>U\u017cyli\u015bmy p\u0142ytki prototypowej, gdzie na jednej szynie (koloru niebieskiego) wetkn\u0119li\u015bmy &#8222;-&#8221; z koszyka baterii oraz GND Arduino. Do tej &#8222;szyny&#8221; pod\u0142\u0105czone by\u0142y masy serw (przewody koloru br\u0105zowego). Druga szyna (czerwona &#8211; z drugiej strony p\u0142ytki, dla naszej wygody) doprowadzone mia\u0142a przew\u00f3d &#8222;+&#8221; z koszyka baterii i tam pod\u0142\u0105czone by\u0142y zasilania silnik\u00f3w serw (czerwone przewody serw). UWAGA: <strong>nie mo\u017cna \u0142\u0105czy\u0107<\/strong> pinu 5V Arduino z zewn\u0119trznym zasilaniem baterii &#8211; mo\u017ce to spowodowa\u0107 uszkodzenie p\u0142ytki! \u0141\u0105czymy (=uwsp\u00f3lniamy) jedynie masy. Przewody steruj\u0105ce serwami (koloru \u017c\u00f3\u0142tego) pod\u0142\u0105czyli\u015bmy do pin\u00f3w PWM Arduino UNO &#8211; u nas #3 i #5.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1075 size-large\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/20180123_165518-1024x576.jpg\" alt=\"\" width=\"640\" height=\"360\" srcset=\"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/20180123_165518-1024x576.jpg 1024w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/20180123_165518-300x169.jpg 300w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/20180123_165518-768x432.jpg 768w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<h2>Program steruj\u0105cy<\/h2>\n<p>Na pocz\u0105tku standardowo do\u0142\u0105czamy do programu bibliotek\u0119 umo\u017cliwiaj\u0105c\u0105 sterowanie serwami. Nast\u0119pnie dodajemy zmienne do obu serw, jedno odpowiedzialne za ruch g\u00f3ra-d\u00f3\u0142, a drugie lewo-prawo.<\/p>\n<pre class=\"lang:arduino decode:true\" title=\"Pod\u0142\u0105czanie sewomechanizm\u00f3w\">#include &lt;Servo.h&gt;\r\nServo GoraDol;\r\nServo LewoPrawo;\r\n\r\nvoid setup (){\r\n  Serial.begin(9600);\r\n  GoraDol.attach(3);\r\n  LewoPrawo.attach(5);\r\n}\r\nint x,y;<\/pre>\n<p>W kolejnej cz\u0119\u015bci deklarujemy zmienne odpowiadaj\u0105ce za po\u0142o\u017cenie obu osi joysticka &#8211; dok\u0142adnie tak, jak w pierwszym programie odczytuj\u0105cym po\u0142o\u017cenia joy-a. Wy\u015bwietlamy warto\u015bci x oraz y w monitorze szeregowym. Joystick zwykle nie jest idealnie skalibrowany, jednak nie ma to znaczenia przy niewielkiej precyzji.<\/p>\n<p>Funkcja&nbsp;<strong>map<\/strong> pozwala na \u0142atwe proporcjonalne przeliczenie warto\u015bci. U\u017cywamy jej, poniewa\u017c po\u0142o\u017cenia joysticka s\u0105 z zakresiu 0-1023, natomiast sterowanie serwem chcemy wyra\u017camy w stopniach 0-180. Wynik przypisujemy od razu do zmiennych x oraz y (u\u017cywamy tych samych zmiennych, niszcz\u0105c ich poprzednie warto\u015bci). W argumentach funkcji wpisujemy zmienn\u0105 do przeliczenia, nast\u0119pnie jej obecny zakres i na ko\u0144cu zakres po zamianie. Po przeliczeniu warto\u015bci mo\u017cemy je przekaza\u0107 do serwomechanizm\u00f3w.<\/p>\n<pre class=\"lang:arduino decode:true\" title=\"Funkcja map i sterowanie\">   x=map(x,0,1023,0,180); \/\/funkcja map\r\n   LewoPrawo.write(x);\r\n   y=map(y,0,1023,0,180);\r\n   GoraDol.write(y);\r\n   delay(10);<\/pre>\n<h1>Nak\u0142adka (shield) na Arduino<\/h1>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1070\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/shieldjoystick-300x300.jpg\" alt=\"\" width=\"289\" height=\"289\" srcset=\"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/shieldjoystick-300x300.jpg 300w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/shieldjoystick-150x150.jpg 150w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/shieldjoystick.jpg 498w\" sizes=\"auto, (max-width: 289px) 100vw, 289px\" \/><\/p>\n<p>Fajnym rozwi\u0105zaniem jest wykorzystanie specjalnej nak\u0142adki (shield), kt\u00f3ra poszerza mo\u017cliwo\u015bci Arduino. Piny obu komponent\u00f3w pasuj\u0105 do siebie, wi\u0119c nie da si\u0119 pomyli\u0107 przy wpinaniu nak\u0142adki. Joystick oraz przyciski s\u0105 fabrycznie pod\u0142\u0105czone do pin\u00f3w, wi\u0119c nie musimy tego robi\u0107 w programie. Na nak\u0142adce wszystkie piny s\u0105 podpisane, wi\u0119c p\u00f3\u017aniej b\u0119dziemy tylko operowa\u0107 odpowiednimi oznaczeniami pin\u00f3w.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1073 size-large\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/20180123_170600-1024x576.jpg\" alt=\"\" width=\"640\" height=\"360\" srcset=\"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/20180123_170600-1024x576.jpg 1024w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/20180123_170600-300x169.jpg 300w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/01\/20180123_170600-768x432.jpg 768w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<h2>Modyfikacja programu &#8211; przycisk &#8222;zamra\u017caj\u0105cy&#8221; po\u0142o\u017cenie wie\u017cyczki<\/h2>\n<p>Program steruj\u0105cy jest bardzo podobny do poprzedniego. Jedyn\u0105 r\u00f3\u017cnic\u0105 jest brak pod\u0142\u0105czenia pin\u00f3w cyfrowych. <strong>Dodatkow\u0105 funkcj\u0105<\/strong>, kt\u00f3r\u0105 wprowadzamy do naszego programu, <strong>jest zatrzymywanie serwa w ustawionej pozycji<\/strong>. Chcemy aby wci\u015bni\u0119cie wybranego przycisku (np. koloru czerwonego) zablokowywa\u0142o dalsze sterowanie wie\u017cyczk\u0105. Kolejne wci\u015bni\u0119cie tego przycisku powoduje odblokowanie sterowania. W tym celu do kodu wprowadzamy zmienn\u0105 typu logicznego <strong>bool <\/strong>(nazwan\u0105&nbsp;<em>tryb<\/em>)&nbsp;i ustawiamy j\u0105 na warto\u015b\u0107 <em>true<\/em>. Nast\u0119pnie wybieramy przycisk (np. ten czerwony), kt\u00f3ry ma sterowa\u0107 zatrzymaniem serwa i&nbsp; sprawdzamy, kt\u00f3ry numer pinu u odpowiada. W naszym programie jest to pin 5.&nbsp; Tworzymy instrukcj\u0119 steruj\u0105c\u0105 <em>if<\/em>, kt\u00f3ra wykona si\u0119 po wci\u015bni\u0119ciu przycisku. Do warto\u015bci zmiennej <em>tryb<\/em>, przypisujemy jej odwrotno\u015b\u0107. Czyli je\u015bli <em>tryb<\/em> jest <em>true<\/em>, zostanie zmieniony na <em>false<\/em> i odwrotnie. Funkcja delay() wprowadzamy aby zarejestrowa\u0107 tylko jedn\u0105 zmian\u0119 ustawienia przycisku (przyciski lubi\u0105 &#8222;drga\u0107&#8221; co powoduje nie jeden &#8222;klik&#8221; a wiele takich &#8222;klik\u00f3w&#8221; &#8211; op\u00f3\u017anienie je zniweluje). Dzia\u0142a to w taki spos\u00f3b, \u017ce je\u015bli <em>tryb<\/em> jest warto\u015bci\u0105 <em>false<\/em>, czyli zostanie raz zmieniony we wcze\u015bniejszym <strong>if&#8217;<\/strong>ie, sterowanie joyem zostaje zablokowane. Natomiast po kolejnym u\u017cyciu przycisku, <em>tryb<\/em> zmieni si\u0119 z <em>false<\/em> na <em>true<\/em>, a sterowanie zostanie odblokowane.<\/p>\n<pre class=\"lang:arduino decode:true \">bool tryb=true;\r\nvoid loop(){\r\n  x=analogRead(A0);\r\n  y=analogRead(A1); \r\n   if (digitalRead(5)==HIGH){\r\n      tryb=!tryb;\r\n      delay(50);\r\n   }\r\n\r\n   if(tryb==true){ \r\n   x=map(x,0,1023,0,180); \/\/funkcja map\r\n   LewoPrawo.write(x);\r\n   y=map(y,0,1023,0,180);\r\n   GoraDol.write(y);\r\n  }\r\n}<\/pre>\n<h1>Podsumowanie<\/h1>\n<p>Jak mo\u017cna zauwa\u017cy\u0107 programy umo\u017cliwiaj\u0105ce sterowanie servami nie s\u0105 skomplikowane ani d\u0142ugie. Mo\u017cna sprytnie wykorzysta\u0107 komponenty posiadaj\u0105ce wi\u0119cej ni\u017c jedn\u0105 o\u015b ruchu, dzi\u0119ki czemu nasze mo\u017cliwo\u015bci si\u0119 poszerzaj\u0105. Jednak precyzyjne sterowanie takimi joystikami nie jest \u0142atwe&#8230;<\/p>\n<p style=\"text-align: right;\">(c) Ewelina, KG 2017<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Na zaj\u0119ciach sterowali\u015bmy serwomechanizmami za pomoc\u0105 joysticka. Na pocz\u0105tku u\u017cywali\u015bmy niewielkiego modu\u0142u z joystickiem pod\u0142\u0105czanego bezpo\u015brednio do Arduino. W drugiej cz\u0119\u015bci u\u017cyli\u015bmy nak\u0142adki (shield) na Arduino z joystickiem oraz czterema przyciskami (podobnie jak na gamepadach). Modu\u0142 z joystickiem Modu\u0142 posiada pi\u0119\u0107 pin\u00f3w. GND oraz 5V pod\u0142\u0105czamy do Arduino. VRx i VRy to piny steruj\u0105ce odpowiednio [&hellip;]<\/p>\n","protected":false},"author":16,"featured_media":1088,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[52],"tags":[67,207,154,209,208,72,71,206],"class_list":{"0":"post-1068","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","6":"hentry","7":"category-fibot","8":"tag-analogread","9":"tag-gnd","10":"tag-joystick","11":"tag-masa","12":"tag-masy","13":"tag-servo","14":"tag-serwo","15":"tag-uwspolnianie","17":"post-with-thumbnail","18":"post-with-thumbnail-large"},"_links":{"self":[{"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/posts\/1068","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1068"}],"version-history":[{"count":14,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/posts\/1068\/revisions"}],"predecessor-version":[{"id":1093,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/posts\/1068\/revisions\/1093"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/media\/1088"}],"wp:attachment":[{"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1068"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1068"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1068"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}