Forum: Mikrocontroller und Digitale Elektronik Phasenmessung mit Mikrocontroller


von Franky (Gast)


Lesenswert?

Hallo zusammen,

ich möchte gerne eine Phasenverschiebung von zwei Sinussignalen mit 
jeweils einer Frequenz von 50Hz messen. Um die Phase mit dem µC zu 
bestimmen habe ich eine Nullpunktdetektion aufgebaut, die ein 
Rechtecksignal mit steigender Flanke bei einem positiven Nulldurchgang 
der Sinussignale erzeugt.

Geplant habe ich bis jetzt diese zwei Signale auf zwei externe 
Interrupteingänge zu schalten und einen 16-Bit Timer mit 1MHz nebenher 
laufen zu lassen. Bei Erkennung der ersten Flanke von Signal1 
(Referenzsignal) soll der Timer starten. Bei einer Flanke des Signals2 
wird der Wert des Timers in einer Variablen (Phase) gespeichert. Bei 
einer erneuten Flanke von Signal1 wird der Wert des Timers in einer 
anderen Variablen (Frequenz) gespeichert, der Timer auf Null gesetzt und 
neu gestartet. Nun beginnt die Messung von neuem.
Mit den zwei Zählwerten können nun die Frequenz und dann daraus die 
Phasenverschiebung bestimmt werden.

Als Controller habe ich den ATMega 328 angedacht (es werden noch eine 
ADC Wandlung und eine Displayausgabe via I²C oder SPI hinzukommen)

Meine Fragen sind nun:

- Habt ihr vielleicht bessere/sinnvollere Lösungen?

- Wie könnte ich den Fehler abschätzen den der Controller durch 
Verzögerung (Latenz) verursacht?

Vielen Dank schon mal für eure Antworten

Mfg Franky :)

von Jens (Gast)


Lesenswert?

Eine bessere Lösung fällt mir auch nicht ein. Kannst du so machen.
Zum Thema Latenz:
Ein 50Hz Signal ist für den Controller schon langsam. Da sollten die 
Takte für den Interrupteinsprung nicht ins Gewicht fallen. Betreibe ihn 
halt mit der maximalen Frequenz.
Außerdem ist die Verzögerung ja Konstant und könnte sich kallibriereb 
lassen.

von Franky (Gast)


Lesenswert?

Jens schrieb:
> Eine bessere Lösung fällt mir auch nicht ein. Kannst du so machen.
> Zum Thema Latenz:
> Ein 50Hz Signal ist für den Controller schon langsam. Da sollten die
> Takte für den Interrupteinsprung nicht ins Gewicht fallen. Betreibe ihn
> halt mit der maximalen Frequenz.
> Außerdem ist die Verzögerung ja Konstant und könnte sich kallibriereb
> lassen.

Ich wollte den Controller mit 8 MHz und einem Prescaler von 8 Betreiben 
(daher die 1MHz Timerfrequenz). Vielleicht habe ich noch einen 16MHz 
Quarz da. Damit könnte ich die Genauigkeit verdoppeln.
Ich weis dass 50Hz für den Controller sozusagen DC sind. Aber es ist für 
meine Abschlussarbeit und da wäre eine theoretische Fehlerabschätzung 
nicht schlecht :-P

Hat jemand sonst noch eine Idee für meine beiden gestellten Fragen?

von Franky (Gast)


Lesenswert?

Jens schrieb:
> Außerdem ist die Verzögerung ja Konstant und könnte sich kallibriereb
> lassen.

Wie lässt sich diese Kalibrieren?

von Karl H. (kbuchegg)


Lesenswert?

Franky schrieb:

> - Wie könnte ich den Fehler abschätzen den der Controller durch
> Verzögerung (Latenz) verursacht?

Nimm einfach mal eine plausible Worst-Case Latenz an.

Sagen wir mal 30 Takte. D.h. vom Auftreten des Ereignisses, bis dann 
dein Programm die Finger an den Zahlenwert kriegt, vergehen 30 Takte.

Ja, ich weiß. 30 Takte sind viel zu großzügig geschätzt, aber nehmen wir 
das einfach mal an.

Welche Zeit ist das?
Bei 1Mhz wären also in 1 Sekunde 1Mio Takte fällig.
30 Takte sind dann
1
      1000000         1
2
         30           x
3
    ----------------------
4
5
           30 * 1
6
      x = -------------- = 0.00003 Sekunden
7
           1000000
Bei 50Hz dauert jede Schwingung 1/50 = 0.02 Sekunden

0.00003 sind daher wieviele Prozent davon
1
       0.02        100
2
       0.00003      x
3
     -------------------
4
5
           0.00003 * 100
6
       x = ------------- = 0.15%
7
               0.02
d.h. du kannst deine 50Hz mit einer Abweichung messen, die kleiner als 
0.15% ist.
Wichtig: die zugrundelegende Zahl, nämlich die 30 Takte, wurden 
absichtlich absurd hoch gewählt.

von Karl H. (kbuchegg)


Lesenswert?

Franky schrieb:
> Jens schrieb:
>> Außerdem ist die Verzögerung ja Konstant und könnte sich kallibriereb
>> lassen.
>
> Wie lässt sich diese Kalibrieren?

So wie immer:
du nimmst dein Messgerät und wirfst ihm eine Messgröße vor, die du 
kennst. Dann siehst du dir an, was dein Messgerät dazu sagt und die 
Differenz zum bekannten korrekten Wert ist der Wert mit dem du das 
Messgerät kalibrierst.

Kurz gesagt und vereinfacht:
Kalibrieren ist nichts anderes als so lange am Messgerät 'rumschrauben', 
bis es das anzeigt, was es anzeigen soll wenn man ihm eine bekannte 
Messgröße vorwirft. In der Praxis wird man das natürlich mit mehreren 
unterschiedlichen bekannten Messgrößen machen, aber kurz gesagt ist es 
im Prinzip genau das.

