步驟1:基本設(shè)計(jì)
反應(yīng)游戲非常簡(jiǎn)單。它是一個(gè)計(jì)時(shí)器,一個(gè)顯示器以及您需要多少個(gè)發(fā)光按鈕。
反應(yīng)游戲接線的主要部分是兩個(gè)重復(fù)的獨(dú)立電路的集合。這兩個(gè)電路是:
1。按鈕
在Arduino官方網(wǎng)站上有很多關(guān)于向Arduino添加按鈕的教程。
2。獨(dú)立點(diǎn)亮的LED(12v)
對(duì)于LED,由于我們使用的是12v LED,我們需要與Arduino分開(kāi)的外部電源,該電源只能在5v的電壓下工作。對(duì)于先前的項(xiàng)目(我希望在某個(gè)時(shí)候?qū)懸粋€(gè)照相亭),我使用MOSFET在Raspberry PI和一些LED燈之間建立接口。我使用了關(guān)于PI和LED之間的連接的出色教程。對(duì)于這個(gè)項(xiàng)目,我只是簡(jiǎn)單地重復(fù)了多次練習(xí)。
輸出顯示
游戲的第三部分是用于顯示得分的LED矩陣顯示和剩余時(shí)間。為此,我使用了4個(gè)鏈接的MAX7219矩陣顯示器。為了使它們正常工作,我使用了鏈接到驅(qū)動(dòng)程序庫(kù)的鏈接教程,并提供了使用顯示器的示例。
步驟2:電路板-按鈕連接器
在構(gòu)建我制作的第二個(gè)反應(yīng)游戲時(shí),編寫了指令。在制作第一個(gè)反應(yīng)游戲的過(guò)程中,我犯了一些小錯(cuò)誤,因此在設(shè)計(jì)上有所改進(jìn)。 (理想情況下,我想為所有電子設(shè)備制作PCB,并且我打算在有更多時(shí)間的情況下這樣做)。
在其中鉆兩個(gè)6mm孔vero板位于方便的位置。如果使用相同的Vero板,則建議使用與以前相同的位置。這樣可以避免所有主要路線,包括我用于地面的大型路線。這些孔用于將板安裝到反應(yīng)游戲的背面。在我最初的設(shè)計(jì)中,我沒(méi)有這樣做,最終將電路板熱粘合。除非出現(xiàn)問(wèn)題,否則我很麻煩!
使用1.5mm的鉆頭,沿一個(gè)邊緣增加銷的尺寸。我用來(lái)將每個(gè)按鈕連接到板上的4針凹型連接器的針腳明顯更寬。由于4針連接器每個(gè)跨2個(gè)孔,因此僅每個(gè)其他孔都需要加寬。
將所有8個(gè)母連接器推到板上,并焊接到位。
步驟3:電路板-主接線
本節(jié)詳細(xì)介紹了主要組件與電路板的接線。
一個(gè)16針公插頭,它在板的底部。這是按鈕,LED和Arduino
之間的接口。由于使用了Vero板,因此很容易將單獨(dú)的電路(LED和按鈕)分為幾組。母連接器跨越8個(gè)孔。這意味著LED可以使用4個(gè)孔,按鈕可以使用4個(gè)孔,以將電路保持在相同的“垂直”狀態(tài)。因此,所有8個(gè)電路可以以8個(gè)孔的間隔重復(fù)進(jìn)行。
為使布線更簡(jiǎn)單,我傾向于依次為每個(gè)電路依次布線所有相同的零件(如圖所示)
步驟4 :板
要安裝電子設(shè)備,我購(gòu)買了可以運(yùn)輸?shù)淖畲蟮陌澹?10毫米x 1220毫米x 9毫米)。
我標(biāo)記了所有按鈕的位置。
每個(gè)角按鈕距角100毫米x 100毫米。
中間的頂部和底部按鈕位于中間,但距離邊緣100毫米
中間的兩個(gè)按鈕(左側(cè)和右側(cè))與其他按鈕的距離相等適當(dāng)?shù)囊幻妗?/p>
在標(biāo)記了按鈕的位置之后,我使用了25毫米的平頭鉆頭來(lái)鉆出按鈕的孔。
我標(biāo)記了顯示器的位置
一個(gè)朋友有一個(gè)擺動(dòng)的多功能工具,所以我借用他在顯示器上切出矩形孔。
由于我使用的顯示器的厚度和設(shè)計(jì),我使用了路由器將MDF的深度去除了約5mm。
我為木板切了3個(gè)支撐腿。腿部被切割成一定角度,使木板既可以躺在桌子上,也可以直立在墻上。中腿需要一個(gè)用于穿過(guò)電纜的插槽。
在項(xiàng)目的第1版中,我只用了2條腿,但是當(dāng)傾斜到“桌面”(平躺)位置時(shí),會(huì)導(dǎo)致板子彈跳很多。
將腿粘到位。
我用黑板漆畫了木板。這主要是為了使我們能夠使用粉筆在板上畫廣告,并在按鈕上寫下不同的游戲名稱。
最后,我將兩個(gè)螺栓熱粘合到電路板上(電路板頂部附近),以通過(guò)先前在PCB中鉆出的2個(gè)孔安裝電子設(shè)備。我還將一圈膠水熱粘在螺栓上(現(xiàn)在在螺栓的上側(cè)),以最大程度地減少短路的風(fēng)險(xiǎn)。
步驟5:接線并組裝
為每個(gè)按鈕切斷適當(dāng)長(zhǎng)度的電纜。這些電纜的長(zhǎng)度會(huì)因面板/按鈕的距離而異。
在一端,將剝開(kāi)的電線擰入連接塊中。對(duì)于每個(gè)連接塊,將所有4根電線保持在相同的順序,因?yàn)檫@將簡(jiǎn)化以后的接線,也使解決任何問(wèn)題變得更加容易。我使用的順序是:
紅色-LED 12v
黑色-LED接地
黃色-切換到引腳
灰色-切換5v
在另一端,我壓接了連接器以保持連接的美觀和整潔。我確實(shí)沒(méi)用完連接器,所以不是我的所有連接器都做完了
所有連接器都連接好后,按如下所示組裝按鈕。我的LED沒(méi)有標(biāo)記,因此按正確的方向進(jìn)行操作會(huì)引起反復(fù)試驗(yàn),但這要等到代碼完成后才能實(shí)現(xiàn)
我的按鈕背面有兩小塊塑料在板上時(shí)停止旋轉(zhuǎn)按鈕。這就要求在每個(gè)按鈕的板子前面鉆兩個(gè)小孔。我發(fā)現(xiàn)最簡(jiǎn)單的方法是將按鈕放入并旋轉(zhuǎn)45度。取出按鈕后,可以看到銷釘畫的兩條線。用一個(gè)3mm的小鉆頭在每條線的一端鉆孔。確保您在每條線的同一端都進(jìn)行了鉆孔(例如,兩行的順時(shí)針?lè)较颍。?/p>
步驟6:接線Arduino
以下說(shuō)明用于連接Arduino MEGA。
需要將16針公對(duì)母帶狀跨接電纜從PCB上的16針接頭連接到Arduino上的數(shù)字?jǐn)?shù)據(jù)針,如圖所示。
兩個(gè)引腳從Arduino連接到PCB。 5v轉(zhuǎn)到具有紅線的PCB上的小電路。接地引腳從Arduino到PCB,
顯示器的接線方式如接線圖所示。
最后將LED的12v線連接到母插孔連接器上。
顯示器
顯示器已配對(duì)并放入孔(確保正確放置)。我使用膠帶將顯示屏固定在板上。
我使用膠帶并且不將顯示屏永久固定在原位的原因是我希望能夠與玩家站在一塊墻,或平躺在桌子上。這就是為什么后面的支桿被切成一定角度的原因。但是,這兩個(gè)位置都需要切換顯示,以便每次都能正確顯示。因此,通過(guò)使用膠帶方法可以輕松更改它們。
第7步:對(duì)Arduino進(jìn)行編碼
我不會(huì)在此提供大量教程Arduino編程,因?yàn)橛幸恍┖馨舻慕坛蹋俏覍⒅鸩浇榻B我的代碼,并提供一般概述。我確信我可以改進(jìn)代碼,并添加許多其他游戲。
該項(xiàng)目需要HCMAX7219庫(kù)??赡苡卸鄠€(gè)版本,但是我使用了Hobby Components Blog引用的版本。這就是我建議從此處獲取矩陣顯示的原因,因?yàn)槭褂盟鼈兊墓ぷ魉坪鹾芎竦蓝痪栀?zèng)!
下載后,編輯HCMAX7219.h文件并將以下行更改為4:
(第31行)
#define NUMBEROFDRIVERS 4
此值確定以菊花鏈方式將多少個(gè)LED矩陣顯示器鏈接在一起。對(duì)于單人游戲,我們使用4;對(duì)于兩人游戲,我們使用8。
附加到Instructable是我的代碼。
該代碼包含兩個(gè)數(shù)組,一個(gè)用于LED,一個(gè)用于按鈕:
const int LED[8] = { 2, 4, 6, 8, 22, 24, 26, 28 };
const int BUTTON[8] = { 3, 5, 7, 9, 23, 25, 27, 29 };
通過(guò)使用數(shù)組,可以索引特定的按鈕,然后返回
該程序包括以下主要部分:
設(shè)置-在Arduino通電時(shí)運(yùn)行一次以設(shè)置游戲
循環(huán)-持續(xù)運(yùn)行
ScreenSaver-隨機(jī)點(diǎn)亮按鈕,直到按下按鈕。程序中有3個(gè)屏幕保護(hù)程序,它們是隨機(jī)選擇的
CountDown-按下按鈕時(shí),請(qǐng)進(jìn)行短暫的倒計(jì)時(shí),并越來(lái)越快地閃爍燈光,以便播放器準(zhǔn)備開(kāi)始
PlayGame-玩實(shí)際游戲
設(shè)置
設(shè)置通過(guò)從屏幕上讀取“噪聲”來(lái)隨機(jī)化種子模擬端口。
如果設(shè)置了DEBUG,它將打開(kāi)串行端口。在設(shè)置了DEBUG的情況下運(yùn)行時(shí),讀取按鈕會(huì)有很大的延遲,因此在正確運(yùn)行游戲時(shí)應(yīng)關(guān)閉DEBUG
正確設(shè)置所有輸入和輸出引腳
/*
Set up the game
*/
void setup() {
// Set up the seed
if (DEBUG)
Serial.begin(9600);
// Set up the pins
for (int i = 0; i 《 NUMBER_BUTTONS; i++)
{
pinMode(LED[i], OUTPUT);
pinMode(BUTTON[i], INPUT);
}
}
循環(huán)
主循環(huán)啟動(dòng)“屏幕保護(hù)程序”,等待按鈕按下
顯示閃爍的倒計(jì)時(shí)在開(kāi)始播放
玩游戲之前
/*
The main loop
*/
void loop()
{
Debug(“DEBUG ON - ”, 0);
// Run the screen saver
ScreenSaver();
// Countdown to start
CountDown();
// Play the game
PlayGame();
}
屏幕保護(hù)程序
“屏幕保護(hù)程序”只是閃爍按鈕在不同的模式。這對(duì)于調(diào)試電子設(shè)備以及“宣傳”反應(yīng)游戲正在運(yùn)行并準(zhǔn)備就緒可發(fā)揮作用。我創(chuàng)建了3種不同的屏幕保護(hù)程序,從簡(jiǎn)單地隨機(jī)顯示燈光,建立和分解所有燈光,以及以“反彈”的不同線條顯示燈光。每個(gè)屏幕保護(hù)程序都有其自身的功能,可以在等待按下按鈕的同時(shí)打開(kāi)和關(guān)閉相應(yīng)的燈。因?yàn)槲覀冇?個(gè)按鈕,所以每個(gè)按鈕對(duì)應(yīng)一個(gè)字節(jié)中的一位。這使SetLEDs函數(shù)可以使用按位操作來(lái)打開(kāi)和關(guān)閉燈。
“構(gòu)建和行”屏幕保護(hù)程序使用包含要顯示的字節(jié)模式的查找表。隨機(jī)屏幕保護(hù)程序僅選擇一個(gè)介于1和255之間的b =數(shù)字,并顯示與該數(shù)字相對(duì)應(yīng)的燈光。
/*
Randomly does a screen saver
*/
void ScreenSaver()
{
int screenSaver = random(3);
bool response = false;
while (!response)
{
switch(screenSaver)
{
case 0:
Debug(“Screen saver random: ”, screenSaver);
response = ScreenSaverRandom();
break;
case 1:
Debug(“Screen saver build up: ”, screenSaver);
response = ScreenSaverBuildUp();
break;
case 2:
Debug(“Screen saver lines: ”, screenSaver);
response = ScreenSaverLines();
break;
default:
Debug(“Screen saver default: ”, screenSaver);
response = ScreenSaverRandom();
}
}
}
設(shè)置LED
以下兩個(gè)功能用于設(shè)置LED的開(kāi)和關(guān)(取決于調(diào)用它們的要求)。
SetLED寫入特定的引腳,將引腳設(shè)置為HIGH或LOW。
SetLEDs使用字節(jié)模式來(lái)設(shè)置多個(gè)LED的開(kāi)和關(guān)。
/*
Set a button
*/
void SetLED (int button, int led)
{
if (button != HIGH)
digitalWrite(led, LOW);
else
digitalWrite(led, HIGH);
}
/*
Set the LED pattern using bits
0000 0001 - LED 01
0000 0010 - LED 02
0000 0100 - LED 03
0000 1000 - LED 04
0001 0000 - LED 05
0010 0000 - LED 06
0100 0000 - LED 07
1000 0000 - LED 08
*/
void SetLEDs (int pattern)
{
Debug(“SetLEDs: ”, pattern);
int bitPattern = 0x01;
for(int i=0;i if ((pattern & bitPattern) != 0)
SetLED(HIGH, LED[i]);
else
SetLED(LOW, LED[i]);
bitPattern = bitPattern 《《 1;
}
}
檢查是否按下了按鈕
如果按下了任何按鈕,則以下函數(shù)返回true,
/*
Check to see if any button is pressed
*/
bool CheckButtons()
{
for (int i=0; i《 NUMBER_BUTTONS; i++)
{
if(digitalRead(BUTTON[i]) 》 0)
{
Debug(“CheckButtons() - pressed: ”, i);
return true;
}
} Debug(“CheckButtons() - NOT PRESSED - ”, -1);
return false;
}
玩游戲
此功能是主要的單人游戲。它僅循環(huán)運(yùn)行31秒,即可更新時(shí)間,打開(kāi)單個(gè)LED并等待按下相應(yīng)的按鈕。按下適當(dāng)?shù)陌粹o后,它會(huì)增加分?jǐn)?shù),隨機(jī)選擇其他按鈕并重復(fù)。
游戲?qū)嶋H上持續(xù)了31秒,但使用30秒時(shí),您的感覺(jué)是您獲得了29秒。對(duì)于31秒的游戲,計(jì)時(shí)器顯示30秒,然后等待一秒鐘遞減。當(dāng)達(dá)到0時(shí),游戲停止。如果使用30秒計(jì)時(shí)器,則游戲?qū)@示30秒,然后立即更改為29秒。看來(lái)您還沒(méi)用完30秒(盡管可以)。我發(fā)現(xiàn),比讓用戶認(rèn)為自己在被騙更值得多花一秒鐘!
時(shí)間一到,它會(huì)顯示玩家得分10秒,并在適當(dāng)?shù)臅r(shí)候更新高分并返回到屏幕保護(hù)程序(顯示游戲的最高得分)。
/*
Play the game
*/
void PlayGame()
{
unsigned long endTime = millis() + 31000;
int score = 0;
Debug(“endTime: ”, endTime);
Debug(“millis(): ”, millis()); long randButton = random(8);
while (millis() 《 endTime)
{
// Set the button to press as lit
SetLED(HIGH, LED[randButton]);
UpdateDisplay((endTime - millis())/1000, score);
// Check to see if the button was pressed
if(digitalRead(BUTTON[randButton]))
{
score ++;
// Turn off the button
SetLED(LOW, LED[randButton]);
// Get the new button and check it has changed
int newButton = random(8);
while(newButton == randButton)
{
newButton = random(8);
}
// Values differ, so continue
randButton = newButton;
}
}
// Clear all the LEDs
SetLEDs(0);
// Wait 10 seconds to show the score
delay(10000);
// If a new high score, set it
if (score 》 highScore)
highScore = score;
}
更新顯示內(nèi)容
此功能可在游戲過(guò)程中更新顯示內(nèi)容。該函數(shù)將時(shí)間和分?jǐn)?shù)轉(zhuǎn)換為字符串,在任何1個(gè)字符值的前面加上“ 0”以將其填充。然后將緩沖區(qū)發(fā)送到HCMAX7219庫(kù)以打印值,然后刷新顯示。
高分函數(shù)的工作非常相似,但顯示值HI和高分。
void UpdateDisplay(unsigned long time, int score)
{
// Update the time, make sure it is 2 digits
String timeStr = String(time);
if(timeStr.length() 《 2)
timeStr = “0” + timeStr;
// Add the score which must be 2 digits
String scoreStr = String(score);
if(scoreStr.length() 《 2)
scoreStr = “0” + scoreStr;
// Combine the string
String numberStr = timeStr + scoreStr;
char charBuf[5];
numberStr.toCharArray(charBuf, 5);
// Display the string
HCMAX7219.printMatrix(charBuf,32);
HCMAX7219.Refresh();
}
2人游戲的改進(jìn)
我對(duì)2人游戲進(jìn)行了一些改進(jìn),應(yīng)將其移回到單人游戲。其中包括:
高分存儲(chǔ)在EEPROM中,以便在關(guān)閉游戲時(shí)保存高分。首次打開(kāi)游戲時(shí),已修改設(shè)置以查找被按下的按鈕7。如果在啟動(dòng)時(shí)按下按鈕7,則會(huì)將高分重置為0。
如果未按下任何按鈕或按下的按鈕的值,則CheckButtons函數(shù)已更改為返回-1。這樣,主菜單就可以檢查返回的值并選擇要在主循環(huán)中玩的其他游戲。
步驟8:可選改進(jìn)
隨著我在原始項(xiàng)目上的進(jìn)展,我正在不斷改進(jìn),更新和完善自己的工作。
用于2個(gè)玩家游戲的第二個(gè)板子
最初,我只是在看一個(gè)玩家反應(yīng)游戲,但在進(jìn)行游戲測(cè)試時(shí),提出了其他可以實(shí)施的想法。第一個(gè)是兩個(gè)玩家選項(xiàng)。通過(guò)擁有第二塊棋盤,可以對(duì)大量其他游戲進(jìn)行編碼。通過(guò)使用Arduino Mega,可以在一個(gè)處理器上運(yùn)行兩個(gè)板。
提高游戲類型的數(shù)量
有很多游戲類型可用。大多數(shù)是主題的變體
反應(yīng)游戲-類似于“‘鼠”。如果它點(diǎn)亮,請(qǐng)按按鈕,得到一個(gè)指示,重復(fù)30秒。
反應(yīng)減游戲-與游戲#1相同,但是每次按錯(cuò)都會(huì)輸?shù)粢粋€(gè)點(diǎn)。不過(guò),您只能返回零(顯示的大小不足以容納負(fù)數(shù))。
多個(gè)按鈕反應(yīng)游戲-與#1類似,但多個(gè)按鈕會(huì)亮起,并且必須先清除所有按鈕,然后才能顯示一組新的隨機(jī)按鈕。
西蒙(Simon)說(shuō)-盡管我所有的按鈕都是單一顏色,但可以按給定順序點(diǎn)亮燈光并讓玩家重復(fù)給定圖案
將顯示添加到按鈕中
如果可以將矩陣顯示添加到每個(gè)按鈕中,并在中間添加較大的矩陣顯示,則可以提出簡(jiǎn)單的問(wèn)題,并選擇多項(xiàng)答案。即使每個(gè)按鈕上都沒(méi)有顯示,您也可以給每個(gè)按鈕編號(hào),然后問(wèn)一些簡(jiǎn)單的數(shù)學(xué)問(wèn)題。
責(zé)任編輯:wv
-
led
+關(guān)注
關(guān)注
242文章
23311瀏覽量
661633 -
Arduino
+關(guān)注
關(guān)注
188文章
6472瀏覽量
187347
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論