Von den vielen in Elektor erschienenen Beiträgen ist mir einer immer noch im Gedächtnis: 'Wer misst, misst Mist'.
Darin ging es um die Bedingungen, wie man was am besten misst. Und da ich im allgemeinen oft die von vielen
ungeliebte measure-Anweisung gebrauche, fragte ich mich, wie LTspice das Messen eigentlich bewerkstelligt.
Sebstverständlich ist da kein imaginäres Männchen, das ein ebenso imaginäres Messinstument an die Knoten
anlegt - alles in LTspice beruht letztendlich auf Berechnungen.
Wie das vonstatten geht, fand ich interessant genug, um das an einer Sinusspannung zu erkunden.
Für die Demo benutzen wir eine Periode einer 1kHz-Sinuswelle, für Vergleichszwecke ergänzt mit einer zweiten von 1.5kHz.

Einige Daten legen wir vorab als Parameter fest, für die Sinuswelle sind das DC-Offset, Amplitude und Frequenz.
.param dc.offs=0.5
.param ampl=0.5
.param f.tst=1k
.param f2.tst=1k5
.param t.tst=0.1m
Die Simulationszeit ergibt sich für eine Periode aus t = 1/f. Die Spannung kann man zu einem beliebigen,
willkürlich festgelegten Zeitpunkt messen, wir legen diese Testzeit auf 0.1ms fest.
Wollen wir jedoch die Spannung der Sinuswelle in einem bestimmten Winkel (z.B. 30°) messen,
so ist eine Umwandlung des Winkels in einen entsprechenden Zeitpunkt erforderlich.
Um das Ganze so allgemein wie möglich zu halten, habe ich die relevanten Formeln als Funktionen definiert,
sodass Umwandlungen von Grad ins Bogenmass sowie umgekehrt vom Bogenmass in Grad möglich sind.
Der Winkel zu einem beliebigen Zeitpunkt einer Sinuswelle ergibt sich aus '2 * pi * f * t'.
Das Resultat ist jedoch in Bogenmass! Um Bogenmass in Grad umzuwandeln, multiplizieren wir mit 180°/pi.
Pi kürzt sich weg, somit lautet die Umwandlung '2 * 180° * f * t' (= 360°*f*t).
Um vom Winkel aus die Zeit zu berechnen, lösen wir die betreffenden Formeln nach der Zeit auf.
Ingesamt ergeben sich so die folgenden Funktionen:
.function rad2deg(rad) {rad*180/pi}
.function deg2rad(deg) {deg*pi/180}
.function GetTime.R(rad, f) {rad/(2*pi*f)}
.function GetTime.D(deg, f) {deg/(360*f)}
.function GetAngle.rad(f, t) {2*pi*f*t}
.function GetAngle.deg(f, t) {2*180*f*t}
Als erstes wollen wir mal den Winkel in Grad zum Zeitpunkt t.tst "messen" und uns die zugehörigen Sinuswerte anzeigen lassen.
.meas angle.deg1 param GetAngle.deg(f.tst, t.tst)
.meas angle.deg2 param GetAngle.deg(f2.tst, t.tst)
.meas Sin.x01 param sin(angle.deg1)
.meas Sin.x02 param sin(angle.deg2)
angle.deg1: getangle.deg(f.tst, t.tst)=36
angle.deg2: getangle.deg(f2.tst, t.tst)=54
sin.x01: sin(angle.deg1)=0.587785
sin.x02: sin(angle.deg2)=0.809017
Ein Vergleich mit den Werten der beigefügten Sinustabelle bestätigt das Ergebnis.
Als nächstes testen wir die Umwandlung von Bogenmass (radians, Abk. rad) in Grad (degree, Abk. deg) und umgekehrt.
.meas angle.rad param GetAngle.rad(f.tst, t.tst)
.meas angle.deg param rad2deg(angle.rad)
.meas angle.rev param deg2rad(angle.deg)
angle.rad: getangle.rad(f.tst, t.tst)=0.628319
angle.deg: rad2deg(angle.rad)=36
angle.rev: deg2rad(angle.deg)=0.628319
Auch hier gibt es erwartungsgemäss keine Unstimmigkeiten.
Nun kommen wir zur Spannung in unserem Testzeitpunkt.
Mittels der Sinusfunktion bestimmen wir die Spannung nach der Formel:
V.calc = dc.offs + ampl * sin(angle.deg) und vergleichen das mit der Messung per measure-Anweisung: .meas V.meas find v(out) at t.tst
v.calc: dc.offs+ampl*sin(angle.deg)=0.793893
v.meas: v(out)=0.793893 at 0.0001
Sowohl Berechnung wie auch "Messung" liefern ein identisches Ergebnis.
Wir machen noch abschliessend eine zweite Berechnung, diesmal zu einem Winkel von 30°.
Wir berechnen den Sinuswert, den zum 30°-Winkel gehörenden Zeitpunkt
und lassen uns die berechnete sowie die "gemessene" Spannung der Sinuskurve anzeigen.
sin.x2: sin(deg.tst)=0.5
t2.tst: gettime.d(deg.tst, f.tst)=8.33333e-005
v.calc2: dc.offs+ampl*sin(deg.tst)=0.75
v.meas2: v(out)=0.75 at 8.33333e-005
Der Sinuswert stimmt, gleiches gilt für die Spannung - perfekt!
RudiS
P.S.Die Datei "sine meas+calc.inc.txt" in "sine meas+calc.inc" umbenennen!
Darin ging es um die Bedingungen, wie man was am besten misst. Und da ich im allgemeinen oft die von vielen
ungeliebte measure-Anweisung gebrauche, fragte ich mich, wie LTspice das Messen eigentlich bewerkstelligt.
Sebstverständlich ist da kein imaginäres Männchen, das ein ebenso imaginäres Messinstument an die Knoten
anlegt - alles in LTspice beruht letztendlich auf Berechnungen.
Wie das vonstatten geht, fand ich interessant genug, um das an einer Sinusspannung zu erkunden.
Für die Demo benutzen wir eine Periode einer 1kHz-Sinuswelle, für Vergleichszwecke ergänzt mit einer zweiten von 1.5kHz.