von Martin W.T. (Gast)


Lesenswert?

Zumindest Nullpunktabgleich bei Phasenmessung bei derart niederigen 
Frequenzen ist ja sehr einfach: An beide Eingänge exakt das gleiche 
Signal anschließen.
Mehr als 0-Abgleich ist hier auch nicht nötig, weil die Verzögerung 
frequenzunabhängig ist.

von Franky (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Franky schrieb:
>
>> - Wie könnte ich den Fehler abschätzen den der Controller durch
>> Verzögerung (Latenz) verursacht?
>
> Nimm einfach mal eine plausible Worst-Case Latenz an.
>
> Sagen wir mal 30 Takte. D.h. vom Auftreten des Ereignisses, bis dann
> dein Programm die Finger an den Zahlenwert kriegt, vergehen 30 Takte.
>
> Ja, ich weiß. 30 Takte sind viel zu großzügig geschätzt, aber nehmen wir
> das einfach mal an.
>
> Welche Zeit ist das?
> Bei 1Mhz wären also in 1 Sekunde 1Mio Takte fällig.
> 30 Takte sind dann      1000000         1
>          30           x
>     ----------------------
>
>            30 * 1
>       x = -------------- = 0.00003 Sekunden
>            1000000
> Bei 50Hz dauert jede Schwingung 1/50 = 0.02 Sekunden
>
> 0.00003 sind daher wieviele Prozent davon       0.02        100
>        0.00003      x
>      -------------------
>
>            0.00003 * 100
>        x = ------------- = 0.15%
>                0.02
> d.h. du kannst deine 50Hz mit einer Abweichung messen, die kleiner als
> 0.15% ist.
> Wichtig: die zugrundelegende Zahl, nämlich die 30 Takte, wurden
> absichtlich absurd hoch gewählt.

Müsste ich bei deiner Berechnung nicht die CPU Clockfrequenz mit 8MHz 
nehmen? Die 1MHz sind ja nur der Zählertakt (8MHz CPU-Frequenz mit 
Prescaler 8)
Hm ja die Berechnung an sich ist sonst ganz klar aber die 30 Takte sind 
nun auch so geraten. Gibt es keinen Anhaltspunkt wie schnell ein 
Interrupt auf ein Ereignis reagiert?
Wäre vielleicht eine Lösung dafür einen externen Interrupt durch ein 
Ereignis auszulösen und einen Portpin einzuschalten und die 
Zeitverzögerung am Oszilloskop zu messen? (Kommt natürlich die zeit für 
das Einschalten des Portpins hinzu, aber man muss ja schließlich später 
auch eine Variable beschreiben, somit könnte das ähnliche Latenzen 
erzeugen)

Martin W.T. schrieb:
> Zumindest Nullpunktabgleich bei Phasenmessung bei derart
> niederigen
> Frequenzen ist ja sehr einfach: An beide Eingänge exakt das gleiche
> Signal anschließen.
> Mehr als 0-Abgleich ist hier auch nicht nötig, weil die Verzögerung
> frequenzunabhängig ist.

Okay das werde ich mal versuchen. Danke :)

von Reinhard Kern (Gast)


Lesenswert?

Hallo,

es gibt schon eine bessere Methode, aber die ist viel viel aufwendiger. 
Siehe z.B.:
http://www.labviewforum.de/Thread-Kreuzkorrelation-zweier-Sinus-Signale

Gruss Reinhard

von Sebastian P. (spir6s)


Lesenswert?

Ich würde mir mal das Lock-In-Verfahren anschauen.

von Amateur (Gast)


Lesenswert?

Ein kleiner Pferdefuß ist aber im System:

Es kann nur einen (Interrupt) geben: Also gerade bei Phasengleichheit 
wollen beide, zur gleichen Zeit, ran ans Eingemachte.

von Marek N. (Gast)


Lesenswert?

Und warum nicht beide Signale auf ein externes XOR-Gatter geben und die 
Pulsdauer der resultierenden PWM capturen?

von public (Gast)


Lesenswert?

Hey Franky,


bei den ATMegas gibt es doch diese Input Capture Eingänge. Vor einem 
dieser Eingänge hängt noch ein Komparator, dessen Ausgang damit direkt 
auf einen Timer geschaltet werden kann. Du kannst dir also ein Rechteck 
sparen und direkt den Sinus (Nulldurchgänge) als Gate/Zähltor benutzen. 
Das übrige Rechteck dann auf einen Interrupteingang und den Timerwert 
wegschreiben.

Ich hoffe ich habe dein Problem richtig verstanden... :-)

Also schau doch mal ins Datenblatt unter dem Punkt Comparator...


Beste Grüße
public

von Wolfgang (Gast)


Lesenswert?

Franky schrieb:
> Gibt es keinen Anhaltspunkt wie schnell ein Interrupt auf ein Ereignis
> reagiert?
Nein, das hängt davon ab, was sonst so auf dem Prozessor läuft. Wenn 
z.B. eine andere ISR läuft, blockiert die Abarbeitung eines weiteren 
Interrupts so lange, bis sie fertig ist oder den Interrupt frei gibt. 
Und es hängt natürlich davon ab, was beim Interrupt alles an 
Verwaltungskram erledigt wird, bevor die eigentliche Aufgabe angegangen 
wird. Mit einem Capture des Zählerstandes per Hardware wäre man 
unabhängig von solchen softwareabhängigen Dingen. Und zur Not gibt es 
auch noch den Simulator im AVR Studio, um soetwas durchzuspielen.

von Franky (Gast)


Lesenswert?

