تطوير وخلق من الصفر آلة ممر لأربعة لاعبين

صورة

في نوفمبر 2019 ، تركت وظيفتي وقررت تخصيص عدة أشهر لتعلم مهارة جديدة كنت أرغب في تعلمها منذ فترة طويلة. في ذلك الوقت عملت كمطور ويب. قبل ذلك ، درست تطوير البرمجيات. وحتى في وقت سابق ، عندما كنت طفلاً ، كنت أجرب باستمرار على الإلكترونيات والبرامج. لذلك ، شعرت بالثقة الكافية في إنشاء البرامج.

ومع ذلك ، كان هناك دائمًا هذا الشيء السحري المسمى "الحديد" ، والذي أستخدمه يوميًا ، ولكن ليس لدي أي فكرة عن كيفية عمله بالفعل. لا يحتاج مطور البرامج (وخاصة مطور الويب) إلى فهم الأجهزة. نظرًا لأن جميع رموز تطوير الويب عالية المستوى جدًا ، نادرًا ما يتبين أن المشكلة في برنامجنا تتعلق بالأجهزة.

لذلك ، لم أعمل أبدًا على "الحديد" ولم يكن لدي أي معرفة عامة بالهندسة الكهربائية ، باستثناء تلك التي أعطيت لنا في المدرسة الثانوية. وأردت تغيير هذا الوضع. حددت لنفسي هدفاً سخيفاً بدا في ذلك الوقت بعيداً جداً عن معرفتي. ثم ... بدأت للتو في التجريب. خططت للتحقق من المسافة التي يمكن أن أقطعها قبل نفاد الدافع. لم أتوقع تحقيق هدفي ، لكني نجحت بطريقة ما.

ها هي نتيجتي:


كان هدفي المذهل هو إنشاء وحدة تحكم لعبة أركيد بأربعة لاعبين من الصفر. يستخدم متحكمًا كدماغ ، وشريط LED كشاشة. باستخدام عصا التحكم وأربعة أزرار لكل لاعب موجود على حواف الطاولة ، يتحكم اللاعبون في لعبة يتم تحميلها ديناميكيًا في النظام من شريحة ذاكرة. بفضل هذا ، تشبه طريقة اللعب على الجهاز وحدات التحكم القديمة الجيدة. الآن فقط لا نحتاج إلى النفخ على الخرطوشة للتخلص من الأخطاء.

لدهشتي ... لقد تمكنت حقًا من إكمال المشروع. استغرق الأمر مني حوالي ثلاثة أشهر عمل كاملة لدورات التجارب والفشل وقراءة الوثائق واليأس وإعادة المحاولة. سيكون من الضروري تحديد عدد ساعات العمل لمعرفة مقدار الوقت الذي أمضيته في ذلك. سأفترض أن حوالي 800-900 ساعة. (بافتراض أنني عملت 6/7 أيام في الأسبوع لمدة 8-10 ساعات في اليوم ، وهو قريب جدًا من الحقيقة.)

حاولت توثيق عملية تجربتي من البداية إلى النهاية ، والتقاط الصور وتسجيل مقاطع الفيديو. مع هذا المنشور سأوثق المشروع وتجربتي لنفسي. آمل أن تصبح مصدر إلهام بالنسبة لك إذا قررت أيضًا أن تشرع في تنفيذ مشروع لا يصدق.

الحصول على العمل


كما قلت في بداية المقال ، عندما بدأت المشروع ، لم يكن لدي أي معرفة بالإلكترونيات ، باستثناء صيغة قانون أوم التي تم تذكرها بشكل غير صحيح. لذلك ، أولاً ، كنت بحاجة إلى دراسة كيفية عمل الإلكترونيات عمليًا ، وحينها فقط حاول تجميع وحدة تحكم ألعاب. لم أكن أعرف حتى كيفية تشغيل LED باستخدام متحكم. لذا ، خطوتي الأولى: طلب إلكترونيات بسيطة ووحدة تحكم دقيقة للتجارب. للبدء ، سأحاول تشغيل LED. أنا متأكد تقريبًا من أن محاولتي الأولى لتشغيل LED أدت إلى حرقها. لكن هذا لم يتم توثيقه على الكاميرا ، لذلك دعونا نتظاهر بأنه لم يكن كذلك.


تجارب مع متحكم ، مقاومات ، ترانزستور ، و LED.

كان هذا أول معلم رئيسي. نحن الآن نعرف كيفية إنشاء رمز يعمل في وحدة التحكم الدقيقة. تعلمنا أيضًا كيفية استخدام الترانزستورات كمفتاح كهربائي بسيط لتشغيل LED. رائعة حقا!

مغامرة مع EEPROM



تين. 1. استخدام سجلات التحول للتحكم في 16 خط إخراج مع 3 دبابيس إخراج فقط.

كان جزء من المشروع هو القدرة على كتابة منطق اللعبة إلى شرائح الذاكرة (EEPROM). كان يجب قراءتها عند إدخال خرطوشة بها مشغل في النظام.

على المدى الطويل ، يؤلمني أنني لم أتعلم معلومات كافية حول نوع EEPROM الذي يجب استخدامه في هذا المشروع. كنت شغوفًا جدًا لدرجة أنني اشتريت رقائق EEPROM القديمة المتوازية (W27C512).

