Leider gab es lange keine Updates in diesem Blog. Das liegt im wesentlichen daran, daß ich mich in den vergangenen Monaten in Qt und C++ eingearbeitet habe. Darüber nachfolgend ein kurzer Bericht.
Qt ist ein Anwendungsframework und GUI-Toolkit zur plattformübergreifenden Entwicklung von Programmen und grafischen Benutzeroberflächen. Qt setzt das Programmieren in C++ voraus, was ich bisher immer vermeiden konnte. Privat und auch in meinem gesamten Berufsleben kam ich stets mit Ansi‑C aus und habe auch immer die jeweils neuesten Erweiterungen in C95, C99 und zuletzt C11 mitverfolgt und z.T. gerne genutzt. Die Limitierung auf Ansi‑C liegt schlichtweg daran, daß ich im wesentlichen hardwarenahe embedded Programme geschrieben habe und für die wenigen Windows-Programme auch die Win32-API nicht unbedingt C++ verlangt.
Die Win32-API ist naturgemäß nur unter Windows lauffähig, mit Einschränkungen wohl auch mit Wine unter Linux, was ich aber nie getestet habe. Ich bin kein Linux-Jünger und habe nur die eine oder andere virtuelle Ubuntu-Maschine laufen, damit ich da nicht ganz abgehängt werde. Freundlicherweise gibt es Visual Studio von Microsoft für Privatanwendungen kostenlos. Es hat kleine nicht relevante Einschränkungen, mit denen man als Hobbyist gut leben kann. Dennoch möchte ich mich nicht allzu abhängig von Windows machen, schon garnicht, wenn es um meine Hobbyanwendungen geht. Außerdem wird der von mir immer noch verwendete Ressourcen-Editor namens Resedit nicht mehr gewartet. Die Website ist verschwunden. Ein Schwenk auf eine neue und zukunftssichere Cross-Plattform Entwicklungsumgebung war daher überfällig.
Es gibt dafür mehrere Lösungen, die letztendlich für kostensensible Hobbyanwendungen aber nur auf zwei konkurrierende Pakete hinauslaufen, nämlich wxWidgets und Qt. Nach dem Lesen vieler Artikel im Internet habe ich mich für Qt entschieden. Jeder mag persönlich zu einer anderen Entscheidung finden. Klar ist, daß man für jedes Paket mit einer mehrwöchigen oder auch mehrmonatigen Einarbeitungsphase rechnen muß.
Für Qt gibt es viele Youtube-Videos, die mir die Einarbeitung sehr erleichtert haben. Erste Erfolge hat man damit im Grunde in wenigen Stunden oder Tagen, aber bis man sinnvolle Applikationen schreiben kann, wird man doch mehrere Wochen investieren müssen. Bei mir kam noch die neue Programmiersprache C++ hinzu. Sie ist natürlich aus C entstanden und sehr ähnlich, aber die objektorientierte Herangehensweise war mir neu und ist mir immer noch etwas mysteriös. Insbesondere hadere ich damit, daß hinter den Kulissen Dinge passieren, die ich nicht überblicke. Das schöne ist, daß sie funktionieren, aber ich habe oft (noch) kein Gefühl dafür, welche Ressourcen bezüglich CPU-Zeit oder Speicherbedarf eine gewisse Operation benötigt. Vielleicht ist das aber auch eine Krankheit aus der Beschränkung von embedded Systemen, die man einfach überwinden muß. Auf einem PC hat man von allem genug, CPU-Zeit, Speicher und CPU-Kerne. Und wenn nicht, dann wartet man einfach auch die nächste Prozessorgeneration. QStrings sind beispielsweise eine sehr schöne Sache, die ich gerne verwende. Aber wie sie hinter den Kulissen funktionieren, ohne daß man explizit eine maximale Länge angeben muß, wie z.B. bei char-Arrays in C, ist mir im Moment noch ein Rätsel. Der Overhead ist sicherlich nicht gering, aber in einer PC-Umgebung ist das wohl völlig vernachlässigbar. Das sind wahrscheinlich Reflexe aus der Embedded-Programmierung, die man halt einfach überwinden muß.
Zur Dokumentation meines bisherigen Fortschritts sollen hier nur zwei Screenshots eines Kommunikationsprogramms gezeigt werden, das über einen USB-RS485-Konverter mit den an anderer Stelle in diesem Blog vorgestellten Modbus-Geräten (Antennentuner und Antennenumschalter) kommuniziert.
Diagnose-Tab des KommunikationsprogrammsConfig-Tab des Kommunikationsprogramms
Qt unterstützt die Gestaltung der Benutzeroberfläche mit dem Qt Creator und stellt die notwendigen Bibliotheken für das Ziel-Betriebssystem zur Verfügung. Diese Bibliotheken unterstützen nicht nur die grafische Ein- und Ausgabe, sondern z.B. auch die Kommunikation über eine serielle Schnittstelle. Man bindet sich also nirgends direkt an das Betriebssystem.
Als Nachteil empfinde ich im Moment, daß Qt zumindest in der Standardkonfiguration seine Bibliotheken nicht statisch linked. So muß man selbst bei einem kleinen „Hello World“ Programm etwa 10 DLLs mit knapp 50 MB Größe mitliefern. Das macht das Handling etwas schwierig, gerade bei kleinen „Kiki-Programmen“. Da gibt es bestimmt bessere Lösungen, z.B. indem man die DLLs irgendwo zentral speichert und mit einer Environment-Variablen darauf zeigt. Da muß ich noch etwas forschen, hat aber keine hohe Priorität.
Ich bin noch Anfänger bezüglich Qt und C++, aber ich kann Qt auf jeden Fall sehr empfehlen. Meine zukünftigen Projekte werden Qt-basiert sein. Die Unterstützung im Internet lässt keine Wünsche offen.
Nachdem die erste Version des Antennentuners (hier und hier) seit einem Jahr sehr zufriedenstellend läuft, sollte nun eine neue Version mit verbesserten Funktionen gebaut werden. Die erste Version ist ein gefräster Prototyp, der jeweils nur sechs Spulen und Kondensatoren schalten kann. Das ist ausreichend, denn eine ungenügende Anpassung bis zu einem Stehwellenverhältnis von 3 kann der eingebaute Tuner im IC-7300 gut kompensieren. Nun sollte eine mechanisch kompatible Leiterplatte entwickelt werden, die aufgrund ihrer professionellen Fertigung engere Leiterbahnführungen und somit letztlich auch jeweils acht Spulen und Kondensatoren schalten kann. Sie passt damit in das bereits am Antennenmast montierte alte Gehäuse.
Als Steuerung wird wieder das ATMEGA644PA-AU Board (bzw. die geringfügig überarbeitete Variante V1.1) und der dazu passende Relaistreiber in der Version 1.1 eingesetzt. Sie haben sich inzwischen beide gut bewährt und sie sind recht immun gegen HF-Störungen. Auf einem oder zwei Bändern gibt es bei maximaler Ausgangsleistung Kommunikationsfehler, die nach Abschalten der HF wieder verschwinden. Auch Maus und Tastatur am PC haben solche Aussetzer. Das könnten Direkteinstrahlungen von der nur wenige Meter entfernten Drahtantenne sein, es könnte auch an dem mangelhaften Mantelwellenfilter liegen.
Die Induktivitäten und Kapazitäten verdoppeln sich mit jeder Schaltstufe (ungefähr), daher gibt der kleinste Wert jeweils die Schrittweite an. Für die Kondensatoren wurde eine Kaskade von 2,5 pF bis 330 pF gewählt, für die Spulen 80 nH bis 10,24 µH. Wegen der unvermeidlichen parasitären Kapazitäten und Induktivitäten, sind die niedrigsten einstellbaren Werte aber jeweils höher, als die Schrittweite. Die höchsten einstellbaren Impedanzen sind jeweils die Summe der Einzelelemente, zuzüglich der dann nicht mehr ins Gewicht fallenden parasitären Impedanzen.
Die Spulen wurden alle als kernlose Spulen gewickelt, diejenigen mit hohen Induktivitäten zweilagig. Dazu waren die hier gemachten Erfahrungen hilfreich. Kernlose Spulen haben gegenüber Spulen mit Ferritkern generell den Vorteil höherer Güte und höherer Belastbarkeit. Man muß sich um die magnetische Sättigung keine Gedanken machen. Anders als Ferritkernspulen haben kernlose Spulen aber den Nachteil, daß sie wegen der höheren Windungszahl und damit höheren parasitären Kapazitäten eine niedrigere Selbstresonanzfrequenz haben. Gerade bei den höheren Kurzwellenbändern sind daher die großen Spulen nicht mehr nutzbar, normalerweise aber auch nicht notwendig.
Der Tuner ist ganz simpel aufgebaut, nur als jeweils acht kaskadierte Spulen und Kondensatoren. Es gibt keinen Richtkoppler, mit dem ein automatischer Abgleich möglich wäre. Widerstands- und Kondensatorkaskade können unabhängig voneinander mit der Kommunikationssoftware am PC eingestellt werden. Ein während des Abgleichs mitlaufender VNWA zeigt sofort die resultierende Impedanz an. Liegt die möglichst nahe bei 50 Ohm, werden die Einstellungen für das jeweilige Band gespeichert und später im Funkbetrieb wieder gelesen und eingestellt. Damit ist es mit einem 20 m langen Antennendraht auf allen Kurzwellenbändern, inklusive der WARC Bänder und inklusive der 4 m und 6 m Bänder gelungen, das Stehwellenverhältnis auf unter 3, meistens sogar unter 1,5 zu bekommen. Die einzige Ausnahme ist das 160 m Band, für das ein 20 m langer Draht einfach zu kurz ist. Ein Stehwellenverhältnis von 3 oder weniger kann der eingebaute Antennentuner im IC-7300 kompensieren. Im sogenannten Emergency Mode gelingt sogar eine notdürftige Anpassung auf dem 160 m Band. Damit ist immerhin Betrieb mit der halben Maximalleistung möglich, also 50 Watt. Über den Wirkungsgrad dieser Antenne sollte man sich freilich keinen Illusionen hingeben.
Hier noch ein paar Fotos des fertig aufgebauten Tuners
Für den ATMEGA verwende ich z.Zt. Microchip Studio V 7.0 und für die Host Software Visual Studio 2022. Beide Toolpakete sind kostenlos von den Websites der Anbieter (Microchip bzw. Microsoft) herunterzuladen.
Nachdem ich die letzten Wochen damit verdaddelt habe, meinen neuen Notebook soweit herzurichten, daß er wieder mit allen benötigten Programmen rund läuft, komme ich nun endlich dazu, das PC-Interface zum Frequenzzähler zu beschreiben.
Wie bereits im ersten Teil beschrieben, benutzt der Frequenzzähler wieder ein RS485-Interface zur Kommunikation mit dem PC. Das ist ein sehr störsicheres Interface, wenn man längere Strecken bis über 1 km zuverlässig überwinden muß. Daher habe ich es für die Kommunikation mit dem Antennenumschalter und dem Antennentuner verwendet, die immerhin 20 m vom Shack entfernt und höheren HF-Leistungen ausgesetzt sind. Das ist mit USB nicht mehr ohne weiteres zu machen. In diesem Fall ist RS485 aber eher suboptimal, weil der Zähler sowieso nahe am PC betrieben wird und weil immer einen USB-RS485-Umsetzer benötigt wird. Daher plane ich jetzt schon ein Redesign, das dann direkt einen FTDI USB-RS232-Umwandler beinhalten wird. Die entsprechenden Module sind ja für ein bis zwei Euro zu kaufen und auch in dem USB-RS485-Umsetzer verbaut. An der Software wird sich daher nichts ändern.
Die PC-Bedieneroberfläche
Die Bedienersoftware ist wie auch die für den Antennenumschalter und Tuner wieder für einen Windows-PC geschrieben. Der Frequenzzähler meldet sich über den USB-RS485-Umsetzer als COM-Schnittstelle an. Als Interface-Protokoll ist auch hier wieder der ModBus implementiert.
Der nachfolgende Screenshot zeigt die Benutzeroberfläche des Frequenzzählers:
Benutzeroberfläche des Frequenzzählers
Das Hauptfenster oben zeigt die gemessene Frequenz in Hz, die anderen Fenster und Steuerelemente dienen der Konfiguration, die nachfolgend kurz beschrieben werden soll. Es wird übrigens die europäische Zahlennotation angewendet, nach der ein Komma als Dezimaltrennzeichen und ein Punkt als Tausendertrennzeichen verwendet wird.
Fref
Fref ist die tatsächliche Referenzfrequenz in Hertz. Sie kann manuell in diesem Fenster eingegeben werden. Wenn der TCXO verwendet wird, wird die Referenzfrequenz aus der aktuell gemessenen Temperatur und einer hinterlegten Temperaturkurve errechnet.
Fref Precision
Hier wird die Genauigkeit der Referenzfrequenz in ppb (parts per billion = 10-9) angegeben. Daraus wird nach der Messung die Präzision des Meßergebnisses berechnet. Die Genauigkeit der üblichen Quarze und Quarzoszillatoren liegt in der Größenordnung von 10.000 ppb (= 10 ppm) und die Genauigkeit eines GPSDO ist besser als 1 ppb.
Timer Reload und Gate Time
Hier wird Anzahl der Takte zur Bestimmung der Torzeit oder direkt die Torzeit in Millisekunden eingetragen. Bei Änderung eines dieser Felder wird automatisch der andere Wert aus Fref und der Betriebsart (normal oder revers) errechnet.
Counter Temperature
Hier wird die momentane Temperatur des Frequenzzählers angezeigt. Der verwendete Sensor hat ein Genauigkeit von 0.5 K und eine Auflösung von 1⁄16 K. Er ist aber im jetzigen Modul so weit vom eingebauten Quarzoszillator entfernt, daß die Messung der Oszillatortemperatur ziemlich ungenau ist.
Resolution und Precision
In diesen Feldern wird nach der Messung die momentane Frequenzauflösung und die maximale Meßabweichung von der tatsächlichen Frequenz, also die Genauigkeit der Meßergebnisses, angezeigt. Die Frequenzauflösung hängt von den Einstellungen (z.B. der Torzeit) ab, während in die Präzision auch noch die Genauigkeit der Referenzfrequenz eingeht. Die Präzision ist eine Kombination aus dem in „Fref Precision“ eigegebenen Wert und der Frequenzauflösung. Daher ist die Präzision immer schlechter als jeder einzelne dieser Werte.
fref und fcheck Radiobuttons
Mit den fref- und fcheck-Auswahlknöpfen wird die Referenzfrequenz und die zu messende Frequenz ausgewählt. clk0 ist der Oszillator des CPU-Moduls, clk1 und clk2 sind die SMA-Buchsen mit nachfolgendem Vorverstärker und clk3 ist die Frequenz des eingebauten 100 MHz Quarzoszillators. Ein externer Referenzoszillator, z.B. ein GPSDO, wird an clk1 oder clk2 angeschlossen, an den verbleibenden Eingang kommt die zu messende Frequenz.
Prescaler
Mit dem Prescaler wird der Eingangsteiler ausgewählt, der den mit fcheck ausgewählten Takt durch 1, 2, 4 oder 8 teilt. Damit muß sichergestellt werden, daß fcheck kleiner als fref/2 ist.
TCXO
Wird hier ein Haken gesetzt, dann verwendet der Frequenzzähler den Oszillator des CPU-Moduls an clk0 oder den eingebauten Quarzoszillator an clk3 als Referenz und errechnet seine Frequenz anhand der momentanen Temperatur. Dessen Frequenzgang über der Temperatur muß vorher ausgemessen worden sein, wie in dem Beitrag zur Meßdatenanalyse mit LibreOffice beschrieben wurde.
Revers
Wird hier ein Haken gesetzt, arbeitet der Frequenzzähler im Reversbetrieb. Statt fref bestimmt dann fcheck die Torzeit und der Zähler zählt die Anzahl der fref-Takte während dieser Zeit.
Continuous
Ein Haken in diesem Feld führt dazu, daß der Zähler kontinuierlich zählt, statt nach einer Messung aufzuhören.
Open Log
Mit dieser Schaltfläche kann eine Logdatei geöffnet werden, in der im CSV-Format die Meßwerte abgelegt werden. Falls die Datei noch nicht existiert, wird sie neu angelegt, ansonsten fortgeschrieben.
Trigger Measurement
Mit dieser Schaltfläche wird die Messung gestartet und im Falle der kontinuierlichen Messung auch wieder gestoppt.
Remote Device
Hier wird ein optionales, am RS485-Bus angeschlossenes Device adressiert, dessen Betriebstemperatur hier angezeigt und gelogged wird. Zu Testzwecken kann hier auch die Device-ID des Frequenzzählers angegeben werden. Damit wird auch in diesem Feld nochmal dieselbe Temperatur angezeigt, wie unter Counter Temperature.
Beispielmessung
In der ersten Messung wird die Frequenz des eingebauten 100 MHz Quarzoszillators mit einem GPSDO als Referenz gemessen.
Frequenz des eingebauten Quarzoszillators mit GPSDO gemessen.
Der Quarzoszillator ist an clk3 angeschlossen, der GPSDO an clk1. Es wurde eine Torzeit von 1 Sekunde gewählt und der Vorteiler teilt durch 4, damit die zu messende Frequenz niedriger als die halbe Referenzfrequenz ist. Daraus ergibt sich eine Auflösung von 4.0 Hertz. Für höhere Auflösungen muß die Torzeit verlängert werden. Wegen der hohen Genauigkeit des GPSDO von besser als 1 ppm, wird die Präzision des Meßergebnisses von der Auflösung dominiert.
Die nächste Messung mißt die Frequenz des Oszillators auf dem CPU-Board (clk0), die nominal 8 MHz beträgt.
Frequenz des CPU Taktes mit GPSDO gemessen.
Da die Referenzfrequenz weitaus höher ist, als die zu messende Frequenz, kann der Vorteiler auf 1 bleiben. Auch hier ist die Auflösung wieder ein Hertz, weil die Torzeit auf eine Sekunde eingestellt wurde.
Stellt man eine Torzeit von 40 Sekunden ein, dann verbessert sich die Auflösung auf 25 mHz und die Genauigkeit auf 33 mHz, wie der nachfolgende Screenshot zeigt:
Frequenz des CPU Taktes mit GPSDO gemessen. Torzeit 40 Sekunden.
Leider muß man dabei auch 40 Sekunden auf das Ergebnis warten. Man ignoriere hier den Timer Reload Wert. Der wird leider als vorzeichenbehaftete 32-bit Zahl dargestellt.
Damit man bei niedrigen zu messenden Frequenzen auch bei kurzer Meßdauer auf ein gut aufgelöstes Ergebnis kommt, benutzt man den Reversbetrieb. Dabei wird die Dauer der Referenzperiode mit dem hohen Referenztakt ausgemessen. Bei 100 MHz Referenzfrequenz erreicht man also eine Auflösung von 10 ns.
Das hier gezeigte Meßergebnis wurde im Reversbetrieb bei einer Sekunde Meßdauer erzielt. Es erreicht eine Genauigkeit von 88 mHz.
Frequenz des CPU Taktes mit GPSDO gemessen. Reversbetrieb, Torzeit 1 Sekunde.
Durch Verlängern der Meßdauer läßt sich auch im Reversbetrieb die Genauigkeit weiter steigern. Bei 10 Sekunden Meßdauer erreicht man eine Genauigkeit von 16 mHz.
Frequenz des CPU Taktes mit GPSDO gemessen. Reversbetrieb, Torzeit 10 Sekunden.
Verwendet man statt dem hochpräzisen GPSDO den auf dem Frequenzzähler verbauten 100 MHz Oszillator als Referenz, dann ist die Genauigkeit sehr viel geringer.
Frequenz des GPSDO mit eingebautem XO gemessen.
Hier ist der GPSDO auf den Meßeingang geschaltet, der für Amateurzwecke exakt 100 MHz Ausgangsfrequenz hat. Die Messung weicht also um 676 Hz von der tatsächlichen Frequenz ab und liegt damit innerhalb der durch die 10 ppm angegebenen Fehlergrenzen, die eine Abweichung bis 1004 Hz erlauben würden.
Wie oben schon beschrieben, kann der eingebaute Oszillator per Software temperaturkompensiert werden, indem man einen Haken bei TCXO setzt. Dadurch sinkt die Meßabweichung auf etwa 1 Hz, wie der nachfolgende Screenshot zeigt.
Frequenz des GPSDO mit eingebautem TCXO gemessen.
Für schnelle Messungen kann man so also auf den GPSDO verzichten und dennoch sehr genau messen.
Anhang
Nachfolgend werden die mathematischen Formeln zum Berechnen der gemessenen Frequenz und der jeweiligen Auflösung dokumentiert. Hier nochmal als Referenz das Blockdiagramm des Frequenzzählers:
Blockdiagramm des Frequenzzählers
In den unten dokumentierten Formeln werden folgende Bezeichner verwendet:
cntr: Counter-Register, 32 bit
prsc: selprsc[1:0], 2 bit
fref: f_ref, Referenzfrequenz
rld: Timer reload value, 32 bit
gt: gate time (Torzeit) [s]
Δ(f): Frequenzauflösung [Hz]
Hier kommt nun der erste Teil der Beschreibung des Frequenzzählers. Hier soll die Hardware besprochen werden, inklusive der Logik im verwendeten CPLD und der Software des Controllers.
Eine kurze Erwähnung fand der Zähler schon vor ein paar Wochen in der Übersicht der aktuellen Projekte. Dort findet sich auch der Schaltplan und die 3D-Ansicht, beides hier nochmal zum direkten Zugriff:
Der Frequenzzähler basiert wieder auf dem ATMEGA644-CPU-Board mit RS485-Schnittstelle, das sich inzwischen in unterschiedlichen Projekten bewährt hat. Dieses CPU-Board kommuniziert über eine synchrone serielle Schnittstelle mit dem in einem EPM240T100 implementierten Frequenzzähler. Die benötigte Geschwindigkeit ist unkritisch und daher wird diese Kommunikation auf dem CPU-Board über I/O‑Pins implementiert („bit-banging“). Da der EPM240 mit 3,3 V betrieben werden muß und keine 5‑V-toleranten I/O‑Pins hat, wird auch das CPU-Board mit 3,3 V betrieben. Das schränkt die Betriebsfrequenz auf maximal 10 MHz ein. Wegen der geringen Anforderungen an die Geschwindigkeit, wurde ein 8 MHz Quarz eingebaut.
Der Schaltplan zeigt unten die Spannungsversorgung und die Kontroll-LEDs, darüber zwei gleichartige Breitband-Verstärker in klassischer Emitter-Schaltung für den Eingangstakt. Sie sind eingangsseitig mit 50 Ω abgeschlossen und heben den Pegel von etwa 6 dBm (8 mA Treiberstärke) auf den für die CPLD-Takteingänge benötigten Hub von 3.3 V an. Wegen der Schmitt-Trigger-Eingänge darf es auch etwas weniger sein. Acht LEDs und vier DIP-Schalter können optional zur Statusanzeige und zur Konfiguration verwendet werden. Außerdem ist ein 100 MHz Quarzoszillator eingebaut sowie jeweils eine JTAG-Programmierschnittstelle für das CPU-Board und das CPLD.
Funktionsweise
Zur digitalen Bestimmung einer Frequenz gibt es prinzipiell zwei Methoden: man zählt die Anzahl der Takte während eines möglichst genau bekannten Intervalls oder man misst die Zeitdauer zwischen zwei oder mehreren Takten. Die erste Methode wird nachfolgend als Normalbetrieb bezeichnet, die zweite Methode als Reversbetrieb. Beide Verfahren benötigen eine möglichst präzise Referenzfrequenz.
Prinzipiell sind beide Betriebsarten gleichwertig, sie unterscheiden sich aber in der Dauer der Messung. Die Auflösung im Normalbetrieb ist umgekehrt proportional zum Messintervall. Um eine Auflösung von 1 Hz zu erreichen, muß man eine Sekunde lang messen, bei 0,1 Hz Auflösung schon zehn Sekunden. Den 32 kHz Takt einer Uhr kann man auf diese Weise in einer Sekunde also nur auf etwa 30 ppm genau messen (2-15).
Im Reversbetrieb teilt man den Takt der Uhr beispielsweise durch 215 und bekommt so auch ein Intervall von einer Sekunde. Zählt man in der Zeit die Takte einer 100 MHz Referenz, dann erreicht man auf eine Auflösung von 10 ns, was 0,01 ppm = 10 ppb entspricht.
Kurz zusammengefasst: damit das Messintervall kurz gehalten werden kann, wählt man den Normalbetrieb am besten bei hohen Frequenzen im Vergleich zur Referenzfrequenz, den Reversbetrieb bei niedrigen Frequenzen.
Das CPLD
Ein CPLD ist für diese Art von Aufgaben prädestiniert. Es besteht aus einer Anzahl Logik-Elemente, in diesem Fall 240 Blöcke, die weitgehend frei verschaltet werden können und über schnelle Verbindungen zu den Pins verfügen. Anders als die meisten FPGAs, haben CPLDs nichtflüchtige Speicher und müssen daher nicht bei jeden Systemstart neu konfiguriert werden. Man benötigt allerdings ein preiswertes Werkzeug, in diesem (Intel/Altera-) Fall den sogenannten USB-Blaster, um das CPLD in der Schaltung zu programmieren. Das kann man auch mehrfach machen, aber die Anzahl der Programmierzyklen ist auf etwa 100 beschränkt, während der Flash-Speicher einer CPU normalerweise auch 10.000 bis 100.000-mal programmiert werden kann.
Die Logik wird in einer Programmiersprache ähnlich einer Software-Programmiersprache eingegeben. Zwei Sprachen haben sich etabliert, VHDL und Verilog. Verilog hat Elemente der Programmiersprache „C“ und ist für jemanden, der diese Sprache kennt, relativ leicht zu erlernen. Der Unterschied ist freilich, daß Software im wesentlichen sequenziell abgearbeitet wird, während in Hardware vieles gleichzeitig passiert. Wie auch bei der Softwareprogrammierung benötigt man Werkzeuge, die den erstellten Quellcode in ein Binärformat umwandeln, das man in das CPLD laden kann. Diese Werkzeuge stellt der Hersteller der Logikbausteine, gegebenenfalls in einer abgespeckten Version, kostenlos zur Verfügung. Im Falle Intels ist das die „Quartus“-Entwicklungsumgebung, die sogar eine angepasste Version des Mentor ModelSim Simulators enthält, der in der Vollversion auch in der professionellen Chip-Entwicklung verwendet wird.
Blockdiagramm des Frequenzzählers
Genau wie beim Entwurf einer diskret aufgebauten Schaltung, sollte man sich auch bei einem CPLD (oder FPGA) ein Blockdiagramm erstellen, das die Funktionsblöcke darstellt. Die können dann bei Bedarf hierarchisch weiter verfeinert werden, was aber bei dem relativ einfachen Zähler hier nicht notwendig ist.
Blockdiagramm des Frequenzzählers
Dieses Diagramm zeigt nur die Logik des Zählers, nicht das CPU-Interface. Zunächst gibt es die vier Takteingänge clk0 .. clk3, die über den Eingangsmultiplexer verteilt werden. clk1 und clk2 sind über die oben beschriebenen Vorverstärker mit den beiden SMA-Buchsen verbunden und für den Referenztakt und die zu messende Frequenz vorgesehen. clk0 ist fest mit dem CPU-Takt verbunden und clk3 wird von dem 100 MHz Quarzoszillator betrieben.
f_check ist die zu messende Frequenz, die über einen optionalen Vorteiler auf die Referenzfrequenz f_ref synchronisiert wird. Daher muß die Referenzfrequenz mindestens doppelt so hoch sein, wie die ggf. heruntergeteilte zu messende Frequenz. Der Eingangsmultiplexer bestimmt, welcher der vier Takteingänge auf f_check und f_ref geschaltet wird. Es gibt hier keine Einschränkungen, zu Testzwecken kann auch derselbe Takt auf beide Signale geschaltet werden.
Die Referenzfrequenz wird üblicherweise in der Größenordnung von 50 bis 100 MHz liegen und wenn die zu messende Frequenz mehr als halb so hoch ist, muß sie mit dem Prescaler heruntergeteilt werden.
Der eigentliche Zähler besteht aus einem 32-bit breiten Register, dessen Inhalt von der CPU eingelesen werden kann, sinnvollerweise nachdem die Messung beendet ist und der Wert sich nicht mehr ändert. Der ebenfalls 32-bit breite programmierbare Teiler wird beim Start des Meßzyklus mit dem Wert des Timer-Reload-Registers geladen und anschließend heruntergezählt. Er bestimmt damit die Torzeit, also wie lange der Zähler zählen soll. Der Meßzyklus wird beendet, sobald dieser Timer null erreicht. Ein kompletter Meßzyklus besteht aus der Konfiguration des Frequenzzählers (Wahl der Takteingänge, der Betriebsart und Einstellung des Vorteilers), Setzen des Reload-Registers und Triggern der Messung, womit gleichzeitig der Zähler auf null gesetzt wird. Ein Statusflag zeigt an, wenn der Meßzyklus beendet ist und das Ergebnis ausgelesen werden kann.
Timer, Zähler und Steuerlogik liegen in der Clock-Domäne des ausgewählten Referenzsignals, während die von der CPU geschriebenen Konfigurations- und Status-Register in der Clock-Domäne des CPU-Boards liegen (clk0). Die Simulation ergibt eine maximale Eingangsfrequenz von 120 MHz für die Takteingänge des Frequenzzählers und über 50 MHz für das CPU-Interface. Bei Betrieb mit 100 MHz ist man also auf der sicheren Seite und die 32-bit Zähler können dann über 80 Sekunden zählen, ohne überzulaufen.
Im Normalbetrieb wird die Torzeit von der Referenzfrequenz bestimmt und die Anzahl der steigenden Flanken von f_check wird in diesem Intervall gezählt. Im Reversbetrieb bestimmt f_check die Torzeit währenddessen die Anzahl von f_ref Flanken gezählt wird.
Verilog Code
Hier ist nun der Verilog-Code des Frequenzzählers und die notwendigen Projektdateien für die Quartus-Entwicklungsumgebung. Gegebenenfalls müssen Dateipfade angepasst werden.
Das eigentliche Design steckt in der Datei Datei FreqCntr.v, die hinreichend gut kommentiert sein sollte. Zu beachten ist, daß die ursprünglich geplante Parametrisierung über die Parameter COUNTERW, TIMERW und IOREGW nicht konsequent verfolgt wurde. Sie sollten auf ihren Default-Werten bleiben.
FreqCntr_EPM240.v instanziiert den Frequenzzähler für das EPM240 CPLD auf dem Frequenzzähler-Board. Die beiden weiteren Verilog Dateien FreqCntr_tb_Counter.v und FreqCntr_tb_Serial_IO.v enthalten die ModelSim-Testbenches für den Zähler und die serielle CPU-Schnittstelle. Die zugehörigen Skripte tb_Counter.do und tb_Serial_IO.do werden in ModelSim ausgeführt und starten den jeweiligen Test.
Nachtrag: Quartus Prime V21.1
Nachdem ich mir vor ein paar Wochen einen neuen Notebook geleistet habe (der alte war tatsächlich mittlerweile neun Jahre alt), habe ich die jeweils neuesten Versionen der Entwicklungsumgebungen installiert, für CPLDs und FPGAs von Intel (früher Altera) also Quartus V21.1. Dieses Paket beinhaltet nicht mehr Modelsim, sondern dessen Nachfolger Questa (beide von Mentor). Die Bedieneroberfläche ist praktisch gleich geblieben, aber es ist nun eine 64-bit Version und die Simulationsgeschwindigkeit ist beeindruckend (was teilweise auch am neuen Notebook liegen könnte). Leider benötigt diese Version eine zeitlich auf ein Jahr befristete Lizenz, die aber kostenlos ist und danach auch verlängert werden kann.
Folgendes ist zu beachten: die alten mit Modelsim erstellten Projekte sollten durch neue mit Questa erstellte Projekte ersetzt werden. Die alten Projektdateien enthalten Abhängigkeiten, die mit Questa nicht mehr funktionieren. Außerdem muß das „vsim“-Kommando einen Parameter für den Optimizer enthalten (voptargs=“+acc=prn“), damit die Namen der Ports (p), Register (r) und Netze (n) als Debuginformationen erhalten bleiben. Das vollständige vsim-Kommando lautet also beispielsweise folgendermaßen:
vsim <testbench> -voptargs="+acc=prn" -t 1ns
Das sollte dann in den Testbenches tb_*.do entsprechend geändert werden.
ATMEGA644-Code
Die Software, die auf dem ATMEGA644 ausgeführt wird, kann hier als Referenz heruntergeladen werden.
Ich verwende Atmel Studio 7.0 als Entwicklungsumgebung, habe aber keine Projektdateien dazugefügt. Vermutlich hat sowieso jeder seine eigene Philosophie bezüglich der Pfade. Das 7z-Archiv enthält auch eine PDF-Datei mit weiteren Beschreibungen.
Im kommenden zweiten Teil soll die PC-Software zur Bedienung des Frequenzzählers beschrieben werden.
In der Entwicklungsphase des noch zu beschreibenden Frequenzzählers habe ich einige Meßreihen erstellt. Eine davon war der Frequenzgang eines 8 MHz Quarzes auf dem CPU-Board, die andere der Frequenzgang eines 100 MHz Quarzoszillators auf dem Frequenzzähler selbst. Beide Frequenzgänge wurden über die Temperatur gemessen, die mit Kältespray (Butangas, nicht Rauchen, kein offenes Feuer aber offene Fenster!) bzw. einem Föhn geändert wurde.
In beiden Fällen wurde die Temperatur mit dem Temperatursensor auf dem CPU-Board gemessen, einem TMP275. Zwischen ‑40 °C und +125 °C hat er eine Toleranz von +/- 1 °C. Die tatsächliche Temperatur des Quarzes und besonders des Quarzoszillators dürften um einige °C von der gemessenen Temperatur abweichen, weil sie etwas entfernt davon montiert sind. Es soll hier aber nicht um die Präzision der Messung gehen, sondern einzig und allein um die Auswertung mit Libreoffice Calc. Der Frequenzzähler speichert die Meßdaten in einem CSV-File ab, das mit LibreOffice direkt eingelesen werden kann. Die beiden OpenOffice Calc Dateien stehen als Referenz und für eigene Experimente zum Download bereit:
In der ersten Tabelle der jeweiligen Datei stehen die original Meßdaten. Die weiteren Tabellen sind nachfolgend beschrieben.
Auswertung
Zur Auswertung empfiehlt es sich, zunächst eine Pivot-Tabelle („Daten->Pivot-Tabelle->Einfügen) zu erstellen. Als Zeilenfelder wählt man die Temperatur und als Datenfelder die gemessene Frequenz Fcheck. Für die Datenfelder interessiert uns aber nicht die Summe, sondern der Mittelwert. Das muß vor dem Erzeugen der Pivot-Tabelle eingestellt werden. Nun sucht Calc alle in der Tabelle vorkommenden Temperaturen, sortiert sie aufsteigend und ordnet jeder Temperatur den Mittelwert aller für diese Temperatur gefundenen Meßwerte zu. So erhalten wir eine Tabelle der gemittelten Meßwerte von etwa ‑30 °C bis +70 °C (Tabelle: „Pivot-Tabelle“).
Da wir einen 8 MHz bzw. einen 100 MHz Quarzoszillator gemessen haben, liegen alle Meßwerte ziemlich nahe bei 8.000.000 Hz oder 100.000.000 Hz. Ohne vernünftige Skalierung sieht man da nur eine horizontale Linie über der Temperatur. Damit die Meßwerte sinnvoll dargestellt werden können, erstellt man in diesem Fall am besten eine Spalte mit der Differenz der Meßwerte zum Nominalwert, denn alle Werte weichen nur sehr wenig davon ab. Dieses Delta läßt sich dann grafisch über der Temperatur darstellen.
Originaldaten des 8 MHz Quarzoszillators
nur langsame Phase
Originaldaten des 100 MHz Quarzoszillators
nur langsame Phase
Die linken Diagramme zeigen die unveränderten Originaldaten. Man erkennt deutlich den Temperaturgang, aber die vielen Ausreißer sind erschreckend. Die Originaldaten enthalten die sehr schnelle Abkühlphase mit Kältespray und die fast genauso schnelle Aufheizphase mit dem Föhn. Daran schließt sich jeweils eine Phase langsamen Aufheizens bzw. langsamen Abkühlens auf Zimmertemperatur an.
Die rechten Diagramme zeigen nur die langsamen Phasen und die Ausreißer sind hier komplett verschwunden (Tabellen: „Auswahl“ und „Pivot-Tabelle_1“). Die Kurvenform bleibt unverändert. Offensichtlich tun in beiden Fällen die schnellen Temperaturänderungen nicht gut, die Schwingung reißt vermutlich kurzzeitig ab.
Erzeugen einer Ausgleichskurve
Alle weiteren Auswertungen erfolgen nun mit den beiden „langsamen Kurven“, denn sie spiegeln offensichtlich die wahren Verhältnisse. Das Ziel ist nun, die jeweilige Kurve so zu glätten, daß die geglättete Kurve möglichst genau der gemessenen Kurve entspricht, ohne deren Meßabweichungen abzubilden. Die Standardmethode zum Erzeugen einer sogenannten Ausgleichskurve ist die Ausgleichsrechnung. Für ein mathematischen Lösungsverfahren muß dieser Ausgleichsrechnung ein Modell zugrunde liegen. Im allgemeinen Fall ist das ein Polynom der Form
y = a0 + a1 * x + a2 * x2 + … + an * xn
In der Praxis muß man diese Reihe natürlich frühzeitig irgendwo abbrechen, denn sonst wird der Rechenaufwand immer größer. Es sei vorab verraten, daß bei den gezeigten Kurven mindestens ein Polynom dritten Grades nötig ist, also n = 3. Das liegt an den zwei lokalen Minima bzw. Maxima (jeweils grob bei 0 °C und bei 60 °C), bei denen die erste Ableitung des Polynoms null sein muß. Um zwei Nullstellen zu haben, muß die erste Ableitung aber mindestens einen quadratischen Term haben.
Probieren wir dennoch zum Spaß und zu Übungszwecken einfach mal eine Gerade aus, brechen also nach n = 1 ab (Tabelle „Ausgleichsgerade“):
y = a0 + a1 * x
Wir tragen wenn möglich gut erratene Startwerte für die Parameter a0 und a1 in jeweils eine Zelle der Tabelle ein (hier C2 und C3). In eine Spalte (hier: Spalte E) neben den Meßwerten tragen wir dann die Formel für die Gerade ein, mit Bezug auf die Parameter ($C$2 und $C$3) und füllen diese Spalte nach unten auf (obere Zelle und alle Zellen bis zum Ende der Daten auswählen und Strg‑D drücken).
In einer weiteren Spalte berechnen wir dann das Quadrat des Fehlers, den der so errechnete Punkt zum tatsächlich gemessenen Wert hat (hier: Spalte F). Auch diese Spalte füllen wir nach unten auf und errechnen in einer weiteren Zelle (G2) die Summe all dieser Fehlerquadrate. Das Ziel ist nun, a0 und a1 (C2 und C3) so zu bestimmen, daß die Summe der Fehlerquadrate minimal wird.
Von Hand ist das ausgesprochen mühsam, aber zum Glück bietet Calc dafür eine automatische Lösung, den „Solver“. Man startet Extras->Solver und gibt die Zelle mit der Summe der Fehlerquadrate (hier G2) als Zielzelle an. Der Zielwert soll minimal werden und als veränderliche Zellen geben wir C2 und C3 in der Form $C$2:$C$3 an. Der Solver rechnet nun einige Sekunden, denn er muss die Werte in C2 und C3 solange anpassen, bis er einen Minimalwert findet.
8 MHz Quarzoszillator mit Ausgleichsgerade
100 MHz Quarzoszillator mit Ausgleichsgerade
Wie die beiden Diagramme zeigen, findet der Solver nach einigen Sekunden einen plausiblen Wert. Die orange dargestellten Geraden nähern die gemessene Kurve bestmöglich an. Bei nur zwei Variablen und den linearen Eigenschaften einer Geraden kann man auch sicher sein, ein echtes Minimum gefunden zu haben.
Ausgleichskurve mit Polynomen
Die Ausgleichsgerade aus dem vorigen Kapitel ist besser als nichts, aber sie befriedigt nicht wirklich. Für bessere rechnerische Annäherung an die Meßkurve kommt man nicht umhin, höhergradige Polynome zu verwenden. Der Rechenweg unterscheidet sich dabei nicht grundlegend von dem der Ausgleichsgeraden, nur die Formel wird etwas komplizierter. Wir nehmen einfach weitere Terme der Form anxn dazu.
Je größer n wird, je höher also die Ordnung des Polynoms wird, umso genauer können wir die Meßkurve annähern. Probieren wir es der Reihe nach durch, zunächst mit einem Polynom zweiten Grades:
8 MHz Quarzoszillator mit Polynom zweiten Grades
100 MHz Quarzoszillator mit Polynom zweiten Grades
Aus den oben schon genannten Gründen verwundert es nicht, daß das die Meßkurve noch nicht trifft. Wie erwartet gibt es nur einen lokalen Extremwert, ein Minimum bei etwa 20 °C. Versuchen wir es nun mit einem Polynom dritten Grades:
8 MHz Quarzoszillator mit Polynom dritten Grades
100 MHz Quarzoszillator mit Polynom dritten Grades
Damit kommen wir der Form der gemessenen Kurve schon sehr nahe. Gleichzeitig wird die Summe der Fehlerquadrate mit steigendem Grad des Polynoms immer kleiner.
Um es auf die Spitze zu treiben, kann man für den 100 MHz Quarzoszillator auch ein Polynom vierten und fünften Grades ausprobieren, das weitere kleine Verbesserungen bringt:
8 MHz Quarzoszillator mit Polynom vierten Grades
100 MHz Quarzoszillator mit Polynom vierten Grades
8 MHz Quarzoszillator mit Polynom fünften Grades
100 MHz Quarzoszillator mit Polynom fünften Grades
Temperaturkompensation per Software
Das sind nette Spielereien mit einem Spreadsheet-Programm, aber was bringt das ganze nun? Ganz einfach, das so gefundene Polynom gestattet uns eine softwaregesteuerte Temperaturkompensation. Wir können die mutmaßliche tatsächliche Frequenz des Oszillators bei einer bestimmten Temperatur aus seiner Nominalfrequenz annähern.
Das zeigt die Tabelle Poly_n5 für beide Quarzoszillatoren. In der Spalte H wurde die nach der Kompensation verbleibende Abweichung zur gemessenen Frequenz errechnet und in Spalte I in ppm (parts per million) umgerechnet. Die verbleibende Abweichung liegt nun außer an den Temperaturgrenzen bei weniger als 1 ppm. Die unkompensierte Abweichung ist zum Vergleich in Spalte J dargestellt und deren Maximum liegt bei knapp 40 ppm bzw. gut 16 ppm, was für einen mit +/- 25 ppm spezifizierten Quarz auch schon recht gut ist.
8 MHz Quarzoszillator unkompensiert
8 MHz Quarzoszillator temperaturkompensiert
100 MHz Quarzoszillator unkompensiert
100 MHz Quarzoszillator temperaturkompensiert
Man beachte die unterschiedliche Skalierung der y‑Achsen. Von den extremen Temperaturbereichen abgesehen, hat die Temperaturkompensation die Frequenzstabilität also mindestens um den Faktor 10 verbessert. Die deutlichen Abweichungen bei etwa 25 °C liegen an der Meßmethode, denn die Zimmertemperatur war jeweils der Endpunkt der Messungen. Hier gab es mutmaßlich Meßfehler durch den abgesetzten Temperatursensor auf dem CPU Board, der durch die Eigenerwärmung einige Grad mehr anzeigt, als beim Quarz wirklich herrschen.
Suchstrategien
Bei der hier gezeigten Meßdatenanalyse kommt der Calc-Solver schnell an seine Grenzen. Am Ende steht ein Polynom fünfter Ordnung mit sechs unbekannten Parametern a0 .. a5. Der Solver muß im Prinzip alle möglichen Parameter-Werte durchprobieren, die Quadratsumme bilden und versuchen, diese Summe zu minimieren. Ohne halbwegs passend gewählte Startwerte ist das ein Unterfangen, das auf heutigen Rechnern nicht lösbar ist. Der Suchraum ist unendlich groß und der Solver muß ihn auf irgendeine Weise einschränken. Seine Suche gilt als beendet, wenn die Quadratsumme bei jeder kleinen Änderung eines Parameters wieder größer wird. Dabei besteht aber immer die Gefahr, ein lokales Minimum zu finden, das weit weg vom tatsächlichen Minimum liegt. Es kann immer sein, daß hinter den Bergen bei den sieben Zwergen ein Minimum liegt, das tausendmal schöner als das bisher gefundene ist. Man sollte dem Solver also durch geeignete Anfangswerte helfen. Wie macht man das?
Sukzessive Erhöhung des Polynom-Grades
Die einfachste Methode, die hier auch angewendet wurde, ist die sukzessive Erhöhung des Polynom Grades. Man startet mit niedriger Ordnung und lässt den Solver dazu passende Parameter suchen. Geht man schrittweise zu höheren Ordnungen, dann sind diese Parameter zwar nicht mehr ganz richtig, aber auch nicht ganz falsch. Sie sind ein guter Startwert. Man kann auch zunächst mal nur den besten neuen Parameter suchen und erst dann eine weitere Suche über alle bisherigen Parameter starten. So verbessert sich das Ergebnis nach und nach.
Kurvendiskussion
Eine Kurvendiskussion kann beim Erraten günstiger Anfangswerte für die Parameter helfen. Zur Kurvendiskussion benötigt man die Ableitungen der Funktion. Gehen wir zunächst von einem Polynom dritten Grades aus, so ergeben sich folgende Ableitungen:
y = a0 + a1 * x + a2 * x2 + a3 * x3
y‘ = a1 + 2 * a2 * x + 3 * a3 * x2
y“ = 2 * a2 + 6 * a3 * x
Aus der ersten Gleichung erkennt man sofort, daß a0 = y(0) ist, denn wenn x = 0 ist, dann fallen alle anderen Terme weg. a0 ist beim 8 MHz Oszillator also etwa 212 und beim 100 MHz Oszillator etwa 355.
Die erste Ableitung einer Funktion ist an lokalen Extremwerten gleich null. Beim 100 MHz Oszillator finden wir ein lokales Minimum etwa bei x=3 und ein lokales Maximum bei etwa x=60. Mit der ersten Ableitung erhalten wir daraus zwei Gleichungen:
y‘ = a1 + 2 * a2 * 3 + 3 * a3 * 32 = 0
y‘ = a1 + 2 * a2 * 60 + 3 * a3 * 602 = 0
Aus zwei Gleichungen mit drei Unbekannten kann man durch Multiplikation mit einem geeigneten Faktor und anschließender Addition beider Gleichungen eine Gleichung mit zwei Unbekannten machen. Eliminieren wir zunächst a2 durch Multiplikation der ersten Gleichung mit ‑20 und anschließender Addition:
Damit haben wir eine direkte Abhängigkeit zwischen a1 und a3 bzw. a2 und a3 gefunden. Diese beiden Formeln kann man direkt in die Zellen für a1 und a2 eingeben und braucht sie dann nicht mehr in die Liste der Unbekannten für den Solver aufzunehmen. Der Suchraum ist also weiter deutlich eingeschränkt.
Können wir noch mehr tun? Ja klar, wir kennen nun Näherungswerte für a0, a1 und a2 und können die in die Gleichung des Polynoms einsetzen:
y = 355 + 540 * a3 * x – 94,5 * a3 * x2 + a3 * x3
Ohne zu vergessen, daß alles sowieso nur Näherungswerte sind, suchen wir aus der Meßreihe einen Wert x und den zugehörigen Wert y heraus. Dabei versuchen wir einen repräsentativen Wert zu finden, also Sonderfälle an den Temperaturgrenzen und auch die lokalen Extremwerte zu vermeiden. Wie wär’s, mehr oder weniger willkürlich, mit x=40 und y=773? Mit diesen Werten können wir nun einen plausiblen Startwert für a3 ausrechnen:
Aus dieser Gleichung ergibt sich a3 = ‑0,006372 und durch Einsetzen dieses Wertes in die oben schon gefundenen Gleichungen a1 = ‑3,44088 und a2 = 0,602154.
Damit haben wir dem Solver das Leben leichtgemacht. Wir haben plausible Startwerte für alle Parameter des Polynoms dritter Ordnung. Ohne den Solver auch nur zu bemühen, deckt sich diese Kurve schon erstaunlich gut mit der Meßkurve (links):
100 MHz Quarzoszillator mit Polynom dritten Grades aus der Kurvendiskussion
100 MHz Quarzoszillator mit Polynom dritten Grades
Rechts ist nochmal zum Vergleich das oben schon gezeigte Diagramm des mit dem Solver gefundenen Polynoms derselben Ordnung gezeigt. Über große Teile des Diagramms ist die Deckung des von Hand gefundenen Polynoms sogar besser. Allerdings ist die Summe der Fehlerquadrate dennoch höher, denn um den Diagrammteil bei hohen Temperaturen korrekt zu modellieren fehlen die höhergradigen Terme.
Ganz am Schluß kann man dann a0 bis a3 nochmal durch den Solver verbessern lassen. Der findet dabei tatsächlich eine bessere Lösung, als bei der Suche aufs Geratewohl im ersten Ansatz. Die geringste Summe der Fehlerquadrate ergibt sich bei a0 = 339,27, a1 = ‑3,023, a2 = 0,703 und a3 = ‑0,00858.
Mit demselben Vorgehen kann man natürlich auch den Fall des 8 MHz Oszillators nochmal durchspielen, was aber hier keine neuen Erkenntnisse mehr bringt. Das sei daher dem geneigten Leser überlassen.
Anlässlich meiner diversen Designs in den vergangenen Monaten, brauchte ich immer wieder mal die Möglichkeit, einfache Grafiken, Tabellen und Formeln als Text in die Quelltexte der C‑Programme und Verilog-Dateien als Kommentarblöcke einzubetten. Bisher habe ich mehr schlecht als recht mit AACircuit gearbeitet, das allerdings schon reichlich angestaubt ist und auch seine Macken hat. Eine Suche im Internet förderte ein paar sehr hilfreiche Online-Tools zu Tage.
Diagon – ASCII art diagram collection
Diagon (Diagram Online) ist ein Online-Tool, um mathematische Ausdrücke, Tabellen, Flußdiagramme und sonstiges in ASCII- oder UTF-8-Format umzuwandeln. Einfach mal die Website aufrufen und ausprobieren. Man wählt zunächst das Werkzeug aus und kann dann im Eingabefenster die Rohdaten eingeben. Sie werden dann sofort im Ausgabefenster dargestellt und können mit Copy&Paste in den eigenen Code übernommen werden. Für jedes Tool gibt es ein oder mehrere Beispiele, die zeigen, wie es geht.
ASCIIFLOW
ASCIIFLOW ist ein weiteres Online-Tool, das auf das Zeichnen einfacher geometrischer Formen spezialisiert ist. Man kann Rechtecke, Linien und Pfeile zeichnen und natürlich auch Texte eingeben. ASCIIFLOW unterstützt außer dem ASCII-Zeichensatz auch den erweiterten Zeichensatz, der schöne Linien und Ecken darstellen kann. Darüberhinaus kann man das Ergebnis direkt als Kommentare in /* und */ einbetten. Das zeigt, was der Entwickler im Sinn hatte.
Textik
Textik funktioniert ähnlich wie ASCIIFLOW. Auch hier kann man auf einer Leinwand einstellbarer Größe Rechtecke, Linien, Pfeile und Text zeichnen. Anders als ASCIIFLOW kennt Textik unterschiedliche Ebenen in z‑Richtung. Man kann also wählen, ob ein Objekt über oder unter anderen Objekten liegt. Dafür unterstützt Textik aber nur den Standard ASCII Zeichensatz.
Was noch schön wäre…
Ich hätte noch ein Tool gesucht, das einfache (extended-) ASCII-Timing Diagramme darstellen kann. Auch das ist in Quelltexten immer wieder mal nötig. Bisher zeichne ich sowas von Hand, dabei bricht man sich die Finger. Est recht, wenn man daran etwas ändern muß. Wer sowas kennt, kann mich gerne kontaktieren. Ich habe auch schon überlegt, sowas selber zu schreiben.
Die hier beschriebene LibreOffice Tabelle habe ich nun etwas überarbeitet. Ich habe die Struktur grundlegend geändert und die Berechnung um den Skin-Effekt erweitert. Man kann also jetzt auch den Widerstand eines Leiters bei Anlegen einer Wechselspannung bestimmen. Das funktioniert nur angenähert und auch nur bei den Materialien, für die die magnetische Permeabilität verfügbar war. Die neue Tabelle kann hier heruntergeladen werden:
Ich denke daß die Tabelle selbsterklärend ist. Nur die grün hinterlegten Felder müssen ausgefüllt werden. Man wählt das Leitermaterial in B3 und den Querschnitt in B4. Wie in der alten Version kann man Draht (rund), Rohr (rund und hohl) oder Leiterband (rechteckig) auswählen. Dann gibt man die Frequenz, die Temperatur, die Stromstärke (optional) und die Dimensionen an. Darunter werden einige Zwischenergebnisse angezeigt, die man normalerweise nicht braucht, die aber zu Kontrollzwecken nützlich sein können. Die Ergebnisse stehen dann in den Zellen E3 bis I3.
Alles wie immer ohne Gewähr. Wer Fehler findet, möge sie mir bitte mitteilen und ich werde mich um Korrektur bemühen.
Die Anpassung einer endgespeisten Drahtantenne (im englischen als End-Fed-Half-Wave- oder EFHW-Antenne bezeichnet) ist leider nicht so trivial, wie man meinen könnte, insbesondere wenn man mehrere Bänder abdecken möchte. Es geht schon damit los, daß das Verhalten realer Übertrager, auch wenn man sich viel Mühe beim Wickeln macht, in der Regel weit entfernt von dem eines idealen Übertragers ist. Der Koppelfaktor der Windungen liegt deutlich unter 1 und parasitäre Kapazitäten zwischen den Wicklungen machen den Übertrager frequenzabhängig. Darüberhinaus macht die Frequenzabhängigkeit und die magnetische Sättigung des Kernmaterials zu schaffen.
Die Dimensionierung des Übertragers erfordert einige Kompromisse. Zunächst sollte man sich auf die maximal zu übertragende Leistung festlegen. Im Internet findet man Hinweise, daß ein FT-140-Kern für 100 Watt reicht. So pauschal stimmt das aber nicht. Der Crest-Faktor ist bei SSB ein ganz anderer als bei digitalen Betriebsarten. Bei SSB ist die nominale Ausgangsleistung ein Spitzenwert, der nur kurzzeitig erreicht wird, während die gesamte Leistung bei FT‑8 15 Sekunden lang übertragen werden muß, bei WSPR sogar für zwei Minuten, bei RTTY gegebenenfalls sogar noch länger. Messungen mit einer FLIR-Kamera haben gezeigt, daß die Temperatur des Ringkerns meines ersten Anpaßglieds mit einem FT140-77 schon nach kurzem Betrieb (wenige Minuten) mit 50 Watt auf deutlich über 100 °C ansteigt.
Wärmebild des Ringkerns nach wenigen Minuten Belastung mit 50 Watt auf dem 40-m-Band.
So kann das nicht bleiben. Wo liegen die Ursachen und was muß ich ändern?
Nach einer alten Faustregel soll der Blindwiderstand eines Übertragers mindestens viermal so groß sein, wie der reelle Lastwiderstand. Bei 50 Ω auf der Primärseite wären das also mindestens 200 Ω, was bei 7 MHz knapp 5 µH wären. Mit einem FT-140 77 Ringkern wäre diese Induktivität schon bei etwas mehr als einer Windung erreicht. Das ist natürlich schon beim Wickeln der Spule recht unpraktisch, weil ohne Handstand eigentlich nur ganzzahlige Windungszahlen möglich sind. Das größere Problem ist aber die magnetische Flußdichte, die durch den verwendeten Ringkern begrenzt ist. Wird die Flußdichte zu hoch, dann gerät der Kern in die Sättigung und die magnetische Feldstärke im Kern steigt dann nicht mehr proportional zur angelegten Spannung. Das übertragene Signal wird verzerrt und die Kernverluste steigen überproportional, so daß der Kern übermäßig heiß wird.
Die magnetische Flußdichte ist proportional zur angelegten Spannung und umgekehrt proportional zur Windungszahl der Spule. Die maximale Flußdichte, die der Kern verträgt, ist außerdem auch noch frequenzabhängig. Der mini Ringkernrechner berechnet die Flußdichte einer Spule und zeigt freundlicherweise für einige Kerne auch die maximal mögliche Flußdichte an. Der oben genannte Ringkern sollte mindestens 5 Windungen haben, um 100 W auf dem 40-m-Band zu übertragen. Die gewählte Anzahl von 3 Windungen ist also deutlich zu niedrig. Bei 5 Windungen hat die Primärspule aber schon 56 µH und einen Blindwiderstand von 2,5 kΩ. Das wäre auf 40 m bei 7 MHz sicher noch tragbar, aber am anderen Ende bei 29 MHz sind das schon über 10 kΩ und bei den hohen Frequenzen machen sich dann auch die Kapazitäten zwischen den einzelnen Windungen immer deutlicher bemerkbar. Die Windungszahl begrenzt also die obere nutzbare Frequenz des Übertragers. Eine „echter“ Breitbandübertrager ist also immer ein Kompromiß.
Für einen neuen Übertrager habe ich nun zwei gestapelte FT140-43 ausgewählt. Durch das Stapeln halbiert sich der magnetische Fluß für jeden der beiden Kerne und die Induktivität verdoppelt sich, da sich der umwickelte Querschnitt verdoppelt. Der AL-Wert des ‑43-er Kerns ist weniger als halb so groß, wie der des ‑77-er Kerns. Damit ergeben N Windungen auf zwei ‑43-er Kernen etwas weniger Induktivität, als die gleiche Windungszahl auf einem einzigen ‑77-er Kern. Die Flußdichte ist halbiert und liegt bis 100 Watt im 40-m-Band im Rahmen des Erlaubten. Hier ein Foto des ersten Versuchs mit einem Windungsverhältnis von 3:18 (Übertragungsverhältnis 1:36, also 50 Ω am Eingang, 1,8 kΩ am Ausgang):
Übertrager mit zwei FT140-43 Ringkernen
Die letztlich verwendete Version hat ein noch höheres Wicklungsverhältnis von 3:22. Da der bisher verwendete Antennendraht von 18,55 m Länge zu kurz war, habe ich ihn durch einen 20,30 m langen Draht ersetzt. Damit liegt die Resonanz nun deutlich besser auf den Amateurbändern. Die gemessene Impedanz sieht nun folgendermaßen aus:
Impedanz des 20,30 m langen Antennedrahts mit 2xFT140-43 und 100pF Anpassung.
Das Stehwellenverhältnis liegt nun also auf 20- und 40‑m unterhalb von 3:1 und kann vom Antennentuner des IC-7300 angepasst werden. Das 15-m-Band liegt zwar außerhalb, wird aber zumindest im unteren Bereich noch vom Antennentuner erfasst. Das 10-m-Band liegt deutlich außerhalb, funktioniert aber noch im Emergency-Modus mit bis zu 50 Watt Ausgangsleistung.
Nach dem Lehrbuch müssten die oben gezeigten Frequenzen alle im Mittelpunkt des Smith-Charts bei zumindest ungefähr 50 Ω liegen, denn die Bänder sind harmonisch zueinander. Die Abweichungen dürften im wesentlichen an dem immer noch unzulänglichen Übertrager liegen, seinem Kopplungsverhältnis, den parasitären Kapazitäten und den Kernverlusten. Dennoch sieht das Chart realistisch aus, denn nicht-resonante Frequenzen haben hohe Blindanteile. Sie finden sich am Rand des Smith-Diagramms. Bei dem ursprünglichen Übertrager fanden sich fast alle Frequenzen innerhalb des SWV 3:1 Kreises. Das kann nur durch hohe Verluste kommen, denn nur eine Dummy-Load hat über einen großen Frequenzbereich ein Stehwellenverhältnis von 1:1. Eine Aufnahme mit der Wärmebildkamera zeigt, daß sich die Verluste jetzt in Grenzen halten:
Übertrager mit 2xFT140-43 nach mehreren Minuten Betrieb auf 40‑m mit 100 Watt
Auch nach mehreren Minuten Betrieb auf dem 40-m-Band mit 100 Watt steigt die Temperatur nicht mehr wesentlich an. Die Kamera macht zwei Fotos, eines im optischen Bereich und eines im Infrarotbereich, die je nach Abstand des Motivs nicht ganz in Deckung sind.