Pengembangan dan pembuatan dari awal mesin arcade untuk empat pemain

gambar

Pada bulan November 2019, saya berhenti dari pekerjaan saya dan memutuskan untuk mencurahkan beberapa bulan untuk mempelajari keterampilan baru yang sudah lama ingin saya pelajari. Saat itu saya bekerja sebagai pengembang web. Sebelum itu, saya mempelajari pengembangan perangkat lunak. Dan bahkan sebelumnya, sebagai seorang anak, saya terus bereksperimen dengan elektronik dan program. Karena itu, saya merasa cukup percaya diri dalam pembuatan perangkat lunak.

Namun, selalu ada benda ajaib yang disebut "besi" ini , yang saya gunakan setiap hari, tetapi saya tidak tahu bagaimana cara kerjanya. Pengembang perangkat lunak (dan terutama pengembang web) tidak perlu memahami perangkat kerasnya. Karena semua kode pengembangan web sangat tinggi, jarang sekali masalah perangkat lunak kami terkait dengan perangkat keras.

Karena itu, saya tidak pernah mengerjakan "besi" dan tidak memiliki pengetahuan umum tentang teknik elektro, kecuali yang diberikan kepada kami di sekolah menengah. Dan saya ingin mengubah situasi ini. Saya menetapkan tujuan yang tidak masuk akal, yang pada waktu itu tampak sangat jauh dari pengetahuan saya. Dan kemudian ... Saya baru saja mulai bereksperimen. Saya berencana untuk memeriksa seberapa jauh saya bisa pergi sebelum saya kehabisan motivasi. Saya tidak berharap untuk mencapai tujuan saya, tetapi entah bagaimana saya berhasil.

Inilah hasil saya:


Tujuan luar biasa saya adalah membuat konsol permainan arcade empat pemain dari awal. Menggunakan mikrokontroler sebagai otak, dan strip LED sebagai tampilan. Menggunakan satu joystick dan empat tombol untuk masing-masing pemain yang terletak di tepi meja, pemain mengontrol permainan yang secara dinamis dimuat ke dalam sistem dari chip memori. Berkat ini, gameplay pada perangkat menyerupai konsol lama yang baik. Hanya sekarang kita tidak perlu meniup kartrid untuk menghilangkan bug.

Yang mengejutkan saya ... saya benar-benar bisa menyelesaikan proyek. Butuh waktu sekitar tiga bulan penuh untuk siklus percobaan, kegagalan, membaca dokumentasi, putus asa, dan mencoba lagi. Akan diperlukan untuk memperbaiki jumlah jam kerja untuk mengetahui berapa banyak waktu yang saya habiskan untuk ini. Saya akan menganggap itu sekitar 800-900 jam. (Dengan asumsi saya bekerja 6/7 hari seminggu selama 8-10 jam sehari, yang cukup dekat dengan kebenaran.)

Saya mencoba mendokumentasikan proses percobaan saya dari awal hingga akhir, mengambil foto dan merekam video. Dengan posting ini saya akan mendokumentasikan proyek dan pengalaman saya untuk diri saya sendiri. Saya berharap bagi Anda itu akan menjadi sumber inspirasi jika Anda juga memutuskan untuk mengambil proyek yang sama luar biasa.

Mulai bekerja


Seperti yang saya katakan di awal artikel, ketika saya memulai proyek ini, saya tidak memiliki pengetahuan elektronik, kecuali formula hukum Ohm yang salah ingat. Karena itu, pertama-tama, saya perlu mempelajari cara kerja elektronik dalam praktik, dan baru kemudian mencoba membuat konsol game. Saya bahkan tidak tahu cara menyalakan LED menggunakan mikrokontroler. Jadi, langkah pertama saya: memesan elektronik dan mikrokontroler sederhana untuk percobaan. Untuk memulai, saya akan mencoba menyalakan LED. Saya hampir yakin bahwa upaya pertama saya untuk menyalakan LED menyebabkan terbakar. Tapi ini tidak didokumentasikan di kamera, jadi mari kita berpura-pura tidak.


Eksperimen dengan mikrokontroler, resistor, transistor, dan LED.

Ini adalah tonggak utama pertama. Sekarang kita tahu cara membuat kode yang berjalan di mikrokontroler. Kami juga belajar cara menggunakan transistor sebagai saklar listrik sederhana untuk menyalakan LED. Luar biasa!

Petualangan bersama EEPROM



Ara. 1. Menggunakan register geser untuk mengontrol 16 jalur keluaran hanya dengan 3 pin keluaran.

Bagian dari proyek adalah kemampuan untuk menulis logika game ke chip memori (EEPROM). Itu seharusnya sudah dibaca ketika kartrid dengan pemutar dimasukkan ke dalam sistem.

Dalam jangka panjang, itu menyakitkan saya bahwa saya tidak belajar informasi yang cukup tentang jenis EEPROM apa yang harus digunakan dalam proyek ini. Saya sangat bersemangat bahwa saya membeli chip EEPROM paralel lama (W27C512).

Untuk menulis atau membaca dari mereka, saya membutuhkan kemampuan untuk mengatur sinyal tinggi atau rendah pada semua 16 baris. Jika saya tidak ingin menempati semua kontak keluaran dari mikrokontroler, akan logis untuk mempelajari cara menggunakan register geser.


Ara. 2. Sirkuit yang digunakan dalam upaya gagal membaca / menulis data ke chip EEPROM paralel.

Dengan hanya beberapa kontak, kita dapat secara terpisah mengontrol semua 16 jalur.

Sekarang mari kita terapkan pengetahuan ini ke EEPROM! Ya ... tapi tidak. Saya tidak dapat secara stabil menulis data ke EEPROM. Jenis chip ini membutuhkan 12-14 V untuk menghapus atau menulis byte. Saya mencoba menyediakannya dengan menggunakan transistor sebagai saklar untuk memasok tegangan yang meningkat. Dan seperti yang saya pahami, itu HARUS berhasil. Tapi itu tidak berhasil. Saya masih tidak mengerti apa sebenarnya masalahnya. Dalam gbr. Gambar 2 menunjukkan sirkuit yang saya coba gunakan untuk membaca / menulis byte dari / ke EEPROM.


Ara. 3. Sebuah sirkuit yang telah berhasil membaca / menulis byte ke chip EEPROM serial.

Akhirnya, setelah mempelajari informasi lebih lanjut tentang topik ini, saya belajar bahwa EEPROM paralel saat ini tidak sering digunakan. Biasanya, pengembang lebih suka serial EEPROM I2C, dan karenanya, lebih mudah untuk menemukan tutorial tentang mereka. (Misalnya, tutorial Sparkfun yang luar biasa ini ).

Dalam gbr. Gambar 3 menunjukkan skema saya untuk membaca dan menulis data ke EEPROMs serial ... Jauh lebih sederhana dan jauh lebih dapat diandalkan. Ini mengajarkan saya bahwa Anda tidak boleh terlalu senang memesan suku cadang dan mencoba mengembangkan proyek terlalu cepat. Kami menghabiskan sekitar 1-2 minggu untuk EEPROM paralel, dan akhirnya tidak menggunakannya sama sekali. Namun, dalam prosesnya, kami belajar banyak dalam bidang elektronik dan spesifikasi bacaan (yang dengan sendirinya merupakan keterampilan). Upaya itu tidak sepenuhnya sia-sia.

Jadi bagaimana cara kita melakukannya?


Sekarang kita bisa membaca dan menulis ke chip memori. Apa yang akan menjadi langkah selanjutnya? Pada tahap ini, akan logis untuk menggambarkan rencana konsol saya lebih detail menggunakan beberapa gambar sebagai contoh.


Rencana keseluruhan. Ini akan menjadi konsol game dengan pengontrol untuk empat pemain. Setiap pemain memiliki satu joystick dan beberapa tombol.

Lingkaran merah menandai steker untuk kartrij permainan. Konektor ini akan memiliki empat pin logam yang digunakan konsol untuk membaca serial EEPROM untuk memuat game ke dalam memori.

Hijau menunjukkan bagaimana kami berencana membuat layar strip LED. Kami ingin piksel layar menjadi bidang persegi, bercahaya warna, bukan tempat yang menyatu dengan tempat lain.

Untuk mencapai efek yang diinginkan, kami menggunakan skema tersebut untuk memisahkan sumber cahaya satu sama lain. Pada saat yang sama, itu menyebarkan cahaya yang jatuh di atas layar. (Garis-garis putih di bawah kisi-kisi menunjukkan strip LED)

Saya memutuskan untuk membuat tampilan LED 42x42. Artinya, total 1764 LED diperoleh. Saya memilih nomor 42, karena berkat ini, ukuran meja akan pas untuk empat orang.

Menyalakan banyak LED adalah tugas yang menakutkan. Pada kecerahan maksimum, LED RGB mengkonsumsi arus 60 mA. (Yang memberi warna putih dengan kecerahan maksimum). Jika kita mengalikan dengan jumlah LED, maka kita mendapatkan konsumsi arus maksimum 105,84 A pada 5 V! Untuk semakin mendekati arus ini, kami membeli catu daya SE-600–5 MEAN WELL. Ini dapat memasok saat ini hingga 100 A. Yang secara teori kurang dari mungkin 105 A. Tapi saya tidak berusaha untuk menampilkan layar sepenuhnya putih dengan kecerahan maksimum dalam game. Selain itu, kita dapat membatasi kecerahan secara terprogram. Kami juga akan menambahkan sekering untuk mencegah secara tidak sengaja melebihi batas 100 A.


Ara. 4. Prototipe kardus untuk tampilan LED 3x3.

Saya akan kembali ke perakitan layar ini nanti. Pertama, Anda perlu melakukan prototyping. Mari kita lihat apakah kita bisa membuat layar LED kecil berfungsi.

Prototipe 3x3 ini terdiri dari beberapa lembar karton yang memisahkan piksel, dan selembar kertas biasa untuk printer yang menyebarkan cahaya. Itu bekerja dengan baik! Kami telah menerima konfirmasi luar biasa dari kapasitas kerja konsep tersebut.