Einige Daten legen wir vorab als Parameter fest, für die Sinuswelle sind das DC-Offset, Amplitude und Frequenz.
.param dc.offs=0.5
.param ampl=0.5
.param f.tst=1k
.param f2.tst=1k5
.param t.tst=0.1m
Die Simulationszeit ergibt sich für eine Periode aus t = 1/f. Die Spannung kann man zu einem beliebigen,
willkürlich festgelegten Zeitpunkt messen, wir legen diese Testzeit auf 0.1ms fest.
Wollen wir jedoch die Spannung der Sinuswelle in einem bestimmten Winkel (z.B. 30°) messen,
so ist eine Umwandlung des Winkels in einen entsprechenden Zeitpunkt erforderlich.
Um das Ganze so allgemein wie möglich zu halten, habe ich die relevanten Formeln als Funktionen definiert,
sodass Umwandlungen von Grad ins Bogenmass sowie umgekehrt vom Bogenmass in Grad möglich sind.
Der Winkel zu einem beliebigen Zeitpunkt einer Sinuswelle ergibt sich aus '2 * pi * f * t'.
Das Resultat ist jedoch in Bogenmass! Um Bogenmass in Grad umzuwandeln, multiplizieren wir mit 180°/pi.
Pi kürzt sich weg, somit lautet die Umwandlung '2 * 180° * f * t' (= 360°*f*t).
Um vom Winkel aus die Zeit zu berechnen, lösen wir die betreffenden Formeln nach der Zeit auf.
Ingesamt ergeben sich so die folgenden Funktionen:
.function rad2deg(rad) {rad*180/pi}
.function deg2rad(deg) {deg*pi/180}
.function GetTime.R(rad, f) {rad/(2*pi*f)}
.function GetTime.D(deg, f) {deg/(360*f)}
.function GetAngle.rad(f, t) {2*pi*f*t}
.function GetAngle.deg(f, t) {2*180*f*t}
Als erstes wollen wir mal den Winkel in Grad zum Zeitpunkt t.tst "messen" und uns die zugehörigen Sinuswerte anzeigen lassen.
.meas angle.deg1 param GetAngle.deg(f.tst, t.tst)
.meas angle.deg2 param GetAngle.deg(f2.tst, t.tst)
.meas Sin.x01 param sin(angle.deg1)
.meas Sin.x02 param sin(angle.deg2)
angle.deg1: getangle.deg(f.tst, t.tst)=36
angle.deg2: getangle.deg(f2.tst, t.tst)=54
sin.x01: sin(angle.deg1)=0.587785
sin.x02: sin(angle.deg2)=0.809017
Ein Vergleich mit den Werten der beigefügten Sinustabelle bestätigt das Ergebnis.
Als nächstes testen wir die Umwandlung von Bogenmass (radians, Abk. rad) in Grad (degree, Abk. deg) und umgekehrt.
.meas angle.rad param GetAngle.rad(f.tst, t.tst)
.meas angle.deg param rad2deg(angle.rad)
.meas angle.rev param deg2rad(angle.deg)
angle.rad: getangle.rad(f.tst, t.tst)=0.628319
angle.deg: rad2deg(angle.rad)=36
angle.rev: deg2rad(angle.deg)=0.628319
Auch hier gibt es erwartungsgemäss keine Unstimmigkeiten.
Nun kommen wir zur Spannung in unserem Testzeitpunkt.
Mittels der Sinusfunktion bestimmen wir die Spannung nach der Formel:
V.calc = dc.offs + ampl * sin(angle.deg) und vergleichen das mit der Messung per measure-Anweisung: .meas V.meas find v(out) at t.tst
v.calc: dc.offs+ampl*sin(angle.deg)=0.793893
v.meas: v(out)=0.793893 at 0.0001
Sowohl Berechnung wie auch "Messung" liefern ein identisches Ergebnis.
Wir machen noch abschliessend eine zweite Berechnung, diesmal zu einem Winkel von 30°.
Wir berechnen den Sinuswert, den zum 30°-Winkel gehörenden Zeitpunkt
und lassen uns die berechnete sowie die "gemessene" Spannung der Sinuskurve anzeigen.
sin.x2: sin(deg.tst)=0.5
t2.tst: gettime.d(deg.tst, f.tst)=8.33333e-005
v.calc2: dc.offs+ampl*sin(deg.tst)=0.75
v.meas2: v(out)=0.75 at 8.33333e-005
Der Sinuswert stimmt, gleiches gilt für die Spannung - perfekt!
RudiS
P.S.Die Datei "sine meas+calc.inc.txt" in "sine meas+calc.inc" umbenennen!
Anhänge
Zuletzt bearbeitet:
