Skocz do zawartości

Przeszukaj forum

Pokazywanie wyników dla tagów 'Gry'.

  • Szukaj wg tagów

    Wpisz tagi, oddzielając przecinkami.
  • Szukaj wg autora

Typ zawartości


Kategorie forum

  • Elektronika i programowanie
    • Elektronika
    • Arduino i ESP
    • Mikrokontrolery
    • Raspberry Pi
    • Inne komputery jednopłytkowe
    • Układy programowalne
    • Programowanie
    • Zasilanie
  • Artykuły, projekty, DIY
    • Artykuły redakcji (blog)
    • Artykuły użytkowników
    • Projekty - DIY
    • Projekty - DIY roboty
    • Projekty - DIY (mini)
    • Projekty - DIY (początkujący)
    • Projekty - DIY w budowie (worklogi)
    • Wiadomości
  • Pozostałe
    • Oprogramowanie CAD
    • Druk 3D
    • Napędy
    • Mechanika
    • Zawody/Konkursy/Wydarzenia
    • Sprzedam/Kupię/Zamienię/Praca
    • Inne
  • Ogólne
    • Ogłoszenia organizacyjne
    • Dyskusje o FORBOT.pl
    • Na luzie

Kategorie

  • Quizy o elektronice
  • Quizy do kursu elektroniki I
  • Quizy do kursu elektroniki II
  • Quizy do kursów Arduino
  • Quizy do kursu STM32L4
  • Quizy do pozostałych kursów

Szukaj wyników w...

Znajdź wyniki, które zawierają...


Data utworzenia

  • Rozpocznij

    Koniec


Ostatnia aktualizacja

  • Rozpocznij

    Koniec


Filtruj po ilości...

Data dołączenia

  • Rozpocznij

    Koniec


Grupa


Imię


Strona


TempX