Marek N. schrieb:
> Und warum nicht beide Signale auf ein externes XOR-Gatter geben
> und die
> Pulsdauer der resultierenden PWM capturen?

Da ich gerne die Frequenz noch ausgeben möchte. Bei Phasengleichheit 
oder 180° Verschiebung hätte ich nur noch ein Low- bzw ein Highpegel und 
könnte daraus nicht mehr die Frequenz bestimmen.

Amateur schrieb:
> Ein kleiner Pferdefuß ist aber im System:
>
> Es kann nur einen (Interrupt) geben: Also gerade bei Phasengleichheit
> wollen beide, zur gleichen Zeit, ran ans Eingemachte.

Hm ja da hast du recht. Ich könnte den höherprioren Interrupt als 
Referenz verwenden und wenn innerhalb dieses Interrupts das 
Interruptrequest-Flag des zweiten Interrupts gesetzt wird (kann ich das 
überhaupt abfragen?!) dann weis ich, dass (ungefähr, wieder mit einem 
gewissen Fehler verbunden) 0° anliegen oder?

public schrieb:
> Hey Franky,
>
> bei den ATMegas gibt es doch diese Input Capture Eingänge. Vor einem
> dieser Eingänge hängt noch ein Komparator, dessen Ausgang damit direkt
> auf einen Timer geschaltet werden kann. Du kannst dir also ein Rechteck
> sparen und direkt den Sinus (Nulldurchgänge) als Gate/Zähltor benutzen.
> Das übrige Rechteck dann auf einen Interrupteingang und den Timerwert
> wegschreiben.
>
> Ich hoffe ich habe dein Problem richtig verstanden... :-)
>
> Also schau doch mal ins Datenblatt unter dem Punkt Comparator...
>
> Beste Grüße
> public

Hm ja daran habe ich auch schon gedacht, aber ich hatte folgende 
Überlegungen:
1. Darf laut Datenblatt keine nennenswerte negative Spannung an den Pins 
angelegt werden (-0.5V ... VCC+0.5V). Das könnte ich (was ich bei den 
Komparatoren auch gemacht habe) durch einen Vorwiderstand und zwei 
Antiparallele Schottky-Dioden gegen Masse eingrenzen. Aber es sind eben 
absolute Maximum Ratings und nicht die empfohlene Betriebsart.

2. Der Offsetwert des Komparators ist recht hoch (bis 40mV, Datenblatt 
S. 141). Ich habe Spannungen die auch mal 50mV Effektiv betragen können. 
Da laufe ich Gefahr, dass der Komparator dann nicht anspricht oder?

3. Wenn ich beide Signalwege identisch aufbaue, könnten sich die Fehler 
auf beiden Zuleitungen durch die Komparatoren (Verzögerungszeiten) auch 
identisch auswirken, sodass im Endeffekt der Fehler wieder 
auskompensiert wird (nahezu, durch Bauteiltoleranzen sind die Wege nicht 
exakt identisch)

Falls ich irgendwo falsch liegen sollte bitte korrigiert mich :)

von Franky (Gast)


Lesenswert?

Franky schrieb:
> Datenblatt
> S. 141)

Korrektur: es ist S. 314

von Martin W.T. (Gast)


Lesenswert?

Franky schrieb:
> Marek N. schrieb:
>> Und warum nicht beide Signale auf ein externes XOR-Gatter geben
>> und die
>> Pulsdauer der resultierenden PWM capturen?
>
> Da ich gerne die Frequenz noch ausgeben möchte. Bei Phasengleichheit
> oder 180° Verschiebung hätte ich nur noch ein Low- bzw ein Highpegel und
> könnte daraus nicht mehr die Frequenz bestimmen.
>
Ja, ist aber die bessere Methode imho. Deine MCU hat einiges an 
Ressourcen, du könntest also einfach die XOR-Lösung mit der 
Interruptlösung kombinieren und je nach Dutycycle des XOR-Signals 
entscheiden, wie gemessen wird.

> Amateur schrieb:
>> Ein kleiner Pferdefuß ist aber im System:
>>
>> Es kann nur einen (Interrupt) geben: Also gerade bei Phasengleichheit
>> wollen beide, zur gleichen Zeit, ran ans Eingemachte.
>
> Hm ja da hast du recht. Ich könnte den höherprioren Interrupt als
> Referenz verwenden und wenn innerhalb dieses Interrupts das
> Interruptrequest-Flag des zweiten Interrupts gesetzt wird (kann ich das
> überhaupt abfragen?!) dann weis ich, dass (ungefähr, wieder mit einem
> gewissen Fehler verbunden) 0° anliegen oder?
>

Unsaubere Lösung. Geht aber, prinzipiell kann der AVR nested interrupts.

von Martin W.T. (Gast)


Lesenswert?


von amateur (Gast)


Lesenswert?

Die Idee extern die Phasen zu vergleichen, z.B. mittels XOR, um dann den 
Abstand zu messen/zählen ist im Grunde genommen nicht schlecht. Aber, 
bei dieser Messart geht leicht der Bezug bzw. das Vorzeichen verschütt. 
Ist aber nur der Absolutwert interessant, so geht’s bestimmt ganz gut.

von M. N. (Gast)


Lesenswert?

Franky schrieb:
> ich möchte gerne eine Phasenverschiebung von zwei Sinussignalen mit
> jeweils einer Frequenz von 50Hz messen.

Welche Phasenverschiebungen werden erwartet, wie genau müssen sie erfaßt 
werden und wie schnell?
Das sollte doch zunächst geklärt werden, bevor es um eine Lösung geht.

von Peter D. (peda)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wichtig: die zugrundelegende Zahl, nämlich die 30 Takte, wurden
> absichtlich absurd hoch gewählt.