Untuk mengontrol LED menggunakan mikrokontroler, kami menggunakan perpustakaan FastLED. Namun, ternyata jika LED dikendalikan oleh satu bus data, maka tidak mungkin memperbarui 1764 LED dengan kecepatan yang cukup untuk permainan. Diberikan frekuensi 800 kHz, kita bisa mencapai frame rate sekitar 17 frame per detik. Tidak persis apa yang kami perjuangkan. Secara pribadi, saya suka bermain dengan setidaknya 60FPS. Untungnya, ini mungkin. Cukup menggunakan lebih dari satu data bus. Layar 42x42 dapat dengan mudah dibagi menjadi 7 bagian yang sama. Masing-masing bagian ini dapat dikontrol secara terpisah, dengan bus data sendiri. Ini dimungkinkan berkat penggunaan fungsi keluaran paralel dari perpustakaan FastLED di mikrokontroler Teensy 4 . Dengan menggunakan 7 bus data, kami dapat mencapai kecepatan refresh maksimum sekitar 120FPS!

Saya tidak merencanakan ini, tetapi kebetulan, pada awal proyek, saya memilih mikrokontroler ini. Tampak bagi saya bahwa untuk kelancaran permainan akan membutuhkan waktu pemrosesan yang cepat yang disediakan oleh MK ini. Prototipe pada Gambar. 4 sudah dikontrol oleh fungsi output paralel. Namun, dalam prototipe ini kami hanya menggunakan 2 bus data, hanya untuk menguji apakah semuanya benar-benar berfungsi sebagaimana dinyatakan.

Bagaimana kita menjalankan kode dengan EEPROM?


Jadi, pada tahap ini, kita dapat membaca dan menulis ke EEPROM, dan kami juga memiliki bukti kerja dari konsep tampilan LED. Apa berikutnya?

Hanya ada dua tugas teknis serius yang tersisa: pengorganisasian metode input untuk semua pemain (tombol dan joystick). Dan kita juga perlu memikirkan cara menjalankan logika game dari EEPROM dan menampilkan hasil dari instruksi ini di layar.

Tombol dan joystick yang dipesan belum tiba. Oleh karena itu, pertama-tama kita akan terlibat dalam pelaksanaan logika game dari EEPROM.

Ada banyak cara untuk menjalankan instruksi (kode) dari EEPROM. Namun, pertama-tama kita perlu menetapkan persyaratan tertentu:

1) Kode harus mudah ditulis.

2) Kode harus kecil (ukuran file).

3) Kode harus dapat berinteraksi dengan perpustakaan yang sudah jadi, misalnya, FastLED, untuk mengurangi jumlah pekerjaan saya.

4) Kode harus dapat memuat ke dalam RAM secepat mungkin untuk mengurangi waktu buka.

5) Anda membutuhkan kemampuan untuk meniru kode pada PC biasa untuk menguji game.

6) Solusi kami harus berkinerja tinggi (sediakan setidaknya 60FPS).

7) Suatu solusi seharusnya tidak mengharuskan pembelian sejumlah besar peralatan tambahan.

8) Solusinya harus bekerja pada Teensy 4.0 MK.

9) Solusinya harus mudah diimplementasikan.

Saya datang dengan empat cara berbeda untuk mengeksekusi kode dari EEPROM:

- Kami menulis di EEPROM kode Arduino yang dikompilasi yang biasa. Kemudian kami memaksa programmer Arduino eksternal untuk membaca kode yang dikompilasi dari EEPROM dan memprogram ulang Arduino dengan cepat setiap kali game baru dimuat.

- Kami memuat kode assembler dalam RAM dan menjalankannya dari sana.

- Kami menggunakan juru bahasa kode siap pakai, misalnya, ArduinoBASIC atau Bitlash .

- Kami menulis juru kode kami sendiri.

Berikut ini adalah perbandingan singkat tentang kelebihan dan kekurangan dari empat solusi untuk proyek kami:


(1) Ukuran file untuk solusi dengan programmer eksternal mengerikan. Bersama dengan logika permainan, semua pustaka kode yang kami gunakan dalam proyek ini harus disimpan dalam EEPROM. Untuk menampilkan kondisi permainan, setiap EEPROM harus memiliki salinan FastLED library-nya sendiri. Ini tidak bagus sama sekali. Masalah ini mungkin dapat diatasi dengan menambahkan kode dasar ke programmer eksternal, yang kemudian dikombinasikan dengan kode di EEPROM sebelum memprogram Arduino. Ini akan menjadi tugas yang berisiko tinggi, karena tidak begitu mudah untuk menemukan tutorial di Internet. Kami mungkin akan menghabiskan terlalu banyak waktu untuk itu.

(2) Menjalankan assembler dari RAM adalah pilihan yang bagus. Itu sebabnya saya memutuskan untuk mempertimbangkannya. Kompleksitas penulisan kode dapat dikurangi dengan menggunakan beberapa bahasa tingkat tinggi, misalnya, C, yang kemudian dikompilasi ke dalam kode assembler yang benar. Namun, tidak jelas betapa mudahnya untuk berinteraksi dengan perpustakaan lain di Arduino, jadi saya memutuskan untuk mengabaikannya.

