{"id":1984,"date":"2019-09-10T16:04:59","date_gmt":"2019-09-10T16:04:59","guid":{"rendered":"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/?p=1984"},"modified":"2019-09-17T15:50:19","modified_gmt":"2019-09-17T15:50:19","slug":"sterowanie-serwem-za-pomoca-joysticka-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-2-3-2-2-4-2-2-2-2-2-2-3-2-2-2-2-2-2-2-2-2-4","status":"publish","type":"post","link":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/?p=1984","title":{"rendered":"Kontroler do pojazdu &#8212; tekstowy protok\u00f3\u0142"},"content":{"rendered":"<h2>Pojazd sterowany &#8211; nRF24L01<\/h2>\r\nPan Przemek dalej kombinuje z komunikacj\u0105 radiow\u0105 na bazie uk\u0142adu nRF24. Jako now\u0105 zabawk\u0119 dosta\u0142 <a href=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/?p=709\">JoyShield-a do Arduino<\/a>, o takiego:\r\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-1985\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/09\/joyshield-0-300x199.jpg\" alt=\"\" width=\"300\" height=\"199\" srcset=\"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/09\/joyshield-0-300x199.jpg 300w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/09\/joyshield-0.jpg 600w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/>\r\n\r\nJest to bardzo ciekawy uk\u0142ad, bo nie do\u015b\u0107, \u017ce ma joystick oraz 7 przycisk\u00f3w (4 du\u017ce, kolorowe, jeden w joysticku, oraz 2 ma\u0142e &#8211; mikrostyki), to ma jeszcze adaptery na radi\u00f3wk\u0119 nRF24 (i inne te\u017c, ale tego nie tykamy). Wszystko z\u0142o\u017cone w &#8222;kanapk\u0119&#8221; <strong>mo\u017ce pe\u0142ni\u0107 funkcj\u0119 kontrolera<\/strong> &#8211; po przyczepieniu bateryjki 9V (np. gumk\u0105 recepturk\u0105).\r\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-1986\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/09\/joyshield-1-300x300.jpg\" alt=\"\" width=\"300\" height=\"300\" srcset=\"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/09\/joyshield-1-300x300.jpg 300w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/09\/joyshield-1-150x150.jpg 150w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/09\/joyshield-1.jpg 500w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/> <img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2028\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/09\/DSC_8592-1-300x220.jpg\" alt=\"\" width=\"300\" height=\"220\" srcset=\"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/09\/DSC_8592-1-300x220.jpg 300w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2019\/09\/DSC_8592-1.jpg 671w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/>\r\n<h2>Tekstowy protok\u00f3\u0142 &#8212; kodowanie<\/h2>\r\nBazujemy na <strong>protokole tekstowym<\/strong> &#8211; shield odczytuje po\u0142o\u017cenie joysticka, oraz 5 przycisk\u00f3w (chwilowo nie obs\u0142ugujemy wszystkich). Dane wysy\u0142ane s\u0105 przez nRF24 jako <strong>tekst<\/strong>, a poszczeg\u00f3lne pola oddzielone s\u0105 <strong>\u015brednikiem<\/strong>. Jedna paczka danych wygl\u0105da wi\u0119c tak:\r\n\r\n<strong>507;512;0;1;1;0;0;<\/strong>\r\n\r\ngdzie pierwsza liczba okre\u015bla po\u0142o\u017cenie joy-a na osi X, druga na osi Y, a kolejne zera i jedynki to stan logiczny 5-ciu przycisk\u00f3w. Bardzo proste w utworzeniu tego napisu &#8212; dzi\u0119ki klasie String i jego licznie przeci\u0105\u017conych konstruktorach, oraz operatorowi &#8222;dodawania&#8221;.\r\n<pre class=\"lang:arduino decode:true \" title=\"Wysy\u0142anie danych w naszym protokole\">#include &lt;SPI.h&gt;\r\n#include &lt;nRF24L01.h&gt;\r\n#include &lt;RF24.h&gt;\r\n \r\nRF24 radio(9, 10);\/\/CE, CS\r\n \r\nuint8_t rxAddr[6] = \"grzyb\";\r\n \r\nvoid setup(){\r\n  Serial.begin(9600);\r\n  Serial.print(\"nRF24 INIT=\");\r\n\r\n  bool ok=radio.begin();\r\n  Serial.println(ok);\r\n  radio.setRetries(15, 15);\r\n\r\n  radio.openWritingPipe(rxAddr);  \r\n  radio.stopListening();\r\n\r\n  \/\/dla modulu JoyShield\r\n  pinMode(2, INPUT);\r\n  pinMode(3, INPUT);  \r\n  pinMode(4, INPUT);  \r\n  pinMode(5, INPUT);  \r\n  pinMode(6, INPUT); \r\n}\r\n \r\nchar bufor[32];\r\nString napis;\r\n \r\nvoid loop(){\r\n  \/\/tworzymy napis wedlug naszego protokolu \r\n  napis = String(analogRead(A0)) + \";\" + String(analogRead(A1)) + \";\" + String(digitalRead(2)) + \";\" + String(digitalRead(3)) + \";\" + String(digitalRead(4)) + \";\" + String(digitalRead(5)) + \";\"  + String(digitalRead(6)) + \";\";\r\n\r\n  \/\/przygotowujemy bufor -- tablice z napisem...\r\n  napis.toCharArray(bufor, 32);\r\n\r\n  \/\/wazne! wysylamy bufor a nie napis!\r\n  radio.write(&amp;bufor, sizeof(bufor));\r\n}<\/pre>\r\nPoniewa\u017c <em>radio<\/em> wysy\u0142a dane w postaci tablicy, nie mo\u017cemy wysy\u0142a\u0107 obiektu <em>napis<\/em>. Dlatego korzystamy z metody <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/variables\/data-types\/string\/functions\/tochararray\/\">toCharArray()<\/a> klasy String i przekopiowujemy zawarto\u015b\u0107 napisu do bufora &#8211; tablicy. W &#8222;<a href=\"https:\/\/pl.wikipedia.org\/wiki\/Eter_(fizyka)\">eter<\/a>&#8221; wysy\u0142amy tablic\u0119 <em>bufor<\/em>.\r\n<h2>Tekstowy protok\u00f3\u0142 &#8212; odczyt<\/h2>\r\nNo w\u0142a\u015bnie, prostota u\u017cycia napis\u00f3w poci\u0105ga za sob\u0105 &#8222;problem&#8221; odczytywania takich danych. W gr\u0119 wchodz\u0105 bardzo przydatne metody klasy <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/variables\/data-types\/stringobject\/\">String<\/a>:\r\n<ul>\r\n \t<li><a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/variables\/data-types\/string\/functions\/indexof\/\">indexOf<\/a>(<em>napis<\/em>) &#8212; zwracaj\u0105ca pozycj\u0119 <em>napisu<\/em> w danym stringu (u nas <em>napis<\/em> to \u015brednik, kt\u00f3rym oddzielali\u015bmy liczby)<\/li>\r\n \t<li><a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/variables\/data-types\/string\/functions\/length\/\">length<\/a>() &#8212; zwracaj\u0105ca d\u0142ugo\u015b\u0107 stringu<\/li>\r\n \t<li><a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/variables\/data-types\/string\/functions\/remove\/\">remove<\/a>(<em>od, do<\/em>) &#8212; ucinaj\u0105ca napis od pozycji <em>od <\/em>do pozycji <em>do<\/em><\/li>\r\n \t<li><a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/variables\/data-types\/string\/functions\/substring\/\">substring<\/a>(<em>od, do<\/em>) &#8212; zwracaj\u0105ca podci\u0105g w danym napisie, od pozycji <em>od <\/em>do pozycji <em>do<\/em><\/li>\r\n \t<li><a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/variables\/data-types\/string\/functions\/toint\/\">toInt<\/a>(<em>napis<\/em>) &#8212; zamienia <em>napis<\/em> na liczb\u0119 ca\u0142kowit\u0105 (int)<\/li>\r\n<\/ul>\r\nPoni\u017cej program dekoduj\u0105cy nasz protok\u00f3\u0142 &#8211; czyli zamieniaj\u0105cy <em>napis<\/em> na\r\n\r\nint x,y;\r\nbyte b1,b2,b3,b4,b5;\r\n\r\nNapis wczytany z klawiatury, przez komunikacj\u0119 szeregow\u0105 &#8211; dzi\u0119ki temu mo\u017cemy testowa\u0107 nasz program na r\u00f3\u017cne sposoby (o przeniesieniu tego kodu na radio &#8212; b\u0119dzie za tydzie\u0144).\r\n<pre class=\"lang:arduino decode:true\" title=\"Dekodowanie prostokolu - dane z Seriala\">void setup() {\r\n  \/\/dane wprowadzamy z klawiatury przez Serial\r\n  Serial.begin(9600);\r\n}\r\n\r\nString tekst;\r\nString ciag;\r\nchar znak = ';';\/\/separator pola\r\nint x,y; \/\/wspolrzedne x,y\r\nbyte b1,b2,b3,b4,b5;\/\/stan 5 przyciskow\r\nint k,l;\/\/pomocnicze\r\n\r\nunsigned long int t1,t2;\r\n\r\nvoid loop() {\r\n if(Serial.available()&gt;0){\r\n    tekst=Serial.readString();\r\n    Serial.println(tekst);\r\n\r\n    t1=micros();\r\n    k=tekst.indexOf(znak);\r\n    ciag=tekst.substring(0,k);\r\n    x=ciag.toInt();\r\n    l=k+1;\r\n    \r\n    k=tekst.indexOf(znak,l);\r\n    ciag=tekst.substring(l,k);\r\n    y=ciag.toInt();  \r\n    l=k+1;\r\n    \r\n    k=tekst.indexOf(znak,l);\r\n    ciag=tekst.substring(l,k);\r\n    b1=ciag.toInt();\r\n    l=k+1;\r\n\r\n    k=tekst.indexOf(znak,l);\r\n    ciag=tekst.substring(l,k);\r\n    b2=ciag.toInt();  \r\n    l=k+1;\r\n\r\n    k=tekst.indexOf(znak,l);\r\n    ciag=tekst.substring(l,k);\r\n    b3=ciag.toInt();  \r\n    l=k+1;\r\n\r\n    k=tekst.indexOf(znak,l);\r\n    ciag=tekst.substring(l,k);\r\n    b4=ciag.toInt();  \r\n    l=k+1;\r\n\r\n    k=tekst.indexOf(znak,l);\r\n    ciag=tekst.substring(l,k);\r\n    b5=ciag.toInt();  \r\n    l=k+1;\r\n    \r\n    t2=micros();\r\n    \r\n    Serial.print(\"Pozycja X: \");\r\n    Serial.println(x);\r\n    Serial.print(\"Pozycja Y: \");\r\n    Serial.println(y);\r\n    Serial.print(\"PRZYCISK 1: \");\r\n    Serial.println(b1);\r\n    Serial.print(\"PRZYCISK 2: \");\r\n    Serial.println(b2);\r\n    Serial.print(\"PRZYCISK 3: \");\r\n    Serial.println(b3);\r\n    Serial.print(\"PRZYCISK 4: \");\r\n    Serial.println(b4);\r\n    Serial.print(\"PRZYCISK 5: \");\r\n    Serial.println(b5);\r\n    Serial.print(\"czas dekodowaia [mikrosekundy]= \");\r\n    Serial.println(t2-t1);\r\n  }\/\/if\r\n}\/\/loop\r\n<\/pre>\r\n<h2>Tekstowy protok\u00f3\u0142 &#8212; szybko\u015b\u0107 dekodowania<\/h2>\r\nWielokrotne u\u017cycie powy\u017cszych funkcji powoduje, \u017ce odkodowanie napisu <em>507;512;0;1;1;0;0; <\/em>i zamiana go na\r\n\r\nint x, y;\r\nbyte b1,b2,b3,b4,b5;\r\n\r\nzajmuje dla Arduino UNO<strong> od 260 do 550 mikrosekund<\/strong> (czyli ~0.5ms). A dlaczego nie jeden, r\u00f3wny czas? Bo w zale\u017cno\u015bci od postaci dekodowanego <em>napisu<\/em> mikrokotrolerek musi wi\u0119cej lub mniej pracowa\u0107. Mniej &#8222;m\u0119czy&#8221; si\u0119 w przypadku ci\u0105gu <em>1;1;1;0;0;0;0;<\/em> a wi\u0119cej w przypadku <em>1012;1017;0;0;0;1;1; <\/em>Dobra, zrozumia\u0142e. A czy to du\u017cy czas? Dla cz\u0142owieka to nic, dla elektroniki sporo&#8230; Czy to nam wystarczy &#8211; czy nie spowoduje op\u00f3\u017anie\u0144 (tzw &#8222;lag\u00f3w&#8221;) w sterowaniu pojazdem? O tym przekonamy si\u0119 po zastosowaniu tego protoko\u0142u do pojazdu (za tydzie\u0144).\r\n<h2>Tekstowy protok\u00f3\u0142: modyfikacje &#8212; suma kontrolna<\/h2>\r\nMo\u017cna pomy\u015ble\u0107 o rozbudowie naszego protoko\u0142u na dodatkowe &#8222;pole&#8221;, b\u0119d\u0105ce sum\u0105 kontrol\u0105. Jeden z pomys\u0142\u00f3w to wysumowanie wszystkich danych (w ko\u0144cu to liczby ca\u0142kowite) i zapisanie tej sumy jako ostatni, dodatkowy element. Dla naszego przypadku wygl\u0105da\u0142oby to tak: 507;512;0;1;1;0;0;<strong>1021;<\/strong> Po stronie odbiornika dekodujemy napis, liczymy sum\u0119 x+y+b1+b2+b3+b4+b5 i por\u00f3wnujemy z ostatni\u0105 warto\u015bci\u0105 &#8211; nazwijmy j\u0105 <em>sumak. <\/em>A Je\u015bli nie ma r\u00f3wno\u015bci&#8230; odrzucamy (ignorujemy) paczk\u0119 danych i czekamy na kolejn\u0105.\r\n<h2>Tekstowy protok\u00f3\u0142: modyfikacje &#8212; protok\u00f3\u0142 binarny<\/h2>\r\nLepiej by by\u0142o stworzy\u0107 podobny protok\u00f3\u0142 ale <strong>binarny<\/strong>, czyli nie bawi\u0107 si\u0119 w zapis liczb w postaci <strong>string\u00f3w<\/strong>, dodatkowo oddziela\u0107 je przecinkami tylko wysy\u0142a\u0107 x,y jako integer, a przyciski b1,b2,b3,b4 i b5 jako <strong>byte<\/strong> (nie 5 bajt\u00f3w, a jeden &#8211; wszak 1 bajt = 8 bit\u00f3w, mamy wi\u0119c nadam zapas). Zyskujemy na tym mniejsze porcje danych &#8211; wszystkie informacje z JoyShielda to tylko 5 bajt\u00f3w, a nie 14 (najlepszy przypadek) czy nawet 20 bajt\u00f3w (najgorszy przypadek). No i nie ma zabawy w dekodowanie danych z wykorzystaniem metod klasy String&#8230; Ale to mo\u017ce przy innej okazji \ud83d\ude09\r\n<p style=\"text-align: right;\"><em>(c) K.G.<\/em><\/p>\r\n<!-- \/wp:post-content -->","protected":false},"excerpt":{"rendered":"<p>Pojazd sterowany &#8211; nRF24L01 Pan Przemek dalej kombinuje z komunikacj\u0105 radiow\u0105 na bazie uk\u0142adu nRF24. Jako now\u0105 zabawk\u0119 dosta\u0142 JoyShield-a do Arduino, o takiego: Jest to bardzo ciekawy uk\u0142ad, bo nie do\u015b\u0107, \u017ce ma joystick oraz 7 przycisk\u00f3w (4 du\u017ce, kolorowe, jeden w joysticku, oraz 2 ma\u0142e &#8211; mikrostyki), to ma jeszcze adaptery na radi\u00f3wk\u0119 [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":1985,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[52],"tags":[339,336,140,142,110,130,294,152,338,337],"class_list":{"0":"post-1984","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","6":"hentry","7":"category-fibot","8":"tag-indexof","9":"tag-kontroler","10":"tag-nrf","11":"tag-nrf24","12":"tag-protokol","13":"tag-radio","14":"tag-radiowka","15":"tag-string","16":"tag-substring","17":"tag-tochararray","19":"post-with-thumbnail","20":"post-with-thumbnail-large"},"_links":{"self":[{"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/posts\/1984","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\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1984"}],"version-history":[{"count":15,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/posts\/1984\/revisions"}],"predecessor-version":[{"id":2029,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/posts\/1984\/revisions\/2029"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/media\/1985"}],"wp:attachment":[{"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1984"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1984"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1984"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}