Nö, sind sie nicht.
Der Worst-Case ist, daß eine Flanke auftritt wärend ein anderer 
Interrupt gerade läuft.
Nur 30 Takte für einen Handler sind sehr sportlich, rechne eher mit 50 
.. 200 Takten.

Die perfekte Lösung wären 2 ICP-Eingänge, z.B. beim ATmega1284.

von Jens (Gast)


Lesenswert?

Was du auch machen kannst:

-Du nimmst dir einen externen Oszillator mit einer bestimmten Frequenz. 
Sagen wir mal 10MHz.
-Du baust dir zwei Edge Detektoren auf. Beide schalten, wenn dein Sinus 
durch den Nulldurchgang geht.
-Du schaltest die beiden Detektoren auf ein Toggle-FF.
-Das Ausgangssignal ist dein Enable-Signal für den Oszillator (Ausgang 
Oszillator und EN-Signal sind mit AND verknüpft).

Wenn einer deiner Sinus Signale durch den Nulldurchgang geht, wir ein 
EN-Signal an den Oszillatorgegeben. Diese zählst du mit Timer1.
Wenn dein zweiter Sinus durch den Nulldurchgang geht, wird der Takt 
wieder gestoppt.
Du brauchst dann nur noch deinen Timer Wert auslesen und das entspricht 
schon deiner Phase.
Der Fehler lässt sich mit der Oszillatorfrequenz dann auch einfach 
bestimmen.
Ich habe das schonmal so mit einem Oszillator gemacht. Funktioniert 
super. Vorteil ist auch, dass du komplett von der Software unabhängig 
bist!

Gruß, Jens

von Franky (Gast)


Lesenswert?

Martin W.T. schrieb:
> Franky schrieb:
>> Marek N. schrieb:
>>> Und warum nicht beide Signale auf ein externes XOR-Gatter geben
>>> und die
>>> Pulsdauer der resultierenden PWM capturen?
>>
>> Da ich gerne die Frequenz noch ausgeben möchte. Bei Phasengleichheit
>> oder 180° Verschiebung hätte ich nur noch ein Low- bzw ein Highpegel und
>> könnte daraus nicht mehr die Frequenz bestimmen.
>>
> Ja, ist aber die bessere Methode imho. Deine MCU hat einiges an
> Ressourcen, du könntest also einfach die XOR-Lösung mit der
> Interruptlösung kombinieren und je nach Dutycycle des XOR-Signals
> entscheiden, wie gemessen wird.

Das ist doch umständlicher oder nicht? So hätte ich einen höheren 
Schaltungsaufwand?! Um die Sonderfälle 0° und 180° abzudecken muss ich 
doch dann sowieso die Signale an den µC führen.

amateur schrieb:
> Die Idee extern die Phasen zu vergleichen, z.B. mittels XOR, um
> dann den
> Abstand zu messen/zählen ist im Grunde genommen nicht schlecht. Aber,
> bei dieser Messart geht leicht der Bezug bzw. das Vorzeichen verschütt.
> Ist aber nur der Absolutwert interessant, so geht’s bestimmt ganz gut.

Ja das ist das nächste Problem. Ich möchte gerne von 0° bis 359° messen 
können. Mit der Lösung eines XORs bekomme ich ja nur die 
Phasenverschiebung von  0 < phi < 180° raus.

M. N. schrieb:
> Welche Phasenverschiebungen werden erwartet, wie genau müssen sie erfaßt
> werden und wie schnell?
> Das sollte doch zunächst geklärt werden, bevor es um eine Lösung geht.

Phasenverschiebung wird von 0° bis 359° erwartet, also das volle 
Spektrum. Über die Genauigkeit habe ich mich schon in einem anderen 
Thread unterhalten (Beitrag "Optokoppler IL710 schließt Signal kurz") 
und bin zum Entschluss gekommen, dass mir eine Genauigkeit von 0,5° 
genügt. Die Geschwindigkeit bis das Ergebnis da ist muss nicht schnell 
sein, da die Phasenverschiebung auf einem Display ausgegeben wird und 
(noch) nicht zur Weiterverarbeitung verwendet wird.

Peter Dannegger schrieb:
> Die perfekte Lösung wären 2 ICP-Eingänge, z.B. beim ATmega1284.

Hm ja der Controller hört sich gut an. Das wäre denke ich mal die beste 
Lösung. Wie würde das denn genau ablaufen?
Wenn ich das richtig verstanden habe werden die Timer gestartet 
(Gleichzeitig!) und die Timerwerte bei einer Flanke am jeweiligen 
Eingang in ein eigenes Register geschrieben. Durch dieses Ereignis kann 
jeweils ein Interrupt ausgelöst werden in welchem die Berechnungen für 
die Phase und Frequenz stattfinden. Habe ich das so richtig verstanden?