(3) Menggunakan juru bahasa yang sudah jadi juga merupakan solusi yang cukup bagus. Namun, sejauh yang saya tahu, semua penafsir ini dieksekusi berdasarkan serangkaian karakter. Antrian panjang ini harus ditulis ke EEPROM. Ini bukan masalah besar, tapi jelas bukan cara terbaik untuk memperkecil ukuran file. Selain itu, tidak jelas apakah penerjemah ini dapat berinteraksi dengan perpustakaan Arduino. Karena itu, saya memutuskan bahwa menggunakan penerjemah yang sudah jadi bukanlah ide yang baik.

(4) Akhirnya, kami memiliki solusi 4: membuat juru bahasa kami sendiri. Itu memenuhi semua persyaratan, karena cara penerjemah diimplementasikan sepenuhnya tergantung pada saya. Dia akan melakukannyamemiliki kecepatan tinggi jika saya mencapai kecepatan tinggi dari penerjemah itu sendiri. Ya, ukuran file akan kecil dan kodenya akan mudah ditulis ... jika saya memberikan ini sendiri. Dengan kata lain, kita akan memiliki kendali penuh atas segalanya. Dan jika saya berusaha, maka semuanya akan menjadi sempurna. Satu-satunya kelemahan serius dari solusi semacam itu adalah waktu pengembangan yang panjang. Anda mungkin ingat bahwa saya menghabiskan 800-900 jam untuk proyek ini. Artinya, jelas bahwa saya memutuskan untuk memilih solusi 4 - untuk membuat juru bahasa saya sendiri. Waktu bukanlah masalah bagi saya. Saya mengambil kesempatan ini untuk belajar bagaimana bahasa pemrograman dibuat. Saya akan mencari tahu mengapa satu atau beberapa keputusan arsitektur dibuat dalam bahasa-bahasa ini.

Kelahiran ArcadableScript


Prinsip umum penerjemah cukup sederhana. Saya tidak akan merinci struktur internalnya, karena pada saat penulisan, saya berencana untuk sepenuhnya menulis ulang penerjemah sehingga akan menjadi lebih efisien dan akan lebih mudah baginya untuk menulis kode. Namun, dasar-dasarnya tetap sama. Penerjemah akan mengeksekusi loop kode sederhana untuk setiap ukuran permainan:


Kelemahan besar dari skema semacam itu adalah bahwa input dan kondisi permainan diperiksa hanya sekali per frame. Untuk gim yang tidak memerlukan reaksi cepat, ini normal. Namun, di game lain, pemain tidak akan bisa bereaksi di antara frame. Saya akan memecahkan masalah ini dalam versi penerjemah berikutnya.


Ara. 5

Dalam diagram dengan gambar. Gambar 5 menunjukkan bagaimana saya berencana untuk meningkatkan juru bahasa dalam waktu dekat, menciptakan dua siklus terpisah untuk keadaan permainan dan bingkai permainan. Ini akan memungkinkan kami untuk memperbarui keadaan permainan ratusan kali per detik, dan tampilan - hanya 60 kali per detik.

Sayangnya, pada Teensy 4.0 tidak dimungkinkan untuk mengeksekusi kode multi-thread perangkat keras. Karenanya, kita tidak akan dapat melakukan dua siklus ini secara paralel. Tapi saya yakin saya akan menemukan sesuatu.


Setelah beberapa waktu, saya berhasil menulis dua program sederhana menggunakan bahasa bytecode saya sendiri. Mereka menggunakan angka mentah sebagai input untuk meminimalkan ukuran file. Yaitu, saya menyelesaikan penulisan kedua program ini, secara harfiah menuliskan daftar angka yang dapat dipahami oleh penerjemah. Untuk memberikan gambaran tentang seberapa mudahnya bytecode ini terbaca, saya akan mendemonstrasikan instruksi nyata yang digunakan dalam program contoh yang menggerakkan titik di layar:

// TODO: Write/read all untyped... data to/from ROM
  int untypedGamestate[] = {
    0, // Previous time, to keep track of game time/framerate.
    0, // Player position x.
    0, // Player position y.
    0, // Player R color value.
    0, // Player G color value.
    255, // Player B color value.
  };
  int untypedValues[][3] = {
    // ID, Type, Value
    {0, 0, 0}, // Move up button value 
    {1, 0, 1}, // Move right button value
    {2, 0, 2},  // Move down button value
    {3, 0, 3},  // Move left button value
    {4, 3, 1},  // True/1
    {5, 3, 0},  // False/0
    {6, 4, 0},  // Current millis since game start
    {7, 2, 0},  // Gamestate previous time
    {8, 2, 1},  // Gamestate player x
    {9, 2, 2},  // Gamestate player y
    {10, 2, 3}, // Gamestate player r color
    {11, 2, 4}, // Gamestate player g color
    {12, 2, 5}, // Gamestate player b color
    {13, 3, 1}, // Move player up after button press boundary check
    {14, 1, 0}, // System config screen width
    {15, 1, 1}, // System config screen height
    {16, 3, 3}, // Move player down after button press boundary check
    {17, 3, 5}, // Move player left after button press boundary check
    {18, 3, 7}, // Move player right after button press boundary check
  }
  int untypedCalculations[][5] = {
    // ID, ending, valueLeftID, calculationRightID, calculationOperator
    {0, 0, 9, 1, 1}, // Current player y position - 1
    {1, 1, 4, 0, 0}, // True/1
    {2, 1, 0, 0, 0}, // Up button
    {3, 1, 2, 0, 0}, // Down button
    {4, 1, 5, 0, 0}, // False/0
    {5, 1, 9, 0, 0}, // Current player y position
    {6, 0, 15, 1, 1} // screenheight - 1
    {7, 0, 9, 1, 0}, // Current player y position + 1
    {8, 1, 3, 0, 0}, // Left button
    {9, 1, 1, 0, 0}, // Right button
    {10, 1, 8, 0, 0}, // Current player x position
    {11, 0, 8, 1, 0}, // Current player x position + 1
    {12, 0, 8, 1, 1}, // Current player x position - 1
    {13, 0, 14, 1, 1} // screenwidth - 1
  }
  int untypedInstructions[][10] = {
    // ID, rootInstruction, conditionCalculationLeftID, conditionCalculationRightID, conditionOperator, conditionSuccesValueLeftID,
    // conditionSuccessCalculationRightID, hasFailedCondition, conditionFailedValueLeftID, conditionFailedCalculationRightID
    {0, 1, 2, 1, 0, 13, 0, 0, 0, 0}, // move player up when up button is pressed.
    {1, 0, 5, 4, 1, 9, 0, 0, 0, 0}, // move the player up when the boundary is not reached.
    {2, 1, 3, 1, 0, 16, 0, 0, 0, 0}, // move player down when down button is pressed. 
    {3, 0, 5, 6, 1, 9, 7, 0, 0, 0} // move the player down when the boundary is not reached.
    {4, 1, 8, 1, 0, 17, 0, 0, 0, 0}, // move player left when left button is pressed.
    {5, 0, 10, 4, 1, 8, 12, 0, 0, 0}, // move the player left when the boundary is not reached.
    {6, 1, 9, 1, 0, 18, 0, 0, 0, 0}, // move player right when right button is pressed.
    {7, 0, 10, 13, 1, 8, 11, 0, 0, 0}, // move the player right when the boundary is not reached.
  };

Jika Anda meluangkan waktu untuk mempelajari kode dengan cermat, Anda dapat memahami bagaimana versi awal penerjemah ini bekerja. Prinsip umum menggunakan "nilai", "perhitungan" dan "instruksi" dipertahankan dalam versi saat ini. Namun, banyak yang berubah. Kami tidak lagi memiliki daftar tetap nilai gamestate, sekarang mereka hanya bagian dari daftar nilai biasa. Selain itu, kami memisahkan "kondisi" dari instruksi. Berkat ini, kami dapat menggunakan kembali instruksi dalam kode, yang mengurangi ukuran file.

Mari kita tidak membahas detail penerjemah, karena dalam versi yang dirancang ulang, semua ini akan segera berubah.

Sekarang kita berada pada tahap ketika kita tahu cara membaca / menulis ke EEPROM, dan kita dapat menjalankan instruksi berdasarkan array angka biasa. Langkah logis berikutnya adalah menghapus daftar instruksi yang telah di-hardcode dari kode dan menuliskannya ke EEPROM. Mulai sekarang, kita akan dapat mencoba membaca dan menjalankan instruksi yang tersimpan di EEPROM.


Pada tahap ini, kita memiliki semua bukti kapasitas kerja konsep yang kita butuhkan untuk mulai menciptakan hasil akhir!

Tentunya, setiap bagian individu dari prototipe yang kami buat masih membutuhkan banyak pekerjaan. Tapi, menurut saya, tugas yang paling sulit sudah diselesaikan. Yang harus saya lakukan adalah mengembangkan apa yang sudah saya miliki. Semuanya sederhana!

Unit Display LED



Butuh banyak pekerjaan untuk merakit tampilan. Sangat banyak pekerjaan. Saya mulai dengan menyolder kabel ke 42 strip terpisah. Setiap strip membutuhkan tiga kabel di satu sisi dan dua di sisi lainnya. Artinya, hanya sekitar 200 kabel. Sebelum proyek ini, saya tidak memiliki banyak praktik dalam menyolder, sehingga Anda dapat dengan jelas melihat bahwa semakin banyak saya melakukan penyolderan, semakin kuat kualitasnya. Tentu saja, pada akhirnya, saya harus mengulang banyak strip LED pertama, karena saya tidak suka hasilnya. Semua ini adalah bagian dari proses pembelajaran!


