DFT

Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte

Elektronik Forum Nicht eingeloggt       Einloggen       Registrieren




[Registrieren]      --     [FAQ]      --     [ Einen Link auf Ihrer Homepage zum Forum]      --     [ Themen kostenlos per RSS in ihre Homepage einbauen]      --     [Einloggen]

Suchen


Serverzeit: 29 3 2024  07:08:08      TV   VCR Aufnahme   TFT   CRT-Monitor   Netzteile   LED-FAQ   Osziloskop-Schirmbilder            


Elektronik- und Elektroforum Forum Index   >>   Microcontroller        Microcontroller : Hardware - Software - Ideen - Projekte


Autor
DFT

    







BID = 422848

Zreal2

Gerade angekommen


Beiträge: 12
Wohnort: Austria
 

  


Hi leute!

Hätte da ein mehr oder minder kleines problem!
bräuchte dringenst eine DFT, hab aber leider keine ahnung wo ich hierfür einen entsprechenden source code finden könnte!
Ideal währe ein source code in C
hab auch schon gegoogelt aber es ist schwer da etwas entsprechendes zu finden!

Naja ich hoffe ihr könnt mir etwas bei der Lösung dieses Problems helfen.

GLG Zreal2

BID = 422850

Benedikt

Inventar

Beiträge: 6241

 

  

Brauchst du wirklich eine DFT ? Eine FFT liefert dasgleiche Ergebnis, verwendet nur einen anderen Lösungsweg und ist schneller (DFT: n², FFT: n*log(n) glaube ich). Zu FFT gibt es einiges im Internet.

BID = 422858

Dombrowski

Stammposter



Beiträge: 450

Moin.

Eine FFT mit bit-reverse Shifting u. Butterfly-Algorithmus usw. ist aber zunächst mal viel aufwendiger zu implementieren. Die Grundformel zur DFT hatte ich ja schon im alten Thread genannt. Erläuterung in vielen Büchern (und Websites?) zur Digitalen Signalverarbeitung. Aber wenn es doch FFT sein soll: von der libfftw abgucken oder sie gleich ganz verwenden.

D.

BID = 423006

Dombrowski

Stammposter



Beiträge: 450

Moin.

Ich habe mal ein Beispielprogramm zur DFT gemacht und mit FFT verglichen. Dies ist das Programm:


Code :

#include <complex.h> 

#include <math.h>
#include <stdio.h>
#include <sys/time.h>

#define NN 256
#define FNAME "dft_test.out"

void create_time_function (complex in[], int N)
{
int k;

for (k = 0; k < N; k++) {
if ((0 <= k) && (k < N/8))
creal(in[k]) = 0.0;
if ((N/8 <= k) && (k < N/4))
creal(in[k]) = 8.0/N * k - 1.0;
if ((N/4 <= k) && (k < 3*N/8))
creal(in[k]) = -8.0/N * k + 3.0;
if ((3*N/8 <= k) && (k < N/2))
creal(in[k]) = 0.0;
if ((N/2 <= k) && (k < 5*N/8))
creal(in[k]) = 0.0;
if ((5*N/8 <= k) && (k < 3*N/4))
creal(in[k]) = 8.0/N * k - 5.0;
if ((3*N/4 <= k) && (k < 7*N/8))
creal(in[k]) = -8.0/N * k + 7.0;
if ((7*N/8 <= k) && (k < N))
creal(in[k]) = 0.0;
cimag(in[k]) = 0.0;
}
}

void dft (complex tim[], complex frq[], int N)
{
int n, j;
complex sum;

for (n = 0; n < N; n++) {
creal(sum) = cimag(sum) = 0.0;
for (j = 0; j < N; j++) {
sum += tim[j] * cexp(-I*2.0*M_PI*n*j/N);
}
frq[n] = /* 1.0 / (double) N * */ sum;
}
}

int main (void)
{
complex in[NN], out[NN];
double power_spectrum[NN/2+1];
int k;
FILE *fp;
struct timeval start, end, run;

create_time_function (in, NN);
gettimeofday (&start, NULL);
dft (in, out, NN);
gettimeofday (&end, NULL);
timersub (&end, &start, &run);
printf ("Running %ld usecs\n", 1000000L*run.tv_sec + run.tv_usec);

power_spectrum[0] = creal(out[0])*creal(out[0]);
for (k = 1; k < (NN+1)/2; ++k)
power_spectrum[k] = creal(out[k])*creal(out[k]) + cimag(out[k])*cimag(out[k]);
if (NN % 2 == 0)
power_spectrum[NN/2] = creal(out[NN/2])*creal(out[NN/2]);

fp = fopen (FNAME, "w");
for (k = 0; k < NN; k++) {
double f1;

if (k <= NN/2)
f1 = power_spectrum[k];
else
f1 = 0.0;
fprintf (fp, "%03d %f %f\n", k, creal(in[k]), f1);
}
fclose (fp);

return 0;
}


Die erzeugte Datei mit den Zahlenwerten ist zur Darstellung mittels gnuplot o.ä. gedacht. Die FFT-Variante ist bis auf den Aufruf der Funktion dft() weitestgehend gleich; sie benutzt Funktionen aus der librfftw (http://www.fftw.org).

Ergebnis:
1. Die berechneten Zahlenwerte sind identisch! Jedenfalls bei der Anzeigegenauigkeit, die der gcc beim Format-Argument "%f" standardmäßig auswählt, nämlich "%.6f".
2. Ich muss anerkennen, der Geschwindigkeitsvorteil von FFT ist atemberaubend. Die DFT-Routine verbraucht ca. 55 Millisekunden; die Zeiten schwanken etwas von Aufruf zu Aufruf. Die FFT-Berechnung, die wie gesagt auf dasselbe Zahlenresultat führt, benötigt ca. 490 Mikro(!)sekunden.

D.

BID = 423008

Zreal2

Gerade angekommen


Beiträge: 12
Wohnort: Austria

hmmm leider kann ich mit den tipps nicht viel anfangen! Leider!

hab mir jedoch mal gedacht ich versuchs selbst zu programmieren. Anbei habe ich mal den source code beigefügt! wäre unter umständen fein wenn mir jemand bei der fehlersuche helfen könnte!

#include <18F4550.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
//#fuses HSPLL,CPUDIV2,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
#device ADC=10
#use delay(clock= 20000000)
#use RS232(baud=9600, xmit=pin_c6, rcv=pin_c7)
#include <math.h>


float sinWert[451];

float pee=3.14159;
int kf_re[32];
int kf_im[32];
int kf_abs[32];
int k,p;

int in[64];
int out;
long n=1000;
long a,x,w;
int f=1;


void main(){

//----- Setup PWM -----
setup_ccp1(CCP_PWM);
setup_timer_2(t2_div_by_1,255,1);

//----- Setup ADC -----
setup_adc_ports(AN0_TO_AN2);
SETUP_ADC(ADC_CLOCK_INTERNAL);



sinWert[0]=0.0000;
sinWert[1]= 0.01745;
sinWert[2]= 0.03490;
sinWert[3]= 0.05234;
sinWert[4]= 0.06976;
sinWert[5]= 0.08716;
sinWert[6]= 0.10453;
sinWert[7]= 0.12187;
sinWert[8]= 0.13917;
sinWert[9]= 0.15643;
sinWert[10]= 0.17365;
sinWert[11]= 0.19081;
sinWert[12]= 0.20791;
sinWert[13]= 0.22495;
sinWert[14]= 0.24192;
sinWert[15]= 0.25882;
sinWert[16]= 0.27564;
sinWert[17]= 0.29237;
sinWert[18]= 0.30902;
sinWert[19]= 0.32557;
sinWert[20]= 0.34202;
sinWert[21]= 0.35837;
sinWert[22]= 0.37461;
sinWert[23]= 0.39073;
sinWert[24]= 0.40674;
sinWert[25]= 0.42262;
sinWert[26]= 0.43837;
sinWert[27]= 0.45399;
sinWert[28]= 0.46947;
sinWert[29]= 0.48481;
sinWert[30]= 0.50000;
sinWert[31]= 0.51504;
sinWert[32]= 0.52992;
sinWert[33]= 0.54464;
sinWert[34]= 0.55919;
sinWert[35]= 0.57358;
sinWert[36]= 0.58778;
sinWert[37]= 0.60181;
sinWert[38]= 0.61566;
sinWert[39]= 0.62932;
sinWert[40]= 0.64279;
sinWert[41]= 0.65606;
sinWert[42]= 0.66913;
sinWert[43]= 0.68200;
sinWert[44]= 0.69466;
sinWert[45]= 0.70711;
sinWert[46]= 0.71934;
sinWert[47]= 0.73135;
sinWert[48]= 0.74314;
sinWert[49]= 0.75471;
sinWert[50]= 0.76604;
sinWert[51]= 0.77715;
sinWert[52]= 0.78801;
sinWert[53]= 0.79864;
sinWert[54]= 0.80902;
sinWert[55]= 0.81915;
sinWert[56]= 0.82904;
sinWert[57]= 0.83867;
sinWert[58]= 0.84805;
sinWert[59]= 0.85717;
sinWert[60]= 0.86602;
sinWert[61]= 0.87462;
sinWert[62]= 0.88295;
sinWert[63]= 0.89101;
sinWert[64]= 0.89879;
sinWert[65]= 0.90631;
sinWert[66]= 0.91355;
sinWert[67]= 0.92050;
sinWert[68]= 0.92718;
sinWert[69]= 0.93358;
sinWert[70]= 0.93969;
sinWert[71]= 0.94552;
sinWert[72]= 0.95106;
sinWert[73]= 0.95630;
sinWert[74]= 0.96126;
sinWert[75]= 0.96593;
sinWert[76]= 0.97030;
sinWert[77]= 0.97437;
sinWert[78]= 0.97815;
sinWert[79]= 0.98163;
sinWert[80]= 0.98481;
sinWert[81]= 0.98769;
sinWert[82]= 0.99027;
sinWert[83]= 0.99255;
sinWert[84]= 0.99452;
sinWert[85]= 0.99619;
sinWert[86]= 0.99756;
sinWert[87]= 0.99863;
sinWert[88]= 0.99939;
sinWert[89]= 0.99985;
sinWert[90]= 1.00000;

.
.
.
.
und so weiter bis 451 des tua i jetzt aber nit eine




//###########################################################################

while(1){

if(a==n){
a=0;
}


out = 0;
for(k=0;k<=f;k++){
x=360*k*a/n;

//for(x=360*k*a/n;x>=361;x=x-360){
//Hallo;
//}

if(x>=91){
if(x<=180){
x=180-x;
}
}
if(x>=181){
if(x<=270){
x=x-180;
sinWert[x]=-sinWert[x];

}
}
if(x>=271){
if(x<=360){
x=360-x;
sinWert[x]=-sinWert[x];
}
}


out = out + kf_abs[k]*sinWert[x];
}
set_PWM1_duty(out);

//------------------------------------------------------------------------------

for(p=0;p<=f;p++){
w=360*p*a/n;

//for(w=360*p*a/n;w>=361;w=w-360){
//Hallo;
//}

if(w>=91){
if(w<=180){
w=180-w;
}
}
if(w>=181){
if(w<=270){
w=w-180;
sinWert[w]=-sinWert[w];

}
}
if(w>=271){
if(w<=360){
w=360-w;
sinWert[w]=-sinWert[w];

}
}

kf_im[p]=kf_im[p]+in[a]*sinWert[w];
kf_re[p]=kf_re[p]+in[a]*sinWert[w+90];
if(a==n-1){
kf_abs[p]=sqrt(kf_re[p] * kf_re[p] + kf_im[a] * kf_im[p]);
}
}

//------------------------------------------------------------------------------

in[a]=read_adc();


a++;

}

//##########################################################################


}




das ganze hab ich mit einem PIC 18F450

BID = 423042

Zreal2

Gerade angekommen


Beiträge: 12
Wohnort: Austria

Danke Dombrowski für deine unterstützung! wie ich meins heute nachmittag reingeschrieben hab war deins bei mir noch nicht online! also den ersten satz mit "Leider!" bitte vergessen!
werd dein programm grad mal durchstudieren. mal schaun ob ich es auch zum laufen bring!

LG

BID = 423135

Dombrowski

Stammposter



Beiträge: 450

Moin.

Wenn der µC eine PC-Schnittstelle hat, würde ich die Abtastwerte zunächst mal zum PC schicken und dort per FT auswerten. Dort kann man grafisch darstellen und schnell beurteilen, ob das alles Sinn macht, usw. Die Werte müssen aber mit einer Abtastfrequenz ermittelt werden, die nicht total von der endgültigen Frequenz abweicht.

Aber ich weiß nicht, was du bisher schon an Vorarbeit durchlaufen hast. Vielleicht erzählst du ein bisschen zur Aufgabenstellung. Es geht also darum, ein Signal regelmäßig abzutasten und aus dessen Spektrum eine Stellgröße für eine PWM-Steuerung zu ermitteln. Soweit richtig? Was für Eigenschaften sind über das abzutastende Signal bekannt?

D.

BID = 423150

Zreal2

Gerade angekommen


Beiträge: 12
Wohnort: Austria

Also zur Aufgabenstellung:

Wir bauen sowas wie ein Lasermikrophon. Um dies genauer zu erklären: man leuchtet mit einem Laserpunkt auf eine scheibe und nimmt das reflektierte signal von der fensterscheibe mit einer photodiodenmatrix auf.

d.h. wir haben uns eine photodiodenmatrix gebaut (SMD) welche in form einer antiparallelschaltung aufgebaut ist. Man kann sich das sowie ein schachbrettmuster vorstellen. diese photodiodenmatrix liefert uns je nach auslenkung des empfangenen laserpunkts werte von 0.5-4.5V welche der PIC nun berechnen soll mittels FFT,DFT oder was auch immer. Anschließend soll dieses berechnete signal über den PWM ausgegeben werden und dann über eine audiostufe hörbar gemacht werden. Prinzipiell funktioniert das alles auch schon bis auf die Programmierung des PIC.

Klar werden sich manche jetzt sagen bau einen Bandpass rein. Doch das ist eben genau das was wir nicht machen wollen,dürfen....naja!

soviel mal zu den hintergrundinformationen wofür wir den PIC brauchen.

GLG


Zurück zur Seite 0 im Unterforum          Vorheriges Thema Nächstes Thema 


Zum Ersatzteileshop


Bezeichnungen von Produkten, Abbildungen und Logos , die in diesem Forum oder im Shop verwendet werden, sind Eigentum des entsprechenden Herstellers oder Besitzers. Diese dienen lediglich zur Identifikation!
Impressum       Datenschutz       Copyright © Baldur Brock Fernsehtechnik und Versand Ersatzteile in Heilbronn Deutschland       

gerechnet auf die letzten 30 Tage haben wir 22 Beiträge im Durchschnitt pro Tag       heute wurden bisher 0 Beiträge verfasst
© x sparkkelsputz        Besucher : 180686076   Heute : 1970    Gestern : 12674    Online : 423        29.3.2024    7:08
3 Besucher in den letzten 60 Sekunden        alle 20.00 Sekunden ein neuer Besucher ---- logout ----viewtopic ---- logout ----
xcvb ycvb
0.109137058258