ساخت بازی دونفره آردوینو آرکید با WS2811 (جذاب)
محتویات
از بازی های قدیمی آرکید که همگی شبیه به هم هستند و مثل هم کار می کنند، خسته شدید؟ می خواهید یک بازی سرگرم کننده که بتوانید آن را در کنار دوستان و خانواده خود بازی کرده و لذت ببرید بسازید؟ پس، به جای درستی آمده اید.
در این مطلب یاد می گیریم که چگونه این بازی دونفره را با آردوینو بسازیم. ابتدا درباره نوار ال ای دی WS2811 و سپس درمورد طراحی، الکترونیک آن و کدنویسی این بازی مطالعه می کنیم.
قبل از این بازی، بازی هایی مثل “مسابقه ی فضایی با آردوینو”، “بازی تتریس با آردوینو” و “بازی اعصاب سنج یا Buzzer Wire Game با آردوینو” را ساخته ایم.
قطعات لازم
- نوار ال ای دی WS2811
- 2 عدد کلید فشاری سرصاف AHF
- آردوینو نانو
- بازر
- باتری لیتیوم یون یاLi-ion
- سوییچ
- اسپیسر 50 میلی متری M3
- اسپیسر 20 میلی متری M3
- پیچ و مهره ی 10 میلی متری M3
پین اوت (شرح پایه ها) نوار ال ای دی WS2811:
نوار LED از طریق پایه ی VCC و GND تغذیه میشود. این نوار یک اتصال دهنده مرد یا نری ( میل کانکتر) و یک اتصال دهنده زن ( فیمیل کانکتر) دارد که پین وسط اتصال دهنده زن، همان پین داده است.
حال بیایید قدم به قدم این پروژه را بسازیم.
طراحی قاب آکریلیک در نرم افزار Solidworks
در ابتدا باید یک فایل با پسوند .dxf در هر نرم افزار مدل سازی جامدات ایجاد کنیم. ما از نرم افزار Solidworks استفاده کردیم ولی شما می توانید ازهر نرم افزاری که بخواهید استفاده کنید. باید طراحی را طوری انجام دهیم که فضای کافی برای قرار گرفتن هر 50 لامپ LED و دو کلید فشاری را بر روی نوار LED داشته باشیم. خوب است که جنبه ی زیبایی شناختی قاب را رعایت کنیم. هم چنین باید یک اسلات سوییچ قرار دهیم تا هر وقت که نیاز شد، بازی را بین دو حالت on و off سوییچ کنیم و تغییر دهیم.
بعد از ساعت ها تلاش و امتحان کردن طراحی های مختلف، در نهایت به طرح زیر رسیدیم.
شما می توانید فایل های stl را از این لینک دانلود کنید.
مدار اتصالات WS2811 با برد آردوینو نانو
مدار کامل شده این پروژه نسبتا ساده است. در WS2811 دو سیم آزاد VCC و GND داریم که باید به ترتیب به پایه 5 ولت و GND برد آردوینو متصل شوند.
در کانکتور زن یا همان فیمیل کانکتر3 حفره داریم که حفره وسط، پایه داده است. آن را به پایه داده دیجیتال برد آردوینو متصل می کنیم. (در اینجا، به پین شماره 5 آردوینو)
یکی از ترمینال های اولین کلید فشاری را به پین 2 آردوینو و ترمینال دیگر را به زمین (GND) متصل کنید. شکل زیر به شما نشان میدهد که چگونه از کلید به بیرون سیم بکشید.
یکی از خروجی های دومین کلید فشاری را به پین 3 آردوینو و خروجی دیگر را با سیم های جامپر زمین کنید.
به طور مشابه، پایانه مثبت بازر را به پین 7 آردوینو و پایانه منفی را با جامپر به زمین متصل کنید.
و در نهایت سوییچ را به پین Vin آردوینو و باتری 7.4 ولتی لیتیوم یون متصل کنید.
کد بازی دونفره برد آردوینو
هنگامی که اتصالات سخت افزاری را انجام دادید، باید با استفاده از IDE آردوینو، برد آردوینو نانو خود را کدنویسی کنید.
در این قسمت، کد این پروژه را توضیح می دهیم. می توانید کد کامل و نهایی را در انتهای این مطلب مشاهده کنید.
#include <FastLED.h>
این خط از کد، کتابخانه FastLED را به برنامه ما اضافه می کند که شامل تابع های لازم برای کنترل نوار LED آدرس پذیر است.
#define LED_PIN 5 #define BUZZER_PIN 7 #define NUM_LEDS 50 #define BUTTON_PIN1 2 #define BUTTON_PIN2 3 #define DELAY_MS 50 #define RED_BUTTON_FREQ 100 // Frequency for the red button sound #define GREEN_BUTTON_FREQ 200 // Frequency for the green button sound
در خط های بالا، مقادیر ثابتی را برای پایه های استفاده شده در اتصال نوار LED، بازر، کلیدها و پارامترهای دیگر، تعریف کرده ایم.
CRGB leds[NUM_LEDS];
در این خط، یک آرایه از اشیای CRGB تعریف کردیم که بیانگر همان نوار LED مان است. طول این آرایه را با NUM_LEDS درون کروشه مشخص کردیم که 50 است. یعنی 50 لامپ LED داریم.
int ledCount1 = 0; // Number of red LEDs to light up from one end int ledCount2 = 0; // Number of green LEDs to light up from the other end bool buttonState1 = false; bool lastButtonState1 = false; bool buttonState2 = false; bool lastButtonState2 = false; bool isRedButtonPressed = false; bool isGreenButtonPressed = false;
در این خط، متغیرهایی را برای ذخیره مقدار جریان و حالت قبلی کلیدها، تعدادLED های قرمز و سبزی که در طی بازی روشن میشوند و پرچم ها، که نشان میدهند کلید سبز فشار داده شده یا کلید قرمز، تعریف کرده ایم.
void setup() { FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS); pinMode(BUTTON_PIN1, INPUT_PULLUP); pinMode(BUTTON_PIN2, INPUT_PULLUP); pinMode(BUZZER_PIN, OUTPUT); }
در ابتدا وقتی برد آردوینو شروع به کار میکند، تابع setup() یک بار فراخوانی میشود. این تابع، نوار LED را به کار می اندازد، پین های متصل به کلیدها را با مقاومت های پول آپ به عنوان ورودی و پین متصل به بازر را به عنوان خروجی پیکربندی می کند.
void loop() { buttonState1 = digitalRead(BUTTON_PIN1) == LOW; buttonState2 = digitalRead(BUTTON_PIN2) == LOW;
بعد از کامل اجرا شدن تابع setup()، تابع loop() به صورت مداوم فراخوانده میشود. این تابع با استفاده از تابع digitalRead()، مقادیر پین های BUTTON_PIN1 و BUTTON_PIN2 را که وضعیت فعلی کلیدها هستند را می خواند و متغیرهای buttonState1 و ButtonState2 را متناسب با آنچه خوانده، به روز میکند.
if (buttonState1 != lastButtonState1) { if (buttonState1) { // Button 1 is pressed ledCount1++; if (ledCount1 > NUM_LEDS) { ledCount1 = NUM_LEDS; } isRedButtonPressed = true; tone(BUZZER_PIN, RED_BUTTON_FREQ); // Play the red button sound } lastButtonState1 = buttonState1; }
این بلوک کد، وضعیت buttonState1 (که متصل به کلید اول است) را چک می کند که نسبت به حالت قبلی تغییری کرده است یا نه. اگر کلید اول فشار داده شده باشد یعنی buttonState1 درست و true باشد، مقدار ledCount1 را افزایش می دهد و اطمینان حاصل می کند که تعداد لامپ های روشن متصل به کلید اول از تعداد کل LED ها که 50 تا بود، بیشتر نشود.
هم چنین متغیر isRedButtonPressed را هم true میکند چون کلید قرمز فشار داده شده است. سپس با اجرای تابع tone() با فرکانسی که از طریق مقداردهی به متغیر RED_BUTTON_FREQ تعیین کرده ایم، بازر را به صدا درمی آورد.
if (buttonState2 != lastButtonState2) { if (buttonState2) { // Button 2 is pressed ledCount2++; if (ledCount2 > NUM_LEDS) { ledCount2 = NUM_LEDS; } isGreenButtonPressed = true; tone(BUZZER_PIN, GREEN_BUTTON_FREQ); // Play the green button sound } lastButtonState2 = buttonState2; }
این بلوک کد هم مثل بلوک کد قبلی است با این تفاوت که حالت کلید دوم را بررسی میکند.(buttonState2) سپس مقدار ledCount2 را افزایش میدهد و اطمینان حاصل می کند که تعداد لامپ های روشن متصل به کلید 2، از تعداد کل لامپ ها بیشتر نشود.
متغیر isGreenButtonPressed را true میکند و با اجرای تابع tone() با فرکانسی که از طریق مقداردهی به متغیر GREEN_BUTTON_FREQ تعیین کرده ایم، بازر را به صدا درمی آورد.
FastLED.clear();
این خط، تمام LED ها را خاموش میکند و عمل پاک کردن یا clear را انجام میدهد.
for (int i = 0; i < ledCount1; i++) { leds[i] = CRGB::Green; }
با این حلقه، رنگ اولین لامپ LED ای که ledCount1 میشمرد را سبز میکنیم. یعنی مشخص میکنیم که لامپ هایی که به کلید اول متصل هستند، باید سبز شوند.
for (int i = NUM_LEDS - 1; i >= NUM_LEDS - ledCount2; i--) { leds[i] = CRGB::Red; }
این حلقه، از انتهای نوارLED شروع کرده و رنگ لامپ های ledCount2 را قرمز میکند. یعنی مشخص میکنیم که لامپ هایی که به کلید دوم متصل هستند، باید قرمز شوند.
if ((ledCount1 + ledCount2) >= NUM_LEDS) { if (ledCount1 > ledCount2) { greenChaserEffect(); } else if (ledCount2 > ledCount1) { redChaserEffect(); } else { // It's a tie tieChaserEffect(); } ledCount1 = 0; ledCount2 = 0; }
این بلوک کد، مجموع لامپ های روشن متصل به هر دو کلید (ledCount1+ledCount2) را محاسبه میکند و چک می کند که آیا آنچه که حساب کرده با مجموع LEDهای موجود که 50 عدد است مساوی بزرگتر است یا نه. اگر که هست، مشخص میکند که بیشتر لامپ های روشن چه رنگی هستند و سپس با این داده ها، تابع مناسب را از بین سه تابع tieChaserEffect()، redChaserEffect() و greenChaserEffect() فراخوانی میکند تا اثرتعقیب را بر روی نوار نمایش دهد.
سپس، مقدار هر دو متغیر ledCount1 و ledCount2 را ریست کرده و برابر صفر میکند.
FastLED.show();
با این خط، وضعیت نوار را با رنگ های جدیدی که در مرحله قبل تنظیم شده، به روز میکنیم.
if (isRedButtonPressed || isGreenButtonPressed) { delay(50); noTone(BUZZER_PIN); isRedButtonPressed = false; isGreenButtonPressed = false; }
اگر کلید سبز یا کلید قرمز فشار داده شده بود ( متغیر isRedButtonPressed یا isGreenButtonPressed درست بود) یک تاخیر ایجاد می شود تا مدت زمانی که بازر به صدا درمی آید کنترل شود. با تابع noTone() صدای بازر را قطع کرده و پرچم کلید ها را ریست میکنیم.
delay(50);
در این خط، با قراردادن تاخیر 50 میلی ثانیه ای، فرصت برگشتن کلیدها به حالت اصلی خود و کنترل سرعت پاسخ کد را فراهم میکنیم.
void tieChaserEffect() { // ... }
هنگامی که لامپ های قرمز و سبز به سمت هم و به طرف مرکز نوار حرکت میکنند، اثر تعقیب ایجاد میشود که با استفاده از تابع tieChaserEffect() که قبلا به آن اشاره شد، اثر تعقیب را نمایش می دهیم.
void greenChaserEffect() { // ... }
هنگامی که لامپ های سبز از یک طرف نوار به طرف دیگر حرکت میکنند، اثر تعقیب ایجاد میشود که با استفاده از تابع greenChaserEffect() که قبلا به آن اشاره شد، اثر تعقیب را نمایش می دهیم.
void redChaserEffect() { // ... }
هنگامی که لامپ های قرمز از یک طرف نوار به طرف دیگر حرکت میکنند، اثر تعقیب ایجاد میشود که با استفاده از تابع redChaserEffect() که قبلا به آن اشاره شد، اثر تعقیب را نمایش می دهیم.
توضیحات کد در اینجا تمام میشود. اگر سوالی دارید، آن را با ما درمیان بگذارید.
مونتاژ قاب بیرونی بازی آرکید
بعد از تمام شدن مدار، باید قطعات الکترونیکی را با قاب آکریلیکی مونتاژ کنیم که در نهایت به این شکل درمی آید.
پروسه ی ساخت این بازی بسیار جذاب بود و نتایج هم در انتهای کار بی نظیر بودند.
اگر هرگونه سوالی درباره ی این موضوع دارید، در قسمت نظرات آن را با ما درمیان بگذارید.
موارد موجود در فایل : سورس کامل
برای دانلود فایل ها باید حساب کاربری داشته باشید ثبت نام / ورود