Langkah selanjutnya: kita pasang semua strip LED ke panel kayu besar. Melihat ke belakang, saya pikir mungkin demi konduktivitas termal yang lebih baik ada gunanya menggunakan lembaran logam, karena setelah satu jam operasi tampilan sekarang menjadi hangat (40-50 ° C). Tapi ini masih tidak sering terjadi, jadi itu bukan masalah besar. Namun, jika saya memutuskan untuk mengulangi proyek, saya akan memperbaiki aspek ini.


Selanjutnya, kami memasang kabel dengan diameter lebih besar ke konduktor positif dan negatif dari strip strip LED. Kita harus memastikan bahwa kabel berdiameter besar andal tahan arus maksimum 100 A. Untuk perlindungan tambahan, kami juga menambahkan 15 sekering A ke setiap bagian layar.Pada

tahap ini, kami siap melakukan upaya pertama untuk mengontrol tampilan. Setelah banyak kegagalan dan manipulasi dengan parameter perangkat lunak dan kabel, saya akhirnya berhasil menampilkan satu warna pada layar tanpa distorsi dan gangguan. Butuh waktu lama, dan hasilnya masih jauh dari sempurna. Untuk waktu yang lama, saya masih memiliki masalah dengan sinyal yang terdistorsi sampai saya memposting pertanyaan tentang itu di electronics.stackexchange.com. Orang-orang hebat dari situs ini membantu saya mendiagnosis masalahnya. Saya masih belum sepenuhnya mengerti tentang apa itu, tetapi dengan menghubungkan kabel negatif langsung di sepanjang bus data dari landasan ke terminal landasan dekat input data, saya bisa menyelesaikannya. Sejak itu saya tidak punya masalah dengan distorsi pada layar.


Seperti yang kita lihat dari ilustrasi di atas, dua lapisan material ditumpangkan pada strip LED.

Sebagai bahan untuk pelapisan ini, kita membutuhkan sesuatu yang kuat, transparan, tetapi menyebarkan cahaya. Namun, saya tidak ingin menggunakan kaca karena harganya mahal dan rapuh. Oleh karena itu, saya memutuskan untuk mengambil polystyrene transparan standar. Agar dia menyebarkan cahaya, saya mengobatinya dengan ampelas halus sedemikian rupa sehingga tidak mungkin untuk melihat. Semuanya sangat sederhana.

Jauh lebih banyak waktu dihabiskan untuk membuat kisi yang akan ditempatkan langsung di atas strip. Saya pikir hanya memesan grille dengan parameter yang diperlukan untuk memesan, tetapi mereka memanggil saya harga sekitar 500 euro. Menurut saya, dia tidak layak. Karena itu, saya harus mengambilnya sendiri. Untuk ini kita perlu strip plastik tipis (tidak lebih dari 2 mm), tahan lama, buram putih. Cukup banyak persyaratan. Karena itu, pemilihan material yang tepat membutuhkan banyak waktu. Ternyata, garis-garis dari kerai jendela (lamella) adalah ideal.


Pertama, kami membuat pegangan kecil untuk membuat seragam, bahkan memotong garis lebar. Dalam hal ini, strip plastik yang agak kecil diperoleh. Kemudian kami perlu membuat sayatan di tengah setiap strip tepat di tempat yang tepat. Ini diperlukan untuk menghubungkan potongan-potongan plastik dan merakit jeruji. Inilah yang saya lakukan di foto ketiga. Sebelum melakukan ini, Anda harus memastikan bahwa lebar gergaji sama atau sedikit lebih besar dari lebar strip yang Anda potong. Kalau tidak, parut tidak dapat dirakit. Dalam kasus saya, ternyata gergaji besi untuk logam memiliki ketebalan yang ideal.

Pada foto keempat, hasil pemasangan semua strip ke kisi terlihat. Itu adalah pekerjaan yang sangat menjengkelkan dan monoton, tetapi panggangan ternyata sangat tahan lama. Secara umum, sepertinya semua sel memiliki ukuran yang sama. Tidak ada banyak variasi antara ukuran sel, jika tidak tampilan akan terlihat aneh, jadi semuanya ternyata cukup bagus. Saya senang dengan panggangan ini.


Kemudian saya menutup jeruji dalam bingkai kayu yang melakukan beberapa tugas. Pertama, dia memegang selembar polystyrene di bagian atas panggangan. Ini memastikan bahwa gril tidak bergerak. Selain itu, bingkai kayu menekan semua kabel sehingga mereka menahan lebih aman dan tidak bisa terlepas (yang terjadi beberapa kali ketika saya memindahkan layar).


Foto ini menunjukkan selembar polystyrene yang diampelas diletakkan di rak kawat. Perhatikan bahwa panggangan sekarang hampir tidak terlihat, itulah yang kami inginkan.


Setelah menghabiskan berjam-jam bereksperimen dengan implementasi kontrol tampilan yang benar, kami akhirnya berhasil membuatnya bekerja. Masalah besar adalah pelestarian integritas sinyal. Tapi seperti yang saya katakan di atas. Komunitas dari electronics.stackexchange membantu saya dengan ini!

Layarnya cerah, jauh lebih terang dari yang saya harapkan. Itu perlu untuk meramalkan ini, memesan unit 100 A untuk catu dayanya.


