Konsola do gier video na Arduino

Tenis to najstarsza z gier video. Swoją premierę miała już w 1972 roku. Ja pamiętam ją jeszcze z mojego dzieciństwa  – w wersji na konsolę TVG-10. Spędziłem nad nią wiele godzin:)

pong_04Wspomnienia wróciły po wizycie w Muzeum Konsol Gier Video Karpaczu. Szybkie poszukiwanie w Sieci pokazało się, że w oparciu o Arduino można zbudować mini-konsolę podłączaną do telewizora. No to do roboty!

Projekt

Moja konsolka będzie oparta na Arduino UNO. Używając biblioteki TVOUT będę generował obraz analogowy w systemie PAL, który z kolei wyświetlę na telewizorze.

ovr_00Konsolka będzie wyposażona w mały wyświetlacz LED oparty o TM1637. Do sterowania systemem wykorzystam kilka przycisków typu tact. Przyda się również wyprowadzony na zewnątrz reset.

Gry będę obsługiwał za pomocą dwóch kontrolerów. Zamierzam zrobić właśnie takie, jakie były w TVG-10: walcowate z obracaną końcówką. Są znacznie wygodniejsze niż potencjometryczne (stosowane w niektórych typach urządzeń).

Całą konsolę zamknę w plastykowej obudowie. Konsola będzie zasilana przez zewnętrzny zasilacz 12v.

Podobne projekty były już opisywane w Sieci wielokrotnie – lista inspiracji na końcu tekstu.

Kontrolery

Moje kontrolery będą oparte na potencjometrach. Pamiętacie dzielnik napięciowy?

divider_1Potencjometr kontrolera wstawię w miejsce rezystora R2 i zmierzę na nim napięcie za pomocą pinu przetwornika analog/cyfra A0 (i A1 dla drugiego gracza):scheme_arduuVid_03

Oczywiście możecie zastosować ten potencjometr łącząc 5v i masę do pinów skrajnych a środkowy – do wejścia analogowego. Ale wtedy potrzebowalibyście 3 kabelków i nie można by już było wykorzystać prostego gniazda DC.

Dla rezystora R1=4k7 i potencjometry P1=10kΩ, napięcie mierzone przez A0 będzie wynosiło:
{U_{A0}}=5 \cdot {{P_1} \over {P_1+4700}}

Dla P1 = 0Ω (skrajna pozycja potencjometru), napięcie powinno być bliskie zeru. Dla P1 = 10kΩ (druga skrajna pozycja potencjometru):
{U_{A0}}=5 \cdot {{10000} \over {10000+4700}} = 3.4v

Biorąc pod uwagę, że funkcja „analogRead()” zwraca 0 dla 0v i 1023 dla 5v, przy tym dzielniku zwracane wartości powinny zwierać się w przedziale 0..690. W praktyce na pinie 5v nigdy nie ma 5v – pewnie coś około 4.8 do 4.9v. Rezystory mają swoje odchylenia od wartości nominalnych. W rezultacie pin A0 zwracał wyniki w zakresie 0..720 – ale jedynie, gdy potencjometr był podłączony. W przeciwnym wypadku – 1023.

Wartości te będą potrzebne do mapowania ustawienia potencjometru (zwracanego przez pin analogowy) do pozycji rakietki na ekranie, np.:

Zmienne ymin i ymax to współrzędne najwyższej i najniższej linii ekranu.

Do podłączenia kontrolerów użyłem gniazda zasilające DC do wtyków 2.1mm:

arduPong_04Z lenistwa kupiłem gotowy kabel z wtykiem pasującym do tych gniazd:

arduPong_05Pozostało przylutować kabeki:

arduPong_06Z drugiej strony do kabla przylutowałem potencjometr:

arduPong_09No i pomysł na kontrolery: butelki po kosmetykach:)

ctrl_00aWystarczyło zeszlifować gwint:

ctrl_01W zakrętkę włożyłem gałkę od potencjometru. Użyłem distala, żeby je połączyć:

ctrl_06 ctrl_07Z drugiej strony butelki wywierciłem otwór na potencjometr i odciąłem denko:

ctrl_02 ctrl_03 ctrl_05Pozostało wkleić  to denko wewnątrz tuby:

ctrl_04W efekcie:ardupong_17

ardupong_18 Operację należy powtórzyć dwa razy:)

Wyświetlanie obrazu na telewizorze

Do wyświetlania obrazu na telewizorze wykorzystałem bibliotekę TVOUT: https://github.com/Avamander/arduino-tvout/

Wystarczy  pobrać ją z wskazanego GitHuba jako plik zip i rozpakować do katalogu z bibliotekami Waszego Arduino IDE.

