Hier gibt es einen kleinen Widerstandsrechner für Zweipol-Netzwerke mit den Bauelementen R, L, C und auch G. Das Programm kann die (komplexe) Impedanz einer Schaltung mit Widerständen (bzw. Leitwerten), Induktivitäten und Kapazitäten zu einer bestimmten Frequenz berechnen.
Berechnen Sie die Impedanz folgender Schaltung bei einer Frequenz von 2 kHz.
Allgemein: ((C1 + G1) || (L + G1)) + R
Die Eingabe der Schaltung erfolgt in der gebräuchlichen Schreibweise mit || für Parallelschaltungen und + für Reihenschaltungen, wie wir sie v.a. im ersten und zweiten Semester ständig verwendet haben. Wichtig ist, dass alle Zahlen mit einem Dezimalpunkt statt Komma eingegeben werden! Eine Besonderheit ist, dass man Bauelemente die mehrfach vorkommen (wie hier G1) beim ersten Vorkommen in der Formel definieren kann (G1=2mS) und bei weiteren Vorkommen einfach verwenden kann (auch mit Faktor davor, z.B. 2 R).

Hier gibt es den RLCRechner zum Download. Die Anwendung ist in Java programmiert und liegt in einer JAR-Datei. Unter Windows kann das Programm ganz einfach mit der beiliegenden Batch-Datei gestartet werden, sobald beide Dateien entpackt sind.
Hier ist der Quellcode des Parsers. Die Definition der Zweipol-Klassenhierarchie findet man hier (Uebung 6).
Das (für mich) tolle an dem Programm ist eigentlich nur der Parser, der die Eingabe der Schaltung einliest und umsetzt in eine Composite-Struktur aus Instanzen der Klasse Zweipol.
Die Idee hatte ich schon im ersten oder zweiten Semester (Elektro-/Informationstechnik an der Hochschule München), aber daraus ist damals nichts geworden. Erst jetzt im vierten Semester bin ich wieder darauf gestoßen, als wir im Praktikum Programmieren, Versuch 6 bei Prof. Thomas eine Klassenhierarchie für Zweipole erstellen sollten. So ein Zweipol kann entweder ein konkretes Bauelement sein, oder eine Kombination (Reihen-/Parallelschaltung) aus zwei anderen Zweipolen. (Eine wunderbare Anwendung des Composite Patterns [GoF:163].) Überhaupt der ganze Versuch hat mir gut gefallen: Design Pattern, Wiederverwendung der Klasse Complex aus dem vorherigen Praktikumsversuch, und sehr praxisbezogen.
Der Parser, der die Schaltung einliest, war dabei vorgegeben. Es war extra eine "Schaltungsbeschreibungssprache" definiert, die ich mangels Name PTE-Schaltungsbeschreibung nenne. PTE hat etwas zu tun mit Praktikum Programmieren, Prof. Thomas und dem E, das die Wirkung einer Klammer zu ) hat und wohl für "End" steht. Diese Beschreibungssprache war durch eine Syntax in Backus-Naur-Form definiert. P eröffnet eine Parallel-, S eine Serienschaltung, E "schließt" die Schaltung wieder. Nach R kommt der Wert für einen Widerstand, C und L analog.
P S R 250 C 4.7e-9 E S R 1000 L 9.3e-3 E R 570 E E
entspricht damit
(250 + 4.7 nF) || (1k + 9.3mH) || 570
|| steht für Parallelschaltung, + für Reihenschaltung, bei Widerständen lasse ich die Einheit weg, ansonsten Farad, Henry oder Siemens, SI-Prefixe sind möglich.
Für diese zweite, viel übersichtlichere Form der Schaltungsbeschreibung habe ich jetzt eben einen Parser programmiert! Um auch etwas davon zu haben und den Parser einsetzen zu können, ist eben das Programm RLCRechner enstanden.
Der StandardParser implementiert mein Interface RLCParser, das im Wesentlichen nur die Methode parse deklariert. Der Rückgabewert dieser Funktion ist ein Zweipol. Die Eingabe wird als String übergeben. Damit das Geparse möglichst einfach wird gibt es noch eine Hilfsklasse RLCInputStream. Diese übernimmt aber aus praktischen Gründen die Funktionen peek und poll von Queue (in Java) und erweitert diese. Der RLCInputStream vereinfacht die Algorithmen stark, verglichen mit einem Parser der direkt einen String analysiert.
Die Syntax der Eingabe muss die Folgende sein Backus-Naur-Form (BNF):
reihe ::= paral { + paral }
paral ::= ausdruck { || ausdruck }
ausdruck ::= bauelement | ( reihe )
bauelement ::= widerstand | leitwert | induktivitaet | kapazitaet
widerstand ::= [ faktor ] R [ name ] | [ faktor ] R [ name ] = wert [ sisuffix ]
| wert [ sisuffix ]
leitwert ::= [ faktor ] G [ name ] | [ faktor ] G [ name ] = wert [ sisuffix ] [ masseinheit ]
| wert [ sisuffix ] masseinheit
induktivitaet ::= [ faktor ] L [ name ] | [ faktor ] L [ name ] = wert [ sisuffix ] [ masseinheit ]
| wert [ sisuffix ] masseinheit
kapazitaet ::= [ faktor ] C [ name ] | [ faktor ] C [ name ] = wert [ sisuffix ] [ masseinheit ]
| wert [ sisuffix ] masseinheit
faktor ::= Positive Gleitkommazahl (ohne Vorzeichen), nicht in Exponentialschreibweise!
name ::= literal { literal }
literal ::= { buchstabe | ziffer | _ }
wert ::= Positive Gleitkommazahl
siprefix ::= f | p | n | u | µ | m | k | M | meg | G | T | P
masseinheit ::= Zur Größe passende Masseinheit ([R] = keine, [G] = S, [L] = H, [C] = F)
Zwischen Groß- und Kleinschreibung wird unterschieden! Klammern haben höchste Priorität, dann ||-Schaltungen und als letztes die Reihenschaltung.
Es gibt also Bauelemente ohne Namen, wenn nur der Wert angegeben wird, z.B. 2mH + 5uS. Sobald aber z.B. L = 5m oder C1=5nF vorkommt, ist L bzw. C1 der Name des Bauelements und das rechts vom = der Wert. Ab jetzt kann man den symbolischen Namen wie eine Konstante verwendet werden, z.B. R=1k || R + 2nF || R.
Zusätzlich gibt es jetzt auch noch Faktoren für symbolische Namen, ein paar Beispiele:
Wer es übersichtlicher will und auf diese implizite Zuweisungen verzichten möchte, kann (selbes Parser-Objekt vorrausgesetzt) zuerst die Zuweisungen eingeben und dann die symbolischen Namen verwenden. Die benutzerdefinierten Bauelemente werden nämlich bei jeder Parser-Instanz in einer Hashmap gespeichert (Zuordnung: symbolischer Name, Bauelementwert).
(c) 2011 Jakob Schöttl - Letztes Update: 2011-06-16