Pojďme programovat elektroniku | Chrome

Vyrobili jsme automat, který za nás hraje dinosaura v Chromu. Pomohly dva fotorezistory

  • Skrytou hru s dinosaurem zná úplně každý
  • Dnes ji za nás bude hrát primitivní automat
  • Kaktusy a ptáky bude hledat fotorezistorem

Máte na počítači Chrome? V tom případě jste si určitě alespoň jednou v životě zahráli dinosauříka – někdejší easter egg, který je dnes nedílnou součástí prohlížeče od Googlu a můžete jej kdykoliv vyvolat naťukáním interní adresy chrome://dino.

Pokud Chrome nepoužíváte, nic se neděje, černobílá hra stylizovaná do prehistorických osmibitů z osmdesátek se totiž dočkala hromady předělávek dostupných na webu. Stačí do vyhledávače napsat třeba dino game.

Postavíme automat na dinosaura

Logika hry je jednoduchá. Před ještěrem se objevují kaktusy, které musíte přeskakovat mačkáním mezerníku. Občas se ale z nebes snese i nějaký ten pták, takže se musíte naopak skrčit přidržením směrové šipky. Celá scéna ke všemu neustále zrychluje, čili pokud nejste hyperaktivní terminátor, dříve či později selžete.

Já se ve hře nikdy nedostal příliš daleko, vedle postřehu a obratnosti mi totiž chybí to zdaleka nejdůležitější: trpělivost. A proto dnes budu tak trochu podvádět a namísto vlastních očí, nervové soustavy a prstů na klávesnici do hry zapojím prototypovací destičku Pro Micro s osmibitovým řídícím čipem ATmega32U4 a dvojici fotorezistorů.

Čip bude hrát za mě a já budu jen s nohama na stole zírat, jak daleko se pokaždé dostane.

Podívejte se na video stavby automatu krok za krokem a na velký gameplay v závěru (automat hraje od 08:14):

Fotorezistor mění odpor podle intenzity světla

K čemu je nám takový fotorezistor vlastně dobrý? Díky tomu, že je hra alespoň v první fázi černobílá (tmavé prvky nad bílým pozadím), pomocí fotorezistoru připevněného k povrchu monitoru můžeme jednoduše detekovat překážky.

Fotorezistor (dříve fotoodpor) je totiž pasivní elektrická součástka, která už podle svého názvu reaguje na intenzitu světla a mění hodnotu elektrického odporu v zapojeném obvodu.

GL53528 za tři koruny

Pětimilimetrový fotorezistor typu GL5528 (PDF) pořídíte na českých e-shopech zhruba za 3 Kč. V naprosté tmě sníží svoji vodivost na minimum, takže jeho elektrický odpor vyskočí na 1 a více megaohmů. Při intenzitě osvětlení 10 luxů to bude zhruba 8-20 tisíc ohmů a při intenzitě 100 a více luxů pod 1 tisícem ohmů.

efef965b-8db4-4a13-907c-5913c3d58895
Fotorezistor GL55285. Blíže si jej představíme a vyzkoušíme ve videu v úvodu článku

Dělič napětí

Naše destička Pro Micro s čipem ATmega32U4, kterou české e-shopy prodávají zhruba za tři stovky, samozřejmě neumí měřit velikost elektrického odporu přímo, pomůže nám ale jeden z e základních elektrických obvodů s druhým rezistorem, kterému říkáme dělič napětí (voltage divider).

c21a7a47-f20a-4681-be92-cb0b6134c651
Dělič napětí v praxi

Dělič napětí používáme pro získání výstupního napětí, které je úměrné tomu vstupnímu a jeho podstata vychází z Ohmova zákona a faktu, že oběma rezistory v sériovém zapojení prochází stejný proud.

Platí tedy:

U = U₁ + U₂

A zároveň:

U₁ = R₁ × I

U₂ = R₂  × I

Z čehož lze odvodit:

U₂ = U × (R₂/(R₁+R₂))

Pokud v našem zapojení bude prvním rezistorem (R₁) proměnlivý fotorezistor, druhým rezistorem v sérii (R₂) třeba pevný rezistor s elektrickým odporem 10 tisíc ohmů a obvod připojíme k pracovnímu napětí desky 5 V (U), pak mezi uzlem uprostřed rezistorů a systémovou zemí naměříme napětí (U₂), které bude úměrné intenzitě dopadajícího světla na fotorezistor.

Když na fotorezistor posvítíme baterkou, jeho odpor klesne téměř k nule a naměřené napětí (U₂) se bude blížit tomu vstupnímu (U). Když fotorezistor umístíme do naprosté tmy, odpor vyskočí na velmi vysokou hodnotu a napětí nám klesne.

99a629a4-c4d1-497e-a655-76567e09ae90 4147394a-1f94-4f4a-8c5d-548d97be0df5
Fotorezistor snímá bílé a jasné pozadí, takže se nám v sériovém terminálu vypisují vyšší hodnoty okolo 870 (poslední sloupec; ostatní slouží pro určení minima a maxima A/D převodníku)
65587886-3003-4df1-b1f6-e7010c460f01dffaf3db-996f-414f-9bf1-720f721b422c
Nyní je pod fotorezistorem černý objekt kaktusu, takže intenzita světla klesla. V posledním sloupci na druhém obrázku tedy vidíme hodnoty okolo 649

Podstatné je to, že elektrické napětí v pracovním rozsahu desky (0 až 5 V) už můžeme měřit pomocí jejího vnitřního A/D převodníku a funkce Arduina anlalogRead. Ten je desetibitový, takže měřené napětí vyjádří celým číslem v rozsahu 0 až 1023.

Jeden fotorezistor hledá ptáky, druhý kaktusy

Čili zpět k mému dinosaurovi. Když fotorezistor zblízka namířím na svůj rozsvícený monitor, A/D převodník bude vracet hodnotu zhruba 870. Když se ale pod fotorezistorem zrovna nakreslí šedý kaktus, hodnota klesne zhruba na 650.

f210dc7c-7fae-4021-9de1-9ee1d13f99ca
Obvod našeho herního automatu s 5V deskou Pro Micro 

Kaktus zabírá jen pár pixelů a animace postupně zrychluje, náhlá změna v jasu tedy bude trvat třeba jen pár desítek milisekund.

Je na to třeba myslet a snímač připevnit v dostatečné vzdálenosti před ještěrem, fotorezistory jsou totiž sice laciné, ale také relativně pomalé. Náběh může trvat celé milisekundy. Kdybychom chtěli něco rychlejšího, nabízí se třeba kvalitní fotodioda. O ní ale zase někdy příště.

ATmega32U4 podporuje USB, takže i HID

Světelný odporový detektor, který je i tak stále mnohem svižnější než třeba čip kalibrovaného luxmetru, bychom tedy měli, no a o zbytek se už postará řídící čip ATmega32U4. Volba na něj padla především z toho důvodu, že podporuje protokol USB, a tak může počítači odeslat instrukci třídy USB HID – Human Interface Device Class.

Právě tento protokol používají USB klávesnice a myši a my v ní proměníme i náš řídící čip. Vše usnadní vestavěná knihovna ve vývojovém prostředí Arduino s prostým názvem Keyboard. USB HID nejprve nastartujeme metodou begin, no a když budeme potřebovat stisknout mezerník, aby náš dinosauřík vyskočil, metodou press odešleme numerický ASCII kód mezerníku 32, načež metodou release stisk zase uvolníme.

S letícími ptáky je to trošku složitější

Ještě se potřebujeme skrčit před létajícími ptáky, které bude sledovat druhý fotorezistor o pár milimetrů výše. Když zaznamená náhlé snížení intenzity světla, skrze USB tentokrát vyšleme stisk šipky dolů.