للكتابة أو القراءة منها ، كنت بحاجة إلى القدرة على تعيين إشارة عالية أو منخفضة على جميع الخطوط الـ 16. إذا لم أكن أرغب في شغل جميع جهات اتصال الإخراج لوحدة التحكم الدقيقة ، فسيكون من المنطقي معرفة كيفية استخدام سجلات التحول.


تين. 2. الدائرة المستخدمة في محاولة فاشلة لقراءة / كتابة البيانات على رقاقة EEPROM موازية.

من خلال بضع جهات اتصال فقط ، يمكننا التحكم بشكل منفصل في جميع الخطوط الـ 16.

الآن دعنا نطبق هذه المعرفة على EEPROM! نعم ولكن لا. لم أتمكن من كتابة البيانات بشكل ثابت إلى EEPROM. يتطلب هذا النوع من الرقاقات 12-14 فولت لإزالة أو كتابة وحدات البايت. حاولت توفيرها باستخدام الترانزستورات كمفاتيح لتزويد الجهد الزائد. وكما أفهمها ، يجب أن تعمل. لكنها لم تنجح. ما زلت لا أفهم ما هي المشكلة بالضبط. في التين. يوضح الشكل 2 الدوائر التي حاولت استخدامها لقراءة / كتابة وحدات البايت من / إلى EEPROM.


تين. 3. المخطط ، الذي نجح في قراءة / كتابة وحدات البايت إلى شريحة EEPROM التسلسلية.

وأخيرًا ، بعد دراسة المزيد من المعلومات حول هذا الموضوع ، علمت أنه لا يتم استخدام EEPROMs المتوازية اليوم كثيرًا. عادة ، يفضل المطورون EEPROM I2C التسلسلي ، وبالتالي ، من الأسهل بكثير العثور على برامج تعليمية عليهم. (على سبيل المثال ، هذا البرنامج التعليمي الرائع Sparkfun ).

في التين. يوضح الشكل 3 مخططي لقراءة البيانات وكتابتها إلى EEPROMs التسلسلية ... إنه أبسط بكثير وأكثر موثوقية. علمني هذا أنه يجب ألا تكون سعيدًا جدًا في طلب الأجزاء ومحاولة تطوير المشروع بسرعة كبيرة. قضينا حوالي أسبوع إلى أسبوعين في موازنات EEPROM المتوازية ، وفي النهاية لم نستخدمها على الإطلاق. ومع ذلك ، في هذه العملية ، تعلمنا الكثير في مجال الإلكترونيات ومواصفات القراءة (وهي في حد ذاتها مهارة). لم تضيع الجهود بالكامل.

فكيف نفعل ذلك على أي حال؟


الآن يمكننا القراءة والكتابة على رقائق الذاكرة. ماذا ستكون الخطوة التالية؟ في هذه المرحلة ، سيكون من المنطقي وصف خطة وحدة التحكم الخاصة بي بمزيد من التفصيل باستخدام عدة رسومات كمثال.


خطة شاملة. ستكون هذه وحدة تحكم لعبة مع وحدات تحكم لأربعة لاعبين. لكل لاعب عصا تحكم واحدة والعديد من الأزرار.

تشير الدائرة الحمراء إلى قابس خرطوشة اللعبة. سيحتوي هذا الموصل على أربعة دبابيس معدنية تستخدمها وحدة التحكم لقراءة EEPROMs التسلسلية لتحميل الألعاب في الذاكرة.

يوضح اللون الأخضر كيف خططنا لإنشاء شاشة لشرائط LED. أردنا أن تكون بكسل الشاشة عبارة عن رقعة ملونة مربعة مضيئة ، وليس بقعة تمزج مع البقع الأخرى.

لتحقيق التأثير المطلوب ، استخدمنا هذا المخطط لفصل مصادر الضوء عن بعضها البعض. في الوقت نفسه ، ينثر الضوء الذي يسقط على الجزء العلوي من الشاشة. (تشير الخطوط البيضاء أسفل الشبك إلى شريط LED)

قررت أن أصنع شاشة LED 42x42. أي أنه في المجموع يتم الحصول على 1764 LEDs. لقد اخترت الرقم 42 ، لأنه بفضل هذا ، سيكون حجم الطاولة مناسبًا لأربعة أشخاص فقط.

يعد تشغيل العديد من مصابيح LED مهمة شاقة في حد ذاتها. في أقصى سطوع ، يستهلك LED RGB 60 مللي أمبير من التيار. (الذي يعطي الأبيض مع أقصى سطوع). إذا ضربنا في العدد الإجمالي لمصابيح LED ، فعندئذ نحصل على أقصى استهلاك حالي يبلغ 105.84 أمبير عند 5 فولت! للاقتراب من هذا التيار ، قمنا بشراء مورد طاقة SE-600-5 MEAN WELL. يمكن أن توفر تيارًا يصل إلى 100 أ. وهو أقل من الممكن نظريًا 105 أ. لكنني لا أسعى إلى عرض شاشات بيضاء بالكامل بأقصى سطوع في الألعاب. بالإضافة إلى ذلك ، يمكننا الحد من السطوع برمجيًا. سنضيف أيضًا الصمامات لمنع تجاوز هذا الحد عن 100 أ.


