I det här roliga projektet lär vi oss hur man gör ett buzz-trådspel med Arduino. Många av de delar som behövs finns i en startpaket. Vad ingår i ett startpaket Vad ingår i ett Arduino Starter Kit? [MakeUseOf Förklarar] Vad ingår i ett Arduino Starter Kit? [MakeUseOf Explains] Jag har tidigare introducerat Arduino open- källa hårdvara här på MakeUseOf, men du behöver mer än bara den faktiska Arduino att bygga något ut av det och faktiskt komma igång. Arduino "startpaket" är ... Läs mer?) och runt huset. Detta projekt använder en Arduino, även om du kan använda nästan alla mikrokontroller du har runt (kolla på denna jämförelse mellan $ 5 mikrokontroller $ 5 Microcontrollers: Arduino, Raspberry Pi Zero eller NodeMCU? $ 5 Microcontrollers: Arduino, Raspberry Pi Zero eller NodeMCU? Det var vanligt att om du ville få en dator skulle du behöva remortgage ditt hus för att betala för det. Nu kan du få en till en Abraham Lincoln. Läs mer för lite inspiration).
Kolla in resultatet - det spelar även musik:
Vad du behöver
Här är kärndelarna du behöver för att slutföra projektet:
- 1 x Arduino UNO eller liknande.
- 1 x metallhängare.
- 2 x 220 ohm motstånd.
- 1 x brödbräda.
- 1 x Piezo summer.
- 2 x krokodilklämmor.
- Assorterad värmekrympslang.
- Man-till-han-kopplingskablar.
Elenco TL-6 Alligator Lead Set, 10-Piece, 14 tums Elenco TL-6 Alligator Lead Set, 10-Piece, 14 inches Köp Nu På Amazon $ 5, 59
Här är några valfria delar för att förbättra byggnaden:
- 1 x extra piezo summer.
- 1 x Dowel rod.
- 1 x fyrkant sju segmentvisning.
- 1 x 220 ohm motstånd.
- 1 x Moment-knapp.
- Man-till-kvinnliga hookup-ledningar.
- Träplanka (för väska).
- Diverse träskruvar.
Nästan alla Arduino kommer att fungera, förutsatt att den har tillräckligt med pinnar. Ta en titt på denna köpguide Arduino Köpguide: Vilket styrelse ska du få? Arduino Köpguide: Vilket styrelse ska du få? Det finns så många olika typer av Arduino brädor där ute, du skulle bli förlåtad för att vara förvirrad. Vilket ska du köpa för ditt projekt? Låt oss hjälpa till med den här Arduino-köpguiden! Läs mer om du inte är säker på vad du behöver.
Byggplanen
Även om det här kan se ut komplexa, är det faktiskt ganska enkelt. Jag börjar med det grundläggande spelet och lägger till ytterligare komponenter för att öka komplexiteten. Du kan "välja och välja" som du vill, beroende på vilka komponenter du har tillgång till.
Kärnmekanikern består av en trådform och en slinga på ett handtag. Spelaren måste styra slingan runt banan utan att de två berörs. Om de två berörs, är kretsen färdig och summeren låter. Det är självklart möjligt att bygga den här kretsen med ingen mikrokontroller, men var är det roligt i det (och hur annars skulle du få lyssna på Monty Python's "Flying Circus" temansång)?
Kursen
Detta är formen spelaren kommer att behöva styra sin loop runt. Det är grunden för hela spelet, så gör det bra! Jag valde att ha en liten droppe följt av en stor klättring. Böj en metallhängare i den form du behöver. Mässingstråd eller kopparrör fungerar lika bra, även om en hängare kan vara billigast.
Du kan behöva bära handskar och använda tång eller en hammare för att få saker perfekt. Skär bort eventuellt överskott med bultskärare. Lämna två vertikala stolpar för att skjuta genom basen. Du vill sätta in de skurna ändarna för säkerhet. Slutligen skär två stycken värmekrympslang och placera över ändarna enligt följande:
Detta kommer att isolera slingan från kursen, vilket ger en start / slut eller säkerhetszon. Alternativt kan tejp eller ens halm göra om du inte har någon värmekrympslang.
Montera nu en kabel i ena änden av banan. Du har två alternativ här: Du kan antingen lödda eller använda krokodilklämmor. En krokodilklämma är det enklare alternativet, men lödning är ett mer tillförlitligt och långsiktigt alternativ. Var noga med att "grova upp" ytbehandlarens yta först med sandpapper och använd mycket fluss. Lär dig hur man här Lär dig hur man löds med dessa enkla tips och projekt Lär dig hur man löds med dessa enkla tips och projekt Är du lite skrämmad av tanken på ett hett järn och smält metall? Om du vill att börja arbeta med elektronik, du kommer att behöva lära dig att löda. Låt oss hjälpa. Läs mer.)
Beroende på hålets storlek borrar du i basen i nästa steg, du kan behöva mata kabeln genom monteringshålet först. Att använda två trådar som vrids ihop ökar hållbarheten:
Att använda en borr för att göra detta hjälper mycket:
Basen
Det är dags att skapa basen. Detta tjänar till att hålla kursen i upprätt läge, samt att ge en plats för att förankra elektroniken till. Jag använde några pine offcuts, även om du kan använda allt du har runt huset - även en kartong.
Skär tre stycken för att bilda en "n" -form. Bara skruva (eller lim) dessa tre bitarna ihop. Kom ihåg att borra ett pilothål i sidstyckena först för att förhindra att de splittras. Du kanske vill försänka skruvarna (speciellt om du ska fylla och sedan måla), och jag rekommenderar starkt en försänkningsborr. Om du inte har ett försänkningsverktyg eller borrborrning, kommer en borr med större diameter att göra tricket.
Borra två hål tillräckligt långt ifrån varandra för att kursens ändar ska sitta i. Lossa undersidan klar för limning.
Handtaget
Nu är det dags att göra slingan / kontrollenheten. Vrid en liten bit av pälshängaren i ena änden för att skapa en slinga med ett litet metallhandtag. Se till att du lägger in kanten och täcker om det är nödvändigt med tejp / skum.
Detta kommer att bilda den andra halvan av kretsen - när den här kretsen berör kursen kommer den att slutföra kretsen (precis som en brytare). Loddare (eller använd en krokodilklämma) en annan ledning till botten av detta, exakt samma som tidigare för kursen.
Klipp en liten dyk för det verkliga handtaget. Denna metallslinga kommer in i detta handtag. Om du inte har någon dowel, kan du runda av en bit kvadrat barrträd med en bältes- eller skivskytt (du kan också använda sandpapper, men det tar lång tid).
Borra ett hål genom detta handtag. Detta måste vara tillräckligt stor för att passa metallslingan och tråden genom:
Detta är möjligt att göra på en pelare borr, även om det är knepigt. En svarv gör jobbet perfekt:
Ja, jag är ganska medveten om att det här är en metallkoppling (för någon som är intresserad, det är en Boley-urmakare från 1930-talet. Jag tror att det är en 3C, men jag skulle gärna höra från dig om du vet mer om det).
Du kan också använda en kulspetspenna med centrum borttagen.
Slutligen använd hett lim för att fästa kabeln och slingan i handtaget. Varmt lim kommer att ge en stark (men inte permanent) fixtur, så det är perfekt för detta.
Avsluta
Sätt i trådbanan i hålen i basen. Glöm inte att lägga till slingan / kontrollenheten först. Använd hett lim igen för att fästa kursen på basen genom att fylla de försänkta hålen på undersidan av basen enligt följande:
Kretskortet
Här är hela kretsen. Du behöver inte göra din så komplexa som denna - läs vidare när vi bryter ner varje del.
Förbind först de två piezoelementen till digitala stift 10 och 11. Polariteten spelar ingen roll:
Du behöver inte använda två piezos - den enda anledningen till att jag har gjort det är att ha ett mycket starkare ljud när trådarna berör. Anslut en sida till den digitala tappen och den andra till jord.
Anslut nu metallbanan och hantera:
Återigen spelar ingen roll vilken väg runt dessa två är trådbundna. Denna del av kretsen är precis som en knapp eller byta - spelaren fullbordar kretsen när slingan berör kursen. Se till att du inkluderar båda motstånden.
Ett motstånd knyter kretsen till marken (kallas ett nedslagsmotstånd), vilket säkerställer att det inte är "flytande" (detta gör det möjligt för Arduino att upptäcka att kretsen ändras). Det andra motståndet skyddar Arduino. När de två delarna berörs, går + 5V i digitalstiften. Om det här motståndet inte var närvarande skulle det vara en död kort - datorn skulle koppla ur USB-uttaget för att dra för mycket ström om du har tur .
Anslut signalledningen (lila, på diagrammet) till digital stift 9.
Anslut sedan en tryckknapp till digital stift 2:
Slutligen anslut LED-displayen med sju segment:
Denna speciella modell är från Seeed. Detta använder en TM1637 för att driva fyra skärmar - det betyder att endast två digitala stift behövs. Anslut GND till Arduino jord och VCC till Arduino + 5V. Anslut D10 till Arduino digital stift 13 och CLK till digital stift 12.
Koden
För att göra detta projekt arbete behöver du ytterligare två filer. Den första kallas pitches.h
. Den här filen kartlägger helt enkelt notnamn till deras piezo-värde. Detta gör det mycket lättare att skriva en melodi, eftersom du helt enkelt kan säga "NOTE_C3" istället för "31". Detta är offentligt och finns tillgängligt på Arduino hemsida här. Följ anvisningarna för att skapa en ny fil som heter pitches.h
(alternativt klistra in koden i ditt befintliga skript).
Därefter behöver du en metod för att faktiskt spela anteckningar / melodier på piezoen. Det här läget av Anthony DiGirolamo på Github innehåller koden du behöver. Kopiera allt mellan "void buzz" och "}}" och klistra in det i din huvudfil. För referens, här är det:
void buzz(int targetPin, long frequency, long length) { /* Buzzer example function by Rob Faludi http://www.faludi.com https://gist.github.com/AnthonyDiGirolamo/1405180 */ long delayValue = 1000000/frequency/2; // calculate the delay value between transitions //// 1 second's worth of microseconds, divided by the frequency, then split in half since //// there are two phases to each cycle long numCycles = frequency * length/ 1000; // calculate the number of cycles for proper timing //// multiply frequency, which is really cycles per second, by the number of seconds to //// get the total number of cycles to produce for (long i=0; i< numCycles; i++){ // for the calculated length of time... digitalWrite(targetPin, HIGH); // write the buzzer pin high to push out the diaphragm delayMicroseconds(delayValue); // wait for the calculated delay value digitalWrite(targetPin, LOW); // write the buzzer pin low to pull back the diaphragm delayMicroseconds(delayValue); // wait again for the calculated delay value } }
Det sista biblioteket du behöver är att styra sju segmentskärmen - du kan hoppa över det här steget om du inte använder en. Detta bibliotek heter TM1637 och skapades av Seeed, samma företag som skapade förarbrädet.
I Arduino IDE, gå till "Hantera bibliotek" ( Sketch > Include Library > Manage Libraries ). Detta kommer att hämta biblioteksledaren. Tillåt det några sekunder att uppdatera och sök sedan i den högra högra sökrutan "TM1637". Två bibliotek kommer att hittas - du vill ha "TM1637" och inte "TM1637Display". Välj och klicka sedan på "installera".
En sista uppgift med detta bibliotek - det är inte komplett! Som det står kan biblioteket bara visa nummer 0-9 och bokstäver A-F. Om det här täcker allt du vill visa kan du hoppa över det här steget. Om inte, måste du ändra koden. Koppla av! Det här är inte så svårt som det låter, och om du kan skriva kod med Arduino IDE kan du göra det här.
Öppna först bibliotekets mapp. Detta kommer att finnas i din Arduino-mapp. På Mac OS X är detta i /Users/Joe/Documents/Arduino/Libraries
. Öppna mappen TM1637 . Du måste redigera filen TM1637.cpp
- du kan säkert ignorera den andra filen med tillägget .h
. Öppna den här filen i din favorit textredigerare (för mig, det är Sublime Text 3), Anteckningar eller Arduino IDE.
Ändra den tredje raden av kod från detta:
static int8_t TubeTab[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};//0~9, A, b, C, d, E, F
Till detta:
static int8_t TubeTab[] = { /* defaults */ 0x3f, // 0 0x06, // 1 0x5b, // 2 0x4f, // 3 0x66, // 4 0x6d, // 5 0x7d, // 6 0x07, // 7 0x7f, // 8 0x6f, // 9 0x77, // A -- 10 0x7c, // b -- 11 0x39, // C -- 12 0x5e, // d -- 13 0x79, // E -- 14 0x71, // F -- 15 /* additional */ 0x174, // h -- 16 0x176, // H -- 17 0x138, // L -- 18 0x15, // M -- 19 0x137, // n -- 20 0x73, // P -- 21 0x67, // q -- 22 0x131, // r -- 23 0x78, // t -- 24 0x240 // - 25 };
Du kan nu spara och stänga den här filen. Efter varje element beskriver kommentaren vilken karaktär det här är. Nästa del av kommentaren är elementets index.
Det är dags för den faktiska koden. Först, inkludera de två bibliotek som nämnts tidigare:
#include #include
Skapa nu visningsobjektet:
TM1637 *_display = new TM1637(12, 13);
Oroa dig inte om du inte förstår syntaxen - den här raden berättar för Arduino att stiften 12 och 13 är anslutna till en sju segmentskärm och att konfigurera den på lämpligt sätt.
Låten lagras i melody
och tempo
. Dessa innehåller alla anteckningar och notens längd för musiken. Om du vill ändra musiken, ändra dessa arrays (även om det inte är så enkelt att klistra in anteckningsvärdena, är timing en mycket viktig del av musiken). songState
variabeln lagrar bara läget för den sista spelade noten. Detta säkerställer att melodin spelas från början till slut, istället för att hoppa runt inkonsekvent:
int songState = 0; int melody[] = { NOTE_F4, ...} int tempo[] = { 8, ...}
Observera att jag har tagit bort innehållet i arraysna, se nedan för hela koden.
Denna kod är inte blockerad - det betyder att Arduino kan utföra flera uppgifter samtidigt. Ta en titt på denna förklaring Arduino Delay-funktion och varför du inte ska använda den Arduino Delay-funktionen och varför du inte ska använda den Medan fördröjning () är praktisk för grundläggande demonstrationer av hur Arduino fungerar, borde du verkligen inte vara använder den i den verkliga världen. Här är varför, och vad du borde använda istället. Läs mer för mer information. Så här är timern inställd:
unsigned long previousMillis1 = 0; const long interval1 = 1500;
Variabeln previousMillis1
uppdateras senare för att spara aktuell tid. interval1
variabeln lagrar hur länge vänta mellan kodkörning - i det här fallet 1, 5 sekunder. Det definieras som const
, vilket betyder att det är konstant och kommer aldrig att förändras - det gör att Arduino kan optimera koden ytterligare.
Inne i funktionen setup()
finns det några saker som händer. Först är ingångarna och utgångarna inställda. Detta måste göras, så Arduino vet vad som är kopplat till varenda pins:
pinMode(9, INPUT); // setup circuit pinMode(10, OUTPUT); // setup buzzer 1 pinMode(11, OUTPUT); // setup buzzer 2 pinMode(2, INPUT); // setup button
Nu måste displayen konfigurera:
_display->set(5); // set brightness _display->point(false); // remove colon _display->init(); // start display
Metoderna, point
och init
är alla innehållna i _display
objektet. I stället för en punkt används en pekare ("->") för att komma åt dessa. Återigen, oroa dig inte för syntaxen (även om du vill lära dig mer, kolla upp C ++-pekare).
Huvudloopen har två spellägen: utmaning och fritt spel. Gratis spel tillåter spelaren att spela obegränsat antal gånger. Utmaningsläge ställer in en timer i 20 sekunder med hjälp av showCountdown
metoden. Den använder knappen för att starta och stoppa timern. För närvarande är det enda sättet att ändra spellägen att manuellt redigera variabeln kallad mode
. Se om du kan lägga till en annan knapp för att göra detta och ändra koden på lämpligt sätt.
buzz
metoden spelar anteckningarna som ges till den. Detta används tillsammans med sing
. Sjungmetoden går igenom varje anteckning och spelar den. Denna metod kallas regelbundet, även om den bara spelar nästa notering när tillräckligt med tid har gått sedan senaste spelningen. När sången har nått slutet, återställer den låten till vers 1 ( songState = 14
). Du kan ställa in detta till noll för att starta sången i början, men anledningen till att du gör det här är att hoppa över introduktionen. Introduktionen spelas en gång efter att Arduino har slagit på och sedan spelas det inte igen.
showFree
och showPlay
metoderna skriver helt enkelt orden "FrEE" och "PLAY" på displayen. Lägg märke till hur "r" i fria är små bokstäver, när alla andra tecken är stora bokstäver. Detta är en av begränsningarna i sju segmentskärmar. De kan inte visa alla bokstäver i alfabetet, och några av de tecken som de kan visa måste vara i blandat fall.
toggleFreePlay
metoden blinkar mellan "FREE" och "PLAY". Återigen gör det det på ett icke-blockerande sätt.
En annan användbar metod är showNumber
. Detta skriver ett nummer till de två två teckenens mitt på displayen så här:
Skärmen är inte smart nog att veta hur man visar stora nummer, det måste uttryckligen berättas vad man ska göra. Denna metod använder en viss enkel logik för att visa rätt nummer på varje tecken.
Den slutliga metoden som används kallas showCountdown
. Detta startar en räknare vid 20, och minskar den med en sekund varje sekund. Om detta når noll, surrar det tre gånger, för att indikera att tiden är slut.
Här är all den kod som sätts ihop:
#include // include display library #include // include pitches TM1637 *_display = new TM1637(12, 13); // create display object, 12 = CLK (clock), 13 = D10 (data) // music int songState = 0; int melody[] = { NOTE_F4, NOTE_E4, NOTE_D4, NOTE_CS4, NOTE_C4, NOTE_B3, NOTE_AS3, NOTE_A3, NOTE_G3, NOTE_A3, NOTE_AS3, NOTE_A3, NOTE_G3, NOTE_C4, 0, NOTE_C4, NOTE_A3, NOTE_A3, NOTE_A3, NOTE_GS3, NOTE_A3, NOTE_F4, NOTE_C4, NOTE_C4, NOTE_A3, NOTE_AS3, NOTE_AS3, NOTE_AS3, NOTE_C4, NOTE_D4, 0, NOTE_AS3, NOTE_G3, NOTE_G3, NOTE_G3, NOTE_FS3, NOTE_G3, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_AS3, NOTE_A3, NOTE_A3, NOTE_A3, NOTE_AS3, NOTE_C4, 0, NOTE_C4, NOTE_A3, NOTE_A3, NOTE_A3, NOTE_GS3, NOTE_A3, NOTE_A4, NOTE_F4, NOTE_F4, NOTE_C4, NOTE_B3, NOTE_G4, NOTE_G4, NOTE_G4, NOTE_G4, 0, NOTE_G4, NOTE_E4, NOTE_G4, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_D4, NOTE_G4, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_C4, NOTE_B3, NOTE_C4, NOTE_B3, NOTE_C4, 0 }; int tempo[] = { 8, 16, 8, 16, 8, 16, 8, 16, 16, 16, 16, 8, 16, 8, 3, 12, 16, 16, 16, 8, 16, 8, 16, 8, 16, 8, 16, 8, 16, 4, 12, 12, 16, 16, 16, 8, 16, 8, 16, 8, 16, 8, 16, 8, 16, 4, 12, 12, 16, 16, 16, 8, 16, 8, 16, 8, 16, 8, 16, 8, 16, 4, 16, 12, 17, 17, 17, 8, 12, 17, 17, 17, 8, 16, 8, 16, 8, 16, 8, 1 }; // non blocking setup // free play unsigned long previousMillis1 = 0; // time words last changed const long interval1 = 1500; // interval between changing // music unsigned long previousMillis2 = 0; // time last changed const long interval2 = 100; // interval between notes int displayStatus = 0; // keep track of what's displayed int mode = 0; // keep track of game mode -- change to 0 or 1 for different modes bool countdown = false; unsigned long previousMillis3 = 0; // time last changed const long interval3 = 1000; // interval between countdown int count = 20; // challenge mode timer void setup() { // put your setup code here, to run once: pinMode(9, INPUT); // setup circuit pinMode(10, OUTPUT); // setup buzzer 1 pinMode(11, OUTPUT); // setup buzzer 2 pinMode(2, INPUT); // setup button _display->set(5); // set brightness _display->point(false); // remove colon _display->init(); // start display } void loop() { // put your main code here, to run repeatedly: if(mode == 0) { // challenge mode if(digitalRead(2) == HIGH) { delay(25); if(digitalRead(2) == HIGH) { countdown = true; // stop the countdown } else { countdown = false; // stop the countdown } } if(countdown) { showCountdown(); // advance countdown } } else { // free play toggleFreePlay(); } if(digitalRead(10) == HIGH) { delay(25); if(digitalRead(10) == HIGH) { while(digitalRead(10) == HIGH) { buzz(11, NOTE_B0, 1000/24); } } } else sing(); } void showCountdown() { // countdown the time remaining unsigned long currentMillis = millis(); // current time if (currentMillis - previousMillis3>= interval3) { previousMillis3 = currentMillis; --count; showNumber(count); if(count == 0) { // game over countdown = false; count = 20; // reset countdown // buzz 3 times buzz(11, NOTE_B0, 1000/24); delay(100); buzz(11, NOTE_B0, 1000/24); delay(100); buzz(11, NOTE_B0, 1000/24); } } } void showNumber(int number) { // show numbers (maximum 99) on display _display->display(0, 25); // write - to segment 1 _display->display(3, 25); // write - to segment 4 // write number to middle of display if(number == 10) { _display->display(1, 1); _display->display(2, 0); } else if(number>9) { _display->display(1, 1); int newVal = number - 10; _display->display(2, newVal); } else { _display->display(1, 0); _display->display(2, number); } } void toggleFreePlay() { // scroll between words without blocking unsigned long currentMillis = millis(); // current time if (currentMillis - previousMillis1>= interval1) { previousMillis1 = currentMillis; if(displayStatus == 1) showPlay(); else showFree(); } } void showPlay() { // write "PLAY" to the display _display->display(0, 21); // write P to segment 1 _display->display(1, 18); // write L to segment 2 _display->display(2, 10); // write A to segment 3 _display->display(3, 4); // write Y to segment 4 displayStatus = 2; } void showFree() { // write "Free" to the display _display->display(0, 15); // write F to segment 1 _display->display(1, 23); // write r to segment 2 _display->display(2, 14); // write E to segment 3 _display->display(3, 14); // write E to segment 4 displayStatus = 1; } void buzz(int targetPin, long frequency, long length) { /* Buzzer example function by Rob Faludi http://www.faludi.com https://gist.github.com/AnthonyDiGirolamo/1405180 */ long delayValue = 1000000/frequency/2; // calculate the delay value between transitions //// 1 second's worth of microseconds, divided by the frequency, then split in half since //// there are two phases to each cycle long numCycles = frequency * length/ 1000; // calculate the number of cycles for proper timing //// multiply frequency, which is really cycles per second, by the number of seconds to //// get the total number of cycles to produce for (long i=0; i = interval2) { previousMillis2 = currentMillis; int noteDuration = 1000 / tempo[songState]; buzz(10, melody[songState], noteDuration); int pauseBetweenNotes = noteDuration; delay(pauseBetweenNotes); // stop the tone playing: buzz(10, 0, noteDuration); ++songState; // start song again if finished if(songState>79) { songState = 14; // skip intro } } }
Spara den här filen som "buzzwire" ( Arkiv> Spara som ) och ladda sedan upp den till din styrelse ( File> Upload ). Om du inte är säker på hur du laddar upp Arduino, eller om den här koden ser lite skrämmande, ta en titt på vår Arduino Beginners Guide Komma igång med Arduino: En nybörjarguide Komma igång med Arduino: En nybörjarhandbok Arduino är en öppen källkod elektronik prototypning plattform baserad på flexibel, lättanvänd maskinvara och programvara. Den är avsedd för artister, designers, hobbyister och alla som är intresserade av att skapa interaktiva objekt eller miljöer. Läs mer . Allt är bra, du borde nu ha ditt eget buzz wire game - coolt!
Om du gjorde något cool efter att ha läst detta, skulle jag gärna se - låt mig veta i kommentarerna nedan!