AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Frequenzen erkennen, CRC - Check, Timer zu langsam?!
Thema durchsuchen
Ansicht
Themen-Optionen

Frequenzen erkennen, CRC - Check, Timer zu langsam?!

Offene Frage von "MotoNero112"
Ein Thema von MotoNero112 · begonnen am 8. Sep 2006 · letzter Beitrag vom 9. Sep 2006
Antwort Antwort
Seite 1 von 2  1 2      
MotoNero112

Registriert seit: 7. Sep 2006
4 Beiträge
 
#1

Frequenzen erkennen, CRC - Check, Timer zu langsam?!

  Alt 8. Sep 2006, 13:55
Hallo liebes Delphi-PRAXIS Forum!

Jetzt hab ich schon lange Zeit hier im Forum nach Tipps geschaut um mein Vorhaben realisieren zu können. Prinzipiell funktioniert es auch schon, jedoch nicht wirklich "sauber".

Was ich vor habe:

- Über die Soundkarte (Micro, Line-In oder Stereo - Mix) kommt ein Signal
- Dieses Signal soll decodiert werden.

Speziell interessiere ich mich für Telegramme, welche in diesem Signal aufgebaut sind:

Hierbei handelt es sich um Telegramme welche per FSK codiert sind.

FSK:

Signalrate 1200 baud
Low - Level: 1800 Hz (Logisch 0)
High - Level: 1200 Hz (Logisch 1)

Insgesamt besteht solch ein Telegramm aus 68 Bit. Siehe:

FMS - Telegramm

Wobei 1 bit eine Länge von 0,8 ms hat.

Meine Fragen:

1. Ist es per FFT möglich solch "kurze" Signale zu analysieren?
2. Kann die BASS.DLL dafür verwendet werden, oder gibt es bessere Komponenten etc.?

Ich habe nämlich festgestellt, dass mir immer nur ein paar "Werte" ausgegeben werden und, dass diese zudem variieren.

Sprich: Bei einem und dem selben Signal habe ich mal 10001, dann 10101 etc....zudem fehlen dort allerhand bit. Meine Vermutung ist deshalb, dass entweder die FFT zu langsam abläuft, oder einfach, der Timer, der die FFT aufruft zu langsam ist oder zu ungenau arbeitet.

Anders kann ich mir es nicht erklären, dass immer wieder bits fehlen. Schließlich müssten es 68 sein und nicht 4 bis 10.

Wie kann man, wenn man festgestellt hat, dass es entweder eine 1 oder eine 0 ist, dieses Ergebnis, natürlich in richtiger Reihenfolge speichern?


Für Antworten und Hilfen bedanke ich mich bereits im Vorraus.


Mario
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.166 Beiträge
 
Delphi 12 Athens
 
#2

Re: Frequenzen erkennen, CRC - Check, Timer zu langsam?!

  Alt 8. Sep 2006, 14:11
Nutzt du einen WindowsTimer? (TTimer und alles was mit Windows[Timer]API zu tun hat)

Diese Timer haben nur eine Auflösung von etwa 10ms (auf älteren System sogar nur kanpp 20ms)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
MotoNero112

Registriert seit: 7. Sep 2006
4 Beiträge
 
#3

Re: Frequenzen erkennen, CRC - Check, Timer zu langsam?!

  Alt 8. Sep 2006, 14:20
Nein ich benutze den CairnTimer. Aber mir scheint, dass auch dieser nicht schnell genug arbeitet. Ich bräuchte einen Timer der im µs Bereich arbeitet.
  Mit Zitat antworten Zitat
Benutzerbild von mschaefer
mschaefer

Registriert seit: 4. Feb 2003
Ort: Hannover
2.029 Beiträge
 
Delphi XE3 Enterprise
 
#4

Re: Frequenzen erkennen, CRC - Check, Timer zu langsam?!

  Alt 8. Sep 2006, 14:25
Wenn Dein Signal keine anderen Hintergrundgeräusche hat, dann ging folgendes: Da beide Frequenzen mit unterscheidlichen Lautstärkepegeln arbeiten, könntes Du auch diese Pegel abfragen und so das Signal erkennen.

Grüße / Martin
Martin Schaefer
  Mit Zitat antworten Zitat
Gandalfus

Registriert seit: 19. Apr 2003
407 Beiträge
 
Delphi 2006 Professional
 
#5

Re: Frequenzen erkennen, CRC - Check, Timer zu langsam?!

  Alt 8. Sep 2006, 14:34