تين. 4. النموذج الأولي من الورق المقوى لشاشة LED 3x3.

سأعود إلى تجميع هذه الشاشة لاحقًا. تحتاج أولاً إلى عمل نماذج أولية. دعونا نرى ما إذا كان يمكننا الحصول على شاشة LED صغيرة للعمل.

يتكون هذا النموذج الأولي 3x3 من عدة قطع من الورق المقوى تفصل وحدات البكسل ، وقطعة من الورق العادي للطابعات التي تشتت الضوء. عملت بشكل رائع! لقد تلقينا تأكيدًا رائعًا لقدرة العمل على المفهوم.

للتحكم في مؤشرات LED باستخدام متحكم دقيق ، استخدمنا مكتبة FastLED. ومع ذلك ، اتضح أنه إذا تم التحكم في LEDs بواسطة ناقل بيانات واحد ، فمن المستحيل تحديث 1764 LEDs بسرعة كافية للألعاب. نظرًا لتردد 800 كيلوهرتز ، يمكننا تحقيق معدل إطارات يبلغ حوالي 17 إطارًا في الثانية. ليس بالضبط ما نسعى إليه. أنا شخصياً أحب اللعب بمعدل 60 إطارًا في الثانية على الأقل. لحسن الحظ ، هذا ممكن. يكفي استخدام أكثر من ناقل بيانات. يمكن تقسيم الشاشة مقاس 42 × 42 إلى 7 أجزاء متساوية. يمكن التحكم في كل جزء من هذه الأجزاء بشكل منفصل ، باستخدام ناقل البيانات الخاص به. هذا ممكن بفضل استخدام وظيفة الإخراج الموازي لمكتبة FastLED في متحكم Teensy 4 . باستخدام 7 ناقل بيانات ، يمكننا تحقيق معدل تحديث بحد أقصى 120 إطارًا في الثانية تقريبًا!

لم أخطط لهذا ، ولكن بالصدفة النقية ، في بداية المشروع ، اخترت هذا المتحكم الدقيق. يبدو لي أن التشغيل السلس للألعاب يتطلب وقت المعالجة السريع الذي يوفره عضو الكنيست هذا. النموذج الأولي في الشكل. 4 يتم التحكم بالفعل بواسطة وظيفة الإخراج المتوازي. ومع ذلك ، في هذا النموذج الأولي ، نستخدم فقط ناقلتي بيانات ، فقط لاختبار ما إذا كان كل شيء سيعمل حقًا كما هو مذكور.

كيف سننفذ الكود مع EEPROM؟


لذا ، في هذه المرحلة ، يمكننا القراءة والكتابة إلى EEPROM ، ولدينا أيضًا دليل عملي على مفهوم شاشة LED. ماذا بعد؟

لم يبق سوى مهمتين تقنيتين جادتين: تنظيم طريقة الإدخال لجميع اللاعبين (الأزرار وعصا التحكم). ونحتاج أيضًا إلى معرفة كيفية تنفيذ منطق اللعبة من EEPROM وعرض نتائج هذه التعليمات على الشاشة.

لم تصل الأزرار وعصا التحكم المطلوبة بعد. لذلك ، سنقوم أولاً بتنفيذ منطق اللعبة من EEPROM.

هناك العديد من الطرق لتنفيذ التعليمات (التعليمات البرمجية) من EEPROM. ومع ذلك ، نحتاج أولاً إلى تعيين متطلبات معينة:

1) يجب أن تكون التعليمات البرمجية سهلة الكتابة.

2) يجب أن يكون الرمز صغيرًا (حجم الملف).

3) يجب أن تكون الشفرة قادرة على التفاعل مع المكتبات الجاهزة ، على سبيل المثال ، FastLED ، من أجل تقليل كمية عملي.

4) يجب أن يكون الرمز قادرًا على التحميل في ذاكرة الوصول العشوائي بأسرع وقت ممكن من أجل تقليل وقت التحميل.

5) أنت بحاجة إلى القدرة على محاكاة الرمز على جهاز كمبيوتر عادي لاختبار الألعاب.

6) يجب أن يكون حلنا عالي الأداء (يوفر 60 إطارًا في الثانية على الأقل).

7) لا يجب أن يتطلب الحل شراء عدد كبير من المعدات الإضافية.

8) يجب أن يعمل الحل على Teensy 4.0 MK.

9) يجب أن يكون الحل سهل التنفيذ.

توصلت إلى أربع طرق مختلفة لتنفيذ التعليمات البرمجية من EEPROM:

- نكتب على EEPROM رمز Arduino المترجم المعتاد. ثم نجعل مبرمج Arduino الخارجي يقرأ الشفرة المجمعة من EEPROM ونعيد برمجة Arduino على الطاير في كل مرة يتم فيها تحميل لعبة جديدة.

- نقوم بتحميل كود المجمع في ذاكرة الوصول العشوائي وننفذه من هناك.

- نستخدم مترجم الشفرة الجاهزة ، على سبيل المثال ، ArduinoBASIC أو Bitlash .

