Arduino ljud utgång (2 / 10 steg)
Steg 2: Konfigurera DAC och Test
PORTD = 125; //send data till DAC
Detta kallas att ta itu med porten direkt. På Arduino är digital stift 0-7 alla på port d Atmel328 chip. Med PORTD kommando kan oss berättar stift 0-7 gå hög eller låg i en rad (istället för att behöva använda digitalWrite() åtta gånger). Är inte bara enklare att kod, det är mycket snabbare för Arduino att bearbeta och det orsakar stiften till alla förändring samtidigt i stället för en av (du kan bara prata med en PIN-kod på en gång med digitalWrite()). Eftersom port d har åtta stift på den (digital stift 0-7) kan vi skicka det en av 2 ^ 8 = 256 möjliga värden (0-255) att kontrollera stiften. Till exempel, om vi skrev följande rad:
PORTD = 0;
Det skulle ställa stift 0-7 låg. Den DAC ställa upp på stift 0-7 kommer detta produktionen 0V. om vi skickade följande:
PORTD = 255;
Det skulle ställa stift 0-7 hög. Detta kommer att orsaka DAC till utgång 5V. Vi kan också skicka kombinationer av låga och höga stater att mata en spänning mellan 0 och 5V från DAC. Till exempel:
PORTD = 125;
125 = 01111101 i binär. Detta sätter stift 7 låg ( msb är 0), stift 6-2 hög (de kommande 5 bitarna är 1), stift 1 låg (nästa bit är 0) och pin 0 hög ( lsb är 1). Du kan läsa mer om hur detta fungerar här. För att beräkna den spänning som detta kommer ut från DAC, använder vi följande ekvation:
Matningsspänning från DAC = [(värde skickas till PORTD) / 255] * 5V
så för PORTD = 125:
Matningsspänning från DAC = (125 / 255) * 5V = 2.45V
Koden nedan skickar ut flera spänningar mellan 0 och 5V och rymmer vardera för en kort tid att demonstrera de begrepp som jag har beskrivit ovan. I funktionen största loop() skrivit jag:
PORTD = 0; //send (0/255) * 5 = 0V ut DAC
fördröjning (1), //wait 1ms
PORTD = 127; //send (127/255) * 5 = 2.5V ut DAC
fördröjning (2), //wait 2 MS
PORTD = 51. //send (51/255) * 5 = 1V ut DAC
fördröjning (1), //wait 1ms
PORTD = 255; //send (255/255) * 5 = 5V ut DAC
fördröjning (3); //wait 3ms
Utdata visas på ett oscilloskop i fig 4. Horisontella mittlinjen över oscilloskopet representerar 0V och varje vågrät rad representerar en spänning ökning/minskning av 2V. Noter fig 4, bilden visar utdata från varje rad i koden ovan, klicka på bilden för att visa bilden noteringar.
Analog ut
av Amanda Ghassaei
Sept 2012
/*
* Detta program är fri programvara; Du kan vidaredistribuera det och/eller ändra
* det enligt villkoren i GNU General Public License som offentliggjorts av
* den Free Software Foundation; antingen version 3 av licensen, eller
* (på ditt alternativ) någon senare version.
*
*/
void setup() {
ställa in digital stift 0-7 som utgångar
för (int jag = 0; jag < 8; i ++) {
pinMode(i,OUTPUT);
}
}
void loop() {
PORTD = 0; //send (0/255) * 5 = 0V ut DAC
fördröjning (1), //wait 1ms
PORTD = 127; //send (127/255) * 5 = 2.5V ut DAC
fördröjning (2), //wait 2 MS
PORTD = 51. //send (51/255) * 5 = 1V ut DAC
fördröjning (1), //wait 1ms
PORTD = 255; //send (255/255) * 5 = 5V ut DAC
fördröjning (3); //wait 3ms
}
Koden nedan utgångar en ramp från 0 till 5V. I funktionen loop(), variabeln "a" ökas från 0 till 255. Varje gång det ökas, skickas värdet av "a" till PORTD. Det här värdet hålls för 50us innan ett nytt värde för "a" skickas. När "en" når 255, blir det återställs till 0. Tiden för varje cykel av denna ramp (även kallad perioden) tar:
period = (varaktighet för varje steg) * (antal steg)
period = 50us * 256 = 12800us = 0.0128s
så frekvensen är:
frekvens av rampen = 1/0.0128s = 78 Hz
Utdata från DAC på ett oscilloskop kan ses i Fig. 5.
Ramp ut
av Amanda Ghassaei
Sept 2012
/*
* Detta program är fri programvara; Du kan vidaredistribuera det och/eller ändra
* det enligt villkoren i GNU General Public License som offentliggjorts av
* den Free Software Foundation; antingen version 3 av licensen, eller
* (på ditt alternativ) någon senare version.
*
*/
void setup() {
ställa in digital stift 0-7 som utgångar
för (int jag = 0; jag < 8; i ++) {
pinMode(i,OUTPUT);
}
}
void loop() {
för (int en = 0; en < 256; a ++) {
PORTD = a; //send ut rampen till digital stift 0-7
delayMicroseconds (50), //wait 50us
}
}
Koden nedan utgångar en sinusvåg centrerad kring 2.5V, svänga upp till ett max på 5V och en min av 0V. I funktionen loop() ökas variabeln "t" från 0 till 100. Varje gång det ökas, uttrycket:
127+127*sin(2*3.14*t/100)
skickas till PORTD. Det här värdet hålls för 50us innan "t" ökas igen och ett nytt värde skickas ut till PORTD. När "t" når 100, blir det återställs till 0. Denna sinusvåg bör vara:
period = (varaktighet för varje steg) * (antal steg)
period = 50us * 100 = 5000us = 0.005s
så frekvensen bör vara:
frekvens av rampen = 1/0.005s = 200 Hz
Sine ut
av Amanda Ghassaei
Sept 2012
/*
* Detta program är fri programvara; Du kan vidaredistribuera det och/eller ändra
* det enligt villkoren i GNU General Public License som offentliggjorts av
* den Free Software Foundation; antingen version 3 av licensen, eller
* (på ditt alternativ) någon senare version.
*
*/
void setup() {
ställa in digital stift 0-7 som utgångar
för (int jag = 0; jag < 8; i ++) {
pinMode(i,OUTPUT);
}
}
void loop() {
för (int t = 0; t < 100; t ++) {//increment "t"
PORTD = 127 + 127 * sin (2 * 3.14 * t/100); //send sinusvåg till DAC, centrerad kring (127/255) * 5 = 2.5V
delayMicroseconds (50), //wait 50us
}
}
Men detta är inte fallet, utdata från DAC visas i fig 6. Som redovisas i en bild, det har inte en frekvens på 200hz, dess frekvens är mer som 45hz. Detta beror på att linjen:
PORTD = 127+127*sin(2*3.14*t/100);
Det tar mycket lång tid att beräkna. I allmänhet tar multiplikation/division med decimaltal och funktionen sin() Arduino mycket tid att utföra.
En lösning är att beräkna värdena för sine före tid och lagra dem i den Arduino minne. Sedan när den Arduino skissen med Arduino kommer att behöva göra är minns dessa värden från minnet (en mycket lätt och snabb aktivitet för Arduino). Jag sprang en enkel Python skript (nedan) för att generera 100 värden av 127+127*sin(2*3.14*t/100):
importera matematik
x i rad (0, 100):
skriva ut str(int(127+127*math.sin(2*math.pi*x*0.01)),)+str(","),
Jag lagras värdena i en array kallas "sine" i den Arduino skissen nedan. Sedan i min loop skickade för varje värde i "t" jag en del av sinus [] till PORTD:
PORTD = sine [t];
Utdata från denna DAC för denna skiss visas i fig 7. Du kan se att det utgångar en sinusvåg på 200hz, som förväntat.
Sine ut med sparade matrisen
av Amanda Ghassaei
Sept 2012
/*
* Detta program är fri programvara; Du kan vidaredistribuera det och/eller ändra
* det enligt villkoren i GNU General Public License som offentliggjorts av
* den Free Software Foundation; antingen version 3 av licensen, eller
* (på ditt alternativ) någon senare version.
*
*/
byte sine [] = {127, 134, 142, 150, 158, 166, 173, 181, 188, 195, 201, 207, 213, 219, 224, 229, 234, 238, 241, 245, 247, 250, 251, 252, 253, 254, 253, 252, 251, 250, 247, 245, 241, 238, 234, 229, 224, 219, 213, 207, 201, 195, 188, 181, 173, 166, 158, 150, 142, 134, 127, 119, 111, 103, 95, 87, 80, 72, 65 58, 52, 46, 40, 34, 29, 24, 19, 15, 12, 8, 6, 3, 2, 1, 0, 0, 0, 1, 2, 3, 6, 8, 12, 15, 19, 24, 29, 34, 40, 46, 52, 58, 65, 72, 80, 87, 95, 103, 111, 119,};
void setup() {
ställa in digital stift 0-7 som utgångar
för (int jag = 0; jag < 8; i ++) {
pinMode(i,OUTPUT);
}
}
void loop() {
för (int t = 0; t < 100; t ++) {//increment "t"
PORTD = sine [t]; //send sinusvåg till DAC, centrerad kring (127/255) * 5 = 2.5V
delayMicroseconds (50), //wait 50us
}
}