von Franky (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Die perfekte Lösung wären 2 ICP-Eingänge, z.B. beim ATmega1284.

Es gibt irgendwie zwei verschiedene Datenblätter von diesem Typ. Einmal 
mit 2 x 16 Bit Timer und einmal mit nur einem 16 Bit Timer.
Gibt es noch andere Modelle mit zwei ICP Eingängen? Bzw. wo finde ich 
eine Suchfunktion die mir alle Modelle schön darstellt? (Auf der 
Atmelseite kann man nur die gewünschte Timeranzahl einstellen aber nicht 
welchen man haben möchte)

von amateur (Gast)


Lesenswert?

>Ich möchte gerne von 0° bis 359° messen können.

Differenzieren, stark verstärken und bei positiven Ergebnis loslegen.
Die Spannung steigt, beginnend bei ihrem Minimum an (+d) fällt ab dem 
Maximum ab (-d). Erst beim Erreichen des nächsten Minimums geht’s wieder 
aufwärts.
Für die zweite Spannung gilt das gleiche.
Gehst Du davon aus, dass die Erkennung von "jetzt geht's aufwärts" mit 
gewissen Toleranzen versehen ist, so hilft Dir bestimmt die Tatsache, 
dass dies auch für beide Teilnehmer gilt.

von Franky (Gast)


Lesenswert?

Jens schrieb:
> Was du auch machen kannst:
>
> -Du nimmst dir einen externen Oszillator mit einer bestimmten Frequenz.
> Sagen wir mal 10MHz.
> -Du baust dir zwei Edge Detektoren auf. Beide schalten, wenn dein Sinus
> durch den Nulldurchgang geht.
> -Du schaltest die beiden Detektoren auf ein Toggle-FF.
> -Das Ausgangssignal ist dein Enable-Signal für den Oszillator (Ausgang
> Oszillator und EN-Signal sind mit AND verknüpft).
>...

Hört sich nach einer sehr eleganten Lösung an. Jedoch bekomme ich hier 
doch nur den absoluten Zeitwert der Phasenverschiebung raus oder? Um den 
Winkel anzugeben müsste ich die Frequenz messen können. Um dies zu tun 
müsste ich auch das Signal (Referenzsignal) direkt an den Controller 
legen, wodurch ich erneut zwei ICP bräuchte oder nicht?

von amateur (Gast)


Lesenswert?

So hieß es am Anfang:

>jeweils einer Frequenz von 50Hz messen

Ist die "Zeit" bekannt, so ist es kein Problem auch die 
Phasenverschiebung zu berechnen.
Früher einmal waren 50Hz (ein Schlenker) = 20ms. Sollte also mehr 
herauskommen, so musst Du Dir einen neuen Bleistift kaufen. Bei 10ms 
sind es also 180°. Oder so.

von Jens M. (Gast)


Lesenswert?

Franky schrieb:
> - Habt ihr vielleicht bessere/sinnvollere Lösungen?

Pic Controller gibt es mit internen analoge Komparatoren. Einen Ausgang 
legst du über einen Eingang auf das Timer Gate legen. Mit dem 2ten löst 
du einen Int aus um den Timerwert zu erwischen.

Das kann man auch für jeden Prozessor mit Timer gate und Int Eingang 
extern aufbauen.

Das wird auch mit capture/compare ports gehen, kenn mich aber bei AVR 
nicht aus ob und wie das da geht.

von Peter D. (peda)


Lesenswert?

Franky schrieb:
> Es gibt irgendwie zwei verschiedene Datenblätter von diesem Typ.

Das mit 2 16Bit-Timern stimmt.

von Purzel H. (hacky)


Lesenswert?

Nicht vergessen vor beide Eingaenge straffe 50Hz Filter zu setzen. Sonst 
triggert der Zehler ab jedem Scheiss.

von Franky (Gast)


Lesenswert?

amateur schrieb:
> So hieß es am Anfang:
>
>>jeweils einer Frequenz von 50Hz messen
>
> Ist die "Zeit" bekannt, so ist es kein Problem auch die
> Phasenverschiebung zu berechnen.
> Früher einmal waren 50Hz (ein Schlenker) = 20ms. Sollte also mehr
> herauskommen, so musst Du Dir einen neuen Bleistift kaufen. Bei 10ms
> sind es also 180°. Oder so.

Ja die Anwendung ist später bei einem 50Hz Signal. Es soll trotzdem die 
Frequenz gemessen werden, um sicher zu gehen, dass die Frequenz des 
angelegten Signals auch stimmt.

Peter Dannegger schrieb:
> Franky schrieb:
>> Es gibt irgendwie zwei verschiedene Datenblätter von diesem Typ.
>
> Das mit 2 16Bit-Timern stimmt.

Wenn ich aber bei RS schaue 
(http://de.rs-online.com/web/p/mikrocontroller/7380331/) wird ein 
Datenblatt mit nur einem 16Bit Timer angezeigt. Das macht mich sehr 
misstrauisch -.-

Siebzehn oder Fuenfzehn schrieb:
> Nicht vergessen vor beide Eingaenge straffe 50Hz Filter zu setzen.
> Sonst
> triggert der Zehler ab jedem Scheiss.

Ein Filter verdreht mir aber eventuell die Phase oder nicht?

von Peter D. (peda)


Lesenswert?

Franky schrieb:
> Das macht mich sehr
> misstrauisch

Ich benutze Timer 3 schon lange. Wenn er fehlen würde, wäre das 
aufgefallen.

Schau mal auf Table 12-1. Reset and Interrupt Vectors.
"3. Applies only to Atmel ATmega1284P."

von Jens (Gast)


Lesenswert?

> Hört sich nach einer sehr eleganten Lösung an. Jedoch bekomme ich hier
> doch nur den absoluten Zeitwert der Phasenverschiebung raus oder? Um den
> Winkel anzugeben müsste ich die Frequenz messen können. Um dies zu tun
> müsste ich auch das Signal (Referenzsignal) direkt an den Controller
> legen, wodurch ich erneut zwei ICP bräuchte oder nicht?

Das stimmt, die Frequenz brauchst du auch noch.
Aber da musst du die Signale nur anders aufteilen. Du startest den 
Oszillator mit dem Nulldurchgang von Signal1. Wenn Signal zwei den 
Nulldurchgang erreicht, legst du den Edge-Detektor auf den ICP. Dieser 
Wert wird weg gespeichert. Wenn Signal1 den nächsten Nulldurchgang 
erreicht, stoppst du den Oszillator. Dann hast du im ICP Register die 
Phase und im Timer-Count die halbe Frequenz.
Zugegeben, das ist ein wenig mehr Schaltungsaufwand, aber der Fehler 
wird nicht durch die Software größer und lässt sich zuverläassig 
abschätzen.
(Und ich bin ein Fan von analogen Auswertschaltungen um den Controller 
rum :-) )
Signallaufzeiten bei den Gattern und Detektoren sind konstant und können 
dann im Controller kompensiert werden.

Aber: Du hast geschrieben du brauchst nur eine Auflösung von 0,5°. Wenn 
ich mich nicht verrechnet habe, ist das bei 50Hz irgendwas um die 25us. 
In der Zeit kannst du im Controller einiges machen. Da wird der Fehler 
nicht mehr größer. Ich denke da merkst du nicht, wieviele Takte du für 
Interrupt-Einsprünge brauchst.

Gruß, Jens

von Kai G. (kpl)


Lesenswert?

Erzeugst Du eines der 50 Hz signale selbst im MCU?

Dann wäre es besonders einfach und genau messbar.

von Leo C. (rapid)


Lesenswert?

Peter Dannegger schrieb:
> Karl Heinz Buchegger schrieb:
>> Wichtig: die zugrundelegende Zahl, nämlich die 30 Takte, wurden
>> absichtlich absurd hoch gewählt.
>
> Nö, sind sie nicht.

Sind sie doch.

> Der Worst-Case ist, daß eine Flanke auftritt wärend ein anderer
> Interrupt gerade läuft.
> Nur 30 Takte für einen Handler sind sehr sportlich, rechne eher mit 50
> .. 200 Takten.

Karl Heinz hat mit 30 Timertakten gerechnet, und es war von einem 
Prescaler mit 8 die Rede. --> 240 Prozessortakte


> Die perfekte Lösung wären 2 ICP-Eingänge, z.B. beim ATmega1284.

Beim ATmega328P können Timer 0 und Timer 1 synchronisiert werden [1].
Damit hat man 2 ICPs, die auf einander bezogen werden können.


[1] Datenblatt Kapitel 16: Timer/Counter0 and Timer/Counter1 Prescalers

von M. N. (Gast)


Lesenswert?

Franky schrieb:
> Phasenverschiebung wird von 0° bis 359° erwartet,
...
> und bin zum Entschluss gekommen, dass mir eine Genauigkeit von 0,5°
> genügt.

Wenn ich richtig rechne, entsprechen 0,5° Auflösung bei 50Hz einer Zeit 
von rund 28µs.
Das kann man doch locker mit einem Timer und per Software erledigen.

von amateur (Gast)


Lesenswert?

>Karl Heinz hat mit 30 Timertakten gerechnet, und es war von einem
>Prescaler mit 8 die Rede. --> 240 Prozessortakte

Interessante Rechnung...

von M. N. (Gast)


Lesenswert?

Franky schrieb:
> Geplant habe ich bis jetzt diese zwei Signale auf zwei externe
> Interrupteingänge zu schalten und einen 16-Bit Timer mit 1MHz nebenher
> laufen zu lassen. Bei Erkennung der ersten Flanke von Signal1
> (Referenzsignal) soll der Timer starten. Bei einer Flanke des Signals2
> wird der Wert des Timers in einer Variablen (Phase) gespeichert. Bei
> einer erneuten Flanke von Signal1 wird der Wert des Timers in einer
> anderen Variablen (Frequenz) gespeichert, der Timer auf Null gesetzt und
> neu gestartet. Nun beginnt die Messung von neuem.
> Mit den zwei Zählwerten können nun die Frequenz und dann daraus die
> Phasenverschiebung bestimmt werden.

Wenn Du noch die Auswertung der Frequenz hinzufügst, kannst Du auf eine 
fertige Lösung zurückgreifen. 
http://www.mino-elektronik.de/fmeter/fm_software.htm#bsp6

von Detlef _. (detlef_a)


Lesenswert?

Phasenmessungen kann man viel besser als mit mit einem 
Nulldurchgangsdetektor machen.

Wie man die Frequenz und Phase eines Sinus bestimmt habe ich hier mal 
beschrieben:

Beitrag "Re: Phasenverschiebung messen (us Bereich)"

Das Verfahren arbeitet mit Samples des Sinus, Auflösung ist allerdings 
nicht auf die Abtastrate beschränkt. Wenn man  eine Phasenverschiebung 
benötigt muss man beide Signale abtasten.

Das Verfahren ist aufwendiger (A/D Wandler, Rechenleistung), es ist aber 
um Dimensionen genauer als die Nulldurchgangserkennung. Mit dem 
Verfahren habe ich die Phase eines 50Hz Sinus bis auf 10^-7 rad 
bestimmt.

Cheers
Detlef

von Franky (Gast)


Lesenswert?

Kai G. schrieb:
> Erzeugst Du eines der 50 Hz signale selbst im MCU?
>
> Dann wäre es besonders einfach und genau messbar.

Nein das sind Netzspannungen, also L1, L2 und/oder L3.

M. N. schrieb:
> Wenn ich richtig rechne, entsprechen 0,5° Auflösung bei 50Hz einer Zeit
> von rund 28µs.
> Das kann man doch locker mit einem Timer und per Software erledigen.

Hm ja das glaube ich auch. Mir geht es hierbei eigentlich eher um die 
Fehlerabschätzung, da der Fehler bei einer Softwarelösung nicht konstant 
ist.

Leo C. schrieb:
> Beim ATmega328P können Timer 0 und Timer 1 synchronisiert werden [1].
> Damit hat man 2 ICPs, die auf einander bezogen werden können.

Das hört sich sehr interessant an. Wie funtkioniert das dann genau? Ich 
verstehe die Synchronisation in dem Datenblatt so, dass man extern eine 
Taktquelle anlegen kann und diese dann als Zähltakt für die Timer 
verwendet werden kann statt dem internen Takt. Aber das nützt mir doch 
nichts oder?

von M. N. (Gast)


Lesenswert?

Franky schrieb:
> Mir geht es hierbei eigentlich eher um die
> Fehlerabschätzung, da der Fehler bei einer Softwarelösung nicht konstant
> ist.

Wenn Du den ATmega328 mit 20MHz laufen läßt, ist der Meßfehler unter 
1µs. Selbst, wenn noch weitere Interrupts auftreten, ist der zu 
erwartende Fehler weitaus kleiner bzw. besser als Deine Anforderungen. 
Mit Input-capture zu arbeiten, ist nicht notwendig, es sein denn, Du 
möchtest sehen, wie instabil die Nulldurchgangserkennung arbeitet.

Franky schrieb:
> Leo C. schrieb:
>> Beim ATmega328P können Timer 0 und Timer 1 synchronisiert werden [1].
>> Damit hat man 2 ICPs, die auf einander bezogen werden können.
>
> Das hört sich sehr interessant an.

Das Interessante dabei ist, dass es nur einen ICP (den für Timer1) gibt 
:-)

von Jens M. (Gast)


Lesenswert?

Franky schrieb:
> Nein das sind Netzspannungen, also L1, L2 und/oder L3.

Hast du dir deine 3-Phasen mal auf nem Oszi angeschaut?

Unter Last kannst du die nicht mehr erkennen. Übertrieben gesagt ist das 
durch die Rückwirkung der Motoren (wozu braucht man sonst 3 Phasen) nur 
noch ein Frequenzbrei.

Filter (was der Phasenlage nicht wirklich gut tut) oder die in Richtung 
DSP gehende Mathematikwüste von Deltef sind da angesagt.

von Franky (Gast)


Lesenswert?

M. N. schrieb:
> Franky schrieb:
>> Mir geht es hierbei eigentlich eher um die
>> Fehlerabschätzung, da der Fehler bei einer Softwarelösung nicht konstant
>> ist.
>
> Wenn Du den ATmega328 mit 20MHz laufen läßt, ist der Meßfehler unter
> 1µs. Selbst, wenn noch weitere Interrupts auftreten, ist der zu
> erwartende Fehler weitaus kleiner bzw. besser als Deine Anforderungen.
> Mit Input-capture zu arbeiten, ist nicht notwendig, es sein denn, Du
> möchtest sehen, wie instabil die Nulldurchgangserkennung arbeitet.
>
> Franky schrieb:
>> Leo C. schrieb:
>>> Beim ATmega328P können Timer 0 und Timer 1 synchronisiert werden [1].
>>> Damit hat man 2 ICPs, die auf einander bezogen werden können.
>>
>> Das hört sich sehr interessant an.
>
> Das Interessante dabei ist, dass es nur einen ICP (den für Timer1) gibt
> :-)