- نكتب مترجم الشفرة الخاص بنا.

فيما يلي مقارنة موجزة بين مزايا وعيوب الحلول الأربعة لمشروعنا:


(1) حجم ملف حل مع مبرمج خارجي رهيب. جنبًا إلى جنب مع منطق اللعبة ، يجب تخزين جميع مكتبات الكود التي نستخدمها في هذا المشروع في EEPROM. لعرض حالة اللعبة ، يجب أن يكون لكل EEPROM نسختها الخاصة من مكتبة FastLED. هذا ليس رائعًا على الإطلاق. ربما يتم التحايل على هذه المشكلة عن طريق إضافة الرمز الأساسي بطريقة ما إلى مبرمج خارجي ، والذي يتم دمجه بعد ذلك مع الرمز في EEPROM قبل برمجة Arduino. قد تكون هذه مهمة عالية المخاطر ، لأنه ليس من السهل العثور على دروس على الإنترنت. ربما سنقضي الكثير من الوقت في ذلك.

(2) يعد تشغيل المجمّع من ذاكرة الوصول العشوائي خيارًا رائعًا. لذلك قررت النظر في الأمر. يمكن تقليل تعقيد كتابة التعليمات البرمجية باستخدام بعض اللغات عالية المستوى ، على سبيل المثال ، C ، والتي يتم تجميعها بعد ذلك في رمز المجمع الصحيح. ومع ذلك ، لم يكن من الواضح كم سيكون من السهل جعلها تتفاعل مع مكتبات أخرى على Arduino ، لذلك قررت التخلي عنها.

(3) يعد استخدام مترجم جاهز أيضًا حلًا جيدًا. ومع ذلك ، على حد علمي ، يتم تنفيذ جميع هؤلاء المترجمين الفوريين على أساس سلاسل من الشخصيات. يجب كتابة هذه السطور الطويلة إلى EEPROM. هذه ليست مشكلة كبيرة ، لكنها بالتأكيد ليست أفضل طريقة لتقليل حجم الملف. بالإضافة إلى ذلك ، لم يكن من الواضح ما إذا كان هؤلاء المترجمون يمكن أن يتفاعلوا مع مكتبات Arduino. لذلك ، قررت أن استخدام مترجمين فوريين ليس فكرة جيدة.

(4) أخيرًا ، لدينا الحل 4: إنشاء مترجم الشفرة الخاص بنا. إنه يلبي جميع المتطلبات ، لأن طريقة تنفيذ المترجم تعتمد بالكامل علي. و سوفللحصول على سرعة عالية إذا حققت سرعة عالية من المترجم نفسه. نعم ، سيكون حجم الملف صغيرًا ويسهل كتابة الرمز ... إذا قدمت هذا بنفسي. وبعبارة أخرى ، سيكون لدينا سيطرة كاملة على كل شيء. وإذا بذلت جهداً ، فسوف يتحول كل شيء بشكل مثالي. العيب الخطير الوحيد لهذا الحل هو وقت التطوير الطويل. قد تتذكر أنني أمضيت 800-900 ساعة في هذا المشروع. أي ، من الواضح أنني قررت اختيار الحل 4 - لإنشاء مترجم الشفرة الخاص بي. الوقت لم يكن مشكلة بالنسبة لي. انتهزت هذه الفرصة لتعلم كيفية إنشاء لغات البرمجة. سأكتشف سبب اتخاذ قرار معماري أو آخر بهذه اللغات.

ولادة ArcadableScript


المبدأ العام للمترجم بسيط للغاية. لن أخوض في تفاصيل هيكلها الداخلي ، لأنه في وقت كتابة هذا التقرير ، كنت أخطط لإعادة كتابة المترجم بالكامل حتى يصبح أكثر كفاءة وسيكون من الأسهل عليه كتابة التعليمات البرمجية. ومع ذلك ، تبقى الأساسيات كما هي. سيقوم المترجم بتنفيذ حلقة رمز بسيطة لكل مقياس للعبة:


العيب الكبير لمثل هذا المخطط هو أن مدخلات وحالة اللعبة يتم فحصها مرة واحدة فقط لكل إطار. بالنسبة للألعاب التي لا تتطلب رد فعل سريع ، فهذا أمر طبيعي. ومع ذلك ، في الألعاب الأخرى ، لن يتمكن اللاعب من التفاعل بين الإطارات. سأحل هذه المشكلة في الإصدار التالي من المترجم.


تين. 5

في الرسم التوضيحي مع الشكل. يوضح الشكل 5 كيف خططت لترقية المترجم في المستقبل القريب ، وإنشاء دورتين منفصلتين لحالة اللعبة وإطارات اللعبة. سيسمح لنا هذا بتحديث حالة اللعبة مئات المرات في الثانية ، والعرض - 60 مرة فقط في الثانية.

لسوء الحظ ، في Teensy 4.0 لا يمكن تنفيذ التعليمات البرمجية متعددة الخيوط للأجهزة. لذلك ، لن نتمكن من تنفيذ هاتين الدورتين بالتوازي. لكني متأكد من أنني سأخرج بشيء.


