{"id":1126,"date":"2018-02-27T18:43:43","date_gmt":"2018-02-27T18:43:43","guid":{"rendered":"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/?p=1126"},"modified":"2018-03-07T09:59:21","modified_gmt":"2018-03-07T09:59:21","slug":"sterowanie-serwem-za-pomoca-joysticka-3","status":"publish","type":"post","link":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/?p=1126","title":{"rendered":"Przycisk + dioda + random = REFLEKS!"},"content":{"rendered":"<p>Na zaj\u0119ciach wykorzystali\u015bmy proste elementy do zbudowania prototypu maszyny badaj\u0105cej nasz refleks. Ale od pocz\u0105tku.<\/p>\n<h1>Modu\u0142 z przyciskiem<\/h1>\n<p>Modu\u0142 posiada trzy piny &#8211; GND oraz Vcc to zalsilanie, S to stygna\u0142 wysy\u0142any przez p\u0142ytk\u0119 (na innych p\u0142ytkach cz\u0119sto oznaczony OUT). My u\u017cywamy modu\u0142\u00f3w firmy RobotDyn (o nazwie Button Switch module) i trzeba przyzna\u0107 im dobr\u0105 jako\u015b\u0107 wykonania. Na dodatek uk\u0142ady te maj\u0105 wbudowanego LED-a informuj\u0105cego o wci\u015bni\u0119ciu przycisku.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1127\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/03\/Button-key-switch-module-BLUE-With-LED-light-of-action.jpg_640x640.jpg\" alt=\"\" width=\"235\" height=\"197\" srcset=\"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/03\/Button-key-switch-module-BLUE-With-LED-light-of-action.jpg_640x640.jpg 569w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/03\/Button-key-switch-module-BLUE-With-LED-light-of-action.jpg_640x640-300x252.jpg 300w\" sizes=\"auto, (max-width: 235px) 100vw, 235px\" \/><\/p>\n<p>Najpierw sprawdzamy, czy po wci\u015bni\u0119ciu przycisku Arduino &#8222;zobaczy&#8221; jedynk\u0119 (stan HIGH) czy &#8222;zero&#8221; (stan LOW). Prosty programik poni\u017cej:<\/p>\n<pre class=\"lang:arduino decode:true\" title=\"Program PRZYCISK\">#define gdzie 7\r\nvoid setup(){\r\n  pinMode(gdzie, INPUT);\r\n  Serial.begin(9600);\r\n}\r\nvoid loop(){\r\n   Serial.println(digitalRead(gdzie));\r\n   delay(100);\r\n}<\/pre>\n<h1>Liczby losowe &#8211; rand()<\/h1>\n<p>Bibliotyki Arduino wyposa\u017cone s\u0105 w funkcje pseudo losowe &#8211; czyli takie, kt\u00f3re generuj\u0105 liczby &#8222;udaj\u0105ce&#8221; prawdziwe liczby losowe. Mowa tu o funkcji <strong>rand()<\/strong> &#8211; aby to sprawdzi\u0107 piszemy poni\u017cszy kod:<\/p>\n<pre class=\"lang:arduino decode:true\" title=\"Program LICZBY LOSOWE\">void setup(){\r\n  Serial.begin(9600);\r\n}\r\nvoid loop(){\r\n   Serial.print(\"czas= \");\r\n   Serial.print(millis());\r\n   Serial.print(\" los=\");\r\n   Serial.printtln(rand());\r\n   delay(100);\r\n}<\/pre>\n<p>Widzimy wi\u0119c duuuuu\u017ce (i losowe!) liczby ca\u0142kowite, kt\u00f3re wy\u015bwietlaj\u0105 si\u0119 co 100ms. Aby z takich liczb zbudowa\u0107 co\u015b konkretnego, np. typowy rzut kostki do gry &#8211; trzeba to lekko zmodyfikowa\u0107 przez u\u017cycie funkcji <span style=\"text-decoration: underline;\">reszta z dzielenia ca\u0142kowitego<\/span> (tzw. <em>modulo<\/em>, symbol <strong>%<\/strong> w j\u0119zyku C\/C++):<\/p>\n<pre class=\"lang:arduino decode:true\" title=\"Program KOSTKA DO GRY\">void setup(){\r\n  Serial.begin(9600);\r\n}\r\nvoid loop(){\r\n   Serial.print(\"czas= \");\r\n   Serial.print(millis());\r\n   Serial.print(\" kostka=\");\r\n   Serial.printtln(1 + rand()%6);\r\n   delay(100);\r\n}<\/pre>\n<p>Jak to dzia\u0142a? Reszta z dzielenia ca\u0142kowitego przez 6 zwraca liczby z przedzia\u0142u 0..5, ale my dodajemy jeszcze jedynk\u0119 &#8211; otrzymujemy liczby 1&#8230;6 &#8211; czyli nasz\u0105 kostk\u0119 do gry. W ten w\u0142a\u015bnie spos\u00f3b mo\u017cemy modyfikowa\u0107 wynik funkcji <strong>rand()<\/strong> i dopasowywa\u0107 j\u0105 do naszych potrzeb.<\/p>\n<h1>Zapalenie LED-a co losowy czas<\/h1>\n<p>Pod\u0142\u0105czyli\u015bmy niebieskiego LED-a bezpo\u015brednio do pinu 13 Arduino i GND &#8211; bez dodatkowego, wymaganego opornika. Nie jest to poprawne po\u0142\u0105czenie (brak opornika = uszkodzenie LED-a), ALE niebieskie LEDy maj\u0105 (wysokie) napi\u0119cie przewodzenia, oko\u0142o 3V. Arduino zasili je jednak 5V &#8211; co jest za du\u017co &#8211; i uszkadzamy naszego LED-a, ale go nie zniszczymy (celowo wybra\u0142em niebieski LED, a nie inny &#8211; inne LEDy pracu\u0105 na napi\u0119ciu ~2V, wi\u0119c 5V by je zniszczy\u0142o). Zale\u017cy mi tutaj na prostocie budowy uk\u0142adu wi\u0119c darowa\u0142em sobie niezb\u0119dny opornik (no i nie chia\u0142em korzysta\u0107 z wbudowanego LEDa #13 &#8211; bo jest ma\u0142y i niewyra\u017any).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1128\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/03\/DSC_4442-1024x576.jpg\" alt=\"\" width=\"640\" height=\"360\" srcset=\"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/03\/DSC_4442-1024x576.jpg 1024w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/03\/DSC_4442-300x169.jpg 300w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/03\/DSC_4442-768x432.jpg 768w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<p>Chwilowo od\u0142o\u017cyli\u015bmy modu\u0142 z przyciskiem i zaprogramowali\u015bmy w\u0142\u0105czenei LED-a po <strong>losowym czasie od 5s, do 15s<\/strong>:<\/p>\n<pre class=\"lang:arduino decode:true\" title=\"Program LOSOWE W\u0141\u0104CZENIE\">#define LED 13\r\nvoid setup(){\r\n  pinMode(LED, OUTPUT);\r\n}\r\nint i;\r\nvoid loop(){\r\n   \/\/odczekanie 5..15 sekund\r\n   delay(5000+ rand()%10000);\r\n   \/\/wlaczenie LED-a\r\n   digitalWrite(LED, HIGH);\r\n   delay(1000);\r\n   digitalWrite(LED, LOW);\r\n   \/\/miganie - znak, ze za chwile powtarzamy zabawe\r\n   for (i=0; i&lt;4; i++){\r\n       digitalWrite(LED, HIGH); \r\n       delay(200); \r\n       digitalWrite(LED, LOW);      \r\n       delay(200);\r\n   }\/\/miganie\r\n}<\/pre>\n<p>Warto pobawi\u0107 si\u0119 z tym programem, uzupe\u0142niaj\u0105c go o dodatkowe informacje wy\u015bwietlane przez monitor portu szeregowego &#8211; informuj\u0105ce, \u017ce trwa losowe czekanie, a potem, \u017ce w\u0142\u0105czono LEDa i na koniec &#8211; \u017ce zabawa od pocz\u0105tku si\u0119 zaczyna.<\/p>\n<h2>Program &#8222;badamy refleks&#8221;<\/h2>\n<p>Wracamy do przycisku &#8211; rozbudowujemy poprzedni program o odczytanie momentu wci\u015bni\u0119cia przycisku. U\u017cytkownik ma to zrobi\u0107 w momencie zapalenia si\u0119 niebieskiego LEDa &#8212; tylko, \u017ce nie wiadomo, kiedy to dok\u0142adnie nast\u0105pi (losowy czas z poprzedniego programu). Na koniec wy\u015bwietlimy czas jego reakcji &#8211; jego refleksu \ud83d\ude09<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1121\" src=\"http:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/02\/DSC_4439-1024x576.jpg\" alt=\"\" width=\"640\" height=\"360\" srcset=\"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/02\/DSC_4439-1024x576.jpg 1024w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/02\/DSC_4439-300x169.jpg 300w, https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/wp-content\/uploads\/sites\/6\/2018\/02\/DSC_4439-768x432.jpg 768w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<pre class=\"lang:arduino mark:17 decode:true\" title=\"Program REFLEKS\">#define LED 13\r\n#define gdzie 7\r\nvoid setup(){\r\n  pinMode(gdzie, INPUT);   \r\n  pinMode(LED, OUTPUT);\r\n  Serial.begin(9600);\r\n}\r\nint i;\r\nunsigned long int t1,t2;\r\nvoid loop(){\r\n   Serial.println(\"START!\");\r\n   \/\/odczekanie 5..15 sekund\r\n   delay(5000+ rand()%10000);\r\n   t1=millis();\r\n   \/\/wlaczenie LED-a\r\n   digitalWrite(LED, HIGH);\r\n   while (digitalRead(gdzie)== HIGH);\r\n   t2=millis();\r\n   digitalWrite(LED, LOW);\r\n   Serial.print(\"Rekacja (refleks)=\");\r\n   Serial.print(t2-t1);\r\n   Serial.println(\" ms\");\r\n   delay(500);\r\n   \/\/miganie - znak, ze za chwile powtarzamy zabawe\r\n   for (i=0; i&lt;4; i++){\r\n       digitalWrite(LED, HIGH); \r\n       delay(200); \r\n       digitalWrite(LED, LOW);      \r\n       delay(200);\r\n   }\/\/miganie\r\n}<\/pre>\n<p>Kluczowa jest linia #17 &#8211; to w niej nast\u0119puje zatrzymanie dzia\u0142ania programu i oczekiwanie na rekacj\u0119 u\u017cytkownika. Zrealizowa\u0142em to za pomoc\u0105 p\u0119tli podczytuj\u0105cej przycisk &#8211; w moim module naci\u015bni\u0119cie przycisku powoduje odczyt stanu LOW, natomiast stan HIGH oznacza brak wci\u015bni\u0119cia. Jak wida\u0107 ta p\u0119tla NIC nie robi. W\u0142a\u015bnie o to mi tu chodzi\u0142o &#8211; p\u0119tla nic nie robi, wi\u0119c ponownie wracamy do sprawdzenia warunku p\u0119tli while &#8211; bez straty czasu. I tak w k\u00f3\u0142ko, a\u017c w ko\u0144cu naci\u015bni\u0119ty zostanie przycisk.&nbsp;<\/p>\n<p>A jak mierz\u0119 czas? Za pomoc\u0105 funkcji&nbsp;<strong>millis()<\/strong> &#8211; kt\u00f3ra zwraca czas (w milisekundach) od uruchomienia Arduino. Robi\u0119 to dwukrotnie &#8211; przed odczytaniem przycisku zapisuj\u0119 do zmiennej t1, a po naci\u015bni\u0119ciu przycisku &#8211; do zmiennej t2. R\u00f3\u017cnica tych czas\u00f3w jest w\u0142a\u015bnie Twoim czesem reakcji &#8211; Twoim refleksem.<\/p>\n<h1>Pomys\u0142y<\/h1>\n<p style=\"text-align: left;\">Program nale\u017cy rozbudowa\u0107 &#8211; o dwa przyciski, dwa LEDy. To wzbogaci zabaw\u0119, bo losowo zapali si\u0119 albo jeden LED, albo drugi. Warto wybra\u0107 dwa kolory LED-\u00f3w i dwa kolory przycisk\u00f3w. To b\u0119dzie dodatkowe utrudnienie dla u\u017cytkownika &#8211; ma on bowiem wcisn\u0105\u0107 odpowiedni przycisk (np. LED \u017c\u00f3\u0142ty &#8211; to i przycisk \u017c\u00f3\u0142ty, a nie niebieski. Niebieski to dyskwalifikacja! I na odwr\u00f3t).<\/p>\n<p>Inna modyfikacja polega na&nbsp;<strong>wychwyceniu falstartu<\/strong> &#8211; zapobiegni\u0119ciu sytuacji, \u017ce u\u017cytkownik bezmy\u015blnie &#8222;klika&#8221; przyciskiem w nadziei, \u017ce gdy LED si\u0119 za\u015bwieci &#8211; on w\u0142a\u015bnie wcisn\u0105\u0142 przycisk i otrzyma\u0142 bardzo kr\u00f3tki czas reakcji. Trzeba tak zrobi\u0107, aby wci\u015bni\u0119cie przycisku PRZED za\u015bwieceniem ko\u0144czy\u0142o zabaw\u0119. Podpowied\u017a: zamiast funkcji delay() w linii #13 trzeba sprytnie wykorzysta\u0107 p\u0119tl\u0119 while&#8230;<\/p>\n<p style=\"text-align: right;\">(c) KG 2018<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Na zaj\u0119ciach wykorzystali\u015bmy proste elementy do zbudowania prototypu maszyny badaj\u0105cej nasz refleks. Ale od pocz\u0105tku. Modu\u0142 z przyciskiem Modu\u0142 posiada trzy piny &#8211; GND oraz Vcc to zalsilanie, S to stygna\u0142 wysy\u0142any przez p\u0142ytk\u0119 (na innych p\u0142ytkach cz\u0119sto oznaczony OUT). My u\u017cywamy modu\u0142\u00f3w firmy RobotDyn (o nazwie Button Switch module) i trzeba przyzna\u0107 im dobr\u0105 [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":1121,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[52],"tags":[212,215,177,174,214,108,216,213],"class_list":{"0":"post-1126","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","6":"hentry","7":"category-fibot","8":"tag-button","9":"tag-los","10":"tag-millis","11":"tag-przycisk","12":"tag-rand","13":"tag-random","14":"tag-reakcja","15":"tag-refleks","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\/1126","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=1126"}],"version-history":[{"count":4,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/posts\/1126\/revisions"}],"predecessor-version":[{"id":1136,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/posts\/1126\/revisions\/1136"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=\/wp\/v2\/media\/1121"}],"wp:attachment":[{"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1126"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1126"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/physics.uwb.edu.pl\/wf\/fi-bot\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1126"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}