Erstellung von speziellen Scope-Elementen mit dem SSelfDef-Script

Ein SSelfDef-Element hat im Allgemeinen folgenden Grundaufbau:

Für die Eingänge (InputVolts) gilt das Selbe wie beim DSelfDef, nur dass hier die aktuellen Pin-Spannungen
(nicht PinOld-Spannungen) verwendet werden. Eingangskapazitäten sind auch nicht definierbar.
Ein SSelfDef kennt 2 verschiedene Methoden die Messwerte (Uin's) zu verarbeiten, Measurement und
PostProcessing. Es kann immer nur eine von Beiden (exclusiv) in einem Element verwendet werden.

zu Measurement:
Hier werden die Eingangsspannungen für jeden Zeitschritt sofort verarbeitet und dem Graph übergeben.

zu PostProcessing:
Hier werden die Eingangsspannungen jeweils in einem Vektor gesammelt. Erst am Ende der Analyse-
Session werden die Vektoren verarbeitet, so das Ergebniss-Vektoren entstehen, die dem Graph übergeben
werden können. Wenn man z.Bsp. eine FFT machen möchte, müssen die Eingangswerte komplett für die
gesamte Zeit abgespeichert vorliegen. Das Ergebniss ist dann wieder ein Vektor mit den Spectral-Linien.

Wir scripten ein Voltmeter:

Schauen wir uns nun ein einfaches Beispiel, nämlich ein Voltmeter an:

#ScopeName = VoltMeter
#MBitmap = Voltmeter.mbmp
#Token = M
#AutoComment = <ScopeName>

#PinDescriptions ;optional
Pin1 = Volt+
Pin2 = Volt-
#End

#Units
XUnit = s
YUnit = V
#End

#DefaultViewPropertys ;Optional
logx = 0 ;0-Off, 1-On
logy = 0
panecolor = DARKBLUE
textcolor = WHITE
gridcolor = GRAY
framecolor= WHITE
bulkcolor = DARKBLUE
#End

#Parameter
Rmu = RMessVoltage(Ohm), 10M
#End

#VarsAndConstants
#End

#InputVolts
ui = 1,2, Rmu
#End

#CurveDefs
y1 = Voltage, YELLOW, 2
#End

#Measurement
x = g_time
y1 = ui
#End

zu #Units:
Hier werden die Einheiten-Kürzel für die X-Achse und die Y-Achse im Graphen festgelegt. 

zu #DefaultViewPropertys:
Die standartmäßigen Haupteinstellungen des Charts können hier festgelegt werden. Diese Einstellungen
können zu jeder Zeit im Property-Dialog des ScopeElements geändert werden.

zu #InputVolts:
Wie bei den DSelfDefs ist die Syntax für eine Zeile hier analog: <USymbol> = <+Pin>, <-Pin>, <Rin>
Wir definieren hier also die Symbole für die Mess-Spannungen. Einem <Pin> kann auch die 0 zugewiesen
werden (interne Masse).

zu #CurveDefs:
Hier wird pro Zeile eine Ausgabe-Kurve definiert. Folgende Syntax ist einzuhalten:
<YSymbol> = <Bezeichnung>, <Farbe>, <Strich-Stärke>
<YSymbol> ist das Kurven-Symbol, welches auch als Ergebniss-Variable in #Measurement verwendet werden muß.

zu #Measurement:
Hier findet die Berechnung der Y-Werte für jede Kurve aus den Eingangsspannungen (InputVolts) statt. Diese
Berechnung wird für jeden Zeitschritt ausgeführt, wobei die Ergebnisse dem Graphen zugestellt werden. 
Dem Symbol 'x' ist unbedingt ein X-Wert zu zuweisen. Jedem YSymbol ist unbedingt ein Y-Wert zu zuweisen.
In der Regel wird 'x' die Zeit (globale Variable g_time) zugewiesen.
In diesem Beispiel haben wir die Eingangsspannung ui als Funktion der Zeit g_time deklariert.

Wir erweitern das Voltmeter:

Damit wäre unser einfaches Voltmeter schon fertig. Wir erweitern nun dieses Scope mit einer Mittelwert-
und einer Effektivwert-Kurve.

Für den gleitenden Mittelwert (Average) gilt das Integral:

Numerisch läßt sich dieses Integral mit der Trapez-Regel folgendermaßen lösen:

Da wir nicht für jeden Zeitschritt die vollständige Summe berechnen wollen (können), überführen wir die Summe
in eine rekursive Darstellung:


Für den gleitenden Effektiv-Wert (Effective) gilt das Integral:


Wieder in numerischer Summen-Darstellung:

Und schliesslich wieder die rekursive Form:

Wir erweitern nun #CurveDefs um die 2 neuen Kurven:

#CurveDefs
y1 = Voltage, YELLOW, 2
y2 = Average, GREEN, 2
y3 = Effective, RED, 2
#End

Mittels der grau hinterlegten Formeln können wir #Measurement erweitern. Wir substituieren aber erst:
U(tn) --> Ui,  U(tn-1) --> Uiold,  U(tn)^2 --> Uih2,  U(tn-1)^2 --> Uioldh2
sowie t(n) --> g_time,  dt(n) --> g_timestep, Uav(tn) --> y2, Uef(tn) --> y3.

Uiold, Uioldh2 sowie Sum, Sum2 müssen wir als StateVars definieren und mit 0 initialisieren.

Erweitert sieht das nun so im Script aus:

#StateVars 
;for Average
sum = 0
uiold = 0
;for Effective
sum2 = 0
uioldh2 = 0
#End

#Measurement
x = g_time
y1 = ui

;Average
sum += (ui+uiold)*g_timestep*son(g_time,0)
y2 = {g_time > 0 ? sum/(2*g_time) : 0}
uiold = ui

;Effectiv
uih2 = ui*ui
sum2 += (uih2+uioldh2)*g_timestep*son(g_time,0)
y3 = {g_time > 0 ? sqrt(sum2/(2*g_time)) : 0}
uioldh2 = uih2

#End

Man sieht, dass erst ab t > 0 die Summen als auch die Y-Werte berechnet werden. Bei t = 0 sind y2 und y3 0 zusetzen.
uiold und uioldh2 werden am Ende die aktuellen Werte zugewiesen, um im nächsten Zeitschritt als alte Werte zu dienen.

Hier der vollständige Script von Voltmeter.sselfdef.

Bitte die Schaltung DocSamples/Test_Voltmeter.circ öffnen und Dyna durchführen um das Ding im Einsatz zu sehen:

Man sieht: der Mittelwert tendiert gegen 0, der Effektiv-Wert läuft gegen 0.707V (Wert für unendlich lange Sinus-
Schwingung der Amplidute 1V).

Klickt man mit der rechten Maustaste auf das Scope-Element öffnet der SelfDef-Scope-Dialog:

Hier kann man die altbekannten Einstellungen machen, sowie Aussehen und Bezeichnung der Kurven ändern.
 

Wir konstruieren ein Powermeter:

    

Rmi ist ein sehr kleiner Messwiderstand (Shunt) in Dem der Strom berechnet wird.
Wir wollen noch den Leistungs-Mittelwert anzeigen lassen. Für den gleitenden Mittelwert der Leistung gilt:

Und gleich die rekursive Form für die numerische Berechnung:

In den Script können wir nun hinein schreiben:

#InputVolts
uu = 1,2, Rmu
ui = 2,3, Rmi
#End

#CurveDefs
y1 = Power, RGB_0_255_0, 2
y2 = Average, RGB_255_0_0, 2
#End

#StateVars
sum = 0
y1old = 0
#End

#Measurement
x = g_time
y1 = uu*ui/Rmi

sum = sum + (y1+y1old)*g_timestep*son(g_time,0)
y2 = {g_time > 0 ? sum/(2*g_time) : 0}
y1old = y1
#End

Für P(tn) wird y1, für P(tn-1) wird y1old, für Pav wird y2 gesetzt. Sonst ist alles analog zum Voltmeter und muß nicht
weiter erklärt werden.

Hier der vollständige Script von Powermeter3Pins.sselfdef.

Bitte die Schaltung DocSamples/Test_Powermeter.circ öffnen und Dyna durchführen um das Ding im Einsatz zu sehen:

Wir beobachten hier ein Alternieren der Momentan-Leistung zwischen positiven und negativen Werten. Bei
positiven Wert fließt Energie in die Induktivität hinein, um dann bei negativen Wert wieder abgegeben zu
werden. Die Energie wird also in der Spule gespeichert und nicht verbraucht (sonst könnte Sie ja nicht wieder
abgegeben werden). Der Mittelwert der Leistung tendiert gegen 0, da sich im Mittel die hineinfließende und
herausfließende Energie aufheben. Es wird also keine Energie umgesetzt, also auch keine Wärme erzeugt.
Deswegen spricht man hier auch von der sogenannten Blindleistung.

Und noch der X/Y-Schreiber:

    

Das XY-Scope ist sehr einfach zu modellieren, man setzt für die X-Achse nicht g_time sondern einfach Ux ein.

Im Script schaut das so aus:

#InputVolts
ux = 1,2, Rmu
uy = 3,4, Rmu
#End

#CurveDefs
y1 = Volt X/Y, RGB_0_255_0, 2
#End

#Measurement
x = ux
y1 = uy
#End

Hier der vollständige Script von XYVoltScope.sselfdef.

Bitte die Schaltung DocSamples/Test_XYScope.circ öffnen:

 

Nach Ausführen der Dyna erhalten wir folgende Charts:

Was man hier sieht, sind die sogenannten Lissayus-Figuren (richtig geschrieben ?). Diese entstehen wenn an
beiden Eingängen des XY-Schreibers Sinus-Signale anliegen. Je nach Phasen-Verschiebung und Frequenz-
Unterschied entstehen unterschiedliche Figuren. Früher hat man tatsächlich so Frequenzen und Phasen
mit einem Oszillographen gemessen.

Alle SSelfDef-Scopes sind unter dem Verzeichniss Data/Special Scopes zu finden.

zur Hauptseite