بعد مرور بعض الوقت ، تمكنت من كتابة برنامجين بسيطين باستخدام لغة البايت كود المخترعة الخاصة بي. يستخدمون الأرقام الأولية كمدخل لتقليل حجم الملف. أي ، أكملت كتابة هذين البرنامجين ، وأكتب حرفيا قوائم أرقام يمكن للمترجم أن يفهمها. لإعطاء فكرة عن مدى سهولة قراءة هذا الرمز الثانوي ، سأوضح الإرشادات الحقيقية المستخدمة في برنامج المثال الذي ينقل نقطة عبر الشاشة:

// 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.
  };

إذا خصصت وقتًا لدراسة التعليمات البرمجية بعناية ، يمكنك فهم كيفية عمل الإصدار المبكر من هذا المترجم. يتم الحفاظ على المبدأ العام لاستخدام "القيم" و "الحسابات" و "التعليمات" في الإصدار الحالي. ومع ذلك ، تغير الكثير. لم يعد لدينا قائمة ثابتة بقيم gamestate ، وهي الآن جزء فقط من قائمة القيم العادية. بالإضافة إلى ذلك ، قمنا بفصل "الشروط" عن التعليمات. بفضل هذا ، يمكننا إعادة استخدام التعليمات في التعليمات البرمجية ، مما يقلل من حجم الملف.

دعونا لا ندخل في تفاصيل المترجم ، لأنه في النسخة المعاد تصميمها ، سيتغير كل هذا قريبًا.

نحن الآن في المرحلة عندما نعرف كيفية القراءة / الكتابة إلى EEPROM ، ويمكننا تنفيذ التعليمات بناءً على صفائف الأرقام العادية. ستكون الخطوة المنطقية التالية هي إزالة قوائم التعليمات المشفرة من التعليمات البرمجية وكتابتها في EEPROM. من الآن فصاعدًا ، سنتمكن من محاولة قراءة وتنفيذ التعليمات المخزنة في EEPROM.


في هذه المرحلة ، لدينا كل البراهين على قدرة العمل على المفاهيم التي نحتاجها للبدء في إنشاء النتيجة النهائية!

من الواضح أن كل جزء فردي من النموذج الأولي الذي أنشأناه لا يزال يتطلب الكثير من العمل. لكن في رأيي ، تم بالفعل حل أصعب المهام. كل ما كان علي فعله هو تطوير ما كان لدي بالفعل. كل شيء بسيط!

الجمعية شاشة LED



استغرق الأمر الكثير من العمل لتجميع الشاشة. عمل كثير جدا. بدأت بالحاجة إلى لحام الأسلاك بـ 42 شريحة منفصلة. يتطلب كل شريط ثلاثة أسلاك على جانب واحد واثنان على الجانب الآخر. أي فقط حوالي 200 سلك. قبل هذا المشروع ، لم يكن لدي الكثير من الممارسة في اللحام ، لذلك يمكنك أن تلاحظ بوضوح أنه كلما قمت بعملية اللحام ، كلما كانت الجودة أقوى. بالطبع ، في النهاية ، كان علي إعادة العديد من شرائط LED الأولى ، لأنني لم أحب النتيجة. كل هذا جزء من عملية التعلم!


الخطوة التالية: نربط جميع شرائح LED بلوحة خشبية كبيرة. إذا نظرنا إلى الوراء ، أعتقد أنه من أجل تحسين التوصيل الحراري ، كان من المفيد استخدام صفائح معدنية ، لأنه بعد ساعة من التشغيل تصبح الشاشة الآن دافئة (40-50 درجة مئوية). لكن هذا لا يحدث في كثير من الأحيان ، لذا فهي ليست مشكلة كبيرة. ومع ذلك ، إذا قررت تكرار المشروع ، فسأصحح هذا الجانب.


بعد ذلك ، نعلق أسلاك ذات قطر أكبر على الموصلات الإيجابية والسلبية لشرائط شريط LED. يجب أن نتأكد من أن الأسلاك ذات القطر الكبير تتحمل بشكل موثوق به تيارًا أقصى يبلغ 100 أمبير.لحماية إضافية ، أضفنا أيضًا 15 مصهر A لكل جزء من الشاشة.في

هذه المرحلة ، نحن على استعداد للقيام بالمحاولات الأولى للتحكم في الشاشة. بعد العديد من حالات الفشل والتلاعب بمعلمات البرامج والأسلاك ، تمكنت أخيرًا من عرض لون واحد على الشاشة دون تشويه وتداخل. استغرق الأمر وقتًا طويلاً ، وكانت النتيجة لا تزال بعيدة عن الكمال. لفترة طويلة ، ما زلت أواجه مشكلات في الإشارات المشوهة حتى نشرت سؤالًا عنها على إلكترونيات. stackexchange.com. ساعدني أناس رائعون من هذا الموقع في تشخيص المشكلة. ما زلت لا أفهم تمامًا ما يدور حوله ، ولكن من خلال ربط الأدلة السلبية مباشرة على طول حافلات البيانات من تأريض MK إلى طرف التأريض بجوار إدخال البيانات ، يمكنني حلها. منذ ذلك الحين لم يكن لدي أي مشاكل في التشويه على الشاشة.