Na rozdíl od skoku tlačítko šipky hned neuvolníme, ale počkáme tak dlouho, dokud bude pod fotorezistorem tmavý objekt a zároveň nejméně 250 milisekund. V opačném případě by se totiž mohl ještěr narovnat v okamžiku, kdy nad ním ještě stále letí pták.

Fixní časová prodleva není ideální a nemusí fungovat v rychlejší fázi hry, nicméně pro základní experimenty to stačí. Pomohl by až třetí fotorezistor, který by měřil rychlost animace a upravoval by podle ní časové okamžiky všech operací. Fotorezistor by byl připevněný třeba 5 centimetrů před těmi ostatními, takže bychom snadno změřili, za jak dlouho tímto úsekem prolétne kaktus, kterému se potřebujeme vyhnout.

Zdrojový kód pro Arduino

Další podrobné vysvětlení včetně pohledu pod redakční lupu najdete v úvodním videu, kde si krok za krok vysvětlíme stavbu našeho herního automatu pro chrome://dino. Níže v článku jako vždy najdete komentovaný zdrojový kód pro Arduino, který je nicméně tentokrát opravdu velmi jednoduchý a je to vlastně jen začátek pro další experimenty.

Tak co, kdo z vás dosáhne nejvyššího skóre?

// NAavod k insytalaci podpory desky Pro Micro v prostredi Arduino: 
// https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide/installing-windows

// Knihovna pro USB HID emulaci klavesnice
#include <Keyboard.h>

// Cas prikrceni dinosaurika
uint32_t prikrceni_start = 0;
// Nejkratsi doba prikrceni dinosaurika (ms)
uint32_t prikrceni_doba = 250;

// Hlavni funkce setup se spusti po pripojeni napajeni
void setup() {
  // Aktivace USB HID - nyni se cip chova jako USB klavesnice
  Keyboard.begin();
}

// Smyckqa loop se opakuje stale dokola
void loop() {
  // Pomocne promenne zamku, ktere ohranicuji jednotlive udalosti stisku
  // Abychom do PC poslali vzdy jen jeden stisk klavesy
  static bool zamek_skok = false;
  static bool zamek_prikrceni = false;

  // Pokud fotorezistor detekujici ptaky a pripojeny na pin A0 zaznamenal snizeni intenzity svetla
  if (analogRead(A1) < 850) {
    // Uloz cas prikrceni v ms
    prikrceni_start = millis();
    // Pokud je zamek odemceny
    if (!zamek_prikrceni) {
      // Zamkneme zamek
      zamek_prikrceni = true;
      // Stiskneme klavesu sipky dolu
      Keyboard.press(KEY_DOWN_ARROW);
    }
  // Pokud naopak fotorezistor zaznamnava bilou barvu pozadi
  } else {
    // Pokud je zamek zamceny (probiha dej stisku) a zaroven uplynulo alespon 250 ms
    // od posledniho zaznamenaneho snizeni jasu,  uvolni stisk a odemkn izamek
    if (zamek_prikrceni && millis() - prikrceni_start >= prikrceni_doba) {
      Keyboard.release(KEY_DOWN_ARROW);
      zamek_prikrceni = false;
    }
  }

  // Analogicky postupujeme u druheho fotorezistoru detekujiciho kaktusy a pripojeneho k pinu A0
  // Tentokrat to ale bude jednodussi, mezernik totiz staci jen stisknout a zase uvolnit
  // Neni treba jej drzet, jako u prikrceni
  if (analogRead(A0) < 850) {
    if (!zamek_skok) {
      zamek_skok = true;
      Keyboard.press(32);
      Keyboard.release(32);
    }
  } else {
    zamek_skok = false;
  }
}
Diskuze (10) Další článek: Pošli mi fotku bez trička! Na děti útočí internetový svět. Jak je dobře ochránit a vzdělávat?

Témata článku: , , , , , , , , , , , , , , , , , , , ,