Teraz z katalogu „./arduino-tvout-master/TVoutfonts” skopiujcie wszystkie pliki do katalogu głównego biblioteki (zob. ten wątek). W ten sposób będziecie mogli użyć w swojej aplikacji wszystkie dostępne czcionki:

  • 4×6
  • 6×8
  • 8×8
  • 8x8ext

Otwórzcie nowy projekt i z menu „Szkic/Dodaj bibliotekę” dodajcie „TVOut”:

Dodajcie czcionki i zainicjalizujcie bibliotekę:

Biblioteka ta udostępnia kilka funkcji, które możecie użyć w swoich programach, np:

  • tv.fill(WHITE): wypełnij ekran kolorem białym (BLACK – czarnym),
  • tv.clear_screem(): wyczyść ekran,
  • tv.delay(1000): opóźnienie 1s,
  • tv.draw_column(10,10,50,WHITE): narysuj linię pionową na x=10 dla y=10..50 – białym kolorem (szybsze niż draw_line),
  • tv.draw_rect(50,50,10,10,WHITE): narysuj na ekranie kwadrat o boku 10 pikseli na pozycji (x, y): (50,50),
  • tv.print(): cały zestaw funkcji do wypisywania na ekranie tekstu.

A teraz uwaga (której odkrycie kosztowało mnie trochę czasu):

Biblioteka TVOUT mocno używa przerwań. Może zakłócać działanie innych bibliotek albo instrukcji Arduino. Na przykład… Serial.println().

Użycie w kodzie instrukcji Serial.println spowoduje przedziwne „efekty”. Obraz będzie nagle znikał a aplikacja będzie się wieszać. W związku z tym: nie używajcie modułu Serial.

Podłączenie do telewizora

Dla Arduino UNO:

  • Pin 9: synchronizacja,
  • Pin 7: sygnał video,
  • Pin 11: sygnał audio

Wybór pinów nie jest przypadkowy: dla UNO R3 nie możecie użyć innych. Biblioteka TVOUT wykorzystuje pewne dodatkowe funkcje portów kontrolera. Jeżeli zamiast AtMega328 (napędzającego UNO R3) użyjecie np. Arduino Mega lub Leonardo – będziecie musieli użyć trochę innych pinów – odsyłam do dokumentacji biblioteki.

Piny te wyprowadzę na 2 wtyczki typu cinch – jedną dla video, drugą dla audio. Wewnętrzny styk to sygnał – zewnętrzny to masa.

Do podłączenia video będziecie potrzebowali 2 rezystorów 1kΩ i 470Ω (na podstawie: TVOut library):

scheme_arduuVid_01Audio można podłączyć bezpośrednio:

scheme_arduuVid_02Teraz pozostało nawiercić w obudowie otwory pod gniazda cinch:

arduPong_01Do gniazd przylutowałem kable:

arduPong_02Złącza można dodatkowo zarobić koszulkami termokurczliwymi:

arduPong_03Wyświetlacz

Pomyślałem, że przyda się wyświetlacz, który będzie pokazywał np. wybraną grę albo stopień trudności. W tym celu użyłem modułu z TM1637.

arduPong_07Jego dokładny opis znajdziecie tutaj: Wyświetlacz LED z TM1637. Wyświetlacz przykręciłem do górnej części obudowy za pomocą czterech śrubek fi2mm/16mm:

arduPong_08Klawiatura

Na potrzeby wybierania gry, jej startowania i ustawiania poziomu trudności przyda się kilka przycisków. Mój wybór padł na standardowe przełączniki typu tact. Ponieważ ma być ich 4, postanowiłem podłączyć je poprzez port analogowy.

keys_08Dokładny opis takiego podłączenia znajdziecie w tym tekście: Arduino: przyciski podłączane do wejść analogowych. Przyciski przylutowałem na płytce uniwersalnej. Modulik zasilany jest z 5v. Przyciski podłączyłem do wejścia A2. Pamiętajcie również o połączeniu A2 z D2. W ten sposób będzie można podpiąć przerwanie pod port D2 i sprawdzać stan  klawiatury dopiero po wciśnięciu klawisza .

Dodatkowy reset

Już pierwsze doświadczenia z konsolą pokazały, że dodatkowy reset jest niezbędny. O tyle łatwiej było go wyprowadzić, że płytka rozszerzenia posiadała już pady do wlutowania odpowiedniego przycisku. Wystarczyło je przedłużyć  i wyprowadzić na piny:

arduPong_15_resetZa przycisk posłużył kolejny „tact switch” do którego dolutowałem kabelki z gniazdami gold pin:

arduPong_16_resetTeraz pozostało przykleić go w obudowie – z braku pomysłów użyłem gorącego kleju:

pong_12Widok na obudowie:

reset_00

Montaż

Arduino przykręciłem do podstawki za pomocą śrubek M2 tak, żeby gniazdo zasilające było na samej krawędzi:

arduPong_10arduPong_11

Jak widzicie użyłem Arduino w stylu „leonardo”. Klon był wyposażony w procesor AtMega328 (SMD) – ale w miejsce wielgachnego USB było microUSB. To pozwoliło mi ładniej wpasować płytkę w obudowę.

W górnej części obudowy wypiłowałem otwór na gniazdo DC:

arduPong_12Całość elektroniki zmontowałem na płytce rozszerzenia:

arduPong_13Nie było tego wiele:

  • Gniazda audio/video oraz kontrolerów podłączyłem do terminali,
  • Wyświetlacz, klawiaturę i reset podłączyłem przez gniazda typu gold pin.

arduPong_14Z gold-pinami miałem trochę problemów. Po nałożeniu kabelków po prostu nie mieściły się w obudowie:) Zdjąłem plastykową koronkę i wygiąłem piny…

pong_11pong_10Następnym razem pomyślę o pinach kątowych.

Całość zmieściła się w obudowie:

pong_01 pong_00 pong_03 pong_04

Oprogramowanie…

Na podstawie takiej mini-konsoli możecie napisać kilka całkiem interesujących gier. Tenis to jedna – ale przecież wcale nie musicie się do tego ograniczać. NES i inne konsole ery 8-bitowej mogą dostarczyć Wam wielu inspiracji.

Przykładowy kod tenisa możecie pobrać z blogu: How to recreate the classic Pong game…

Wymagane zmiany:

  • W projekcie How to…, autor użył potencjometrów, które podłączył bezpośrednio do wejść analogowych. Ja użyłem dodatkowych rezystorów, dzięki którym podłączyłem kontrolery na 2 przewodach – a nie 3. W projekcie z bloga potencjometry zwracają wartości z przedziału 0..1023, u mnie – 0..720. Trzeba więc przemapować wartości. W funkcji processInputs() zmieńcie linijki od 63:

    Na:
  • W tym projekcie jedyny klawisz podłączony był do D2. Jego stan odczytywano w procedurze processInputs(). W linijce 67 zamieńcie:

    na:

    W tym momencie wciśnięcie klawisza spowoduje uruchomienie gry

ardupong_00a

W kolejnym tekście z tej serii spróbuję przybliżyć Wam kilka pomysłów.

Podsumowanie

Łatwe? Cóż, wymaga trochę pracy. Zawsze tak jest, gdy z projektów wtykanych na płytce stykowej chcecie zrobić coś, co będzie „bardziej gotowe”. Prawdziwa zabawa zaczyna się gdy dochodzi do lutowania czy konieczności wykonania elementów mechanicznych – choćby tylko zmieszczenia wszystkiego w pudełku.

Polecam Wam jednak takie projekty. Nauczycie się przy nich więcej, niż w przypadku jakiegokolwiek innego projektu na płytce stykowej. A na końcu – można sobie pograć!

Do łatwiejszego pisania programu może Wam się przydać video grabber, opisałem go tutaj: Youtube, streamowanie i Logilink EasyCap.

Materiały

  • Arduino UNO R3, klon z microUSB – może być dowolny – mi taki po prostu pasował do obudowy,
  • Obudowa Z77 124x72x37mm czerwona,
  • Płytka rozwojowa dla Arduino, z resetem,
  • Płytka przewlekana, dwustronna, ok 3×5 cm,
  • Kabel z wtykiem DC 2.1/5.5mm przewód 2×0.22mm, 2 sztuki,
  • Gniazdo zasilające DC 2.1/5.5 mm na panel, 2 sztuki,
  • Potencjometr osiowy liniowy 10k, 2 sztuki,
  • Tact Switch 6x6x8mm czarny, 5 sztuk,
  • Rezystory około 10kΩ i 20kΩ, 1kΩ i 470Ω,
  • Gniazdo CHINCH (RCA) na panel złote 2szt,
  • Terminal blocki, 3 gniazda – 2 sztuki,
  • Śrubki M2 o długości 8mm (do przykręcenia Arduino) i 16mm po 10 sztuk powinno wystarczyć.

Przyda się mini-wiertarka, pistolet na gorący klej, pilniki i papier ścierny.

Źródła

Jeden komentarz do “Konsola do gier video na Arduino”

Dodaj komentarz