كما رأينا من الرسم التوضيحي أعلاه ، يتم فرض طبقتين من المواد على شرائط LED.

كمواد لهذا الطلاء ، نحتاج إلى شيء قوي وشفاف ولكن ضوء متناثر. ومع ذلك ، لم أرغب في استخدام الزجاج لأنه باهظ الثمن وهش. لذلك ، قررت أن آخذ البوليستيرين الشفاف القياسي. حتى أنه بعثر الضوء ، تعاملت معه بورق صنفرة ناعم لدرجة أنه كان من المستحيل النظر إليه. كل شيء بسيط للغاية.

تم قضاء الكثير من الوقت في إنشاء شبكة يمكن وضعها مباشرة فوق الشرائط. فكرت فقط في طلب مصبغة بالمعايير اللازمة للطلب ، لكنهم اتصلوا بي بسعر حوالي 500 يورو. في رأيي ، لم تكن تستحق ذلك. لذلك ، كان علي جمعها بأنفسنا. لهذا نحتاج إلى شرائط بلاستيكية بيضاء متينة وشفافة (لا يزيد سمكها عن 2 مم). الكثير من المتطلبات. لذلك ، استغرق اختيار المادة الصحيحة الكثير من الوقت. كما اتضح ، فإن الخطوط من ستائر النوافذ (الصفائح) مثالية.


أولاً ، لقد صنعنا حاملًا صغيرًا لعمل موحد ، حتى قطع على خطوط واسعة. في هذه الحالة ، تم الحصول على شرائط بلاستيكية صغيرة نوعًا ما. ثم احتجنا إلى عمل شقوق في منتصف كل شريط بالضبط في الأماكن الصحيحة. هذا ضروري لتوصيل قطع البلاستيك وتجميع الشبكة. هذا ما أفعله في الصورة الثالثة. قبل القيام بذلك ، تحتاج إلى التأكد من أن عرض المنشار هو نفسه أو أكبر قليلاً من عرض الشريط الذي قمت بقصه. خلاف ذلك ، لا يمكن تجميع الشبكة. في حالتي ، اتضح أن المنشار المعدني له سمك مثالي.

في الصورة الرابعة ، تظهر نتيجة تجميع جميع الشرائط في الشبكة. لقد كانت مهمة مزعجة ورتيبة للغاية ، ولكن تبين أن الشواية متينة للغاية. بشكل عام ، يبدو أن جميع الخلايا بنفس الحجم. لا يوجد اختلاف كبير بين أحجام الخلايا ، وإلا ستبدو الشاشة غريبة ، لذلك تحول كل شيء إلى جيد جدًا. أنا سعيد بهذه الشواية.


ثم أرفقت الشبكة في إطار خشبي يؤدي عدة مهام. أولاً ، تحمل قطعة من البوليسترين في الجزء العلوي من الشواية. يضمن عدم تحرك الشبكة. بالإضافة إلى ذلك ، يضغط الإطار الخشبي على جميع الأسلاك بحيث يتم تثبيتها بشكل أكثر أمانًا ولا يمكن أن تنفجر عن طريق الخطأ (وهو ما حدث بضع مرات عندما قمت بتحريك الشاشة).


تظهر هذه الصورة ورقة من البوليسترين المغطاة بالرمل وضعت على رف سلكي. لاحظ أن الشواية بالكاد مرئية الآن ، وهذا ما أردناه.


بعد قضاء ساعات طويلة في تجربة التنفيذ الصحيح للتحكم في العرض ، تمكنا أخيرًا من تشغيله. كانت المشكلة الكبيرة هي الحفاظ على سلامة الإشارات. ولكن كما قلت أعلاه. ساعدني المجتمع من Electronics.stackexchange في ذلك!

الشاشة ساطعة وأكثر سطوعًا مما توقعت. كان من الضروري توقع ذلك ، وطلب وحدة 100 A لإمدادات الطاقة الخاصة بها.


كما قلت عدة مرات ، نستخدم مكتبة FastLED للتحكم في مصابيح LED. لكنني لم أذكر أنني أستخدم أيضًا نسخة معدلة من مكتبة FastLED-GFX بواسطة Jürgen Skrocki (وهو في حد ذاته منفذ لمكتبة Adafruit-GFX ) لعرض بسيط للأشكال على الشاشة . التغييرات في هذه المكتبة بسيطة ، لكنها كانت ضرورية حتى يتمكن المترجم من التواصل مع المكتبة بطريقة مناسبة.

العقول و ...


واحدة من آخر المهام التقنية التي تحتاج إلى حل لإكمال هذا المشروع هي إكمال عقول وحدة التحكم. تحتاج إلى تحويلها إلى مجموعة واحدة مريحة وصغيرة الحجم. ولكن علينا أولاً معرفة كيفية التعامل مع جميع إشارات الإدخال للاعبين. دعني أذكرك بأن لكل لاعب 4 أزرار وعصا تحكم واحدة. أي ما مجموعه 16 إشارة إدخال رقمية و 8 إشارات تناظرية. عضو الكنيست ليس لديه ما يكفي من الاتصالات لمثل هذا الإدخال ؛ بالإضافة إلى ذلك ، يتم بالفعل استخدام دبابيس ناقل بيانات لقراءة EEPROM ، وهناك حاجة إلى 7 دبابيس ناقل بيانات متوازية للتحكم في الشاشة.

