Arduino frekvens identifiering (4 / 4 steg)

Steg 4: Generaliserad pitch upptäckt



i den här koden generaliserade jag min frekvens upptäckt algoritm så att den kan hantera vågor av många figurer (förhoppningsvis alla). När du skriver här koden jag ville hålla fast vid det jag sade i steg 1 om att inte använda de toppar och dalar som markörer mäta perioden av signalen (minimera fel på grund av buller). Jag ville också skriva något som var så enkla som möjligt (behöver exekvera på 38,5 kHz) samtidigt som den är tillräckligt robust för att hantera massor av waveshapes. Jag beslutade att använda en teknik som liknar ett oscilloskop utlösa.

I grund och botten var vad jag gjorde att välja en spänning som jag alltid visste skulle vara i gränserna för min våg (2.5V). Sedan tittade jag på varje gång vågen passerat denna nivå med en positiv lutning, låt oss kalla dessa "tröskel händelser". Om detta hänt flera gånger i en cykel valde jag tröskel händelsen med största lutningen vara i början av min cykel. Liknar det sista steget, jag använde en variabel som kallas "tiden" (ökas med en hastighet av 38,5 kHz) att mäta tiden mellan tröskel händelser och lagras detta är en matris kallas timer []. Jag spelade också in lutningen vid varje tröskelvärde händelserna i en matris kallas lutning []. Då jag jämförde element av timer [] och [] lutning att räkna ut var det var en match. När en matchning hittades, jag la upp delarna av timer [] att bestämma varaktighet av cykeln och skickade detta värde till en global variabel kallas "period." Sedan i funktionen huvudsakliga loop() (alla steg jag har bara beskrivit hända i rutinen ADC avbrott) använde jag värdet av perioden att beräkna frekvensen och skriva ut den. Jag bör också tillägga att jag sätter en variabel i den kod som kallas "noMatch" som hjälpte mig att besluta att det hade varit för länge sedan jag hade en bra match och att jag bara ska spela in delar av timer [] och [] lutning.

När du skriver detta tänkte jag på en massa möjliga scenarier som kan bryta algoritmen. Den svåraste våg i mitt sinne är en som passerar den 2.5V tröskeln många gånger i en cykel på liknande sluttar och fördelas längs cykel på samma sätt. Jag du har en våg som denna, bör du hålla slopeTol mycket låg (0-3) och du kanske tycker att sänka timerTol (till 5 kanske) hjälper spåra vågen korrekt. Också, om du vill mäta vågor med mycket branta sluttningar (som pulsvåger) bör du ange värdet för slopeTol upp till 100 eller ännu hela vägen upp till 256 att spåra dem bättre.

Generellt denna del av koden verkar mycket väl hantera massor av former, kan du se några av mina resultat i bilderna ovan. Den inkommande signalen visas i gult och tröskel händelsen som Arduino är spårning indikeras av en puls av stift 12 (blå).

generaliserad wave freq upptäckten 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;
unsigned int tid = 0; //keeps tid och skickar vales att lagra i [timer] ibland
int timer [10]; //sstorage för tidpunkten för händelser
int lutning [10]. //storage fro slutta av händelser
unsigned int totalTimer; //used att beräkna period
unsigned int period; //storage under för wave
byte index = 0; //current storage index
float frekvens; //storage för frekvens beräkningar
int maxSlope = 0; //used att beräkna max lutning som trigger punkt
int newSlope; //storage för inkommande lutning data

variabler för beslutat om du har en match
byte noMatch = 0; //counts hur många icke-matcher du har fått för att återställa variabler om det har gått för långt
byte slopeTol = 3; //slope tolerans - justera detta om du behöver
int timerTol = 10; //timer tolerans - justera detta om du behöver

void setup() {

Serial.BEGIN(9600);

pinMode (13, OUTPUT); //led indikator pin
pinMode (12, OUTPUT); //output pin

(CLI); //diable avbrott

Ställ in kontinuerlig provtagning av analoga pin 0 vid 38,5 kHz

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

PORTB & = B11101111; //set stift 12 låg
prevData = newData; //store tidigare värde
newData = ADCH; //get värde från A0
om (prevData < 127 & & newData > = 127) {//if ökar och passage mittpunkten
newSlope = newData - prevData; //calculate lutning
om (abs(newSlope-maxSlope) < slopeTol) {//if sluttningar är ==
spela in nya data och återställa tiden
sluttningen [index] = newSlope;
timer [index] = tid;
tid = 0;
om (index == 0) {//new max lutning bara reset
PORTB | = B00010000; //set stift 12 hög
noMatch = 0;
index ++; //increment index
}
annars om (abs(timer[0]-timer[index]) < timerTol & & abs(slope[0]-newSlope) < slopeTol) {//if timer varaktighet och backarna match
summa timer-värden
totalTimer = 0;
för (byte jag = 0; jag < index; i ++) {
totalTimer += timer [i];
}
period = totalTimer; //set perioden
återställa nya noll indexvärden att jämföra med
timer [0] = timer [index];
sluttningen [0] = lutningen [index];
index = 1; //set index 1
PORTB | = B00010000; //set stift 12 hög
noMatch = 0;
}
annat {//crossing mittpunkt men inte matchen
index ++; //increment index
om (index > 9) {
Reset();
}
}
}
annars om (newSlope > maxSlope) {//if nya lutning är mycket större än max lutning
maxSlope = newSlope;
tid = 0; //reset klocka
noMatch = 0;
index = 0; //reset index
}
annat {//slope inte brant nog
noMatch ++; //increment ingen match counter
om (noMatch > 9) {
Reset();
}
}
}

om (newData == 0 || newData == 1023) {//if klippning
PORTB | = B00100000; //set stift 13 hög-sväng på klippning indikator ledde
klippningen = 1; //currently klippning
}

tid ++; //increment timer i takt på 38,5 kHz
}

void reset() {//clea ut vissa variabler
index = 0; //reset index
noMatch = 0; //reset matcha couner
maxSlope = 0; //reset lutning
}

void checkClipping() {//manage klippning indikator LED
om (klippning) {//if för närvarande klippning
PORTB & = B11011111; //turn av klippning indikator ledde
klippningen = 0;
}
}

void loop() {

checkClipping();

frekvens = 38462/float (period); //calculate frekvens timer kurs/period

skriva ut resultaten
Serial.Print(Frequency);
Serial.println ("hz");

fördröjning (100); //feel gratis att ta bort detta om du vill

göra andra saker här
}

Jag lade också till en bit kod att stoppa beräkna och skriva ut frekvensen data när amplituden av vågen understiger en viss nivå. (Om det finns liten eller ingen signal då koden ovan ibland spottar ut en massa skräp). Här är det:

generaliserad wave freq upptäckten 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;
unsigned int tid = 0; //keeps tid och skickar vales att lagra i [timer] ibland
int timer [10]; //sstorage för tidpunkten för händelser
int lutning [10]; //storage för lutning av händelser
unsigned int totalTimer; //used att beräkna period
unsigned int period; //storage under för wave
byte index = 0; //current storage index
float frekvens; //storage för frekvens beräkningar
int maxSlope = 0; //used att beräkna max lutning som trigger punkt
int newSlope; //storage för inkommande lutning data

variabler för beslutat om du har en match
byte noMatch = 0; //counts hur många icke-matcher du har fått för att återställa variabler om det har gått för långt
byte slopeTol = 3; //slope tolerans - justera detta om du behöver
int timerTol = 10; //timer tolerans - justera detta om du behöver

variabler för amp upptäckt
unsigned int ampTimer = 0;
byte maxAmp = 0;
byte checkMaxAmp;
byte ampThreshold = 30. //raise om du har en mycket högljudd signal

void setup() {

Serial.BEGIN(9600);

pinMode (13, OUTPUT); //led indikator pin
pinMode (12, OUTPUT); //output pin

(CLI); //diable avbrott

Ställ in kontinuerlig provtagning av analoga pin 0 vid 38,5 kHz

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

PORTB & = B11101111; //set stift 12 låg
prevData = newData; //store tidigare värde
newData = ADCH; //get värde från A0
om (prevData < 127 & & newData > = 127) {//if ökar och passage mittpunkten
newSlope = newData - prevData; //calculate lutning
om (abs(newSlope-maxSlope) < slopeTol) {//if sluttningar är ==
spela in nya data och återställa tiden
sluttningen [index] = newSlope;
timer [index] = tid;
tid = 0;
om (index == 0) {//new max lutning bara reset
PORTB | = B00010000; //set stift 12 hög
noMatch = 0;
index ++; //increment index
}
annars om (abs(timer[0]-timer[index]) < timerTol & & abs(slope[0]-newSlope) < slopeTol) {//if timer varaktighet och backarna match
summa timer-värden
totalTimer = 0;
för (byte jag = 0; jag < index; i ++) {
totalTimer += timer [i];
}
period = totalTimer; //set perioden
återställa nya noll indexvärden att jämföra med
timer [0] = timer [index];
sluttningen [0] = lutningen [index];
index = 1; //set index 1
PORTB | = B00010000; //set stift 12 hög
noMatch = 0;
}
annat {//crossing mittpunkt men inte matchen
index ++; //increment index
om (index > 9) {
Reset();
}
}
}
annars om (newSlope > maxSlope) {//if nya lutning är mycket större än max lutning
maxSlope = newSlope;
tid = 0; //reset klocka
noMatch = 0;
index = 0; //reset index
}
annat {//slope inte brant nog
noMatch ++; //increment ingen match counter
om (noMatch > 9) {
Reset();
}
}
}

om (newData == 0 || newData == 1023) {//if klippning
PORTB | = B00100000; //set stift 13 hög-sväng på klippning indikator ledde
klippningen = 1; //currently klippning
}

tid ++; //increment timer i takt på 38,5 kHz

ampTimer ++; //increment amplitud timer
om (abs(127-ADCH) > maxAmp) {
maxAmp = abs(127-ADCH);
}
om (ampTimer == 1000) {
ampTimer = 0;
checkMaxAmp = maxAmp;
maxAmp = 0;
}

}

void reset() {//clea ut vissa variabler
index = 0; //reset index
noMatch = 0; //reset matcha couner
maxSlope = 0; //reset lutning
}

void checkClipping() {//manage klippning indikator LED
om (klippning) {//if för närvarande klippning
PORTB & = B11011111; //turn av klippning indikator ledde
klippningen = 0;
}
}

void loop() {

checkClipping();

om (checkMaxAmp > ampThreshold) {
frekvens = 38462/float (period); //calculate frekvens timer kurs/period

skriva ut resultaten
Serial.Print(Frequency);
Serial.println ("hz");
}

fördröjning (100); //delete detta om du vill

göra andra saker här
}

Se Steg
Relaterade Ämnen

Pålitlig frekvens identifiering med hjälp av DSP tekniker

korrekt frekvens upptäckt är viktigt för många projekt som gitarr/Piano Tuners, vibrationer analysatorer, hjärtrytm bildskärmar, MEMs Sensor analys och laboratorieutrustning.Det har varit många fina exempel på projekt som försöker lösa detta problem,...

Arduino frekvens synthesizer med 160MHz Si5351

Detta Instructable beskriver konstruktion och drift av en fristående frekvens synt lämpliga för användning som en signalgenerator, eller för användning som den lokala oscillatorn i ett Amatörmässigt musikband sändare eller mottagare.Min prototyp bygg...

Arduino gitarr Tuner

Bygg din egen gitarr tuner använder Arduino! Jag beslöt att göra detta eftersom jag ville experimentera med ljudingång och frekvens identifiering. Jag använde Amanda Ghassaei metod för Arduino frekvensen upptäckt för att få frekvens avläsningar med A...

Arduino Pitch upptäckt algoritm (med AMDF)

Senaste uppdatering: 16 januari 2016 (nyligen lagt till en förbättrad matlab-kod (step7) med prover och massor av anteckningar)Förord: Detta Instructable är skrivna på en att visa hur jag analyserat, testat, genomfört och optimerad en algoritm. Även...

Rita ut Data från Arduino

Arduino inte har mycket i form av debug och analys förmåga inbyggt, så det kan vara mycket användbart att ha en anläggning till tomt data som skickas från Arduino över serieporten.Det finns flera sätt att göra det inklusive bearbetning, Python + Matp...

Arduino IR Remote mottagare

jag har varit framgångsrika i programmering min Arduino att identifiera grupper av siffror från min IR-fjärrkontroll.Med detta program kan du styra 4 lysdioder över en IR-fjärrkontroll.Steg 1: delar Behöver du:-En TV-IR-fjärr (jag använde en från sam...

Frekvens detektor PIC 12F683 Processor med

detta projekt beskriver maskin- och programvara har jag utvecklat som låter en liten 8 bitar PIC mikroprocessor kan fungera som en enda frekvens detektor eller tonen.En sådan krets kan användas för att påvisa förekomsten av en viss frekvens inom en a...

Arduino kompatibel Luna Mod Looper

The Luna Mod Looper, i princip kan du registrera en sekvens med en potentiometer för att styra tonhöjden för noteringen, och sedan spela upp den tillbaka och lägga till effekter. Ända sedan jag såg videor av Luna Mod som spelas, ville jag bygga min e...

Arduino Mini-Shields

Detta är en uppsättning av enkel, liten formfaktor, mini-sköldar som jag skapade nästan av en slump. När jag gjorde mer och mer av dem, insåg jag att de kan vara riktigt användbara. Det som började som ett sätt att använda vissa reservdelar, förvandl...

Komma igång med RFID

Har du någonsin undrat hur ditt ID tag fungerar?I denna handledning kommer vi att kunna visa dig hur man läsa en RFID -knappen, eller tag, om det hålls upp mot ID-12 RFID-läsare eller någon 125 KHz modul. Även är detta projekt ett enkelt och roligt s...

Adafruit Motor sköld användning

Hej vänner, jag nämner robotiserade applikationer i motordrift, en av de mest använda kort adafruit L293d företag som utvecklat den integrerad bar från Adafruit motor sköld motor förarkort. Huvudskälet tillhandahålls för inställningen på grund av ans...

Ihållande Vision småsak. POV dekoration.

Ihållande Vision småsak. POV dekorationDet är tiden på året att få trädet och dekorera med alla underbara ljus, glitter och grannlåt. Och detta projekt handlar om grannlåt, varje gång jag satte dekorationer på ett träd jag inte kan hjälpa men avveckl...

RFID-Emulator - hur man klona RFID-kort, Tag...

Där idén kom.Idén att skapa RFID-Emulator kommer från idén att skapa en miljö för att utveckla och experimentera med olika RFID-tillämpningar. Denna artikel skapades med målet att ingenjörer amatör entusiaster och fans av elektronik som gillar att ex...

Glödande färgskiftande gitarr

I kungariket av rock and roll är det viktigt att ställa sig själv isär. Med miljontals människor i denna värld som kan spela gitarr, kommer spelar enkelt väl bara inte att klippa den. Du behöver något extra att stiga upp som en Gud som rock. Anser de...

Power System frekvens bestämning genom att använda Arduino

IntroduktionNätström distribueras allmänt på 50 eller 60 Hz.This-projektet syftar till att "Beräkna hur levande ac power system ofta använda Arduino" kit och liten transformator ckt setup. Detta projekt är byggd av vårt team caféer, Venkat, Abhi...

Arduino - AC Main frekvens Monitor

Hej, detta är min första gången, så snälla, bli mjuk!Varning: Arbeta med AC-spänning kan vara dödliga. Om du inte vet vad du gör vänligen försök inte detta.Jag har haft i åtanke utveckla en monitor system, för min reservkraft, bestående av 4 6V batte...

Arduioscillo-Arduino VoltMeter/frekvens Generator

vad gjorde jag? Syftet med detta projekt är att skapa en prisvärd och praktisk voltmeter/frekvens generator av material liggande på din arbetsbänk. Denna länk tar dig till min youtube video förklarar enheten http://www.youtube.com/watch?v=dkgbP2kvnME...

Arduino gränssnitt TSL230R ljus frekvens Converter

Syftet med denna sida är att visa hur deTSL239R ljus till frekvensomriktare. Enheten utgångar en 50% duty fyrkantsvåg vars frekvens är proportionell mot ljusintensiteten. Inte bara kan TSL230R användas för att upptäcka ljusintensiteten justera säger...

OBJEKTET identifiering och spårning med hjälp av OPENCV, VISUAL STUDIO C ++ 2010 och ARDUINO

IntroduktionI detta projekt skickar Webcam video ramar till Visual Studio C ++ som innehåller öppen CV biblioteket på vår dator.Om Visual Studio C ++ programmet upptäcker bilden av objektet från webbkameran och sedan beräknas de co koordinaterna X, Y...