Hi,
ich bin grade dabei eine Schaltung + Software zur Impedanzmessung
aufzubauen.
In diesem Thread habe ich meine Grundidee vorgestellt:
TitelBeitrag "Phasenerkennung 50kHz Sinus Signal"
Jetzt sitze ich an der Umsetzung der Software um mein periodisches
Signal zu erfassen mit Hilfe von Subsampling.
Verwendet wird der uC ATmega328p mit einer Taktrate von 16Mhz un der
intern ADC mit einem Takt von 1Mhz (entspricht 76,9kSPS bei 8Bit
Auflösung).
Für den Anfang erzeuge ich mir ein Rechtecksignal, welches ich später
durch einen TP in einen Sinus umwandle. Vorerst messe ich bei meinem
aktuellen Aufbau aber das Rechtecksignal direkt.
Das Signal wir mit Hilfe des Timer2 erzeugt (Ohne Prescale) und toggelt
den Pin PB8 mit Hilfe des Compar2A (Vergleichswert 159 -> alle 100kHz).
Somit erhalte ich am PB3 ein 50kHz Rechteck Signal.
Nun meine Idee zum Subsampling:
Ich verwende den Compare2B um zu einem definierten Zeitpunkt bezogen auf
das Rechtecksignal die AD-Wandlung zu starten. Den Wert vom Compare2B
verändere ich Schrittweise von 4-156 in 8er Schritten.
Beim Timer2_CompareB_Interrupt starte ich die AD-Wandlung.
Dies mache ich einmal für den Teil wo das Rechteck-Signal am Ausgang 0
ist und einmal wo es 1 ist.
Somit erhalte ich jeweils 20 Werte pro Zustand vom Rechtecksignal.
Das ganze wiederhole ich 10-mal und bilde so den Mittelwert der
Messwerte und schreibe diese in ein Array, welches ich mir am Ende
anzeigen lasse.
Nun zu meinem Problem: Ich bekomme die Werte wiederholbar gemessen, nur
haben die gemessenen Werte nur mit sehr viel Fantasy etwas mit einem
Sinus zu tun... Im Anhang die geplotteten Werte.
Hier noch mein Programm-Code:
Irgendwie habe ich gerade das Gefühl du bringst da einige Dinge
durcheinander.
Weisst du wie Subsampling funktioniert? Du benötigst eine sehr genaue
Zeitbasis und eine Sample&Hold Stufe, die in der Lage ist dein 50 KHz
Signal abzutasten.
Ausserdem ist ein sehr steilbandiger Bandpassfilter nötig, um
Aliasfrequenzen auszufiltern.
Einfach das Signal an deinen ADC ranzuhängen und mit 76.9 KHz abzutasten
funktioniert bei 50 KHz natürlich nicht mehr.
Du kannst max. Frequenzen der halben Samplingfrequenz auflösen, und
solltest alles darüber auch mit einem externen Tiefpass möglichst steil
herausfiltern.
Je näher du an FS/2 kommst, desto schlechter wird natürlich die
Signalform, im Grunde wird es ein Rechteck, und du hast lediglich noch
die Amplitude als Information.
Eine Phasenmessung zweier 50 KHz Signale mit einem 76.9 KHz ADC ist so
ziemlich unmöglich.
Ausserdem müssten auch beide ADCs (bzw. die Sample&Hold-Stufen) sehr
präzise synchronisiert sein.
Warum machst du die Phasenmessung nicht analog?
Dazu beide Signal auf annähernd gleichen Pegel bringen, dann über
Komparatoren in Rechtecke wandeln, auf ein XOR geben und danach
Tiefpassfiltern.
Diesen Analogwert kannst du dann mit einem beliebig langsamen ADC mit
hoher Auflösung messen.
Joe F. schrieb:> Irgendwie habe ich gerade das Gefühl du bringst da> einige Dinge durcheinander.
Ähh... ebenso :)
> Ausserdem müssten auch beide ADCs (bzw. die Sample&Hold-> Stufen) sehr präzise synchronisiert sein.
Nö.
Es genügt, wenn Sender und Empfänger, d.h. Generator und
ADC synchronisiert sind. Das ist hier deshalb der Fall,
weil sich beide innerhalb desselben Mikrocontrollers
befinden.
Wenn ein Timer-Kanal die 50 kHz erzeugt und DERSELBE
Timer-Kanal per Capture/Compare die AD-Wandlung startet,
dann wüsste ich nicht, warum das nicht funktionieren
sollte.
> Warum machst du die Phasenmessung nicht analog?
Weil das ein Haufen analoges Gefrickel ist.
Ich weiss, dass das möglich ist, denn eins unserer Messgeräte
hat das so ähnlich gemacht. Aber ganau deshalb weiss ich auch,
dass das analoges Gefrickel ist.
So, hat ein wenig gedauert, bis ich mir deinen anderen Thread
durchgelesen habe, und glaube verstanden zu haben was zu da vor hast.
Mal ein paar grundsätzliche Überlegungen:
Dein Signal hat 50KHz, das entspricht einer Periodendauer von 20us.
Wenn es dir gelänge, den Samplezeitpunkt deines ADC auf einen
Prozessortakt genau in Relation zum erzeugten Signal zu starten, ist das
eine zeitliche Auflösung für dein Subsampling von 1/16 MHz = 62,5ns.
Das entspricht 1,125° deines 50 KHz Signals.
Bei dem von dir zu untersuchenden Bereiches von 0°-25° hast du also eine
maximal mögliche Auflösung von ca. 23 Phasen-Stufen (1,125°
Genauigkeit). Ich gehe davon aus, dass du das berücksichtigt hast, und
du keine höhere Genauigkeit erreichen möchtest.
Um dein Signal mit 16 MHz abzutasten, benötigst du eine Sample&Hold time
von max. 62,5ns.
Dein ADC wird mit 1 MHz getaktet, und die interne Sample&Hold Stufe
braucht mind. 1 ADC-Taktzyklus (ich glaube irgendwo gelesen zu haben,
dass es sogar 2 Zyklen sind).
D.h. die Sample&Hold Stufe deines ADC ist momentan für mindestens 1/1MHz
= 1us "offen".
Bezogen auf dein 50 KHz Signal entspräche dies 18° des Signals, die von
der Sample&Hold Stufe bereits gemittelt werden.
Wenn es 2 ADC Zyklen sein sollten, wären es 36°.
Ich glaube dies allein macht deine Messung schon sehr unbrauchbar.
Ob dein Code korrekt arbeitet, kann ich nicht beurteilen, ich finde ihn
ziemlich schwer zu lesen.
So wie ich es verstehe, samplest du einen Wert, und mittelst ihn mit den
vorherigen Werten (wobei wohl irgendwie noch der nachträglich ermittelte
genaue Samplezeitpunkt die Array-Adresse bestimmt...?).
Deine "Mittelung"
reduziert allerdings sofort schon mal die Auflösung auf 1/2, und
ausserdem wird nicht linear gemittelt, sondern frühere Messwerte
verlieren mit jedem neuen Messwert zunehmend mehr an Bedeutung (uns zwar
nicht linear)?
Ich verstehe auch nicht, warum einmal temp+19 und einmal temp+9 genommen
wird...
Ich würde mal versuchen, die Mittelung wegzulassen, und die Daten
hintereinander weg in ein Array zu schreiben solange es der Speicher her
gibt, und dies dann hinterher extern auszuwerten.
Dann kannst du besser beurteilen, ob die Werte Sinn machen.
Zusätzlich wäre es vielleicht mal einen Versuch wert, das Timing der ADC
Startpunkte zu überprüfen.
Anstatt den ADC zu starten, könntest du mal einen weiteren Output
high/low togglen lassen, und guckst dir am Oszi an, ob die Startpunkte
einigermaßen gleichmäßig im 62,5ns Abstand über dein zu messendes Signal
verteilt sind.
Mit diesem Start-Signal könnte man dann auch eine geeignet schnelle,
externe Sample&Hold Stufe triggern.
Nachtrag:
Klar ist eine analoge Auswertung etwas "einstellbedürftig", allerdings
hätte sie in deinem Fall wirklich Vorteile.
Da du ja weisst, dass sich dein zu messendes Signal nicht mehr als 180°
verschiebt, kannst du auf die XOR Auswertung komplett verzichten.
Alles was du tun müsstest ist das Eingangssignal und das zu
vergleichende Signal auf eine möglichst gleiche Amplitude zu verstärken,
und das zu messende Signal zu invertieren.
Durch Mischen, aktives Gleichrichten und Tiefpassfiltern erhältst du
direkt eine analoge Spannung, die der Phasenlage entspricht.
Mit einem 8-bit ADC könntest du damit theoretisch eine Auflösung von ca.
0,7° erreichen, da du aber nicht mehr so schnell samplen musst, könntest
du auch auf 10-bit gehen, und hättest eine Auflösung von ca. 0,18° -
oder noch genauer, indem du den Messbereich auf <180° einschränkst.