http://blubplayer.de/timertutorial.html
Zitat:
1. Ist es per FFT möglich solch "kurze" Signale zu analysieren?
das müsstest du ausprobieren. Vieleicht könnte man das Signal aufnehmen und dann analysieren.
Besucht doch mal meine Homepage
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#6

Re: Frequenzen erkennen, CRC - Check, Timer zu langsam?!

  Alt 8. Sep 2006, 14:56
Normalerweise nimmt man dazu in Software sogeannte Lock-In-Amplifier oder PSD -> Phase Sensitive Devices oder PPLs -> Phase Locked Loops.

Bei all diesen Verfahren geht es darum das AC Signal mit Hilfe eines "synchonen" Vergleichsignal zu filtern und daraus ein DC Signal zu erzeugen das angibt wie hoch die Übereinstimmung dieser Signale ist.

Das geht in Hardware und auch als Software in sogennate DSPs/FPGA/ASICs usw. umzusetzen. Auf PC ist das auch möglich. Die Performance ist weit besser als bei einer FFT, defakto ist es sogar so das beide Verfahren auf den gleichen math. Grundlagen beruhen.

Wie macht man das nun ?

Man erzeugt zwei Rechtecksignale mit jeweils 1800Hz und 2100Hz Frequenz. Davon werden 2 weitere Signale um 90 Grad in der Phase verschoben erzeugt, also zeitlich versetzt.

Nun werden alle 4 Signale mit dem eingehenden Signal verknüpft. Raus kommen 4 kummulierte Werte=Zahlen. Jeweils ein Signal X für die Amplitude=Stärke der Übereinstimmung und das Signal Y für Phasenverschiebung. Mit r =Wurzel(X^2 + Y^2) hat man nun einen DC Wert für die Übereinstimmung der Referenzsignale zum Eingangssignal.

Man hat dann also zwei Werte r1800 und r2100 die die Signalstärke dieser Frequenzen im EIngangssignal darstellen. In deinem Falle müsste immer nur eine dieser Variablen einen großen Wert haben und die andere einen kleinen Wert.

Auf grund des Nyquist-Theorems muß man natürlich das EIngangssignal ca. 3mal schneller abtatsten als die Frequenzen die man untersuchen möchte. Hinzukommt noch das solche Lock-In-Amplifier selber eine gewisse Zeit zum einschwingen benötigen. Dh. dein Eingangssignal sollte mit mindestens 10Khz gesampelt werden.

Eventuell finde ich die Zeit einen kleinen Source zu bauen, versprechen kann ich es dir aber nicht Es ist aber eine wirklich einfache Sache sowas, sich kompliziert anhörendes, in Software zu machen.

Gruß Hagen
  Mit Zitat antworten Zitat
MotoNero112

Registriert seit: 7. Sep 2006
4 Beiträge
 
#7

Re: Frequenzen erkennen, CRC - Check, Timer zu langsam?!

  Alt 8. Sep 2006, 16:22
Stimmt, von PLL hab ich auch mal was gehört. Ich weiß, dass Funkscanner oder sogar einfache Scanner-Radios PLL verwenden. Wie soetwas in Software, speziell Delphi realisiert werden soll ist relativ klar. Doch wie erzeuge ich die "Referenz - Frequenzen". Es ist einleuchtend, dass PLL schneller läuft als FFT. Wie FFT prinzipiell funktioniert ist mir auch bekannt. Jedoch wäre eine kleine Hilfe sicher ratsam.

So habe ich es bisher verstanden:

- Referenz erstellen mit 1200 Hz und 1800 Hz. Zusätzlich beide Signale um 90° verschoben. Bedeutet das, dass sich eine stehende Welle ergibt?? Mein Physik LK ist nun auch schon etwas her. Oder löschen sich dann beide Wellen aus und addieren sich zu Null??

@negaH: Was genau stellt "r" denn nun dar?
Ein kleiner Source wäre wunderbar. In wie weit lässt sich das mit der Bass.Dll realisieren?

Jetzt komm ich grad selber etwas durcheinander. Wenn ich eine Samplerate von 44100 Hz habe, bedeutet das doch, dass ich pro Sekunde 44100 Samples habe, oder? Also unterteile ich das Signal, das per Micro reinkommt innerhalb von einer Sekunde in 44100 Stücke?? *confused*

Also:

1. Per BASS.DLL Stream aus Microeingang generieren
2. Referenz-Signale (Frequenzen) erstellen mit PLL (wie hätte ich gerne nochmal erklärt; wäre super)
3. Aktuelles Signal mit Referenz vergleichen.
4. Vergleich zwischen Pegel f1200 und f1800. Wenn Pegel(f1800) > Pegel(f1200) dann '0'. Wenn Pegel(f1800) < Pegel(f1200) dann '1'.