Znaleziono 7 wyników

  1. Witam wszystkich! Po dłuższej nieobecności na formu chciałbym zaprezentować Wam kilka z moich najnowszych projektów przy okazji po krótce omawiając magistralę CAN bus. *** Wstęp *** Do tej pory opublikowałem dwa wpisy na forum opisujące budowę analogowych liczników samochodowych od Forda Galaxy oraz Audi A3 8L. Są to projekty niezwykle proste w budowie, wystarczy na określony pin podać 12V, masę lub sygnał z Arduino o określonej częstotliwości aby ożywić cały licznik i wszystkie wskazówki. Jednak ze względu na swoją prostotę projekty te posiadają liczne ograniczenia - przede wszystkim nie jesteśmy w stanie idealnie symulować zmiennej rezystancji czujnika poiomu paliwa oraz temperatury cieczy. Dodatkowo większosć kontrolek działa w logice 12V przez co nie można nimi sterować bezpośrednio z Arduino. Wszystkie te ograniczenia obchodzą liczniki, które do komunikacji wykorzystują magistralę CAN bus. *** Założenia projektu *** Projekt licznika miał być przede wszystkim uniwersalny i działać z szerokim wachlarzem gier - od ETS 2 gdzie prędkości obrotowe silnika wynoszą do 2500 RPM a prędkość rzadko kiedy przekracza 120km/h przez Framingi, BeamNG, Asseto Corsa na F1 kończąc gdzie silnik wkręca się powyżej 10.000 RPM a prędkości znacznie wykraczają za maksymalne wychylenie prędkościomierza licznika samochodowego. Licznik umożliwić ma nie tylko odczyt podstawowych parametrów prowadzonego pojazdu tj. obroty silnika, prędkość, temperatura cieczy, oleju czy poziomu paliwa ale także informować o stanie świateł, silnika czy nawet opon. *** Potrzebne materiały *** Arduino MCP2515 Zasilacz 12V (1A w zupełności starczy) Przewody połączeniowe *** Jak to działa? *** Do budowy projektu wykorzystałem dobrze znane większości z Was Arduino NANO wyposażone w USB-C. Dialog z licznikiem prowadzony jest poprzez moduł CAN MCP-2515 a całość zasila 12V zasilacz sieciowy. Całość umieściłem w małej obudowie wydrukowanej na drukarce 3D. Nie wgryzając się za bardzo w szczegóły techniczne - CAN bus to szeregowa magistrala danych wykorzystująca do komunikacji 2 przewody opisywane jako CAN-H oraz CAN-L. Jak łatwo się domyślić na przewodzie CAN-High panuje nieco wyższe napięcie niż na CAN-Low. CAN Bus jest magistralą działającą w sposób różnicowy czyli mierzy i porównuje napięcia na CAN-H oraz CAN-L. W ten sposób odczytywane są bity dominujące i recesywne tworąc ciąg zer i jedynek. Dla ułatwienia projektu nie oparłem o liczby binarne tylko znacznie przyjemniejsze dla oka - heksadecymalne. Ramka CAN wysyłana do licznika składa się z unikalnego identyfikatora (ID) oraz określonej ilości bajtów danych. Każdy bajt danych może przyjąć wartość od 0 do FF czyli decymalnych 255. Dla przykładu aby zapalić kontrolkę hamulca ręcznego w liczniku od Peugeota 407 muszę nadać ramkę o ID 128 a bicie zerowym nadać wartość 24HEX. Wygląda to mniej więcej tak: [ ID 128 0x24 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ]. Pod pozostałymi bitami kryją się kolejne kontrolki tj. kierunkowskazy, światła mijania, drogowe, przeciwmgielne oraz nielubiany przez kierowców check engine. Pod różnymi ID ramek można odnaleźć pozostałe funkcje licznika - sterowanie wskazówkami, podświetleniem, ustawianie przebiegu itd. Warto pamiętać, że niektóre liczniki po otrzymaniu zasilania będą pozornie wyglądać na martwe. Takie konstrukcje potrzebują tak zwanego sygnału przebudzenia, który "obudzi" licznik. Jeśli taki sygnał występuje to jest to pierwszy krok aby zacząć zabawę z licznikiem. *** Projekt licznika *** Do moich projektów wykorzystuję liczniki z samochodów Peugeot oraz Citroen. Magistrala CAN w obu markach jest bliźniaczo podobna i różnią się jedynie małymi szczegółami. Najważniejsze, że obie marki wykorzystują taką samą szybkość magistrali wynosząca 125Kbps. Do kontroli modułu MCP2515 wykorzystałem bibliotekę MCP2515.h. W pierwszej kolejności łączę moduł CAN z Arduino oraz podłączam magistralę wraz z zasilaniem do licznika. Należy pamiętać, że każdy licznik posiadać może swój własny indywidualny pinout. Powyżej można zobaczyć pinout licznika Citroen C3 I FL. Po podłączeniu wszystkich 4 przewodów wgrywam przygotowany wcześniej kod na Arduino. Warto zatrzymać się na chwilę przy kodzie i zastanowić się jak projektant tworzył licznik. Zespół projektujący licznik miał surowe dane - maksymalne obroty silnika 5200 RPM, maksymalna temp. cieczy 130℃, maksymalna temp. oleju 150℃, maksymalna prędkość 260km/h. Licznik przygotowany jest oczywiście na taki zakres danych z minimalnym zapasem jednak po przekroczeniu skali obrotomierza lub wskaźnika temperatury zaczną dziać się różne dziwne rzeczy. Wartości out of range są różnie traktowane przez liczniki - jedne ustawiają wskaźnik na "0", drugie wyłączają się a trzecie mogą się zawiesić. Dane z gier praktycznie zawsze będą wykraczać poza zakresy ustalone przez producenta więc trzeba przeanalizowaćkażdą grę z osobna i zastosować zabezpieczenia oraz skalowanie tak, aby wartości zawsze znajdowały się w akceptowalnym przez licznik zakresie. Kod musi brać także poprawkę na nieliniowość wskaźników temperatury - rzadko kiedy 1° obrotu silnika krokowgo będzie odpowiadał dokładnie takiemu samemu przyrostowi temperatury. Do przykładu - wskazówka temp. cieczy "zastyga" na 90℃ gdy faktyczna temperatura cieczy waha się od ~85-93℃. Dalszy wzrost temperatury będzie powodował niewielki wzrost wychylenia wskazówki. Jednak gdy temperatura niebezpiecznie wzrośnie to wskazówka momentalnie zwiększy swoją czułość i będzie wykonywać znaczny ruch co każdy 1-2℃. *** Dane z gier *** Po przetestowaniu kodu na "suchych" danych wpisanych "z palca" do kodu wypadałoby przestawić się na dane przesyłane z gier do licznika w czasie rzeczywistym. Za przygotowanie danych odpowiada aplikacja SimHUB współpracująca ze specjalnie napisaną przeze mnie formułą NCalc "obrabiającą" surowe dane z gier na zakresy liczbowe zaimplementowane w kodzie. Wygląd danych, którymi "karmię" kod Arduino przedstawiam poniżej. Jest to oczywiście wycinek danych ponieważ ogranicza mnie pole wyświetlające Raw result. *** Efekt końcowy *** Po wielu próbach i testach udało mi się ujarzmić prawie cały licznik. Wszytskie wskazania licznika: prędkość obrotowa silnika prędkość pojazdu poziom paliwa temp. cieczy temp. oleju wskaźnik biegów Kontrolki: hamulec ręczny kierunkowskazy światła mijania, drogowe, przeciwmgielne brak ładowania akumulatora niskie ciśnienie oleju rezerwa przegrzanie cieczy przebita opona przebieg nastawa tempomatu / aktualna prędkość pojazdu niskie ciśnienie w układzie hamulcowym (ETS2/ATS wykorzystując kontrolkę wody w filtrze paliwa) podniesienie osi (ETS2/ATS wykorzystując kontrolkę wyłączonej poduszki powietrznej pasażera) kończącego się czasu pracy (ETS2/ATS wykorzystując kontrolkę uszkodzenia wspomagania kierownicy oraz kontrolkę pasów bezpieczeństwa) przekroczonego limitu prędkości na drodze (ETS2/ATS wykorzystując kontrolkę usterki tempomatu (tylko Peugeot 407)) zbyt wysokich obrotów (ETS2/ATS wykorzystując kontrolkę trójkąta ostrzegawczego) retardera (ETS2/ATS wykorzystując kontrolkę świec żarowych) ekonomicznej jazdy (wykorzystując kontrolkę ECO) działanie ESP działanie ABS Działanie licznika w grach można zobaczyć na poniższych zdjęciach. *** Zbuduj sam własny projekt i odkrywaj tajniki CAN BUS! *** Z tego miejsca chciałbym gorąco zachęcić wszystkich zainteresowanych do spróbowania swoich sił i budowy własnego projektu z licznikiem opartym na magistrali CAN Bus. Elementy niezbędne do budowy projektu oraz same liczniki są bardzo tanie i projekt powinien spokojnie zamknąć sie w 100-150zł. Magistrala CAN grupy PSA jest bardzo dobrze opisana, obszerną dokumentację stanowiącą fundamentalny filar wiedzy można znaleźć pod TYM linkiem. Jeśli do wybranego przez Ciebie licznika nie ma żadnej dokumentacji to nic straconego, wystarczy napisać bardzo prosty generator losowych wartości bajtówki. Metoda ta nazywa się brute force i jest bardzo efektywna. Należy jednak korzystać z niej ostrożnie ponieważ istnieje niewielka szansa na zbrickowanie licznika. Eksperymentowanie z licznikiem oraz CAN Bus'em pozwoli Tobie także lepiej zrozumieć cały proces komunikacyjny, który finalnie zapala nielubiany check engine na liczniku. Za pomocą modułu MCP2515 możesz także podsłuchać co "szumi" w magistrali CAN Twojego samochodu. Jeśli rozszyfrujesz te dane to nic nie stoi na przeszkodzie abyś zaprojektował swój własny wyświetlacz doładowania, cyfrowy prędkościomierz czy wyświetlacz temperatury oleju w silniku. *** Wykorzystaj mój kod! *** Jeśli jednak nie czujesz się na siłach aby zbudować własny licznik to możesz bez problemu wykorzystać opracowane przeze mnie liczniki wraz z kodem na Arduino. Wszelkie informacje odnośnie budowy takiego projektu znajdziesz w poradniku na moim kanale:
  2. Dzisiaj taki faktycznie mały projekcik, zrealizowany (nie licząc czasu druku) w dwa popołudnia. Od pewnego czasu chodzi za mną małe, przenośne ustrojstwo oparte na RPi, czyli taka przenośna linuksowa konsolka. No - ale sama konsolka byłaby za nudna, warto by było coś tam ciekawego zainstalować... nawet się nie zastanawiałem, i wybrałem emulator VICE. Trochę miałem problemów, ale całość ładnie ruszyła (ekran ST7789 320x240, dźwięk I2S, nad zasilaniem jeszcze się namyślam), ale jeśli już emulacja C64 to przydałby się jakiś joystick (na podłączonej mini-klawiaturze od biedy da się pisać, ale o graniu można zapomnieć). Kupno raczej nie wchodziło w grę, poza tym konsolka ma być mała, a taki Quickshot byłby pewnie co najmniej tak duży jak ona... a chciałem żeby to był0o naprawdę małe, ale jednocześnie używalne. Tak więc trzeba było zajrzeć do swoich rupieci. I co przydatnego znalazłem: Wemos LOLIN32 Lite Joystick analogowy Waveshare (PSP1000) Akumulator 1200 mAh I oczywiście jakieś pstryczki, przełączniki i tym podobne drobiazgi, Zacząłem oczywiście od sprawdzenia sposobu komunikacji joysticka z konsolką. Od razu założyłem, że nie ma tam być żadnych kabli - najprostsze było połączeniu BLE. Po kilku próbach doszedłem do wniosku, że joystick będzie po prostu udawać drugą klawiaturę i użyję klawiszy które nie są zmapowane na klawiaturę C64. No i po paru próbach wyszło mi coś takiego: Urządzenie sprawdza się nadspodziewanie dobrze, przynajmniej w prostych grach. Jedynym problemem były ostre krawędzie w pierwszej wersji obudowy, utrudniające wygodne trzymanie. Kod jest krótki (niecałe 200 linii) więc zamieszczam go w całości: #include <BleKeyboard.h> #include <Bounce2.h> BleKeyboard bleKeyboard("BlueShot-I"); const uint8_t led_pin = 33; const uint8_t key1_pin = 27; const uint8_t key2_pin = 26; const uint8_t fire_pin = 25; const uint8_t x_pin=39; const uint8_t y_pin=36; Bounce AfButton=Bounce(), TfButton=Bounce(), FiButton=Bounce(); bool autoFire=false; uint32_t fireDelays[]={220, 150, 100, 70, 50, 500, 330}; const int fireDelayCnt = sizeof(fireDelays) / sizeof(fireDelays[0]); int fireDelayNo = 0; uint32_t fireTimer; uint32_t ledTimer; void setup() { Serial.begin(115200); pinMode(led_pin, OUTPUT); digitalWrite(led_pin,1); pinMode(fire_pin, INPUT_PULLUP); AfButton.attach(key1_pin, INPUT_PULLUP); TfButton.attach(key2_pin, INPUT_PULLUP); FiButton.attach(fire_pin, INPUT_PULLUP); AfButton.interval(30); TfButton.interval(30); FiButton.interval(10); bleKeyboard.begin(); ledTimer = millis(); } int keys[2][5]={ {KEY_NUM_8, KEY_NUM_2, KEY_NUM_4, KEY_NUM_6, KEY_NUM_0}, {KEY_NUM_SLASH, KEY_NUM_ASTERISK, KEY_NUM_PLUS, KEY_NUM_MINUS,KEY_NUM_PERIOD}}; uint8_t keySet=0; uint8_t lastKeys,thisKeys; int autoFirePos(int fire) { static int lastFire = 0; static bool fireState = false; if (!fire) { lastFire=0; return 0; } if (!lastFire) { fireTimer = millis(); fireState=true; lastFire = 1; } else if (millis() - fireTimer >= fireDelays[fireDelayNo]) { fireState = !fireState; fireTimer=millis(); } return fireState; } int xRead(int pin) { int i,sum; for (i=sum=0;i<32;i++) sum+=analogRead(pin); return sum /32; } #define BIT_JU 1 #define BIT_JD 2 #define BIT_JL 4 #define BIT_JR 8 static uint8_t dirbits[]={ BIT_JR,BIT_JR+BIT_JD, BIT_JD, BIT_JD+BIT_JL, BIT_JL, BIT_JL+BIT_JU, BIT_JU, BIT_JU+BIT_JR}; int readDirection() { int x=xRead(x_pin)-1800; int y=xRead(y_pin)-1800; int w=sqrt(x*x+y*y); if (w < 900) return 0; float a = atan2(y,x) * (4.0/PI) + 4.0625; w=(int)a; return dirbits[w & 7]; } void addKey (KeyReport *kr, uint8_t key) { int i; if (key >= 136) key -= 136; else if (key >= 128) { kr->modifiers |= 1 << (key & 7); return; } for (i=0;i<6;i++) if (!kr->keys[i]) { kr->keys[i] = key; break; } } enum { LEDCTL_NONE=0, LEDCTL_AUTOFIRE, LEDCTL_KEYSET}; uint8_t ledStatus; uint8_t ledControl=0; uint32_t ledControlTimer; void loop() { TfButton.update(); AfButton.update(); FiButton.update(); if (AfButton.rose()) { if (AfButton.previousDuration() > 400) { keySet = 1 - keySet; ledControl = LEDCTL_KEYSET; ledControlTimer = millis(); } else autoFire = !autoFire; } if (TfButton.fell()) { if (ledControl == LEDCTL_AUTOFIRE) fireDelayNo = (fireDelayNo + 1) % fireDelayCnt; else ledControl=LEDCTL_AUTOFIRE; ledControlTimer = millis(); } bool afToLed=false; if(bleKeyboard.isConnected()) { int i,fr; KeyReport kr; thisKeys=0; memset((void *)&kr,0,sizeof(kr)); thisKeys=readDirection(); fr=!FiButton.read(); if (fr) ledControl = LEDCTL_NONE; if (autoFire) { if (fr) afToLed = true; fr=autoFirePos(fr); } if (afToLed) ledStatus = fr; else ledStatus = millis() - ledTimer <= 50; if (fr) thisKeys |= 1<<4; if (thisKeys != lastKeys) { for (i=0; i<5; i++) if (thisKeys & (1<<i)) addKey(&kr,keys[keySet][i]); lastKeys = thisKeys; bleKeyboard.sendReport(&kr); delay(10); } } else { ledStatus = millis() - ledTimer >= 100; } uint32_t delta ; switch(ledControl) { case LEDCTL_KEYSET: delta = (millis() - ledControlTimer)/150; if (delta >= 24) ledControl = LEDCTL_NONE; else { static uint8_t pls[2][8] = { {1,0,1,1,1,0,0,0}, {1,1,1,0,1,0,0,0}}; ledStatus = pls[keySet][delta & 7]; } break; case LEDCTL_AUTOFIRE: delta= millis() - ledControlTimer; if (delta >= 3000) ledControl = LEDCTL_NONE; else { delta /= fireDelays[fireDelayNo]; ledStatus = delta & 1; } break; } digitalWrite(led_pin, ledStatus); if (autoFire) { if (millis() - ledTimer >= 500) ledTimer = millis(); } else { if (millis() - ledTimer >= 1000) ledTimer = millis(); } } Potrzebne biblioteki: stara dobra Bounce2 i ESP32-BLE-Keyboard. Fragment pliku sdl-vicerc dla c64: KeySet1North=264 KeySet1East=262 KeySet1South=258 KeySet1West=260 KeySet1Fire=256 KeySet2North=267 KeySet2East=269 KeySet2South=268 KeySet2West=270 KeySet2Fire=266 Ciekawsze możliwości: Autofire (oczywiście włączany na żądanie) z regulowaną częstotliwością (7 możliwości od 1 do 10 Hz), zsynchronizowany z przyciskiem fire (tzn. wciśnięcie fire od razu oddaje pierwszy strzał) Możliwość przełączenia zestawu klawiszy (w praktyce przy odpowiednim skonfigurowaniu x64 pozwala to na szybkie przełączanie portów). Pojedyncza dioda w czytelny sposób podaje stan połączenia BLE, włączenie i częstotliwość autofire oraz numer zestawu klawiszy. Schematu nie podaję bo jest trywialny - praktycznie wszystko wynika z kodu. Będę chciał tam jeszcze jakoś zmieścić gniazdo DB9 (żeby można było Quickshota podłączyć albo inną stalową wajchę), w programie to dołączenie raptem paru linijek w funkcji readDirection. Jakby ktoś miał jakieś pomysły - bardzo proszę o komentarz.
  3. W tym projekcie chciałbym opisać krok po kroku proces podłączenia licznika samochodowego od Forda Galaxy do naszego Arduino. Potrzebne elementy: Zasilacz 12V Arduino Przewody męsko-żeńskie Licznik samochodowy Zestaw wskaźników od Forda Galaxy posiada 2 wtyczki - czerwoną oraz czarną. Nas w tym projekcie interesuje tylko czerwona wtyczka gdyż znajdują się w niej piny zasilające oraz dostarczające dane do silników krokowych w liczniku. Najpierw zajmijmy się zasilaniem. Do pinu 3 oraz do pinu 4 na liczniku wpinamy 2 przewody i podłączamy je do minusa na naszym zasilaczu a kolejne 2 przewody wpięte w pin 14 oraz w pin 15 podłączamy do +. Jako zasilacz może nam posłużyć zwykły zasilacz komputerowy kub jakikolwiek o napięciu 12V. Dalej zajmijmy się podłączeniem silniczków od wskazówek. obrotomierz - 10 pin prędkościomierz - 27 pin wskaźnik poziomu paliwa - 21 pin wskaźnik temperatury cieczy - 23 pin (pin 1 jest w lewym dolnym rogu wtyczki) Następnie przewody te wpinamy w wejścia cyfrowe do Arduino. W moim przypadku obrotomierz wpiąłem w wejście oznaczone 2, prędkościomierz w wejście nr 3, wskaźnik poziomu paliwa 4 a temp. cieczy w wejście 5. Jeżeli po podpięciu zasilania licznik zadziała (wskazówki ustawią się w położeniu 0 oraz włączy się podświetlenie) to możemy przejść do konfiguracji. Pobieramy oprogramowanie SimHub i instalujemy je. Po uruchomieniu programu przechodzimy do zakładki Arduino a następnie klikamy na zakładkę "My hardware". Wybieramy "Single Arduino" i klikamy "Open arduino setup tool". Następnie definiujemy w jakie wejścia wpięliśmy nasze wskaźniki. Wybieramy z jakiego arduino korzystamy (w moim przypadku jest to UNO) oraz wybieramy port komunikacyjny. Gdy wszystko mamy już zrobione klikamy Upload to arduino i czekamy aż program zostanie wgrany na Arduino. Jeżeli program wgrał się poprawnie przechodzimy do zakładki "Gauges" i kalibrujemy nasz licznik. Wartości liczbowe są indywidualne dla każdego licznika ale to co musimy ustawić do każdego licznika to MAX Tachometer RPM na 7 (jeżeli zakres na tarczy obrotomierza jest inny to podajemy maksymalną liczbę, jeśli jest to 5 to podajemy 5) oraz tachometer cylinders na 6. Warto zaznaczyć opcję "Always use tachometer full range" jednak jeśli sprawia ona problemy możemy ją wyłączyć. Resztę wartości musimy ustawić tak, żeby wskazówka poprawnie wskazywała położenie min i max. Niestety nie ma uniwersalnych wartości i prędkościomierz u mnie wskazuje poprawnie 240 km/h przy wartości 222 (speedo gauge maximum output) jednak w innym liczniku może być to wartość ciut większa lub mniejsza. Na samym końcu wybieramy grę w którą chcemy zagrać z zakładki "Games". Następnie uruchamiamy naszą grę i cieszymy się rozgrywką z naszym licznikiem. Ktoś mi może powiedzieć "Przecież można napisać kod", zgodzę się z tym tylko ja gram od ETS 2 przez Dirt 4 na Forzie kończąc. O wiele łatwiej jest jednym kliknięciem zmienić grę w simhubie niż pisać osobny kod eksportujący dane z telemetrii do Arduino. Jeżeli ktoś potrzebuje tylko licznika do jednej gry to ma to sens jednak w moim przypadku mija się to z celem. Koszt takiego licznika może zamknąć się w okolicach 50 zł. Możemy wykorzystać klona arduino (klon nano możemy kupić za mniej niż 15zł), a licznik możemy znaleźć na portalach aukcyjnych za ok 20zł. Jest to niedrogi i fajny bajer a na dodatek jest bardzo praktyczny. Poniżej znajdują się zdjęcia i gif pokazujący pracę urządzenia.
  4. Cześć, mam ambitny pomysł odbudowy starego kontrolera do gier, z którego została mi tylko obudowa i przyciski. Myślę, że projekt jest na tyle prosty, że można od niego zacząć naukę mikrokontrolerów. Do tej pory robiłem jedynie proste projekty na Arduino uno/nano, który jednak ma tą wadę, że nie potrafi udawać HID. Mój pierwszy plan był, by kupić Arduino micro, który może bezpośrednio rozmawiać z USB ale niestety po pierwsze oryginalne Arduino przekracza mój budżet, po drugie ma za mało wejść (szczególnie ADC). I tu wpadł mi w oko STM32 a konkretniej "blue pill". Nigdy na nim nie programowałem więc mam parę pytań zanim zacznę, żeby oszczędzić sobie przyszłej frustracji: Jak wygląda kompilowanie i wgrywanie programu? Z tego co się już dowiedziałem, nie mogę po prostu wpiąć go do usb jak Arduino i wgrać program. Czy potrzebuję oficjalnego programatora? A może wystarczy chiński konwerter "USB to UART" na bazie CH340 lub PL2303? Czy mógłbym użyć Arduino jako programatora STM32? Jaki software polecacie na początek by pisać i wgrywać programy na kontroler? Który mikrokontroler wziąć na początek? F103C8T6 wydaje się być dość popularny. Czy bez zaawansowanego hackowania można sprawić by ten mikrokontroler przestawiał się komputerowi jako "game pad (HID)" i rozmawiał z komputerem? Czy jest coś o czym nie wiem a powinienem wiedzieć zanim zacznę? Częste błędy i trudności początkujących? Z góry dzięki za wszelkie porady i podpowiedzi
  5. Głównym założeniem tego projektu było stworzenie urządzenia wyświetlającego liczbę klatek na sekundę w grach komputerowych, jak i również innych informacji o obciążeniu komputera. Zdaje sobie sprawę, że projekty podobnego to tego pojawiały się już nie raz w sieci pod różnymi postaciami. W tym projekcie skupiłem się jednak na tym, aby całość zmieściła w małej kompaktowej obudowie, którą można w elegancki sposób zamontować pod monitorem. Możliwość wyświetlania FPS również jest tutaj czynnikiem wyróżniającą ten projekt na tle innych. Jest tak głównie dlatego że o ile informacje o wykorzystywanej ilości pamięci RAM, czy też obciążeniu procesora można dosyć łatwo pozyskać za pomocą różnych bibliotek w programie po stronie komputera, tak z klatkami na sekundę jest trochę trudniej. Użyte komponenty Sama budowa tego monitorka jest naprawdę prosta. Zostały w nim użyte właściwie tylko 3 komponenty: Arduino nano wyświetlacz OLED 128x32 przycisk dotykowy Pierwotnie zakładałem również użycie diody LED do sygnalizacji pewnych błędów, czy też wciśnięcia przycisku dotykowego. Uznałem jednak, że w tym przypadku nie miało by to większego sensu zważając na potrzebę minimalizacji. Można byłoby się zastanowić czemu wybór padł na arduino nano, a nie np. arduino pro micro. Arduino pro micro jest mniejsze, prawda? Zgadza się, dlatego też użyłem tego mikrokontrolera w pierwszej wersji tego wyświetlacza, który skończył dość marnie. Było tak dlatego, że przez przypadek chcąc poprawić przewód HDMI za monitorem, szarpnąłem niechcący za przewód idący do arduino. No i stało się, wyrwałem wtyk micro USB z płytki. Chcąc uniknąć ponownie takiej wpadki w następnej wersji użyłem mikrokontrolera, który kosztem ciut większej wielkości jest tańszy oraz posiada lepiej zamontowany na płytce wtyk USB mini. Jeśli chodzi o wyświetlacz to sprawa była prosta. Taki OLED 128x32 nie tylko rozmiarami idealnie pasuje do całego projektu, ale też po prostu prezentuje się ładnie i daje dużo możliwości. No i na koniec czujnik dotykowy. Dostępny w wielu rozmiarach, tani oraz przede wszystkim nie wymagający praktycznej żadnej siły do jego aktywacji. Ukryty w prawym boku obudowy dodaje estetyczności, nie zmniejszając przy tym komfortu użytkowania. Obudowa Obudowa została w całości wydrukowana na drukarce 3D. Sam model do druku zaprojektowałem w programie Fusion 360. Tak jak już pisałem, zależało mi na niewielkich rozmiarach. Dlatego cały model przeszedł przez wiele iteracji, a w każdej z nich starałem się zminimalizować jego wielkość. Zadbałem tutaj również o to, aby każdy z elementów w środku miał dopasowane pod siebie miejsce celem łatwego montażu. Po historii z wyrwaniem wejścia na płytce, finalnie dodałem jeszcze mały uchwyt na przewód mający minimalizować ryzyko ponownego uszkodzenia portu USB. Software Oprogramowanie po stronie komputera to prosty skrypt napisany w pythonie. Poza łączeniem się z arduino i przesyłaniem mu danych, musi te dane jeszcze skądś brać. I tutaj pojawił się mały problem, jeśli chodzi o pobranie ilości klatek w aktualnie włączonej grze. Nie da się od tak wyliczyć takiej wartości w programie, nie ma też na to gotowej funkcji. Z pomocą przyszedł popularny program o nazwie Msi AfterBurner. Nie wchodząc w szczegóły, program ten pozwala na monitorowanie zasobów komputera ( RAM, CPU, GPU itp.), jak i również uzyskanie potrzebnych nam FPS w aktualnie włączonej grze/programie. Teraz już tylko wystarczyło użyć wbudowanej w program funkcji do logowania tych danych do pliku, oraz odczytać je w pythonie i przesłać do arduino. Czy taki sposób jest wydajny? Cały proces wykorzystania pliku jako bufora do danych nie powinien w znaczący sposób obciążyć komputera, jednak lepszą opcją byłoby wykorzystywanie współdzielenia pamięci między dwoma programami. Aby to jednak osiągnąć potrzebna jest trochę większa wiedza z programowania w C++/C#, której niestety jeszcze nie posiadam. W przypadku arduino program po za odczytaniem danych oraz ich wyświetleniem, obsługuje również dotykowy przycisk. Pojedyncze dotknięcie przycisku zmienia wyświetlaną zawartość na 1 z 6 ekranów, zaś przytrzymanie przycisku powoduje zmianę ekranu co jedną sekundę. Dostępnymi ekranami są: klatki na sekundę, użycie CPU i GPU, temperatura CPU i GPU, użycie pamięci RAM i VRAM, prędkość wentylatora oraz ekran główny powodujący wygaszenie ekranu po paru sekundach. Dalsze plany W przyszłości planuje jeszcze większą minimalizacje wielkości obudowy, bo jest na tym polu jeszcze dużo do zrobienia. Mam zamiar również poduczyć się C++, aby móc wykorzystać współdzieloną pamięć między programami, rezygnując z odczytywać danych z pliku.
  6. Cześć majsterkowicze! Jakiś czas temu zakupiłem konsolę Nintendo Switch, po wielu godzinach frajdy jaką mi dała włączył mi się instynkt majsterkowicza i zrodziła idea zbudowania własnej konsoli. 😃 Początkowo rozważałem użycie Raspberry Pi i zbudowanie handheldowego emulatora na Retro Pi. Jednak biorąc pod uwagę, że z zawodu jestem programistą a tam nie miałbym za wiele do "kodzenia" stwierdziłem, że zejdę poziom niżej i spróbuję coś zrobić w oparciu o AtMegę. Zamysł był prosty, stworzyć konsolę na AtMedze z własnym firmware i silnikiem do tworzenia gier a potem zaprogramować na nią jakieś gry. Pod ręką jednak nie miałem żadnego wolnego "odpowiednio mocnego" mikrokontrolera od MicroChipa, więc musiałem się poratować Arduino ProMini z AtMegą 328. Do interakcji z użytkownikiem wykorzystałem TactSwitche (4 jako przyciski kierunkowe, 1 akcji ale rozważam dodanie 2 przycisku akcji aby stworzyć układ znany z klasycznego GameBoya) oraz wyświetlacz OLED 128x64 komunikujący się z Arduino przez I2C. Do tego wszystkiego dołączyłem Buzzer aby dodać efekty dźwiękowe i proste melodyjki 🙂 Zasilanie całej konsoli odbywałoby się przez stabilizator 7805 z baterii 9V (wiem, że jest niekonieczny przy Arduino ale zostawiłem go na wypadek późniejszej wymiany Arduino na suchą AtMege :D). Poniższy schemat pokazuje nieskomplikowaną budowę konsoli. Jako pierwszą grę stworzyłem klona kultowego Pong ale dla jednego gracza (drugą paletką kieruje sztuczna inteligencja). Kod gry można zobaczyć poniżej: #include <Adafruit_SSD1306.h> #include "engine.h" #define PLAYER_SPEED 50 #define ENEMY_SPEED 80 #define BALL_START_SPEED 40 #define BALL_MAX_SPEED 60 float player_y; float enemy_y; float enemy_movement; unsigned long last_decision; unsigned long last_incrementation; float ball_x; float ball_y; short ball_speed; short ball_motion_x; short ball_motion_y; short player_score; short enemy_score; long currentTime; long oldTime; float deltaTime; void resetBall() { ball_x = 62; ball_y = 30; ball_motion_x = -1; ball_motion_y = 1; ball_speed = BALL_START_SPEED; delay(500); } void gameSetup() { player_y = 22; enemy_y = 22; enemy_movement = 0; player_score = 0; enemy_score = 0; resetBall(); } void gameLoop(short axis_x, short axis_y, bool action) { oldTime = currentTime; currentTime = millis(); deltaTime = (float)(currentTime - oldTime) / 1000; player_y += PLAYER_SPEED * axis_y * deltaTime; enemy_y += ENEMY_SPEED * enemy_movement * deltaTime; // Enemy AI float distance = sqrt(pow(ball_x - 121, 2) + pow(ball_y - enemy_y, 2)); enemy_movement = 0; if (distance > 15 && distance < 100) { if (millis() - last_decision > 50) { if (ball_y > enemy_y + 10) { enemy_movement = 1; } else if (ball_y < enemy_y + 10) { enemy_movement = -1; } last_decision = millis(); } } player_y = constrain(player_y, 0, 44); enemy_y = constrain(enemy_y, 0, 44); // Ball movement ball_x += ball_speed * ball_motion_x * deltaTime; ball_y += ball_speed * ball_motion_y * deltaTime; if (ball_y >= 64 - 4 || ball_y <= 0) { ball_motion_y *= -1; } if (ball_x >= 4 && ball_x <= 7 && ball_motion_x < 0) { if (ball_y > player_y - 4 && ball_y < player_y + 20) { ball_motion_x *= -1; } // Increment ball speed with every successfull bounce if (ball_speed < BALL_MAX_SPEED) { ball_speed++; } } if (ball_x >= 121 && ball_x <= 124 && ball_motion_x > 0) { if (ball_y > enemy_y - 4 && ball_y < enemy_y + 20) { ball_motion_x *= -1; } } // Count score if (ball_x > 128) { player_score += 1; resetBall(); } if (ball_x < 0) { enemy_score += 1; resetBall(); } // Game over condition if (enemy_score > 10) { gameOver(); } // Win condition if (player_score > 10) { playerWins(); } } void gameDraw(Adafruit_SSD1306 display) { display.clearDisplay(); // Draw player display.fillRect(0, player_y, 3, 20, SSD1306_WHITE); // Draw enemy display.fillRect(125, enemy_y, 3, 20, SSD1306_WHITE); // Draw ball display.fillRect(ball_x, ball_y, 4, 4, SSD1306_WHITE); // Draw mid line for (int i = 0; i < 32; i++) { int position = 4 + (4 * (i-1)); display.fillRect(63, position, 2, 2, SSD1306_WHITE); } // Draw score display.setTextColor(SSD1306_WHITE); display.setTextSize(1); display.setCursor(50, 0); display.println(player_score); display.setCursor(72, 0); display.println(enemy_score); display.display(); } Nie jest to "samowystarczalny" kod Arduino, do działania wymaga on jeszcze firmware i silnika do gier, którego ze względu na niedopracowanie nie mogę go teraz pokazać (ale gdy tylko go skończę udostępnię całość na GitHub :D). Kod gry jest banalny. Do grafiki używam biblioteki od AdaFruit. Sztuczną inteligencją kieruje implementacja algorytmu "Chaser" do gry PONG z małymi moimi modyfikacjami (reakcja dopiero w momencie gdy piłka będzie na odpowiednim dystansie oraz opóźnienie reakcji AI aby ją bardziej "uczłowieczyć" i dać jakieś szanse na zwycięstwo graczowi (aczkolwiek i tak z tym cieżko bo czas reakcji bota jest dosyć niski XD, obecnie jest to ok. 50ms. Dla porównania człowiek przeciętnie ma reakcję po ok. 200ms). Gra się kończy gdy jeden z graczy zdobędzie 10 punktów, punkty zdobywamy odbijając piłeczkę tak aby przeciwnik nie mógł jej odbić (gdy piłka "wyleci za paletkę" punkt otrzymuje gracza używający przeciwnej paletki). W silniku brakuje jeszcze wielu rzeczy min. obliczania delta time wewnątrz silnika i przekazywanie wyniku do gry czy bardziej dopracowanego kodu odpowiedzialnego za sterowanie dźwiękiem (w tym prostego "odtwarza" melodyjek zapisanych jako sekwencja dźwięków). Do tego nie ma jeszcze obsługi ekranu końca gry (oraz zwycięstwa) i tak zwane splash screenu przed startem. Jednak gra jest grywalna co można zobaczyć na filmiku na samym dole. Prototyp prezentuje się tak: Jest zbudowany na płytce stykowej (podłączone są na razie tylko dwa przyciski, które są wykorzystywane w grze. Odłączony tak samo jest Buzzer, który na razie odtwarza w pętli trzy dźwięki). W planach jest również stworzenie na drukarce 3D obudowy w tym przeniesienie całego układu na PCB by zrobić z urządzenia pełnoprawną konsole😄 Gdy uda mi się skończyć firmware i silnik w planach mam dalsze wspieranie konsoli tworząc na nią kolejne gry (następne w kolejce są klon Froggera i Tetrisa). Z powodu dodawania kolejnych gier może dojść potrzeba dołączenia dodatkowej pamięci EEPROM lub modułu z kartą SD. (Koncepcja finalnego produktu. Wiem, że artysta ze mnie średni :D) Link do wideo z działaniem konsoli
  7. Cześć wszystkim. To mój pierwszy temat na tym forum, Więc przy okazji witam wszystkich 🙂 Pokaże wam dzisiaj bardzo prosty sposób wykorzystania Raspberry Pi jako konsoli do gier, ja osobiście dzięki temu projektowi zacząłem interesować się elektroniką. O ile sama elektronika nie jest tutaj zbyt zaawansowana to będziemy potrzebować minimalnych umiejętności posługiwania się elektronarzędziami. Zaczynamy. Na początku potrzebujemy Raspberry Pi, Ja osobiście użyłem Raspberry Pi 3 B+ ponieważ pozwala nam zagrać w gry z lepszą grafiką, nawet niektóre tytuły z PSP, jak i w miarę wygodnie korzystać z przeglądarki internetowej. Możecie jednak bez problemu korzystać ze słabszych wersji. Oprogramowanie naszej konsoli znajdziecie w tym linku Retropie możecie też użyć podobnej wersji oferującej praktycznie to samo z tego linku Recalbox Jednak w tym poradniku skupię się na tej pierwszej. Porównanie obu znajdziecie na Youtube. Na temat instalacji samego oprogramowania nie będę pisał bo jest to dość proste i wszystko znajdziecie w tym linku instalacja Powiem jedynie żeby oprócz konsoli nie zapomnieć o możliwości przejścia do Rasbiana, znajdziecie też filmy jak uruchomić dodatkowe konsole i wgrać kodi. O ile tutaj wszystko jest jasne, to trudniejsza częścią jest zabudowa naszej konsoli. Osobiście użyłem Starego automatu który znalazłem na śmietnisku .Nie była to maszyna do gier arcade, a tak zwany jednoręki bandyta, taki jak jak na zdjęciu numer 2 (niestety nie mam zdjęcia jak wyglądał przed). Jednak nie każdy ma do takiego dostęp dlatego wrzucam wymiary mojej, byście mogli wyciąć taką np ze sklejki i poskładać samemu. Jeśli jest to dla was za duży kawał mebla to znajdziecie w na Youtube czy w Google projekty trochę bardziej poręcznych, ale już nie robiących takiego wrażenia. Jako że ja swoją przerabiałem musiałem najpierw zrobić w naklejce na szybie wycięcie na monitor (17cali od starego komputera) i pozbyć się pozostałych w środku resztek starego systemu. Później musimy zamontować przyciski i joystick, są w pełni kompatybilne z konsolą. W moim przypadku zostawiłem 2 działające przyciski Start i Payout z oryginału. Mała rada by przedni panel zrobić otwierany, w przypadku drobnych modyfikacji nie musimy odsuwać szafy od ściany. Trzeba zadbać teraz o audio, u mnie sprawę załatwia mała wieża podłączona pod Raspberry, z oddzielnym wyjściem aux by podłączyć telefon. Otwory na głośniki należy wyciąć w płycie. Nie zapomnij o wnetylatorach i otworach wentylacyjnych. Ponieważ w zamkniętej obudowie potrafi się zrobić gorąco. Ładnie pochowaj, wyprowadź kable i zamontuj raspberry. W przednim panelu zamontowałem atrapę komputera dla wyglądu. Wyprowadź też kable usb by można było podłączyć pady. Ja schowałem je w miejscu na wypłatę monet. W schowku na dole jest szuflada na różne rzeczy jak i mała schładzarka do napojów. Do tego użyłem podobnego zestawu zestawu chłodzącego. Daję radę, ale bardziej do podtrzymywania zimnej temperatury, max udało mi się osiągnąć 13 stopni dlatego polecam użyć większego, trochę droższego zestawu. Schładzarkę należy czymś wyłożyć by zapewnić izolację i w miarę szczelnie zamknąć by nie uciekała nam temperatura. Ja użyłem starej karimaty ale są na pewno lepsze sposoby. Naszą szafę dobrze jest wyłożyć matami głuszącymi dla cichej pracy. Na końcu montujemy Ledy. Projekt można rozwijać o np. licznik monet, panel dotykowy i co tylko przyjdzie do głowy. W przyszłości mam zamiar poprawić lodówkę by działała lepiej, zmienić monitor i dodać trochę więcej przycisków. Mam nadzieję że projekt wam się podoba. Czekam na wasze sprzęty grające. 🙂
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.