- Vereiste materialen:
- Schakelschema:
- Schema's en uitleg:
- Inzicht in de
- Pianoklanken spelen op Arduino:
- Programmeren van de Arduino:
- Speel, neem op, speel opnieuw en herhaal! :
Arduino is een zegen geweest voor mensen die niet uit de elektronica-achtergrond komen om gemakkelijk dingen te bouwen. Het is een geweldige tool voor het maken van prototypes of om iets cools te proberen, in dit project gaan we een kleine maar leuke piano bouwen met behulp van de Arduino. Deze piano is vrij eenvoudig met slechts 8 drukknoppen en zoemer. Het gebruikt de tone () -functie van Arduino om verschillende soorten pianonoten op de luidspreker te creëren. Om het een beetje op te fleuren, hebben we de opnamefunctie aan het project toegevoegd, dit stelt ons in staat een deuntje op te nemen en het herhaaldelijk af te spelen wanneer dat nodig is. Klinkt interessant toch !! Dus laten we gaan bouwen…
Vereiste materialen:
- Arduino Uno
- 16 * 2 LCD-scherm
- Zoemer
- Trimmer 10k
- SPDT-schakelaar
- Drukknop (8 nrs)
- Weerstanden (10k, 560R, 1,5k, 2,6k, 3,9, 5,6k, 6,8k, 8,2k, 10k)
- Breadboard
- Draden aansluiten
Schakelschema:
Het complete Arduino Piano Project kan met enkele aansluitdraden bovenop een breadboard worden gebouwd. Het schakelschema gemaakt met behulp van fritzing dat de breadboard-weergave van het project laat zien, wordt hieronder weergegeven
Volg gewoon het schakelschema en sluit de draden dienovereenkomstig aan, de drukknoppen en zoemer zoals gebruikt met een PCB-module, maar in de werkelijke hardware hebben we alleen de schakelaar en zoemer gebruikt, het zou u niet veel moeten verwarren omdat ze hetzelfde type pin hebben. U kunt ook de onderstaande afbeelding van de hardware raadplegen om uw verbindingen te maken.
De waarde van de weerstanden van links is in de volgende volgorde, 10k, 560R, 1.5k, 2.6k, 3.9, 5.6k, 6.8k, 8.2k en 10k. Als u niet dezelfde DPST-schakelaar heeft, kunt u de normale tuimelschakelaar gebruiken zoals weergegeven in het schakelschema hierboven. Laten we nu eens kijken naar de schema's van het project om te begrijpen waarom we de volgende verbindingen hebben gemaakt.
Schema's en uitleg:
Het schema voor het schakelschema dat hierboven wordt weergegeven, wordt hieronder gegeven, het is ook gemaakt met Fritzing.
Een belangrijke verbinding die we moeten begrijpen, is hoe we de 8 drukknoppen met de Arduino hebben verbonden via de analoge A0-pin. In principe hebben we 8 input-pinnen nodig die kunnen worden aangesloten op de 8 input-drukknoppen, maar voor projecten als deze kunnen we 8 pinnen van de microcontroller niet alleen voor drukknoppen gebruiken, omdat we ze misschien nodig hebben voor later gebruik. In ons geval hebben we het LCD-scherm dat moet worden aangesloten.
We gebruiken dus de analoge pin van de Arduino en vormen een potentiaalverdeler met variërende weerstandswaarden om het circuit te voltooien. Op deze manier wordt bij het indrukken van elke knop een andere analoge spanning aan de analoge pin geleverd. Hieronder ziet u een voorbeeldcircuit met slechts twee weerstanden en twee drukknoppen.
In dit geval ontvangt de ADC-pin + 5V wanneer de drukknoppen niet worden ingedrukt, als de eerste knop wordt ingedrukt, wordt de potentiaalverdeler voltooid via de 560R-weerstand en als de tweede knop wordt ingedrukt, wordt de potentiaalverdeler bestreden met behulp van de 1.5 k weerstand. Op deze manier zal de spanning die door de ADC-pin wordt ontvangen, variëren op basis van de formules van de potentiaalverdeler. Als u meer wilt weten over hoe de potentiële verdeler werkt en hoe u de waarde van de spanning die door de ADC-pin wordt ontvangen, kunt berekenen, kunt u deze calculatorpagina voor potentiële verdelers gebruiken.
Verder zijn alle verbindingen ongecompliceerd, het LCD-scherm is verbonden met pin 8, 9, 10, 11 en 12. De zoemer is verbonden met pin 7 en de SPDT-schakelaar is verbonden met pin 6 van Arduino. Het complete project wordt gevoed via de USB-poort van de laptop. Je kunt de Arduino ook aansluiten op een 9V- of 12V-voeding via de DC-aansluiting en het project werkt nog steeds hetzelfde.
Inzicht in de
De Arduino heeft een handige tone () functie die gebruikt kan worden om verschillende frequentiesignalen te genereren die gebruikt kunnen worden om verschillende geluiden te produceren met een zoemer. Laten we dus eens kijken hoe de functie werkt en hoe deze kan worden gebruikt met Arduino.
Daarvoor zouden we moeten weten hoe een piëzo-zoemer werkt. We hebben misschien op onze school over piëzo-kristallen geleerd, het is niets anders dan een kristal dat mechanische trillingen omzet in elektriciteit of vice versa. Hier passen we een variabele stroom (frequentie) toe waarvoor het kristal trilt en zo geluid produceert. Om de piëzo-zoemer wat geluid te laten maken, moeten we het piëzo-elektrische kristal laten trillen, de toonhoogte en toon van ruis hangen af van hoe snel het kristal trilt. Daarom kunnen de toon en toonhoogte worden geregeld door de frequentie van de stroom te variëren.
Oké, dus hoe krijgen we een variabele frequentie van Arduino? Dit is waar de functie tone () van pas komt. De tone () kan een bepaalde frequentie op een specifieke pin genereren. Indien nodig kan ook de tijdsduur worden vermeld. De syntaxis voor tone () is
Syntaxis toon (pin, frequentie) toon (pin, frequentie, duur) Parameters pin: de pin waarop de toonfrequentie wordt gegenereerd: de frequentie van de toon in hertz - niet-ondertekend int duur: de duur van de toon in milliseconden (optioneel1) - lang ongetekend
De waarden van pin kunnen elk van uw digitale pin zijn. Ik heb hier pincode 8 gebruikt. De frequentie die kan worden gegenereerd, is afhankelijk van de grootte van de timer in je Arduino-bord. Voor UNO en de meeste andere gangbare boards is de minimale frequentie die kan worden geproduceerd 31Hz en de maximale frequentie die kan worden geproduceerd is 65535Hz. Wij mensen kunnen echter alleen frequenties horen tussen 2000 Hz en 5000 Hz.
Pianoklanken spelen op Arduino:
Oké, voordat ik zelfs maar aan dit onderwerp begin, wil ik duidelijk maken dat ik een beginneling ben met muzieknoten of piano, dus vergeef me alstublieft als iets dat onder deze titel wordt vermeld, onzin is.
We weten nu dat we de tonenfunctie in Arduino kunnen gebruiken om sommige geluiden te produceren, maar hoe kunnen we tonen van een bepaalde noot spelen met dezelfde. Gelukkig voor ons is er een bibliotheek met de naam "pitches.h", geschreven door Brett Hagman. Deze bibliotheek bevat alle informatie over welke frequentie gelijk is aan welke noot op een piano. Ik was verrast door hoe goed deze bibliotheek echt kon werken en bijna elke noot op een piano kon spelen, ik gebruikte dezelfde om de pianonoten van Pirates of Caribbean, Crazy Frog, Mario en zelfs titanic te spelen en ze klonken geweldig. Oeps! We raken hier een beetje van het onderwerp af, dus als je daarin geïnteresseerd bent, kun je melodieën spelen met het Arduino-project. In dat project vind je ook meer uitleg over de pitches.h- bibliotheek.
Ons project heeft slechts 8 drukknoppen, dus elke knop kan slechts één bepaalde muzieknoot spelen en dus kunnen we in totaal slechts 8 noten spelen. Ik heb de meest gebruikte noten op een piano geselecteerd, maar je kunt elke 8 selecteren of zelfs het project uitbreiden met meer drukknoppen en meer noten toevoegen.
De noten die in dit project zijn geselecteerd, zijn de noten C4, D4, E4, F4, G4, A4, B4 en C5, die kunnen worden gespeeld met respectievelijk de knoppen 1 t / m 8.
Programmeren van de Arduino:
Genoeg theorie laat ons het leuke gedeelte van het programmeren van de Arduino beginnen. Het volledige Arduino-programma wordt aan het einde van deze pagina gegeven, je kunt naar beneden springen als je nieuwsgierig bent of verder lezen om te begrijpen hoe de code werkt.
In ons Arduino-programma moeten we de analoge spanning van pin A0 lezen, vervolgens voorspellen welke knop is ingedrukt en de respectieve toon voor die knop spelen. Terwijl we dit doen, moeten we ook opnemen welke knop de gebruiker heeft ingedrukt en hoe lang hij / zij heeft ingedrukt, zodat we de toon die later door de gebruiker werd gespeeld opnieuw kunnen creëren.
Voordat we naar het logische gedeelte gaan, moeten we aangeven welke 8 noten we zullen spelen. De respectieve frequentie voor de noten wordt vervolgens uit de toonhoogtes.h- bibliotheek gehaald en vervolgens wordt een array gevormd zoals hieronder weergegeven. Hier is de frequentie om noot C4 te spelen 262 enzovoort.
int noten = {262, 294, 330, 349, 392, 440, 494, 523}; // Stel frequentie in voor C4, D4, E4, F4, G4, A4, B4,
Vervolgens moeten we vermelden op welke pinnen het LCD-scherm is aangesloten. Als u exact dezelfde schema's volgt als hierboven gegeven, hoeft u hier niets te veranderen.
const int rs = 8, en = 9, d4 = 10, d5 = 11, d6 = 12, d7 = 13; // Pinnen waarop LCD is aangesloten LiquidCrystal lcd (rs, en, d4, d5, d6, d7);
Vervolgens initialiseren we in onze setup- functie gewoon de LCD-module en seriële monitor voor foutopsporing. We geven ook een introbericht weer om er zeker van te zijn dat alles werkt zoals gepland. Vervolgens , in de belangrijkste lus functie hebben we twee while loops.
Een while-lus wordt uitgevoerd zolang de SPDT-schakelaar in de opname staat. In de opnamemodus kan de gebruiker de vereiste tonen betalen en tegelijkertijd wordt de toon die wordt gespeeld ook opgeslagen. Dus de while-lus ziet er hieronder als volgt uit
while (digitalRead (6) == 0) // Als de tuimelschakelaar in de opnamemodus staat {lcd.setCursor (0, 0); lcd.print ("Opname.."); lcd.setCursor (0, 1); Detect_button (); Speeltoon (); }
Zoals je misschien hebt gemerkt, hebben we twee functies binnen de while-lus. De eerste functie Detect_button () wordt gebruikt om te zoeken op welke knop de gebruiker heeft gedrukt en de tweede functie Play_tone () wordt gebruikt om de respectieve toon af te spelen. Naast deze functie registreert de functie Detect_button () ook welke knop wordt ingedrukt en de functie Play_tone () registreert hoe lang de knop is ingedrukt.
Binnen de Detect_button () functie lezen we de analoge spanning van de pin A0 en vergelijken met een aantal vooraf bepaalde waarden om te zien welke toets is ingedrukt. De waarde kan worden bepaald met behulp van de spanningsdelercalculator hierboven of door de seriële monitor te gebruiken om te controleren welke analoge waarde voor elke knop wordt gelezen.
void Detect_button () { analogVal = analogRead (A0); // lees de analoge voltag op pin A0 pev_button = button; // onthoud de vorige knop die door de gebruiker is ingedrukt als (analogVal <550) knop = 8; if (analogVal <500) knop = 7; if (analogVal <450) knop = 6; if (analogVal <400) knop = 5; if (analogVal <300) knop = 4; if (analogVal <250) knop = 3; if (analogVal <150) knop = 2; if (analogVal <100) knop = 1; if (analogVal> 1000) knop = 0; / **** Sluit de ingedrukte knoppen in een array *** / if (knop! = pev_button && pev_button! = 0) { record_button = pev_button; button_index ++; opgenomen_knop = 0; button_index ++; } / ** Einde opnameprogramma ** / }
Zoals gezegd registreren we binnen deze functie ook de volgorde waarin de knoppen worden ingedrukt. De geregistreerde waarden worden opgeslagen in een array met de naam record_button. We kijken eerst of er een nieuwe knop is ingedrukt, indien ingedrukt dan kijken we ook of het niet de knop 0 is. Waarbij knop 0 niets is maar er wordt geen knop ingedrukt. Binnen de if-lus slaan we de waarde op de indexlocatie op die wordt gegeven door de variabele button_index en dan verhogen we ook deze indexwaarde zodat we niet te veel schrijven op dezelfde locatie.
/ **** Registreer de ingedrukte knoppen in een array *** / if (knop! = Pev_button && pev_button! = 0) { record_button = pev_button; button_index ++; opgenomen_knop = 0; button_index ++; } / ** Einde opnameprogramma ** /
Binnen de Play_tone () functie zullen we de betreffende toon voor de toets met behulp van meerdere ingedrukt spelen indien omstandigheden. We zullen ook een array gebruiken met de naam opgenomen_tijd waarin we de tijdsduur opslaan waarvoor de knop werd ingedrukt. De bewerking is vergelijkbaar met het opnemen van de volgorde van de knoppen: we gebruiken de millis () -functie om te bepalen hoe lang elke knop is ingedrukt, ook om de grootte van de variabele te verkleinen, delen we de waarde door 10. Voor knop 0, wat betekent dat de gebruiker dat niet is door op iets te drukken, spelen we geen toon voor dezelfde duur. De volledige code binnen de functie wordt hieronder weergegeven.
void Play_tone () { / **** Registreer de tijdvertraging tussen elke druk op een knop in een array *** / if (button! = pev_button) { lcd.clear (); // Maak het vervolgens schoon note_time = (millis () - start_time) / 10; opgenomen_tijd = note_time; time_index ++; start_time = millis (); } / ** Einde van opnameprogramma ** / if (button == 0) { noTone (7); lcd.print ("0 -> Pauze.."); } if (knop == 1) { toon (7, noten); lcd.print ("1 -> NOTE_C4"); } if (knop == 2) { toon (7, noten); lcd.print ("2 -> NOTE_D4"); } if (button == 3) { toon (7, noten); lcd.print ("3 -> NOTE_E4"); } if (knop == 4) { toon (7, noten); lcd.print ("4 -> NOTE_F4"); } if (knop == 5) { toon (7, noten); lcd.print ("5 -> NOTE_G4"); } if (knop == 6) { toon (7, noten); lcd.print ("6 -> NOTE_A4"); } if (knop == 7) { toon (7, noten); lcd.print ("7 -> NOTE_B4"); } if (knop == 8) { toon (7, noten); lcd.print ("8 -> NOTE_C5"); } }
Ten slotte moet de gebruiker na het opnemen de DPST in de andere richting schakelen om de opgenomen toon af te spelen. Wanneer dit is gebeurd, breekt het programma uit de vorige while- lus en gaat het naar de tweede while-lus waar we de noten spelen in de volgorde van de knoppen die gedurende een eerder opgenomen duur zijn ingedrukt. De code om hetzelfde te doen, wordt hieronder weergegeven.
while (digitalRead (6) == 1) // Als de tuimelschakelaar is ingesteld in de afspeelmodus { lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Now Playing.."); voor (int i = 0; i <sizeof (opgenomen_knop) / 2; i ++) { vertraging ((opgenomen_tijd) * 10); // Wacht voordat je het volgende deuntje betaalt if ( record_button == 0) noTone (7); // gebruiker mag een willekeurige knop aanraken anders toon (7, noten - 1)]); // speel het geluid af dat overeenkomt met de knop die door de gebruiker is aangeraakt } } }
Speel, neem op, speel opnieuw en herhaal!:
Maak de hardware volgens het getoonde schakelschema en upload de code naar het Arduino-bord en de weergegeven tijd. Plaats de SPDT in de opnamemodus en begin met het spelen van de tonen van uw keuze, door op elke knop te drukken, wordt een andere toon geproduceerd. Tijdens deze modus geeft het LCD-scherm " Opname…" weer en op de tweede regel ziet u de naam van de noot die momenteel wordt ingedrukt, zoals hieronder weergegeven
Als u eenmaal uw toon heeft gespeeld, schuift u de SPDT-schakelaar naar de andere kant en moet het LCD-scherm " Now Playing.." weergeven en begint u de toon te spelen die u zojuist hebt gespeeld. Dezelfde toon wordt keer op keer afgespeeld zolang de tuimelschakelaar in de positie wordt gehouden zoals weergegeven in de onderstaande afbeelding.
De volledige werking van het project is te vinden in de onderstaande video. Ik hoop dat je het project hebt begrepen en met plezier hebt gebouwd. Als je problemen hebt met het bouwen van dit, plaats ze dan in het commentaargedeelte of gebruik de forums voor technische hulp bij je project. Vergeet ook niet de onderstaande demonstratievideo te bekijken.