لحل هذه المشكلة ، نستخدم زوج من سجلات التحول للإدخال الرقمي. وبالنسبة لجميع المدخلات التناظرية ، سنأخذ معدد الإرسال التناظري.


مخطط لقراءة / كتابة EEOPROM في نفس الوقت ، ومعالجة إدخال المشغل والتحكم في العرض.

ثم يبدأ الارتباك. اسمحوا لي أن أشرح ما يحدث في هذه الصورة ، من اليسار إلى اليمين. يوجد في الجزء العلوي من اللوح الأيسر 7 حافلات بيانات تستخدم للتحكم في العرض. يوجد أدناه المنطقة التي يمكن إدخال EEPROM فيها وقراءتها.

يوجد في الجزء العلوي من اللوح الأوسط معدد إرسال تناظري. يمكن أن يستقبل معدد الإرسال هذا ما يصل إلى 16 إشارة إدخال تناظرية ، واعتمادًا على إشارات الإدخال على معدد الإرسال ، قم بتوصيل إحدى الإشارات التناظرية بـ MK. وبالتالي ، نحن بحاجة فقط إلى دبوس إدخال تناظري واحد وزوج من دبابيس الإدخال الرقمي لمعالجة 16 إدخالًا تناظريًا. يبدو أنه لا يوجد إدخال تمثيلي متصل بالمُعدِّد في هذه الصورة.

تحت معدد الإرسال هو MK Teensy.

على اللوح الأيمن ، نقوم بمعالجة إشارات الإدخال الرقمية. في هذه الصورة ، يتم توصيل 16 إشارة رقمية ببساطة إلى الأرض. كنت لا أزال أنتظر وصول الأزرار ، لذا اختبرت جميع الإشارات الرقمية الـ 16 بهذه الطريقة. بفضل سجلات النقل ، كان هناك حاجة إلى 4 دبابيس فقط للتحكم في جميع الإشارات الرقمية.

النظام كله فوضى كبيرة لا يمكن الاعتماد عليها. من الضروري جعلها أكثر إحكاما حتى لا تنفصل عن زفير غير مبالي. لذلك ، طلبت العديد من لوحات النماذج وبدأت اللحيم مرة أخرى!



وتبين أن هذه مهمة صعبة! ومع ذلك ، كانت هذه مناسبة ممتازة لتعلم كيفية اللحام بدقة.

للتوصل إلى هذه الدائرة ، استخدمت كمثال فوضى الأسلاك على لوحة التوصيل. ثم حاولت الخروج بدائرة أكثر ذكاءً بحيث تكون المكونات التي يجب أن تتواصل مع بعضها أقرب ما يمكن. لذلك حاولت التخلص من الحاجة إلى سحب الكثير من الأسلاك. الآن أعتقد أنه يمكنك استخدام بعض أدوات النمذجة لتصميم الدائرة. ولكن لا يزال اتضح بشكل جيد.

قررت تصميم دائرة من طبقتين. على لوحة النموذج الأولي ، تتم معالجة جميع المدخلات. على كل من توصيلات الإدخال 4 ، لدي 8 خطوط إدخال (1 - أرضي ، 1 - إيجابي ، 4 - إدخال رقمي ، 2 - إدخال تناظري). يتواصل MK مع الطبقة السفلية باستخدام أربعة اتصالات بجوار سجلات التحول وأربعة اتصالات بجوار معدد الإرسال.

يقع مصدر الطاقة على الطبقة العليا ، على اليمين هناك 7 حافلات بيانات الإخراج للعرض ، وفي الأسفل توجد جهات اتصال لقراءة EEPROM. وأخيرًا ، في الوسط ، بالطبع ، هو المتحكم الدقيق.


بين لوحات التحكم الرئيسية ومدخلات اللاعبين ، قمت بوضع لوحات وسيطة لتقليل عدد الأسلاك المطلوبة على كلا الجانبين من 12 إلى 8 ، لأنه ليس من الضروري استخدام جميع الأسلاك الأرضية الخمسة التي تنتقل من اللوحة الرئيسية إلى لوحة الإدخال. تأريض واحد كافٍ لجميع الأزرار وعصا التحكم. لذلك ، هناك أربعة مجالس وسيطة. يعجبني أنه يمكنك ملاحظة تحسن في جودة كل لوحة تالية تجمعها.


بعد عدم تلقي الأزرار المطلوبة ، طلبت مجموعة أخرى من بائع آخر وبعد عدة أيام استلمتها. هذا سمح لنا بالبدء أخيرًا في اختبار جميع الأزرار.


في هذه المرحلة ، كتبت أيضًا اللعبة الأولى التي يمكن لعبها على وحدة التحكم. نعم ، الآن أسميها وحدة التحكم.

لقد نجحت لأنه في عملية العمل على الشاشة قمت بتحسين المترجم في نفس الوقت. على وجه الخصوص ، تمكنت من تحسين عملية التطوير نفسها عند كتابة التعليمات البرمجية. هذه العملية ليست مثيرة للاهتمام من الخارج ، لذلك قررت عدم توثيقها بشكل خاص.


