klein signaal van DC afsnoepen

@YokoTsuno,

Ik zelfs nog verder, bekijk volgende opstelling:

  1. sinus van 10Hz, y = sin(w*t)
  2. We voegen daar ruis aan toe, met de zelfde amplitude y = sin(w*t) + ruis
  3. We berekenen de FFT hiervan
  4. We doen een thresholding in de frequency domein, alle signalen boven een bepaalde amplitude laten we door, al de rest zetten we op 0
  5. We berekenen de IFFT hiervan, en we zien dat de fase en amplitude zeer goed overeen komt met het orginele signaal, we verkrijgen dan een ruis vrij signaal.

Door een FFT te berekenen verlies je echt geen informatie. Als je 1024 samples hebt in het tijdsdomein, en je gaat naar het frequentie domein via FFT, dan kun je ALTIJD terug naar het tijdsdomein via de IFFT ZONDER enig informatie verlies.

Je mist het volledige punt, jouw opmerking over jitter klopt maar dat geldt ENKEL als je sample voor sample bekijkt niet als je bijvoorbeeld met correlatie ligt te werken, hier gebruik je meerdere samples om de informatie er uit te halen.

In het signaal van die 1 bit sinus zit een pak informatie om die sinus terug te kunnen opbouwen met dezelfde fase informatie.

Onderschat niet de volgende structuur AD -> FFT -> DSP -> IFFT -> DA
Het heeft zijn nadelen, maar het grote voordeel ten opzicht van analoge verwerking is dat je kunt gebruik maken van correlatie.

Voorkomen is goed, en zou altijd moeten worden bereikt maar als dit niet gaat zijn er goede methodes om nog iets nuttig van het signaal te maken.

[robint91 is er tussendoor gekomen: ik heb ruim een uur zitten tikken....]

Yoko, jij begrijpt de kracht van de FFT nog steeds niet.

Ik durf te wedden dat als ik de uitvoer van dit programma

code:


#include <math.h>
#include <stdlib.h>
#include <stdio.h>

#define PI 3.1415926535

double rnd ()
{
  double r; 

  r = rand (); 
  r = r / RAND_MAX;
  return r; 
}

int main (int argc, char **argv)
{
  double dc, freq, fase, acampl, fullscale, t, out, noiseampl;
  int i;

  if (argc > 1) srand (atoi (argv[1]));
  dc = 2 + 2 * rnd ();
  freq = 10 + 90 * rnd ();
  fase = rnd (); 
  acampl = 0.01;
  fullscale = 4.5;
  noiseampl = 0.01;
  
  printf ("# dc   = %lf\n", dc  );
  printf ("# freq = %lf\n", freq);
  printf ("# fase = %lf\n", fase);
  for (i=0;i<4096;i++) {
     t = (double)i / 4096.0;
     out =  dc + acampl * sin (freq * (t+fase) * 2 * PI) + noiseampl * (rnd ()-0.5);
     printf ("%d\n", (int) (out / fullscale * 255));
  }
  exit (0);
}

met een FFT behandel, de fase, frequentie en DC waarde er perfect uitgehaald kunnen worden.

Ik heb ./maakdataset xxxx > mydataset gerund, en dan de eerste drie regels weggehaald. Het getal wat ik voor xxxx heb opgegeven hou ik even geheim, anders kan je zo de waardes reproduceren. Het resultaat geeft in 8 bits zo'n 2205 maal "150", 1891 maal "151". Je moet dit zien als 4096 samples die gedurende 1 seconde genomen zijn, dus met een frequentie van 4096 Hz (samples per seconde).

Het gemiddelde is 150.461, hetgeen overeenkomt met de DC waarde 2.655, terwijl de werkelijke waarde 2.663 is geweest. Daar zit dus een kleine afwijking in. Mogelijk structureel (ik had eerst alleen positieve "noise" dat heb ik ondertussen gefixed), mogelijk statistisch.

Maar ik durf te wedden dat de frequentie en fase prima te achterhalen zijn voor mensen die handig met FFTs om kunnen gaan.

Hier is de dataset: http://prive.bitwizard.nl/mydataset
Over een paar dagen verklap ik de random seed die ik heb gebruikt (als ik hem niet vergeten ben).

Ik heb even een "commandline fft" programma gedownload (hier). Die komt zonder problemen met de juiste frequentie op de proppen.

De fase er uit halen ben ik niet goed in. o.a. omdat de frequentie geen integer is weet ik even niet hoe ik dan de fase er uit haal. Maar ik weet zeker dat die er in zit.

Wederom: Dit is allemaal niet bedoeld omdat ik denk dat de TS daar wat aan heeft. Die heeft nog steeds niet duidelijker aangegeven wat ie wil/moet meten. Als hij een seconde lang samples kan nemen en dan geinteresseerd zou zijn in de rotatie-snelheid van een een of ander object wat het signaal veroorzaakt, zou dat met 8 bits en een FFT al die snelheid van rotatie opleveren, ook al verzuipt het signaal in de sample-ruis (*). Een 10-bit ADC is natuurlijk net zo makkelijk en zeker het proberen waard, maar technisch nergens voor nodig.

(*) Merk op dat een beetje ruis NODIG is om het te laten werken. Ideaal is ongeveer 1 LSB aan gausische ruis. Als ik het goed heb.... (zonder ruis meet je als het tegen zit gewoon 4096x dezelfde waarde, die overeenkomt met de waarde die het dichtst bij de DC waarde zit....)

[update]
de commandos:

code:


% fft < mydataset > outfile
% awk '{print $2, $3 } ' outfile > outfile.cur
% fft -c -I < outfile.cur > outputout.out
% awk '{print $2 / 4096 } ' outputout.out > testout
% md5sum testout mydataset 
e60678160994cbf2fd21d7395c16585a  testout
e60678160994cbf2fd21d7395c16585a  mydataset

levert als "testout" identieke data op als wat er in ging. Er is dus zoals verwacht geen bit aan data verloren gegaan. De "troep" in de FFT levert 100% de data op die de ruis kan reconstrueren. Ga je zoals robint voorstelt de boel thresholden om de ruis er uit te halen. hou je alleen het signaal over. Volgens mij zou ik het maximum en z'n twee buren bewaren om zo veel mogelijk info over het echte signaal over te houden.

[Bericht gewijzigd door rew op zondag 17 maart 2013 11:31:25 (10%)

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
rbeckers

Overleden

Dit is een discussie over FFT aan het worden.
De 8 bits FFT die ik wel eens gebruik is die van een digitale scoop.
En die is maar beperkt bruikbaar.

Frederick E. Terman

Honourable Member

Inderdaad zitten we lekker onderling te kletsen, zonder @TS inbreng. Maar dat is toch verder niet erg? We vermaken ons best.

Het signaal waarvan we voorlopig steeds uit gaan (3,5V/0,05Hz 'achter'grond plus 1Hz/10mV signaal) ziet er op het eerste gezicht vreselijk uit, maar door het enorme frequentieverschil is het signaal toch gemakkelijk af te zonderen. Dat je na twee opampjes de achtergrond helemaal niet meer ziet spreekt boekdelen; en ook digitaal moet dit dus een eitje zijn.

Als dit een praktijkprobleem zou zijn, en er niets aan het signaal veranderd zou kunnen worden, zou ik gewoon analoog filteren. Maar dat ligt aan mijn analoge opvoeding. :)
Misschien wel met zo'n switched capacitor filter. Met 8 polen om mee te spelen zou ik dan voor de Bessel oplossing gaan; dat laat de vorm van het signaal mooi overeind.

Keramisch, kalibratie, parasitair: woordenlijst.org
rbeckers

Overleden

Een analoge opvoeding is ok. ;)
Discussie over FFT is prima.

Die switched capacitor filter IC's zijn handig.

Ja, opvoeding is een , als je oud bent is ervaring het belangrijkste en wel in de tak waarin je min of meer toevallig belandde. En uiteraard wel de denkprocessen die je getraind hebt in je adolescentie. Want de moderne elektronica bestond niet; de transistor was zelfs nog niet "ontdekt" door B&B.

In ieder geval denk ik wel dat de signalen bij FFT tevoorschijn komen ook al zijn ze minder dan een level verschil in piek piek amplitude van een ADC, omdat je over 1024 monsters meet, en door de ruis (belangrijk) het signaal in zijn positieve helft meer door de bovenliggende ADC niveau prikt dan wanneer het in de negatieve helft van de sinus zit (en het vaker door het eronder liggende niveau prikt). Als het signaal ruisvrij is moet je dus ruis bijmengen om dit te bewerkstelligen. Anders heb je dikke kans dat er niets te merken is in de digitale representatie van het signaal na de ADC.

Snelle processoren geven voordeel, want als je oversampling toepast verbetert de signaal/quantiseringsruisverhouding, omdat de quantiseringsruisvermogen verdeeld wordt over de totale Nyquistruimte (helft van de bemonsteringsfrequentie)

Opgepast: MaartenBakker citaat: "ruik ik een troll die per ongeluk met de arreslee meegelift is" :