Ja genau das ist ja das Problem. Also geht dieser Lösungsansatz nicht? 
Ich konnte mir auch nicht vorstellen wie das funktionieren soll. Wenn es 
doch geht bitte ich um aufklärung :)

Jens Martin schrieb:
> Franky schrieb:
>> Nein das sind Netzspannungen, also L1, L2 und/oder L3.
>
> Hast du dir deine 3-Phasen mal auf nem Oszi angeschaut?
>
> Unter Last kannst du die nicht mehr erkennen. Übertrieben gesagt ist das
> durch die Rückwirkung der Motoren (wozu braucht man sonst 3 Phasen) nur
> noch ein Frequenzbrei.
>
> Filter (was der Phasenlage nicht wirklich gut tut) oder die in Richtung
> DSP gehende Mathematikwüste von Deltef sind da angesagt.

Hm bis jetzt arbeite ich nur an unbelastetem Drehstromnetz und da sehen 
die Sinussignale einwandfrei aus.

von Michael (Gast)


Lesenswert?

Franky schrieb:
> 1. Darf laut Datenblatt keine nennenswerte negative Spannung an den Pins
> angelegt werden (-0.5V ... VCC+0.5V). Das könnte ich (was ich bei den
> Komparatoren auch gemacht habe) durch einen Vorwiderstand und zwei
> Antiparallele Schottky-Dioden gegen Masse eingrenzen.

Das ist nur die halbe Wahrheit. Wenn du den Strom durch einen Widerstand 
begrenzt, besorgt die Schutzbeschaltung, i.e. die Substratdioden den 
Rest. Atmel schlägt das sogar selber in seiner AN AVR182 vor.

von M. N. (Gast)


Lesenswert?

Michael schrieb:
> Das ist nur die halbe Wahrheit. Wenn du den Strom durch einen Widerstand
> begrenzt, besorgt die Schutzbeschaltung, i.e. die Substratdioden den
> Rest. Atmel schlägt das sogar selber in seiner AN AVR182 vor.

Die Schaltung eignet sich aber eher für Handrührer oder ähnliche 
Gerätschaften in Schutzklasse 2, bei der jeder Cent zählt. Für das 
aktuelle Problem würde ich Signalaufbereitung und Auswerteschaltung 
'säuberlichst' galvanisch voneinander trennen.

Franky schrieb:
> Ja genau das ist ja das Problem.

Das Problem ist, dass Du eine in meinen Augen "überzogene" Lösung 
anstrebst, die mit AVR nicht zu schaffen ist.
ATXmega-Timer haben passende Funktionen, wenn ich nicht irre. Wenn es 
hochgenau sein sollte, würde ich persönlich die TPU eines Renesas H8S/RX 
Prozessores verwenden, bei der pro Timer bis zu vier Capture-Register 
existieren und zudem noch ein Modus capture+clear, wobei der Zählerstand 
gespeichert und gleichzeitig der Zähler noch gelöscht werden. Wie das 
mit einem STM32F4 aussieht, habe ich gerade nicht im Kopf.