Naja gut. Ich finde es super, dass eine hier so schnell und auch ausführlich geantwortet wird. Jetzt hab ich nur das Problem, dass ich soviel gelesen habe, dass ich verschiedenes durcheinander bringe.

Eins steht zumindest fest: Mit FFT und BASS.DLL lässt sich kein befriedigendes Ergebnis erzielen. Es erscheint mir fast so, als wenn das Hanning - Window der BASS.DLL unwichtige Signale durchlässt und wichtige unterdrückt. Von der Resolution her ist die BSS.DLL glaub ich zu ungenau und alles, was ich an Timern kenne zu langsam.

Nun denn, Danke bis hierher für die bereits erfolgten Antworten. Ich bin gespannt, was Euch sonst noch so einfällt.

Grüße Mario
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#8

Re: Frequenzen erkennen, CRC - Check, Timer zu langsam?!

  Alt 8. Sep 2006, 17:01
ok, du bekommst dein Signal mit 44Khz gesampelt. Bei einer Frequenz von 1800Hz, Rechteck, müsst du also eine Variable von -1 auf +1 alle 44000/1800 Samples negieren. So einfach und fertig ist unser Referenztakt von 1.8Khz. Nun das um 90Grad Phasenverschobene Signal: das wäre 1/4 an Takten verzögert, also 44000/1800 = 24.4 / 4 = 6.1 Samples verzögert.

Nun machst du folgendes: Eine Variable die -1 oder +1 enthalten kann. Du multiplizierst dein aktuelles Sample mit dieser Variablen und addierst diesen Wert zu einem Akkumulator = Variable = X. Nach exakt 24 Samples negierst du diese Variable. Nach 48 Samples haben wir ja eine komplette Welle der 1.8KHz durch und führestens zu diesem Zeitpunkt können wir den Akkumulator auswerten. Normalerweise macht man dies aber so das man auf merheren Wellen ausrichtet, also zb. nach 48*10 Samples, was dann 10 Schwingungen a 1.8KHz wären. Das gleiche machst du mit einem Akumulator Y für die Phase. Wieder eine Variable mit -1,+1 aber diesesmal 6 Samples später negiert. Nun wieder Akkumulator Y die Summe aus -1,+1 * Sample addiert. Nach zb. 48*10 Samples werden die Akkumulatoren ausgewertet. r := Sqrt(X^2 + Y^2). R ist dann ein Wert der die Abhängigeit=Übereinstimung unserer Refernezfrequenz zum Inputsignal darstellt. Je höher dieser Wert ist desto mehr Anteile der 1.8Khz sind im Signal.

Gut, Nachteil dabei ist das wir immer erst nach zb. 48*10 Samples einen Wert ermiteln und dieser NICHT fließend ist. Aber auch das ist möglich. Wir nehmen einen Filter wie bei Durschnittsberechnungen möglich. Denn im Grunde genommen berehcnen wir ja nur den Durchschnitt von 480 Samples die aber im Takt von 1.8Khz ständig negiert werden.

Stelle es dir vor wie ein Gleichrichter der enen Sinus gleichrichtet. Nur das unser Gleichrichter exakt im Takt von 1.8KHz gleichrichtet. Ist das Input-Rechecksignal exakt synchron zu 1.8Khz so entsteht eine Gleichspannung, da ja nun alle negativen Halbwellen des Sinus negiert wurden. Sieht dann aus wie ein Pulsirendes Signal, aber immer im positiven Bereich.

Nun verschieden wir unseren 1.8Khz Takt um 90 Grad. Das dadurch entstehende Signal zeigt uns ob wir in der Phase synchron sind. Je geringer dieser Wert also ist um so synchroner gleichrichten wir das Sgnal, um so exakter sind wir Phasensynchron mit unserem Refernezsignal zum Inputsignal.

Je länger deine Samplingphase ist (48 * 10) um so kleinere Signal kannst du detektieren. Denn diese Methode hat den Vorteil das du selbst aus einem Rauschsignal das unser Nutzsignal enthält dieses detektieren kanst. Du kanst davon ausgehen das alle heutigen Hochfrequenzverfahren auf dieser Idee basieren, GPS, GSM usw. wären ohne garnicht denkbar.