Seperti yang saya katakan beberapa kali, kami menggunakan perpustakaan FastLED untuk mengontrol LED. Tetapi saya tidak menyebutkan bahwa saya juga menggunakan versi modifikasi dari perpustakaan FastLED-GFX oleh Jürgen Skrocki (yang itu sendiri adalah port dari Adafruit-GFX-Library ) untuk rendering sederhana angka pada tampilan . Perubahan di perpustakaan ini kecil, tetapi mereka perlu agar penerjemah dapat berkomunikasi dengan perpustakaan dengan cara yang nyaman.

Otak dan ...


Salah satu tugas teknis terakhir yang perlu dipecahkan untuk menyelesaikan proyek ini adalah penyelesaian otak konsol. Anda perlu mengubahnya menjadi satu set yang nyaman dan kompak. Tapi pertama-tama kita perlu mencari tahu bagaimana menangani semua sinyal input dari para pemain. Biarkan saya mengingatkan Anda bahwa setiap pemain memiliki 4 tombol dan satu joystick. Itu adalah total 16 sinyal input digital dan 8 analog. MK tidak pernah memiliki cukup kontak untuk masukan seperti itu; selain itu, dua pin bus data sudah digunakan untuk membaca EEPROM, dan 7 pin bus data paralel diperlukan untuk mengontrol tampilan.

Untuk mengatasi masalah ini, kami menggunakan sepasang register geser untuk input digital. Dan untuk semua input analog, kami akan mengambil multiplexer analog.


Skema untuk membaca / menulis EEOPROM secara bersamaan, memproses input pemain dan kontrol tampilan.

Dan kemudian kebingungan dimulai. Biarkan saya menjelaskan apa yang terjadi di foto ini, dari kiri ke kanan. Di bagian atas papan tempat memotong roti kiri adalah 7 bus data yang digunakan untuk mengontrol tampilan. Di bawah ini adalah area di mana EEPROM dapat dimasukkan dan di mana itu dibaca.

Di bagian atas papan tempat memotong roti tengah adalah multiplexer analog. Multiplexer ini dapat menerima hingga 16 sinyal input analog, dan tergantung pada sinyal input pada multiplexer, sambungkan salah satu sinyal analog ke MK. Jadi, kita hanya perlu satu pin input analog dan sepasang pin input digital untuk memproses 16 input analog. Sepertinya tidak ada input analog yang terhubung ke multiplexer di foto ini.

Di bawah multiplexer adalah MK Teensy.

Di papan tempat memotong roti sebelah kanan, kami memproses sinyal input digital. Dalam foto ini, 16 sinyal digital hanya terhubung ke ground. Saya masih menunggu tombol tiba, jadi saya menguji semua 16 sinyal digital dengan cara ini. Berkat register shift, hanya 4 pin yang diperlukan untuk mengontrol semua sinyal digital.

Seluruh sistem adalah kekacauan besar yang tidak dapat diandalkan. Hal ini diperlukan untuk membuatnya lebih kompak sehingga tidak terlepas dari satu pernafasan yang ceroboh. Oleh karena itu, saya memesan beberapa papan prototipe dan mulai menyolder lagi!



Dan itu ternyata menjadi tugas yang sulit! Namun, ini adalah kesempatan yang bagus untuk belajar cara menyolder secara akurat.

Untuk membuat sirkuit ini, saya menggunakan contoh kekacauan kabel di papan tempat memotong roti. Kemudian saya mencoba membuat sirkuit yang lebih pintar sehingga komponen yang harus berkomunikasi satu sama lain sedekat mungkin. Jadi saya mencoba menyingkirkan kebutuhan untuk menarik terlalu banyak kabel. Sekarang saya pikir Anda bisa menggunakan beberapa alat pemodelan untuk merancang rangkaian. Tapi ternyata masih cukup baik.

Saya memutuskan untuk merancang sirkuit dua lapis. Pada papan prototipe bawah, semua input diproses. Pada masing-masing dari 4 koneksi input, saya memiliki 8 jalur input (1-ground, 1-positif, 4-digital input, 2-analog input). MK berkomunikasi dengan lapisan bawah menggunakan empat koneksi di sebelah register geser dan empat koneksi di sebelah multiplexer.

Catu daya terletak di lapisan atas, di sebelah kanan ada 7 bus data output untuk tampilan, dan di bagian bawah ada kontak untuk membaca EEPROM. Dan akhirnya, di tengah, tentu saja, adalah mikrokontroler.


Antara papan kontrol utama dan input pemain, saya menempatkan papan perantara untuk mengurangi jumlah kabel yang dibutuhkan di kedua sisi dari 12 menjadi 8, karena tidak perlu menggunakan semua 5 kabel ground yang pergi dari papan utama ke papan input. Satu pentanahan sudah cukup untuk semua tombol dan joystick. Oleh karena itu, ada empat papan perantara tersebut. Saya suka bahwa Anda dapat melihat peningkatan kualitas setiap papan berikutnya yang Anda kumpulkan.


