Arduino frekvens identifiering (2 / 4 steg)
Steg 2: Mitten av punkt upptäckt
De viktiga ändringarna i koden återges nedan. Eftersom jag är att mäta den inkommande signalen från A0 med 8 bitar precision (0-255), ger mittpunkten (2.5V) ett värde på 127. Alla följande kod sker i ADC avbrottet (avbryter varje gång en ny analog i värde är redo från A0)
prevData = newData; //store tidigare värde
newData = ADCH; //get värde från A0
om (prevData < 127 & & newData > = 127) {//if ökar och passage mittpunkten
PORTB | = B00010000; //set stift 12 hög
}
annars om (prevData > 127 & & newData < = 127) {//if minskar och passage mittpunkten
PORTB & = B11101111; //set stift 12 låg
}
Fig 1 visar pulsen utgång i blått och den inkommande signalen till A0 i gult. Märker hur varje gång signalen passerar 2.5V, pulsen utgång växlar. Produktionen går särskilt hög när signalen passerar 2.5V med en positiv lutning och signalen går låg när signalen passerar 2.5V med en negativ lutning. Figur 2 visar puls utgången i blå och ljudsignalen innan det har varit + 2.5V DC offset i gult. Kom ihåg att denna DC offset var nödvändigt att få ljudsignalen i intervallet 0-5V för Arduinos analoga ingångsstift, men normalt ljudsignalen svänga runt 0V. I figur 2 visas hur pulsen utgångar växla motsvarar den tid när audiosignalen korsar 0V. Figur 3 visar en godtycklig vågform i gult (igen innan DC offset) och pulsen utgång i blått. Igen, pulsen växlar varje gång den gula signalen korsar 0V, märker hur uppförandet av pulsen utgång med godtyckliga vågformen är mer komplex än med sinusvåg.
Påvisande av mittpunkten korsning med 38,5 kHz samplingsfrekvens och avbryter
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.
*
*/
Clipping indicator variabler
booleska klippning = 0;
data storage variabler
byte newData = 0;
byte prevData = 0;
void setup() {
pinMode (13, OUTPUT); //led indikator pin
pinMode (12, OUTPUT); //output pin
(CLI); //diable avbrott
Ställ in kontinuerlig provtagning av analoga pin 0
Rensa ADCSRA och ADCSRB register
ADCSRA = 0;
ADCSRB = 0;
ADMUX | = (1 << REFS0); ange referens spänning
ADMUX | = (1 << ADLAR); Vänsterjustera ADC värde - så vi kan läsa högst 8 bitar från ADCH register endast
ADCSRA | = (1 << ADPS2) | (1 << ADPS0); ställa in ADC klockan med 32 prescaler - 16mHz/32 = 500 kHz
ADCSRA | = (1 << ADATE); enabble automatisk utlösare
ADCSRA | = (1 << Ebba Grön); Aktivera avbrott när mätningen är klar
ADCSRA | = (1 << ADEN); Aktivera ADC
ADCSRA | = (1 << ADSC); Starta ADC mätningar
SEI (); //enable avbrott
}
ISR(ADC_vect) {//when nya ADC värdet redo
prevData = newData; //store tidigare värde
newData = ADCH; //get värde från A0
om (prevData < 127 & & newData > = 127) {//if ökar och passage mittpunkten
PORTB | = B00010000; //set stift 12 hög
}
annars om (prevData > 127 & & newData < = 127) {//if minskar och passage mittpunkten
PORTB & = B11101111; //set stift 12 låg
}
om (newData == 0 || newData == 1023) {//if klippning
PORTB | = B00100000; //set stift 13 hög-sväng på klippning indikator ledde
klippningen = 1; //currently klippning
}
}
void loop() {
om (klippning) {//if för närvarande klippning
PORTB & = B11011111; //turn off clippng indikator ledde
klippningen = 0;
}
Delay(100);
}