Damit du dein Signal fließend auswerten kannst benutzt man einen Ring-Buffer. In unserem Falle zb. 48*10=480 Werte groß. Über diese 480 Werte berechnet du die Summe zu unserem 1.8Khz Takt. Diese Summe in einer Variablen gespeichert, sie ist ja Akkumulator X. Bei einem neuen Sample subtrahierst du das älteste Sample im Ringbuffer vom Akkumulator und addierst das bearbeite Sample dazu. Dieses Speicherst du im Ringbuffer als letzten Wert.

Der Akkumulator reprsentiert also die summme der letzten 480 Samples, kontinuierlich und im RingBuffer stehen die letzten 480 Werte die im Akkumulator addiert wurden. In unserem Falle also die Samples multipliziert mit (-1,+1) im Takt unserer 1.8Khz.

Da du aber sowieso ein WAV als Input hast benötigst du keinen RingBuffer mehr. Stattdessen wissen wir ja das das 480'te letzte Sample exakt synchon zu unseren 1.8KHz sind. Wir müssen also nur dieses Sample ebenfalls mit unsere Refernezfrequenzvariablen die alle 48 Samples negiert wird ausrechnen un vom Akkumulator X subtrahieren (rausrechnen). Das aktuelle Sample wird danach ebenfalls mit (-1,+1) multpiliziert und auf den Akkumulator addiert.

Pseudcode

Delphi-Quellcode:
var
  Samples: array of SmallInt;
 
ProcessSample;
var
  r: Double;
  aX,aY: Double;
  rX,rY: Integer;
  cX,cY: Integer;
begin
  aX := 0;
  aY := 0;
  rX := -1;
  rY := -1;
  cX := 0;
  cY := 11;
  for I := 44 to High(Samples) do
  begin
    aX := aX - Samples[I - 44] * rX;
    aY := aY - Samples[I - 44] * rY;
    aX := aX + Samples[I] * rX;
    aY := aY + Samples[I] * rY;
    Inc(cX);
    if cX >= 22 then
    begin
      cX := 0;
      rX := -rX;
    end;
    Inc(cY);
    if cY >= 22 then
    begin
      cY := 0;
      rY := -rY;
    end;
    r := Sqrt(Sqr(aX) + Sqr(aY));
  end;
end;
Mit obigem Code würde man auf 44000/44 = 1Khz filtern. Die Phasenverschiebung unseres Referenztaktes wird durch die 90 Grad Verschiebung und der Formel r = Sqrt(x^2 + y^2) beseitigt. Es ist also unwichtig wann du anfängst deine Samples auszuwerten (bei welchen Inxdex) bzw. wie die Phasenverschiebung des Inputsignales ist. Und wie man sieht hat dieser Code zwei Vorteile

1.) kontinuierliche Auswertung ist möglich, maximal eine Welle später als unsere Referenzfrequenz
2.) die Laufzeit sollte wesentlich höher sein als eine FFT

Statt wie oben mit einem Rechtecksignal zu arbeiten kannst du auch ein Sinus als Referenz benutzen, ist aber nicht notwendig, erhöht nur die Genauigkeit wenn unser Signal ebenfalls mit Sinus FSK moduliert wurde.

Gruß Hagen

PS: Tippfehler gehören euch, ich hasse Laptop Tastaturen.
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#9

Re: Frequenzen erkennen, CRC - Check, Timer zu langsam?!

  Alt 8. Sep 2006, 17:18
hm vielleicht nochmal einfacher

Wenn du ein 1Khz Signal mit 44Khz samplest dann heist dies das nach exakt 44000/1000 Samples eine Schwingung eines 1Khz Signales rum ist. Nach exakt 22 Samples also eine Halbwelle dieser 1Khz. Ziel ist es nun die 1'te positive Halbwelle durchzulassen und die 2'te negative Halbwelle zu invertieren -> gleichzurichten -> zu spiegeln. Statt einem Sinus erhalten wir eine gepulste Gleichspannung mit einer Frequenz von 2Khz

Nun addieren wir einfach diese Samples in einem Akkumulator. Da wir aber eventuell zum falschen Zeitpunkt negieren müssen wir wissen ob wie Phasensynchron sind. Dazu verschieben wir unser 1Khz exakt um 90 Grad also 11 Takte und berechnen ebenfalls den Durchschnitt. Mit der Formal r = Sqrt(X^2 + Y^2) beider Akkumuatren errechnen wir die effektive Übereinstimmung unseres 1Khz Signales mit dem Inputsignal. Fertig.

Je länger du nun den Akkumulator inkrementierst zb. statt 44 mal eben 44*10 je größer wird der Gain = Verstärkung und um so stärker verrauschte Signale kann man dekodieren.

