Note Hearing Trainer Door Marc Neeleman
by MarcoSpecial in Circuits > Arduino
1143 Views, 4 Favorites, 0 Comments
Note Hearing Trainer Door Marc Neeleman
Ik heb een doos gemaakt die je door middel van een spelvorm laat oefenen met het herkennen van muzieknoten. Wanneer je de doos aanzet zal het aan de doos verbonden keyboard een willekeurige noot afspelen. De speler kan met behulp van de 8 knoppen op de doos laten weten welke noot deze denkt gehoord te hebben. Dan komt er weer een nieuwe noot en kan de speler weer opnieuw raden. De doos laat ook zien hoeveel procent van de noten je goed/fout hebt beantwoord. Deze score reset elke keer dat je de doos uitzet.
Supplies
Electronica:
Arduino Uno
MIDI connector Digikey CP-2350-ND
Druksensor
Servo Motor
Batterijbox 9v (6x1 AA)
(3x) Prototyping board
(8x) Drukknoppen
(10x) 220 Ohm resistor
Jumper Wires
(Breadboard)
Hardware:
Piano Keyboard met MIDI IN port
Software:
Arduino IDE
Arduino MIDI library
Gereedschap & Behuizing:
Boormachine met boortjes
Houtveil
Soldeerset
Ducttape
Dubbelzijdige tape
Kist of Doos
(Stiften)
Eerdere Ideëen
Ik heb een aantal verschillende ideëen gehad, maar een overeenkomst in al deze ideëen is dat ik graag iets met een piano wilde doen. Daarom had ik al snel de MIDI connector gekocht.
Mijn originele plan was om input van een piano door te geven aan mijn arduino, die dit dan vervolgens kon doorgeven aan Unity. Zo kon ik een game spelen die mijn piano keyboard als controller gebruikt. Ik was van plan om een programma te maken waarin je zelf liedjes kan importeren en dit liedje vervolgens kan oefenen. In Unity zou er dan gecontroleerd worden hoe goed je het liedje meespeelt. Ook zou ik hier een metronoom bij maken met behulp van een servomotor, waarmee je ook de snelheid van het liedje kon aanpassen. Na het inslaan van alle onderdelen merkte ik echter dat het MIDI input circuit niet werkte, het lukte mij niet om de input van mijn piano aan arduino door te geven. Ik heb meerdere reserve onderdelen gekocht en variaties van onderdelen, maar na veel pogingen werkte het nog steeds niet.
Vervolgens keek ik of ik succesvol een MIDI output circuit kon bouwen. Dit lukte, dus ik kon nu noten op mijn piano afspelen. Toen bedacht ik wat ik hier mee zou kunnen doen. Een van mijn experimenten was een piano die zelf liedjes speelt, maar dit was niet interactief.
Een kennis kwam met het idee van een pratende piano: Aan elke noot zou ik een letter toewijzen, en mijn keyboard zou vervolgens alle noten die in een woord of zin staan zeggen. Dit idee sprak mij erg aan, maar zou dan alleen werken voor mensen die goed noten kunnen herkennen op gehoor... Daarom kwam ik vervolgens op het idee om mensen hiermee te laten oefenen!
Het Plan + Aanpak
Hierboven is een schets te zien van een zijaanzicht van de doos. Dit is hoe de interface van de doos er ongeveer uit komt te zien. We gebruiken de druksensor als aanknop, en zorgen dat het spel pas begint als deze aan is gezet. De piano, die kan worden aangesloten aan de MIDI Connector (niet weergegeven in dit plaatje), zal een noot tussen C4 en C5 afspelen. Daarom hebben we 8 drukknoppen nodig: Voor elke pianonoot één.
Het percentage van goede/foute antwoorden van de speler wordt weergegeven door een servo motor: Een hoek van 0 graden betekent dat de speler 0% goed heeft, een hoek van 180 betekent dat de speler 100% goed heeft.
De MIDI connector zal aan een andere zijkant van de doos uitsteken.
Alle Electronica Aansluiten
Het belangrijkste component van de electronica is het verbinden van de MIDI connector. Deze zorgt ervoor dat de arduino signalen door kan geven aan een keyboard met een MIDI IN port, en de piano dus bijvoorbeeld noten kan laten afspelen. De middelste pin (2) van de MIDI connector mis verbonden met de ground, pin 4 (zie afbeelding 2) is met een weerstand aan verbonden aan de stroom. Voor het overgeven van input aan de piano is pin 5 met de TX pin van de arduino verbonden.
Vervolgens zijn er 8 knoppen en een druksensor verbonden aan de arduino. Ook heb ik een servo motor aangesloten. Al deze onderdelen zijn met de 5V en de ground pin van de arduino verbinden en aan een digitale of analoge arduino pin.
MIDI Output Programmeren
Het programma zorgt ervoor dat we daadwerkelijk signalen kunnen doorgeven aan de piano en deze signalen op het juiste moment doorgeven. Om te testen of ik de MIDI connector goed had aangesloten, begon ik met een simpele test: om de seconde liet ik een noot afspelen. Deze testcode kwam van NotesandVolts.com.
/** Code from NotesAndVolts.com Comments by Marc Neeleman **/ #include <MIDI.h> // Imports the arduino MIDI library #define LED 13 MIDI_CREATE_DEFAULT_INSTANCE(); // Setup void setup() { pinMode(LED, OUTPUT); MIDI.begin(MIDI_CHANNEL_OFF); // Setup for piano output } void loop() { digitalWrite(LED, HIGH); // Turn LED on arduino board on MIDI.sendNoteOn(60, 127, 1); // Play the middle C note (with ID 60) on the piano delay(1000); MIDI.sendNoteOff(60, 0, 1); // Stop playing the middle C note (with ID 60) on the piano digitalWrite(LED, LOW); // Turn LED on arduino board off delay(1000); }
Als de MIDI connector goed is aangesloten zou deze nu steeds de middel C moeten afspelen op het keyboard.
Nu zou mijn piano uit zichzelf vanalles kunnen spelen, zoals liedjes of soundeffects.
Game Programmeren
Al deze onderdelen kunnen we met behulp van code vervolgens aansturen om een game te maken. In deze game moeten een aantal dingen gebeuren:
- Door middel van de druksensor kan de game aan en uit worden gezet.
- Er wordt een willekeurige noot op de piano gespeeld wanneer de game aan gaat.
- De speler kan aangeven welke noot deze denk te herkennen door op de corresponderende knop te drukken.
- Na het indrukken van een knop wordt gecheckt of de speler het goed had. Vervolgens wordt er een geluidseffect afgespeeld op de piano, en wordt er een
- De servo motor geeft aan hoeveel procent van de noten de speler goed heeft geraden. Na elke vraag wordt de motor bijgesteld. Bij het opnieuw opstarten wordt dit percentage gereset.
Hieronder staat de code voor het volledige programma, met comments die uitleggen waar elk stuk code voor zorgt.
/** Note Hearing Trainer by Marc Neeleman Description: This program uses a MIDI connector, pressure sensor, a servo motor and 8 buttons to create an interactive game, in which the player keeps trying recognize piano notes. */ #include <MIDI.h> // Library used for using the piano #include <Servo.h> // Library used to control the servo motor #define PressurePin A0 #define servoPin 3 // Piano Notes #define C4 60 // C4 has the ID 60, C#4 is 61, D4 is 62 etc.. #define D4 62 #define E4 64 #define F4 65 #define G4 67 #define A4 69 #define B4 71 #define C5 72 // Box Buttons #define ButtonC4 6 #define ButtonD4 7 #define ButtonE4 8 #define ButtonF4 9 #define ButtonG4 10 #define ButtonA4 11 #define ButtonB4 12 #define ButtonC5 13 Servo servo; bool isOn; int previousNote = 0; // Score & #Questions int currentQuestion = 1; int correctAnswers = 0; int incorrectAnswers = 0; float correctRatio; // Percentage of correct answers MIDI_CREATE_DEFAULT_INSTANCE(); // Setup // Setup and Loop // void setup() { Serial.begin(9600); servo.attach(servoPin); pinMode(PressurePin, OUTPUT); MIDI.begin(MIDI_CHANNEL_OFF); // Setup randomSeed(analogRead(A5)); // Use output from unused analog pin as random seed, since this output is quite random itself. isOn = false; } void loop() { float pressure = analogRead(PressurePin); if (pressure > 6) { pressOnSwitch(); delay(1000); } if (isOn) { checkButtonPress(); // Checks if the player is pressing one of the buttons } } // Logic for starting the game // // Turns the game on/off and starts the game if it is turned on void pressOnSwitch() { isOn = !isOn; if (isOn) {start();} } void start() { resetVariables(); nextQuestion(); } // Sets all variables to its default values void resetVariables() { previousNote = 0; currentQuestion = 0; correctAnswers = 0; incorrectAnswers = 0; correctRatio = 1; moveServo(); } // Game goes on to the next question void nextQuestion() { currentQuestion++; playRandomNote(1000); } // Checks if the player is pressing one of 8 the buttons void checkButtonPress() { if (digitalRead(ButtonC4)) onPlayerAnswer(C4); else if (digitalRead(ButtonD4)) onPlayerAnswer(D4); else if (digitalRead(ButtonE4)) onPlayerAnswer(E4); else if (digitalRead(ButtonF4)) onPlayerAnswer(F4); else if (digitalRead(ButtonG4)) onPlayerAnswer(G4); else if (digitalRead(ButtonA4)) onPlayerAnswer(A4); else if (digitalRead(ButtonB4)) onPlayerAnswer(B4); else if (digitalRead(ButtonC5)) onPlayerAnswer(C5); } // Player Answer Logic // // Check if the player answered correctly and update the score void onPlayerAnswer(int noteID) { if (noteID == previousNote) { onCorrectAnswer(); } else { onIncorrectAnswer(); } // Adjust Servo motor based on Score updateScore(); nextQuestion(); } void onCorrectAnswer() { correctAnswers++; playCorrectEffect(); } void onIncorrectAnswer() { incorrectAnswers++; playIncorrectEffect(); } // Servo Motor void updateScore() { correctRatio = (float) correctAnswers/(float) currentQuestion; moveServo(); } void moveServo() { int servoAngle = correctRatio * (float) 180; servo.write(servoAngle); } // Sound Effects // void playCorrectEffect() { playNote(72, 125); playNote(79, 125); playNote(84, 1000); } void playIncorrectEffect() { playNote(48, 250); playNote(47, 250); playNote(46, 750); } // Plays a specific note void playNote(int noteID, int noteLength) { MIDI.sendNoteOn(noteID, 60, 1); delay(noteLength); MIDI.sendNoteOff(noteID, 60, 1); } // Random Note Logic // // Plays a random note from C4 to C5 on the piano void playRandomNote(int noteLength) { int newNote = returnRandomNote(); while (newNote == previousNote) { // Make sure the next note is different newNote = returnRandomNote(); } // Turn new randomNumber note on MIDI.sendNoteOn(newNote, 60, 1); previousNote = newNote; // Delay and turn the note off delay(noteLength); MIDI.sendNoteOff(newNote, 60, 1); } // Returns a note from C4 to C5 randomly int returnRandomNote() { float randomNumber = random(0, 8); if (randomNumber < 1) { return C4; } else if (randomNumber < 2) { return D4; } else if (randomNumber < 3) { return E4; } else if (randomNumber < 4) { return F4; } else if (randomNumber < 5) { return G4; } else if (randomNumber < 6) { return A4; } else if (randomNumber < 7) { return B4; } else { return C5; } }
Na het aansluiten van de arduino aan een laptop en het uploaden van deze code zou de constructie zich moeten gedragen zoals in de introductievideo.
Solderen
Vervolgens heb ik alle bedrading aan elkaar gesoldeerd. Ik heb hierbij gelet op de lengte van de draden en de gewenste positie van de prototyping board in de behuizing, zodat alle gebruikte draden zijn vastgesoldeerd. Alle knopjes zitten op een apart bordje, zodat ik hier makkelijk mee kon werken bij het maken van de behuizing. Ook de druksensor zit samen met de knopjes. De MIDI connector en de servo motor zijn aan een apart bordje gesoldeerd. Zo kan de MIDI kabel aan de achterkant of een van de zijkanten worden van de doos worden aangesloten.
Behuizing Maken
Tot slot heb ik de behuizing gemaakt. Ik ben begonnen met het maken van een kartonnen prototype, om te testen hoe mijn constructie in een doos zou passen (Zie foto 5+6). In de blokker had ik een theedoos gevonden die goed geschikt was voor deze installatie. Voordat ik begon met boren had ik een schets (Zie foto 4) gemaakt waarin ik de diameter en onderlinge afstanden van alle gaten had genoteerd. Daarna heb ik op de doos afgetekend waar alle gaten geboord moesten worden en begon ik met boren.
Ik begon met het boren van de gaten voor de knoppen, maar omdat ik meteen begon met een boortje van 10mm boorde ik behoorlijk scheef. Later kwam ik erachter dat ik beter eerst met een kleinere boor kon beginnen en vervolgens het rechte gat groter kon maken. Na het boren heb ik wat gaten geveild om ze netter te maken vanaf de buitenkant en om eventuele gaten groter te maken, zodat onderdelen hier makkelijker doorheen zouden passen.
Na het boren en veilen heb ik de borden met de drukknoppen stevig vastgeplakt met ducttape. De arduino, batterijhouder en het andere bord heb ik met dubbelzijdige tape aan de bodem van de doos geplakt. De servomotor bleef al stevig in het goede gat hangen, maar voor de zekerheid heb ik deze ook vastgetaped. Ook heb ik de MIDI connector stevig aan de wand van de doos getaped, zodat ik gemakkelijk de MIDI kabel hiermee kon verbinden. Test tijdens deze stap regelmatig of alles nog werkt!
Tot slot heb ik de doos met een stift versierd om duidelijk te maken wat elk onderdeel doet.
Reflectie & Conclusie
De doos is nu klaar voor gebruik! Sluit de batterijhouder aan de arduino aan en test of alles nog werkt. Je hebt nu je eigen Music Hearing Box.
Verbeterpunten Eindresultaat:
Als ik mijn persoonlijke eindresultaat nog zou aanpassen, zou ik de knopjes en drukknop de volgende keer op een langer prototyping board plaatsen in plaats van op twee verschillende borden, omdat dit betrouwbaarder zou zijn. Hierdoor kan ik dit bordje namelijk ook steviger aan de behuizing bevestigen. Ook zou ik bij het boren beginnen met kleinere boortjes, zodat de gaten rechter zijn. Ik zou de volgende keer ook betere knopjes gebruiken, zodat je deze gemakkelijker in de behuizing kan indrukken. Hierdoor zou de afwerking professioneler overkomen.
Leerpunten:
Ik heb door dit project een hoop nieuwe vaardigheden geleerd. Ten eerste weet ik bij het kopen van nieuwe onderdelen wat er voor nodig is om het te gebruiken en weet ik waar ik kan vinden hoe je het onderdeel kan gebruiken. Ik kan stroomcircuits samenstellen en vervolgens de arduino en code gebruiken om de aangesloten onderdelen aan te sturen. Zo weet ik dus hoe onderdelen onderling met elkaar samenwerken.
Bovendien heb ik voor het eerst gesoldeerd. Voor een oud idee van dit project had ik al een bordje gesoldeerd, en voor dit project heb ik vervolgens ook onderdelen op 3 aparte bordjes gesoldeerd. In het begin was ik erg langzaam en slordig, maar ik merkte bij de laatste keer solderen dat ik een stuk zorgvuldiger en sneller was. Ook dacht ik bij het solderen al na over hoe dit in de behuizing zou passen.
Ik zag het meest tegen de behuizing op, maar heb ik uiteindelijk toch een geschikte doos kunnen vinden en met een beetje hulp van mijn opa de juiste gaten geboord. Zo kon ik alle elektronica in de doos stoppen en mijn project netjes afwerken.
Maar mijn grootste leerpunt van dit project is hoe belangrijk het is om een plan af te werken voordat je het volledig gaat uitwerken. Ik ging namelijk te vroeg door op één idee en had hier al veel werk in gestopt, totdat ik erachter kwam dat ik dit idee niet kon uitvoeren. Hierdoor begon ik in de zomervakantie eigenlijk weer opnieuw met brainstormen. Dit keer heb ik echter eerst een aantal ideëen overwogen en uitgedacht, voordat ik overging naar het uitvoeren van het plan.
Ik vond het leuk om een keer met bedrading en fysieke componenten te werken voor de verandering en ik ben blij dat het mij uiteindelijk gelukt is om hier iets leuks mee te maken!