لقد أنشأت بيئة تطوير بسيطة لكتابة التعليمات البرمجية التي يمكن تنفيذها على وحدة التحكم.

تعمل هذه البيئة في متصفح ، وتسمح لك بكتابة كود لوحدة التحكم دون العبث بالقوائم الفوضوية للأرقام التي رأيناها أعلاه. بالإضافة إلى ذلك ، قمت بإنشاء محاكي وحدة تحكم يعمل في نفس تطبيق الويب.

توفر القدرة على محاكاة الألعاب لوحدة التحكم في تطبيق ويب الكثير من الوقت ، لأن تصحيح الأخطاء على جهاز الكمبيوتر أسهل بكثير من MK.

المحاكي ليس مثاليًا. هناك بعض الأخطاء التي تميز المحاكاة من اللعب على إصدار حقيقي من وحدة التحكم. سأحاول إزالتها في المستقبل عندما أكتب نسخة جديدة من المترجم. كانت الحاجة إلى دعم نسختين من المترجم (أحدهما مكتوب بلغة C ++ ، والأخرى في TS) مزعجة بعض الشيء ، لكنها كانت تستحق ذلك.

ضع كل شيء معا


كل شيء جاهز. يمكننا عرض الصور بناءً على منطق اللعبة المأخوذ من EEPROM ومعالجة إدخال اللاعب من الأزرار وعصا التحكم. الآن نحن بحاجة إلى دمج كل هذا في جهاز واحد دائم.


بدأت بحفر ثقوب في ألواح الألمنيوم التي ستثبت الأزرار وعصا التحكم في مكانها. ثم كان من الممكن إدخال هذه الألواح في أخاديد العلبة الخشبية التي كانت مريحة. وبفضل هذا ، لن يتمكن اللاعبون من خدش المعدن عن طريق الخطأ.



نجمع كل شيء حول الشاشة ونضيف أرجل قابلة للطي يمكن الاعتماد عليها (لسهولة التخزين). تبدو اللوحات المعدنية المطلية بالطلاء الأسود جميلة جدًا. هناك شعور بأن المشروع يتحرك بالفعل نحو الانتهاء.


لكن بالطبع كنت مخطئًا في الاعتقاد بأن المشروع قد اكتمل تقريبًا. إليك ما تبدو عليه وحدة التحكم لمدة شهر تقريبًا.

نجمع كل شيء ، نفهم أن الزر لا يعمل. نقوم بفكها مرة أخرى ، وإصلاح المشكلة باستخدام الزر. يبدو أن كل شيء يعمل. نحن نفهم أن عصا التحكم لا تعمل. تفكيك مرة أخرى. عاجلاً أم آجلاً ، تبدأ جميع الأزرار وعصا التحكم في العمل. ولكن بعد ذلك تتوقف المصابيح عن العمل. لإصلاحها ، تحتاج إلى تفكيك وحدة التحكم بالكامل وإعادة تجميعها من البداية. استمر هذا لمدة شهر تقريبًا ، حتى نجح كل شيء في النهاية.

نتيجة




كل شيء جاهز! بعد بدء العمل في المشروع مرت 3-4 أشهر بالفعل. لذلك ، من المنطقي أن دافعي لمواصلة تحسين المترجم ، ورسم الشجرة وتطوير ألعاب جديدة قد جفت بالفعل. في وقت كتابة هذه السطور ، مر شهر بالفعل ، عندما كنت آخر مرة شاركت في المشروع. اكتسبت القوة أخيرًا لكتابة هذا المنشور الوثائقي لنفسي ولكم أيها القارئ. على الرغم من أنني لا أتوقع أن يقرأ شخص ما في عقله الصحيح كل ما كتبته ، آمل أن تكون قد استمتعت بمشاهدة صور التطور التدريجي للمشروع.

ولكن إذا قرأت كل هذا ، فقد تكون مهتمًا بمستودع Github للمشروع. بالطبع ، كل شفرتي مفتوحة المصدر! https://github.com/Arcadable

المزيد من خطط تطوير المشروع:

- أولاً ، تحتاج إلى عمل خرطوشة أكثر جمالا للعب Pong لمدة أربعة ، والتي تظهر في الفيديو الأخير. في حين أنها قطعة من الورق المقوى مع قطع منحنية من رقائق الألومنيوم ، والتي تستخدم كأسطح ملامسة.

- بالإضافة إلى ذلك ، أريد أن أرسم وحدة التحكم بشكل أفضل. في البداية ، خططت لرسمه مع أصدقاء من ذوي الخبرة الذين يحبون الرسم. ومع ذلك ، الآن بسبب الوباء هذا غير ممكن.

- أخيرًا ، كما قلت عدة مرات ، سأعيد كتابة المترجم بطريقة أكثر فاعلية. سأقوم أيضًا بتحسين بيئة التطوير لجعل الألعاب أسهل. يعمل تصميم تطبيق الويب حاليًا على إعاقة الإنتاجية.


التعويض عن تسجيلات الفيديو العمودية.

All Articles