Karena tidak pernah menerima tombol yang dipesan, saya memesan set lain dari penjual lain dan setelah beberapa hari saya menerimanya. Ini memungkinkan kami untuk akhirnya mulai menguji semua tombol.


Pada tahap ini, saya juga menulis game pertama yang bisa dimainkan di konsol. Ya, sekarang saya menyebutnya konsol.

Saya berhasil karena dalam proses mengerjakan tampilan saya secara simultan meningkatkan penerjemah. Secara khusus, saya berhasil meningkatkan proses pengembangan itu sendiri ketika menulis kode. Proses ini tidak begitu menarik secara eksternal, jadi saya memutuskan untuk tidak mendokumentasikannya secara khusus.


Saya menciptakan lingkungan pengembangan sederhana untuk menulis kode yang dapat dieksekusi di konsol.

Lingkungan ini berfungsi di browser, dan ini memungkinkan Anda untuk menulis kode untuk konsol tanpa mengacaukan daftar angka yang kacau yang kita lihat di atas. Selain itu, saya membuat emulator konsol yang berjalan di aplikasi web yang sama.

Kemampuan untuk meniru permainan untuk konsol dalam aplikasi web menghemat banyak waktu, karena debugging pada PC jauh lebih mudah daripada pada MK.

Emulatornya tidak sempurna. Ada beberapa bug yang membedakan emulasi dari bermain di versi nyata dari konsol. Saya akan mencoba menghilangkannya di masa depan ketika saya menulis penerjemah versi baru. Kebutuhan untuk mendukung dua versi interpreter (satu ditulis dalam C ++, yang lain dalam TS) agak menjengkelkan, tetapi itu sepadan.

Menyatukan semuanya


Semuanya sudah siap. Kami dapat menampilkan gambar berdasarkan logika permainan yang diambil dari EEPROM dan memproses input pemain dari tombol dan joystick. Sekarang kita perlu menggabungkan semua ini menjadi satu perangkat yang tahan lama.


Saya mulai dengan mengebor lubang di pelat aluminium yang akan menahan tombol dan joystick di tempatnya. Kemudian adalah mungkin untuk memasukkan lempengan-lempengan ini ke dalam alur dari kotak kayu di mana mereka mudah disembunyikan. Berkat ini, pemain tidak akan dapat menggores logam secara tidak sengaja.



Kami mengumpulkan semua yang ada di sekitar layar dan menambahkan kaki lipat yang andal (untuk penyimpanan mudah). Pelat logam yang dicat dengan cat hitam terlihat sangat indah. Ada perasaan bahwa proyek ini benar-benar bergerak menuju penyelesaian.


Tapi tentu saja saya salah meyakini bahwa proyek itu hampir selesai. Beginilah bentuk konsol sekitar sebulan.

Kami mengumpulkan semuanya, kami mengerti bahwa tombol tidak berfungsi. Kami membongkar lagi, memperbaiki masalah dengan tombol. Segalanya tampak bekerja. Kami memahami bahwa joystick tidak berfungsi. Bongkar lagi. Cepat atau lambat, semua tombol dan joystick mulai bekerja. Tetapi kemudian LED berhenti bekerja. Untuk memperbaikinya, Anda harus membongkar seluruh konsol dan memasang kembali dari awal. Ini berlangsung selama sekitar satu bulan, sampai akhirnya semuanya bekerja.

Hasil




Semuanya sudah siap! Setelah mulai bekerja pada proyek 3-4 bulan telah berlalu. Oleh karena itu, logis bahwa motivasi saya untuk terus meningkatkan penerjemah, melukis pohon dan mengembangkan permainan baru sudah mengering. Pada saat penulisan ini, satu bulan telah berlalu, ketika saya terakhir terlibat dalam proyek ini. Saya akhirnya mendapatkan kekuatan untuk menulis posting dokumenter ini untuk saya dan Anda, pembaca saya. Meskipun saya tidak berharap bahwa seseorang yang waras akan benar-benar membaca semua yang saya tulis, saya harap Anda menikmati melihat foto-foto perkembangan proyek secara bertahap.

Tetapi jika Anda membaca semua ini, maka Anda mungkin tertarik dengan repositori Github dari proyek tersebut. Tentu saja, semua kode saya adalah open source! https://github.com/Arcadable

Rencana pengembangan proyek lebih lanjut:

- Pertama, Anda perlu membuat kartrid yang lebih indah untuk memainkan Pong untuk empat, yang ditunjukkan dalam video terakhir. Sementara itu adalah selembar karton dengan potongan aluminium melengkung, yang digunakan sebagai permukaan kontak.

- Selain itu, saya ingin mengecat konsol dengan lebih baik. Awalnya, saya berencana melukisnya dengan teman-teman yang sangat berpengalaman yang suka melukis. Namun, sekarang karena pandemi ini tidak mungkin.

- Akhirnya, seperti yang saya katakan beberapa kali, saya akan menulis ulang penerjemah dengan cara yang lebih efisien. Saya juga akan meningkatkan lingkungan pengembangan untuk membuat game lebih mudah. Desain aplikasi web saat ini menghambat produktivitas.


Kompensasi untuk merekam video vertikal.

All Articles