Was willst Du also?
Einen anderen µC einsetzen wie ATXmega, oder, oder ...
oder einfach nur Dein Problem im vorgegeben, überschaubarem Rahmen 
lösen?

Sofern Du beim ATmega328 bleibst, sind INT0 für das Referenzsignal und 
INT1 für das phasenverschobene Signal sehr gut geeignet und völlig 
ausreichend, da sie auch im µC per Hardware die höchsten Prioritäten 
nach /Reset besitzen.
Aber mache es, wie Du meinst.

von Jens M. (Gast)


Lesenswert?

Franky schrieb:
> Hm bis jetzt arbeite ich nur an unbelastetem Drehstromnetz und da sehen
> die Sinussignale einwandfrei aus.

Klar, aber wo gehobelt wird da fallen Späne. Wenn du nur die 
"Schönwetterphasenlage" unter Idealbedingungen messen willst sieht die 
Sache meist anders aus als im "Magnetsturm" aus einem Motor mit ein paar 
kW unter Last.

Erst die Phasen in der Praxis messen und dann ein Messverfahren zu 
wählen ist besser als umgekehrt ;-).

von Leo C. (rapid)


Lesenswert?

Sorry, ich hatte die Benachrichtigung für diesen Thread nicht 
eingeschaltet. Auch wenns jetzt nicht mehr wichtig ist...

Franky schrieb:
> M. N. schrieb:

>> Franky schrieb:
>>> Leo C. schrieb:
>>>> Beim ATmega328P können Timer 0 und Timer 1 synchronisiert werden [1].
>>>> Damit hat man 2 ICPs, die auf einander bezogen werden können.
>>>
>>> Das hört sich sehr interessant an. Wie funtkioniert das dann genau? Ich
>>> verstehe die Synchronisation in dem Datenblatt so, dass man extern eine
>>> Taktquelle anlegen kann und diese dann als Zähltakt für die Timer
>>> verwendet werden kann statt dem internen Takt. Aber das nützt mir doch
>>> nichts oder?

An der von mir zitierten Stelle im Datenblatt steht:
Timer 0 und Timer 1 haben den gleichen Vorteiler. Man kann den Vorteiler 
stoppen, die beiden Timer initialisieren (und dabei auf 0 setzen) und 
anschließend den Vorteiler starten. Dann laufen beide Timer synchron.

>> Das Interessante dabei ist, dass es nur einen ICP (den für Timer1) gibt
>> :-)

Leider stimmt das, obwohl ich es ganz und gar nicht interessant finde. 
;-(
Timer0 wurde bei ATmega48..ATmega328 ggü. ATmega8 erheblich erweitert. 
Ich hatte mir wohl eingebildet, daß dabei auch ein ICP dazu gekommen 
wäre.

> Ja genau das ist ja das Problem. Also geht dieser Lösungsansatz nicht?

So ist es.

> Ich konnte mir auch nicht vorstellen wie das funktionieren soll.

Ich schon. :)

> Wenn es doch geht bitte ich um aufklärung :)

von Franky (Gast)


Lesenswert?

Leo C. schrieb:
>> Ja genau das ist ja das Problem. Also geht dieser Lösungsansatz nicht?
>
> So ist es.

Schade :(

Jens Martin schrieb:
> Franky schrieb:
>> Hm bis jetzt arbeite ich nur an unbelastetem Drehstromnetz und da sehen
>> die Sinussignale einwandfrei aus.
>
> Klar, aber wo gehobelt wird da fallen Späne. Wenn du nur die
> "Schönwetterphasenlage" unter Idealbedingungen messen willst sieht die
> Sache meist anders aus als im "Magnetsturm" aus einem Motor mit ein paar
> kW unter Last.
>
> Erst die Phasen in der Praxis messen und dann ein Messverfahren zu
> wählen ist besser als umgekehrt ;-).

Hm okay, dann muss ich mir wohl mal einen dicken Motor/Trafo oder 
sonstigen Verbraucher mal dazu ins Netz schalten und schauen was da so 
rauskommt^^

M. N. schrieb:
> Michael schrieb:
> Franky schrieb:
>> Ja genau das ist ja das Problem.
>
> Das Problem ist, dass Du eine in meinen Augen "überzogene" Lösung
> anstrebst, die mit AVR nicht zu schaffen ist.
> ATXmega-Timer haben passende Funktionen, wenn ich nicht irre. Wenn es
> hochgenau sein sollte, würde ich persönlich die TPU eines Renesas H8S/RX
> Prozessores verwenden, bei der pro Timer bis zu vier Capture-Register
> existieren und zudem noch ein Modus capture+clear, wobei der Zählerstand
> gespeichert und gleichzeitig der Zähler noch gelöscht werden. Wie das
> mit einem STM32F4 aussieht, habe ich gerade nicht im Kopf.
>
> Was willst Du also?
> Einen anderen µC einsetzen wie ATXmega, oder, oder ...
> oder einfach nur Dein Problem im vorgegeben, überschaubarem Rahmen
> lösen?
>
> Sofern Du beim ATmega328 bleibst, sind INT0 für das Referenzsignal und
> INT1 für das phasenverschobene Signal sehr gut geeignet und völlig
> ausreichend, da sie auch im µC per Hardware die höchsten Prioritäten
> nach /Reset besitzen.
> Aber mache es, wie Du meinst.

Da ich den ATmega328 nun schon bereits bestellt und geliefert bekommen 
habe werde ich wohl beim einem anfänglichen Ansatz bleiben. Die 
Anforderung Hochgenau sehe ich bei 0,5° Genauigkeit eher nicht. Meiner 
Meinung ist ein ATXmega für eine simple Phasenmessung mit zusätzlicher 
Effektivwertberechnung und Ausgabe auf einem Display ziemlich 
überdimensioniert.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.