[edit]
ganz vergessen zu erwähnen, dein Inputsignal muß bipolar sein, heist zb. im Bereich von -127 bis +127 gehen
[/edit]

Gruß Hagen
  Mit Zitat antworten Zitat
MotoNero112

Registriert seit: 7. Sep 2006
4 Beiträge
 
#10

Re: Frequenzen erkennen, CRC - Check, Timer zu langsam?!

  Alt 9. Sep 2006, 02:50
Also der Source-Code ließ sich hervorragend implementieren. Er ist enorm schneller als FFT, liefert auch bessere Werte. Jedoch variieren diese immernoch, was ich mir nicht erklären kann. Mit einem Testgenerator lasse ich stets die gleiche Folge über die Soundkarte laufen, und immer sind die Werte unterschiedlich. Zudem besteht noch das Timerproblem. Ich hab's mit dem MMTimer versucht. Auf 1ms eingestellt (minimum). Folge: Programm friert ein, Rechner am Boden.....Stelle ich den Wert auf 3 ms, so bekomme ich augenscheinlich nur jeden 3. Wert. Eigentlich müsste ich ja unter 0,8 ms um ordentlich Werte zu erzielen.

Auf jeden Fall erstmal vielen Dank für den Source und die äußerst ausführliche Erklärung.

Es muss doch irgendwie eine Möglichkeit geben das Ganze in (annäherend) Echtzeit laufen zu lassen. Schließlich dauert das ja wohl nicht so lange ein Array der Größe 44000 mit Werten zu füllen. Und schon garnicht auf heutigen Rechnern-....Was mache ich nur falsch?

Hier mal die Analyse:

Delphi-Quellcode:
function RecordingCallback():TData;
var
    Samples: TData;
    r_a,r_b: Double;
    aX,aY,aX_B,aY_B: Double;
    rX,rY,rX_B,rY_B: Integer;
    cX,cY,cX_B,cY_B: Integer;

    I,l: integer;
begin

BASS_ChannelGetData(Channel, @Samples,44000);
result:=Samples;

  aX := 0;
  aY := 0;
  rX := -1;
  rY := -1;
  cX := 0;
  cY := 9;
  for I := 36 to 36*2 do
  begin
    aX := aX - Samples[I - 36] * rX;
    aY := aY - Samples[I - 36] * rY;
    aX := aX + Samples[I] * rX;
    aY := aY + Samples[I] * rY;
    Inc(cX);
    if cX >= 18 then
    begin
      cX := 0;
      rX := -rX;
    end;
    Inc(cY);
    if cY >= 18 then
    begin
      cY := 0;
      rY := -rY;
    end;
    r_a := Sqrt(Sqr(aX) + Sqr(aY));
end;
   form1.Edit1.Text:=FloatToStr(r_a);
   if r_B > 4 THEN
    BEGIN
        cou:=cou+1;
        form1.Edit2.Text:=IntToStr(cou);
    END;


  aX_B := 0;
  aY_B := 0;
  rX_B := -1;
  rY_B := -1;
  cX_B := 0;
  cY_B := 6;
  for I := 24 to 24*2 do
  begin
    aX_B := aX_B - Samples[I - 24] * rX_B;
    aY_B := aY_B - Samples[I - 24] * rY_B;
    aX_B := aX_B + Samples[I] * rX_B;
    aY_B := aY_B + Samples[I] * rY_B;
    Inc(cX_B);
    if cX_B >= 12 then
    begin
      cX_B := 0;
      rX_B := -rX_B;
    end;
    Inc(cY_B);
    if cY_B >= 12 then
    begin
      cY_B := 0;
      rY_B := -rY_B;
    end;
    r_B := Sqrt(Sqr(aX_B) + Sqr(aY_B));
    if r_B > 4 THEN
    BEGIN
        cou:=cou+1;
        form1.Edit3.Text:=IntToStr(cou);
    END;
    end;
     end;
Der Timer ruft obige Funktion alle X-ms auf.

Hier die Record-Initialisierung:
Delphi-Quellcode:
procedure StartRecording();
begin

   BASS_ChannelStop(Channel);
                                                    // Nil or @ThresholdRecorder
    Channel:=BASS_RecordStart(44000, 2,BASS_SAMPLE_FLOAT,nil, 0); //BASS_RECORD_PAUSE

 if Channel=0 then
 begin
  Error('Couldn''t start recording');
  Exit;
 end;
    //BASS_ChannelPlay(Channel, false);
end;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz