Was­ser­fall-Dia­gram­me

Schon vor ein paar Mona­ten habe ich ein klei­nes Pro­gramm geschrie­ben, das eine PNG Gra­fik-Datei in eine Audio-Datei umwandelt.

Die­ses Pro­gramm ist nun soweit, daß man es wei­ter­ge­ben kann. Es hat sicher hier und da noch ein paar Macken, daher will ich das nicht als „Release“ bezeich­nen und blei­be bei einer Ver­si­ons­num­mer klei­ner als 1.0. Es ist eine rei­ne Spielerei.

Hier ist eine etwas detail­lier­te­re Beschrei­bung in englisch.

Die Audio­da­tei lässt sich mit dem VLC Media Play­er abspie­len, der es gestat­tet, einen ande­ren Audio-Aus­gang zu wäh­len, als den Laut­spre­cher am PC. Im Menü Audio -> Audio­ge­rät kann man den Audio-Ein­gang eines ange­schlos­se­nen Trans­cei­vers wäh­len und so die Audio­da­tei direkt senden.

Aber bit­te nicht die Mit­men­schen damit ärgern. Beim ersten- und zwei­ten­mal ist das ganz spa­ßig, aber dann nervt es…

Meß­da­ten­ana­ly­se mit LibreOffice

In der Ent­wick­lungs­pha­se des noch zu beschrei­ben­den Fre­quenz­zäh­lers habe ich eini­ge Meß­rei­hen erstellt. Eine davon war der Fre­quenz­gang eines 8 MHz Quar­zes auf dem CPU-Board, die ande­re der Fre­quenz­gang eines 100 MHz Quarz­os­zil­la­tors auf dem Fre­quenz­zäh­ler selbst. Bei­de Fre­quenz­gän­ge wur­den über die Tem­pe­ra­tur gemes­sen, die mit Käl­te­spray (Butan­gas, nicht Rau­chen, kein offe­nes Feu­er aber offe­ne Fen­ster!) bzw. einem Föhn geän­dert wurde.

In bei­den Fäl­len wur­de die Tem­pe­ra­tur mit dem Tem­pe­ra­tur­sen­sor auf dem CPU-Board gemes­sen, einem TMP275. Zwi­schen ‑40 °C und +125 °C hat er eine Tole­ranz von +/- 1 °C. Die tat­säch­li­che Tem­pe­ra­tur des Quar­zes und beson­ders des Quarz­os­zil­la­tors dürf­ten um eini­ge °C von der gemes­se­nen Tem­pe­ra­tur abwei­chen, weil sie etwas ent­fernt davon mon­tiert sind. Es soll hier aber nicht um die Prä­zi­si­on der Mes­sung gehen, son­dern ein­zig und allein um die Aus­wer­tung mit Libre­of­fice Calc. Der Fre­quenz­zäh­ler spei­chert die Meß­da­ten in einem CSV-File ab, das mit Libre­Of­fice direkt ein­ge­le­sen wer­den kann. Die bei­den Open­Of­fice Calc Datei­en ste­hen als Refe­renz und für eige­ne Expe­ri­men­te zum Down­load bereit:

In der ersten Tabel­le der jewei­li­gen Datei ste­hen die ori­gi­nal Meß­da­ten. Die wei­te­ren Tabel­len sind nach­fol­gend beschrieben.

Aus­wer­tung

Zur Aus­wer­tung emp­fiehlt es sich, zunächst eine Pivot-Tabel­le („Daten->Pivot-Tabelle->Einfügen) zu erstel­len. Als Zei­len­fel­der wählt man die Tem­pe­ra­tur und als Daten­fel­der die gemes­se­ne Fre­quenz Fcheck. Für die Daten­fel­der inter­es­siert uns aber nicht die Sum­me, son­dern der Mit­tel­wert. Das muß vor dem Erzeu­gen der Pivot-Tabel­le ein­ge­stellt wer­den. Nun sucht Calc alle in der Tabel­le vor­kom­men­den Tem­pe­ra­tu­ren, sor­tiert sie auf­stei­gend und ord­net jeder Tem­pe­ra­tur den Mit­tel­wert aller für die­se Tem­pe­ra­tur gefun­de­nen Meß­wer­te zu. So erhal­ten wir eine Tabel­le der gemit­tel­ten Meß­wer­te von etwa ‑30 °C bis +70 °C (Tabel­le: „Pivot-Tabel­le“).

Da wir einen 8 MHz bzw. einen 100 MHz Quarz­os­zil­la­tor gemes­sen haben, lie­gen alle Meß­wer­te ziem­lich nahe bei 8.000.000 Hz oder 100.000.000 Hz. Ohne ver­nünf­ti­ge Ska­lie­rung sieht man da nur eine hori­zon­ta­le Linie über der Tem­pe­ra­tur. Damit die Meß­wer­te sinn­voll dar­ge­stellt wer­den kön­nen, erstellt man in die­sem Fall am besten eine Spal­te mit der Dif­fe­renz der Meß­wer­te zum Nomi­nal­wert, denn alle Wer­te wei­chen nur sehr wenig davon ab. Die­ses Del­ta läßt sich dann gra­fisch über der Tem­pe­ra­tur darstellen.

Die lin­ken Dia­gram­me zei­gen die unver­än­der­ten Ori­gi­nal­da­ten. Man erkennt deut­lich den Tem­pe­ra­tur­gang, aber die vie­len Aus­rei­ßer sind erschreckend. Die Ori­gi­nal­da­ten ent­hal­ten die sehr schnel­le Abkühl­pha­se mit Käl­te­spray und die fast genau­so schnel­le Auf­heiz­pha­se mit dem Föhn. Dar­an schließt sich jeweils eine Pha­se lang­sa­men Auf­hei­zens bzw. lang­sa­men Abküh­lens auf Zim­mer­tem­pe­ra­tur an.

Die rech­ten Dia­gram­me zei­gen nur die lang­sa­men Pha­sen und die Aus­rei­ßer sind hier kom­plett ver­schwun­den (Tabel­len: „Aus­wahl“ und „Pivot-Tabel­le_1“). Die Kur­ven­form bleibt unver­än­dert. Offen­sicht­lich tun in bei­den Fäl­len die schnel­len Tem­pe­ra­tur­än­de­run­gen nicht gut, die Schwin­gung reißt ver­mut­lich kurz­zei­tig ab.

Erzeu­gen einer Ausgleichskurve

Alle wei­te­ren Aus­wer­tun­gen erfol­gen nun mit den bei­den „lang­sa­men Kur­ven“, denn sie spie­geln offen­sicht­lich die wah­ren Ver­hält­nis­se. Das Ziel ist nun, die jewei­li­ge Kur­ve so zu glät­ten, daß die geglät­te­te Kur­ve mög­lichst genau der gemes­se­nen Kur­ve ent­spricht, ohne deren Meß­ab­wei­chun­gen abzu­bil­den. Die Stan­dard­me­tho­de zum Erzeu­gen einer soge­nann­ten Aus­gleichs­kur­ve ist die Aus­gleichs­rech­nung. Für ein mathe­ma­ti­schen Lösungs­ver­fah­ren muß die­ser Aus­gleichs­rech­nung ein Modell zugrun­de lie­gen. Im all­ge­mei­nen Fall ist das ein Poly­nom der Form

y = a0 + a1 * x + a2 * x2 + … + an * xn

In der Pra­xis muß man die­se Rei­he natür­lich früh­zei­tig irgend­wo abbre­chen, denn sonst wird der Rechen­auf­wand immer grö­ßer. Es sei vor­ab ver­ra­ten, daß bei den gezeig­ten Kur­ven min­de­stens ein Poly­nom drit­ten Gra­des nötig ist, also n = 3. Das liegt an den zwei loka­len Mini­ma bzw. Maxi­ma (jeweils grob bei 0 °C und bei 60 °C), bei denen die erste Ablei­tung des Poly­noms null sein muß. Um zwei Null­stel­len zu haben, muß die erste Ablei­tung aber min­de­stens einen qua­dra­ti­schen Term haben.

Pro­bie­ren wir den­noch zum Spaß und zu Übungs­zwecken ein­fach mal eine Gera­de aus, bre­chen also nach n = 1 ab (Tabel­le „Aus­gleichs­ge­ra­de“):

y = a0 + a1 * x

  • Wir tra­gen wenn mög­lich gut erra­te­ne Start­wer­te für die Para­me­ter a0 und a1 in jeweils eine Zel­le der Tabel­le ein (hier C2 und C3). In eine Spal­te (hier: Spal­te E) neben den Meß­wer­ten tra­gen wir dann die For­mel für die Gera­de ein, mit Bezug auf die Para­me­ter ($C$2 und $C$3) und fül­len die­se Spal­te nach unten auf (obe­re Zel­le und alle Zel­len bis zum Ende der Daten aus­wäh­len und Strg‑D drücken).
  • In einer wei­te­ren Spal­te berech­nen wir dann das Qua­drat des Feh­lers, den der so errech­ne­te Punkt zum tat­säch­lich gemes­se­nen Wert hat (hier: Spal­te F). Auch die­se Spal­te fül­len wir nach unten auf und errech­nen in einer wei­te­ren Zel­le (G2) die Sum­me all die­ser Feh­ler­qua­dra­te. Das Ziel ist nun, a0 und a1 (C2 und C3) so zu bestim­men, daß die Sum­me der Feh­ler­qua­dra­te mini­mal wird.

Von Hand ist das aus­ge­spro­chen müh­sam, aber zum Glück bie­tet Calc dafür eine auto­ma­ti­sche Lösung, den „Sol­ver“. Man star­tet Extras->Solver und gibt die Zel­le mit der Sum­me der Feh­ler­qua­dra­te (hier G2) als Ziel­zel­le an. Der Ziel­wert soll mini­mal wer­den und als ver­än­der­li­che Zel­len geben wir C2 und C3 in der Form $C$2:$C$3 an. Der Sol­ver rech­net nun eini­ge Sekun­den, denn er muss die Wer­te in C2 und C3 solan­ge anpas­sen, bis er einen Mini­mal­wert findet.

Wie die bei­den Dia­gram­me zei­gen, fin­det der Sol­ver nach eini­gen Sekun­den einen plau­si­blen Wert. Die oran­ge dar­ge­stell­ten Gera­den nähern die gemes­se­ne Kur­ve best­mög­lich an. Bei nur zwei Varia­blen und den linea­ren Eigen­schaf­ten einer Gera­den kann man auch sicher sein, ein ech­tes Mini­mum gefun­den zu haben.

Aus­gleichs­kur­ve mit Polynomen

Die Aus­gleichs­ge­ra­de aus dem vori­gen Kapi­tel ist bes­ser als nichts, aber sie befrie­digt nicht wirk­lich. Für bes­se­re rech­ne­ri­sche Annä­he­rung an die Meß­kur­ve kommt man nicht umhin, höher­gra­di­ge Poly­no­me zu ver­wen­den. Der Rechen­weg unter­schei­det sich dabei nicht grund­le­gend von dem der Aus­gleichs­ge­ra­den, nur die For­mel wird etwas kom­pli­zier­ter. Wir neh­men ein­fach wei­te­re Ter­me der Form anxn dazu.

Je grö­ßer n wird, je höher also die Ord­nung des Poly­noms wird, umso genau­er kön­nen wir die Meß­kur­ve annä­hern. Pro­bie­ren wir es der Rei­he nach durch, zunächst mit einem Poly­nom zwei­ten Grades:

Aus den oben schon genann­ten Grün­den ver­wun­dert es nicht, daß das die Meß­kur­ve noch nicht trifft. Wie erwar­tet gibt es nur einen loka­len Extrem­wert, ein Mini­mum bei etwa 20 °C. Ver­su­chen wir es nun mit einem Poly­nom drit­ten Grades:

Damit kom­men wir der Form der gemes­se­nen Kur­ve schon sehr nahe. Gleich­zei­tig wird die Sum­me der Feh­ler­qua­dra­te mit stei­gen­dem Grad des Poly­noms immer kleiner.

Um es auf die Spit­ze zu trei­ben, kann man für den 100 MHz Quarz­os­zil­la­tor auch ein Poly­nom vier­ten und fünf­ten Gra­des aus­pro­bie­ren, das wei­te­re klei­ne Ver­bes­se­run­gen bringt:

Tem­pe­ra­tur­kom­pen­sa­ti­on per Software

Das sind net­te Spie­le­rei­en mit einem Spreadsheet-Pro­gramm, aber was bringt das gan­ze nun? Ganz ein­fach, das so gefun­de­ne Poly­nom gestat­tet uns eine soft­ware­ge­steu­er­te Tem­pe­ra­tur­kom­pen­sa­ti­on. Wir kön­nen die mut­maß­li­che tat­säch­li­che Fre­quenz des Oszil­la­tors bei einer bestimm­ten Tem­pe­ra­tur aus sei­ner Nomi­nal­fre­quenz annähern.

Das zeigt die Tabel­le Poly_n5 für bei­de Quarz­os­zil­la­to­ren. In der Spal­te H wur­de die nach der Kom­pen­sa­ti­on ver­blei­ben­de Abwei­chung zur gemes­se­nen Fre­quenz errech­net und in Spal­te I in ppm (parts per mil­li­on) umge­rech­net. Die ver­blei­ben­de Abwei­chung liegt nun außer an den Tem­pe­ra­tur­gren­zen bei weni­ger als 1 ppm. Die unkom­pen­sier­te Abwei­chung ist zum Ver­gleich in Spal­te J dar­ge­stellt und deren Maxi­mum liegt bei knapp 40 ppm bzw. gut 16 ppm, was für einen mit +/- 25 ppm spe­zi­fi­zier­ten Quarz auch schon recht gut ist.

Man beach­te die unter­schied­li­che Ska­lie­rung der y‑Achsen. Von den extre­men Tem­pe­ra­tur­be­rei­chen abge­se­hen, hat die Tem­pe­ra­tur­kom­pen­sa­ti­on die Fre­quenz­sta­bi­li­tät also min­de­stens um den Fak­tor 10 ver­bes­sert. Die deut­li­chen Abwei­chun­gen bei etwa 25 °C lie­gen an der Meß­me­tho­de, denn die Zim­mer­tem­pe­ra­tur war jeweils der End­punkt der Mes­sun­gen. Hier gab es mut­maß­lich Meß­feh­ler durch den abge­setz­ten Tem­pe­ra­tur­sen­sor auf dem CPU Board, der durch die Eigen­er­wär­mung eini­ge Grad mehr anzeigt, als beim Quarz wirk­lich herrschen.

Such­stra­te­gien

Bei der hier gezeig­ten Meß­da­ten­ana­ly­se kommt der Calc-Sol­ver schnell an sei­ne Gren­zen. Am Ende steht ein Poly­nom fünf­ter Ord­nung mit sechs unbe­kann­ten Para­me­tern a0 .. a5. Der Sol­ver muß im Prin­zip alle mög­li­chen Para­me­ter-Wer­te durch­pro­bie­ren, die Qua­drat­sum­me bil­den und ver­su­chen, die­se Sum­me zu mini­mie­ren. Ohne halb­wegs pas­send gewähl­te Start­wer­te ist das ein Unter­fan­gen, das auf heu­ti­gen Rech­nern nicht lös­bar ist. Der Such­raum ist unend­lich groß und der Sol­ver muß ihn auf irgend­ei­ne Wei­se ein­schrän­ken. Sei­ne Suche gilt als been­det, wenn die Qua­drat­sum­me bei jeder klei­nen Ände­rung eines Para­me­ters wie­der grö­ßer wird. Dabei besteht aber immer die Gefahr, ein loka­les Mini­mum zu fin­den, das weit weg vom tat­säch­li­chen Mini­mum liegt. Es kann immer sein, daß hin­ter den Ber­gen bei den sie­ben Zwer­gen ein Mini­mum liegt, das tau­send­mal schö­ner als das bis­her gefun­de­ne ist. Man soll­te dem Sol­ver also durch geeig­ne­te Anfangs­wer­te hel­fen. Wie macht man das?

Suk­zes­si­ve Erhö­hung des Polynom-Grades

Die ein­fach­ste Metho­de, die hier auch ange­wen­det wur­de, ist die suk­zes­si­ve Erhö­hung des Poly­nom Gra­des. Man star­tet mit nied­ri­ger Ord­nung und lässt den Sol­ver dazu pas­sen­de Para­me­ter suchen. Geht man schritt­wei­se zu höhe­ren Ord­nun­gen, dann sind die­se Para­me­ter zwar nicht mehr ganz rich­tig, aber auch nicht ganz falsch. Sie sind ein guter Start­wert. Man kann auch zunächst mal nur den besten neu­en Para­me­ter suchen und erst dann eine wei­te­re Suche über alle bis­he­ri­gen Para­me­ter star­ten. So ver­bes­sert sich das Ergeb­nis nach und nach.

Kur­ven­dis­kus­si­on

Eine Kur­ven­dis­kus­si­on kann beim Erra­ten gün­sti­ger Anfangs­wer­te für die Para­me­ter hel­fen. Zur Kur­ven­dis­kus­si­on benö­tigt man die Ablei­tun­gen der Funk­ti­on. Gehen wir zunächst von einem Poly­nom drit­ten Gra­des aus, so erge­ben sich fol­gen­de 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 Glei­chung erkennt man sofort, daß a0 = y(0) ist, denn wenn x = 0 ist, dann fal­len alle ande­ren Ter­me weg. a0 ist beim 8 MHz Oszil­la­tor also etwa 212 und beim 100 MHz Oszil­la­tor etwa 355.

Die erste Ablei­tung einer Funk­ti­on ist an loka­len Extrem­wer­ten gleich null. Beim 100 MHz Oszil­la­tor fin­den wir ein loka­les Mini­mum etwa bei x=3 und ein loka­les Maxi­mum bei etwa x=60. Mit der ersten Ablei­tung erhal­ten wir dar­aus zwei Gleichungen:

y‘ = a1 + 2 * a2 * 3 + 3 * a3 * 32 = 0

y‘ = a1 + 2 * a2 * 60 + 3 * a3 * 602 = 0

Aus zwei Glei­chun­gen mit drei Unbe­kann­ten kann man durch Mul­ti­pli­ka­ti­on mit einem geeig­ne­ten Fak­tor und anschlie­ßen­der Addi­ti­on bei­der Glei­chun­gen eine Glei­chung mit zwei Unbe­kann­ten machen. Eli­mi­nie­ren wir zunächst a2 durch Mul­ti­pli­ka­ti­on der ersten Glei­chung mit ‑20 und anschlie­ßen­der Addition:

‑20 * (a1 + 2 * a2 * 3 + 3 * a3 * 32) + a1 + 2 * a2 * 60 + 3 * a3 * 602 = 0

ergibt nach Auflösung:

a1 = 540 * a3

Durch Mul­ti­pli­ka­ti­on mit ‑1 und anschlie­ßen­der Addi­ti­on lässt sich alter­na­tiv a1 eliminieren:

a1 + 2 * a2 * 60 + 3 * a3 * 602 – (a1 + 2 * a2 * 3 + 3 * a3 * 32) = 0

und nach Ausmultiplizieren

a2 = ‑94,5 * a3

Damit haben wir eine direk­te Abhän­gig­keit zwi­schen a1 und a3 bzw. a2 und a3 gefun­den. Die­se bei­den For­meln kann man direkt in die Zel­len für a1 und a2 ein­ge­ben und braucht sie dann nicht mehr in die Liste der Unbe­kann­ten für den Sol­ver auf­zu­neh­men. Der Such­raum ist also wei­ter deut­lich eingeschränkt.

Kön­nen wir noch mehr tun? Ja klar, wir ken­nen nun Nähe­rungs­wer­te für a0, a1 und a2 und kön­nen die in die Glei­chung des Poly­noms einsetzen:

y = 355 + 540 * a3 * x – 94,5 * a3 * x2 + a3 * x3

Ohne zu ver­ges­sen, daß alles sowie­so nur Nähe­rungs­wer­te sind, suchen wir aus der Meß­rei­he einen Wert x und den zuge­hö­ri­gen Wert y her­aus. Dabei ver­su­chen wir einen reprä­sen­ta­ti­ven Wert zu fin­den, also Son­der­fäl­le an den Tem­pe­ra­tur­gren­zen und auch die loka­len Extrem­wer­te zu ver­mei­den. Wie wär’s, mehr oder weni­ger will­kür­lich, mit x=40 und y=773? Mit die­sen Wer­ten kön­nen wir nun einen plau­si­blen Start­wert für a3 ausrechnen:

773 = 355 + 540 * a3 * 40 – 94,5 * a3 * 402 + a3 * 403

Aus die­ser Glei­chung ergibt sich a3 = ‑0,006372 und durch Ein­set­zen die­ses Wer­tes in die oben schon gefun­de­nen Glei­chun­gen a1 = ‑3,44088 und a2 = 0,602154.

Damit haben wir dem Sol­ver das Leben leicht­ge­macht. Wir haben plau­si­ble Start­wer­te für alle Para­me­ter des Poly­noms drit­ter Ord­nung. Ohne den Sol­ver auch nur zu bemü­hen, deckt sich die­se Kur­ve schon erstaun­lich gut mit der Meß­kur­ve (links):

Rechts ist noch­mal zum Ver­gleich das oben schon gezeig­te Dia­gramm des mit dem Sol­ver gefun­de­nen Poly­noms der­sel­ben Ord­nung gezeigt. Über gro­ße Tei­le des Dia­gramms ist die Deckung des von Hand gefun­de­nen Poly­noms sogar bes­ser. Aller­dings ist die Sum­me der Feh­ler­qua­dra­te den­noch höher, denn um den Dia­gramm­teil bei hohen Tem­pe­ra­tu­ren kor­rekt zu model­lie­ren feh­len die höher­gra­di­gen Terme.

Ganz am Schluß kann man dann a0 bis a3 noch­mal durch den Sol­ver ver­bes­sern las­sen. Der fin­det dabei tat­säch­lich eine bes­se­re Lösung, als bei der Suche aufs Gera­te­wohl im ersten Ansatz. Die gering­ste Sum­me der Feh­ler­qua­dra­te ergibt sich bei a0 = 339,27, a1 = ‑3,023, a2 = 0,703 und a3 = ‑0,00858.

Mit dem­sel­ben Vor­ge­hen kann man natür­lich auch den Fall des 8 MHz Oszil­la­tors noch­mal durch­spie­len, was aber hier kei­ne neu­en Erkennt­nis­se mehr bringt. Das sei daher dem geneig­ten Leser überlassen.

Gesagt getan…

Wie bereits im vori­gen Bei­trag über nütz­li­che Web­sites in Aus­sicht gestellt, habe ich nun doch ein klei­nes Pro­gramm zum Erstel­len von Timing Dia­gram­men im Text-For­mat geschrie­ben: Draw­Ti­ming­Dia­gram.

Das Pro­gramm öff­net ein Ein­ga­be- und ein Aus­ga­be­fen­ster. In das Ein­ga­be­fen­ster kön­nen Kom­man­dos geschrie­ben wer­den, die beim Klick auf den Start-Knopf in ein Timing-Dia­gramm im Aus­ga­be­fen­ster umge­wan­delt wer­den. Ein klei­nes Bei­spiel zeigt der fol­gen­de Screenshot:

Das so erzeug­te Dia­gramm kann über das Clip­board aus dem Aus­ga­be­fen­ster in eine UTF8-Text­da­tei über­nom­men werden.

Eine kur­ze Beschrei­bung der unter­stütz­ten Ein­ga­be­kom­man­dos mit einem etwas kom­ple­xe­ren Timing Dia­gramm Bei­spiel fin­det sich in der Online-Hil­fe.

Nütz­li­che Websites

Anläss­lich mei­ner diver­sen Designs in den ver­gan­ge­nen Mona­ten, brauch­te ich immer wie­der mal die Mög­lich­keit, ein­fa­che Gra­fi­ken, Tabel­len und For­meln als Text in die Quell­tex­te der C‑Programme und Veri­log-Datei­en als Kom­men­tar­blöcke ein­zu­bet­ten. Bis­her habe ich mehr schlecht als recht mit AACir­cuit gear­bei­tet, das aller­dings schon reich­lich ange­staubt ist und auch sei­ne Macken hat. Eine Suche im Inter­net för­der­te ein paar sehr hilf­rei­che Online-Tools zu Tage.

Dia­gon – ASCII art dia­gram collection

Dia­gon (Dia­gram Online) ist ein Online-Tool, um mathe­ma­ti­sche Aus­drücke, Tabel­len, Fluß­dia­gram­me und son­sti­ges in ASCII- oder UTF-8-For­mat umzu­wan­deln. Ein­fach mal die Web­site auf­ru­fen und aus­pro­bie­ren. Man wählt zunächst das Werk­zeug aus und kann dann im Ein­ga­be­fen­ster die Roh­da­ten ein­ge­ben. Sie wer­den dann sofort im Aus­ga­be­fen­ster dar­ge­stellt und kön­nen mit Copy&Paste in den eige­nen Code über­nom­men wer­den. Für jedes Tool gibt es ein oder meh­re­re Bei­spie­le, die zei­gen, wie es geht.

ASCIIFLOW

ASCIIFLOW ist ein wei­te­res Online-Tool, das auf das Zeich­nen ein­fa­cher geo­me­tri­scher For­men spe­zia­li­siert ist. Man kann Recht­ecke, Lini­en und Pfei­le zeich­nen und natür­lich auch Tex­te ein­ge­ben. ASCIIFLOW unter­stützt außer dem ASCII-Zei­chen­satz auch den erwei­ter­ten Zei­chen­satz, der schö­ne Lini­en und Ecken dar­stel­len kann. Dar­über­hin­aus kann man das Ergeb­nis direkt als Kom­men­ta­re in /* und */ ein­bet­ten. Das zeigt, was der Ent­wick­ler im Sinn hatte.

Tex­tik

Tex­tik funk­tio­niert ähn­lich wie ASCIIFLOW. Auch hier kann man auf einer Lein­wand ein­stell­ba­rer Grö­ße Recht­ecke, Lini­en, Pfei­le und Text zeich­nen. Anders als ASCIIFLOW kennt Tex­tik unter­schied­li­che Ebe­nen in z‑Richtung. Man kann also wäh­len, ob ein Objekt über oder unter ande­ren Objek­ten liegt. Dafür unter­stützt Tex­tik aber nur den Stan­dard ASCII Zeichensatz.

Was noch schön wäre…

Ich hät­te noch ein Tool gesucht, das ein­fa­che (exten­ded-) ASCII-Timing Dia­gram­me dar­stel­len kann. Auch das ist in Quell­tex­ten immer wie­der mal nötig. Bis­her zeich­ne ich sowas von Hand, dabei bricht man sich die Fin­ger. Est recht, wenn man dar­an etwas ändern muß. Wer sowas kennt, kann mich ger­ne kon­tak­tie­ren. Ich habe auch schon über­legt, sowas sel­ber zu schreiben.

RS-485 Kom­mu­ni­ka­ti­ons­soft­ware

Hier soll nun kurz die Soft­ware beschrie­ben wer­den, über die ein Win­dows PC mit den Bus­teil­neh­mern über RS-485 kom­mu­ni­ziert. Es wur­de das freie und weit ver­brei­te­te Mod­bus-RTU-Pro­to­koll ver­wen­det. Es ist gut doku­men­tiert, wegen Pari­ty und 16-bit CRC hin­rei­chend feh­ler­re­si­stent und es gibt mit QMod­Ma­ster ein frei­es Win­dows-Pro­gramm, das bei der Imple­men­tie­rung und Feh­ler­su­che sehr hilf­reich ist. Sowohl für den Win­dows-PC wie auch für das Ardui­no Bio­top gibt es fer­ti­ge Software.

Vor­be­mer­kun­gen

Mit Ardui­no habe ich selbst nichts zu tun, ein­fach weil es das noch nicht gab, als ich zum ersten­mal mit Atmel Bau­stei­nen gear­bei­tet habe. Gele­gent­lich wer­de ich mir das mal anschau­en. Die Mod­bus-Biblio­thek für Win­dows habe ich mir einen hal­ben Tag lang ange­schaut und sie nicht zum Lau­fen bekom­men. Sie ist sicher gut und kann alles, aber die paar Funk­tio­nen die ich brau­che, habe ich dann doch sel­ber geschrie­ben. Das schien mir schnel­ler zu gehen, zumal die Funk­tio­nen auf der Gegen­sei­te, dem Atmel Bau­stein, schon fer­tig war und sich nicht grund­sätz­lich unter­schei­det. Damit ist nun die kom­plet­te Soft­ware sowohl auf der Host- wie auf der Device-Sei­te selbst­ge­schrie­ben und kann hier ohne Ein­schrän­kun­gen im Quell­text ver­öf­fent­licht werden:

Quell­text der Host-Software

Quell­text der Device-Soft­ware für den ATMEGA644PU

Wer will, kann bei­des ger­ne unein­ge­schränkt wei­ter­be­nut­zen, eine Garan­tie für die feh­ler­freie Funk­ti­on gibt’s natür­lich nicht. Es sind sicher­lich hier und da noch Feh­ler ein­ge­baut. Außer­dem ist nur ein Sub­set des Mod­bus-Pro­to­kolls imple­men­tiert, auch die eine oder ande­re Funk­ti­on, die in der Spec als „man­da­to­ry“ bezeich­net wird, ist nicht vor­han­den (z.T. imple­men­tiert, aber aus­kom­men­tiert da ungetestet).

Als Ent­wick­lungs­um­ge­bung für Atmel ver­wen­de ich „Atmel Stu­dio 7.0“, für Win­dows „VS Express 2013“. Bei­de Ver­sio­nen sind etwas älter, Atmel gehört inzwi­schen zu Micro­chip, und von VS Express gibt es neue­re Ver­sio­nen, die aber nicht mehr mit Win­dows 7 lau­fen, son­dern Win­dows 10 benö­ti­gen. Soll­te ich jemals auf Win 10 umstei­gen, wer­de ich mir eine neue­re Ver­si­on besor­gen. Es gibt im Moment für mich kei­nen Grund zum Umsteigen.

Bei­de Pro­gram­me sind sehr spe­zi­fisch für mei­nen Anwen­dungs­fall geschrie­ben, daher habe ich auch kei­ne aus­führ­ba­re Datei bei­gefügt. Die Quell­tex­te sol­len als Muster die­nen, wie man es machen kann, aber nicht muß. Das Win­dows Pro­gramm mag gleich­zei­tig als Bei­spiel die­nen, wie man die seri­el­le Schnitt­stel­le mit Win­dows-Funk­tio­nen bedient.

Alle Pro­gram­me sind in ANSI‑C geschrie­ben, der ATMEGA nutzt ein paar win­zi­ge Assem­bler-Funk­tio­nen. Für Win­dows wird ledig­lich das Win32-API ver­wen­det und ResE­dit als Res­sour­cen Edi­tor, weil die kosten­lo­se Ver­si­on von VS Express zumin­dest bis 2013 kei­nen Res­sour­cen Edi­tor dabei hatte.

Host-Soft­ware

Ganz phan­ta­sie­los habe ich die Host-Soft­ware Ser­Com genannt. Da zur Zeit nur der Anten­nen­um­schal­ter ange­schlos­sen ist, ist dies der erste Tab, der nach dem Start ange­zeigt wird:

Tab Antennenumschalter
Die Bedie­nung des Antennenumschalters

Hier wird ledig­lich eine der bis zu sechs Anten­nen aus­ge­wählt. Die Namen sind in der Regi­s­try kon­fi­gu­rier­bar und oben nur Bei­spiel ohne rea­le Bedeu­tung. Die momen­tan akti­ve Anten­ne wird mit dem Icon ange­zeigt, nur eine kann zu einem Zeit­punkt aktiv sein. Port Sta­tus ist eigent­lich eine ver­zicht­ba­re Dia­gno­se­mel­dung. Hier wird der phy­si­ka­li­sche Sta­tus des Ports A ange­zeigt, der die Relais ansteu­ert. Die bei­den Tabs „Rotor“ und „Anten­nen­tu­ner“ sind leer und hier nur Platz­hal­ter für zukünf­ti­ge Steue­run­gen, die am sel­ben Bus hän­gen sollen.

Mit dem Con­fig-Tab wird einer der Bus­teil­neh­mer konfiguriert:

SerCom Config
Ser­Com Config

Beim Start ohne Para­me­ter wer­den hier die Kon­fi­gu­ra­ti­ons­da­ten des PCs und des aus­ge­wähl­ten Devices ange­zeigt, also Baud­ra­te, Device ID und ver­wen­de­ter COM-Port. Wird Ser­Comm mit dem Par­am­ter „-c“ gestar­tet, läuft es im Kon­fi­gu­ra­ti­ons­mo­dus und die hier dun­kel geschal­te­ten Fel­der wer­den weiß und kön­nen geän­dert wer­den. In die­sem Tab wird ein Zäh­ler gezeigt, der angibt, wie oft das EEPROM pro­gram­miert wur­de, denn die Anzahl der Pro­gram­mier­zy­klen ist end­lich (aller­dings wer­den min­de­stens 100k-Zyklen garantiert).

Auch eine Uhr ist imple­men­tiert, deren Datum und Uhr­zeit hier gesetzt und aus­ge­le­sen wer­den kön­nen. Mit dem Wert bei „RTC cor­rec­tion“ kann im Con­fig-Modus ein Kor­rek­tur­wert ein­ge­ge­ben wer­den, mit dem eine Fre­quenz­ab­wei­chung des Quar­zes für die Uhr­zeit kom­pen­siert wird. Mit „Restart Device“ wird auf dem Device ein Watch­dog Reset pro­vo­ziert, also ein ech­ter Hard­ware-Reset. „Refresh“ liest die ange­zeig­ten Daten erneut aus dem Device aus.

Der Dia­gno­se-Tab zeigt eini­ge Daten an, die etwas über den Gesund­heits­zu­stand des Devices aussagen:

SerCom Diagnose
Ser­Com Diagnose

Zunächst wird der Typ des Moduls, sei­ne Takt­fre­quenz und die Ver­si­on der imple­men­tier­ten Soft­ware ange­zeigt. Ver­schie­de­ne Zäh­ler zei­gen dann die Anzahl der unter­schied­li­chen Resets, die Anzahl feh­ler­frei emp­fan­ge­ner eige­ner und frem­der Nach­rich­ten und die Anzahl von Kom­mu­ni­ka­ti­ons­feh­lern an. Auch die Ver­sor­gungs­span­nung und die Tem­pe­ra­tur auf der Device-Sei­te wer­den ange­zeigt. Trotz des nur etwa 30mA gro­ßen Ver­sor­gungs­stroms erwärmt sich das Board merk­lich. Nun­ja, bei 12V sind es ja auch immer­hin 360 mW. Der Tem­pe­ra­tur­sen­sor (TMP275) hat übri­gens eine Genau­ig­keit von 0.5 K und 116 K Auf­lö­sung. Daß drei Stel­len hin­ter dem Kom­ma ange­zeigt wer­den, deu­tet eine höhe­re Genau­ig­keit an.

Außer­dem wer­den die Namen und Zeits­tem­pel der Quell­da­tei­en und der Zeit­punkt des Com­pi­ler­laufs ange­zeigt. Auch hier lässt sich mit der Refresh-Taste der ange­zeig­te Inhalt erneu­ern. Durch Anklicken der „Con­ti­nuous“ Check­box wird der Refresh dau­er­haft aus­ge­führt. Das ist für Dau­er­tests hilf­reich. Ein über Nacht aus­ge­führ­ter Dau­er­test brach­te kei­nen ein­zi­gen Feh­ler her­vor. Daß die Feh­lerzäh­ler funk­tio­nie­ren, zeig­te aller­dings ein erster Test mit 100 W HF auf dem Antennenumschalter.

Seit eini­gen Tagen und Näch­ten ist die Soft­ware im Ein­satz und hat sich bewährt. Für das Inter­face zwi­schen dem USB-RS485-Wand­ler und dem Bus habe ich auch zum Ein­kop­peln der 12V Ver­sor­gungs­span­nung eine klei­ne Box gebaut:

RS485-PC-Box
RS485 PC-Inter­face Box.

Sie fügt noch­mal klei­ne Tief­päs­se in die Kom­mu­ni­ka­ti­ons­lei­tung ein und ent­stört die Ver­sor­gungs­span­nung eines exter­nen Stecker­netz­teils. Das Gehäu­se ist übri­gens ein sehr preis­wer­tes Euro­box-Gehäu­se, das ich auch für ande­re Din­ge ger­ne verwende.

Free Soft­ware Utilities

Here you can down­load some of my uti­li­ties. This site replaces the for­mer down­load page. I will publish any new ver­si­on or new uti­li­ty here. It is just easier to main­tain. Plea­se check the Free­ware Archi­ve for older versions.

Par­Ser:

Par­Ser is a uti­li­ty to con­struct a non-stan­dard resi­stance or capa­ci­tance value from a set of stan­dard resi­stors or capa­ci­tors. Par­Ser sup­ports dif­fe­rent topo­lo­gies of up to three indi­vi­du­al com­pon­ents. Par­Ser can also cal­cu­la­te vol­ta­ge divi­ders and find a set of sui­ta­ble resi­stors. The mini­mum and maxi­mum shunt cur­rent can be spe­ci­fied as well as the nomi­nal load current.

ParSer_Executables (Ver. 1.04)
(MD5: db6a4d42687d77bbd5b16bc5535885cd)

ParSer_Source (Ver. 1.04)
(MD5: b91cf916b63fe6ff60446dbd9a3bafa1)

Chan­ge histo­ry:
V1.04, Dec 2021: Com­pi­led with Visu­al Stu­dio 2019, fixed some Code Ana­ly­sis com­p­laints, no func­tio­n­al changes

Here is the Par­Ser Online Help.

The name Par­Ser is mis­lea­ding. It stands for parallel/serial con­nec­tion of resi­stors or capa­ci­tors. I’m not very hap­py myself with this name, but now it’s out and I’m not going to chan­ge it.

Bin2C:

Bin2C is a uti­li­ty to con­vert bina­ry files to C source code. It pro­vi­des a simp­le way to inclu­de bina­ry files (e.g. images or audio files) in embed­ded pro­jects, which often do not sup­port any file system.

Here is the Bin2C Online Help.

Bin2C Exe­cu­ta­bles (Ver. 2.20)
(MD5: 2b15117dbbf2da5538f361995489911c)

Bin2C Source Files (Ver. 2.20)
(MD5: 0b4afb75ef4f1bcd84b694aae88b57e5)

Chan­ge histo­ry:
V2.20, Dec 2021: Com­pi­led with Visu­al Stu­dio 2019, fixed some Code Ana­ly­sis com­p­laints, no func­tio­n­al changes

Draw­Ti­ming­Dia­gram:

During my recent (most­ly Veri­log) deve­lo­p­ments, I felt the need for a simp­le timing dia­gram gene­ra­tor with text out­put. Such a thing is very hel­pful to docu­ment the beha­vi­or of modu­les insi­de the source code rather than in a sepa­ra­te file. For this pur­po­se I wro­te Draw­Ti­ming­Dia­gram. Here is the Draw­Ti­ming­Dia­gram Online Help.

Draw­Ti­ming­Dia­gram Exe­cu­ta­bles (V1.01)
(MD5: 0804e03edbd13f2c3636ca45d665f97d)

Draw­Ti­ming­Dia­gram Source (V1.01)
(MD5: eacfe0247ae02b65f7ac00b8b3b230b9)

Chan­ge histo­ry:
V1.01, Dec 2021: Initi­al release

Water­fall:

Most­ly all modern ama­teur radio trans­cei­vers are soft­ware defi­ned radi­os (SDR). As such, they come with a built-in water­fall dia­gram dis­play, which in turn invi­tes for stu­pid and useless expe­ri­ments. Sin­ce reti­red, I have time for a litt­le fun and I wro­te a small pro­gram, which con­verts a PNG gra­phics file to a wave file. That wave file can be trans­mit­ted and it gene­ra­tes a water­fall dis­play, which resem­bles the PNG input file. This is strict­ly for fun and shall not be used to annoy anyo­ne, so use it at your own dis­cre­ti­on. Here is a sample:

The result is obvious­ly limi­ted by the low fre­quen­cy- and ampli­tu­de-reso­lu­ti­on of the water­fall dia­gram. Any­way, it works.

The­re is no help file, but the ope­ra­ti­on should be self-explana­to­ry. Here is the user dialog:

Waterfall User Dialog
Water­fall User Dialog

Time per row spe­ci­fies the trans­mit dura­ti­on of one PNG row. The total trans­mit time is the num­ber of rows mul­ti­plied by this value. The ramp spe­ci­fies the dura­ti­on for line­ar­ly fading in and out a sin­gle row. Without such ramps, the signal will beco­me rather dis­tor­ted due to many harmonics.

Here are the down­load files:

Water­fall Exe­cu­ta­bles (V0.2)
(MD5: 32da4134da5e065e32fb29a80bce781c)

Water­fall Source (V0.2)
(MD5: 301307cec175a78f445043aa23769e99)

Note that the­re are a num­ber of dif­fe­rent PNG file for­mats and not all of them are sup­por­ted. I did not do exten­si­ve testing. If you encoun­ter any pro­blems, plea­se let me know. In such a case, plea­se send me sam­ple file for testing.

Gene­ral Comments:

All uti­li­ties are writ­ten for Win­dows and should run on all cur­rent ver­si­ons. Plea­se let me know if you encoun­ter any pro­blems or if you have any recom­men­da­ti­on for impro­ve­ments. None of the uti­li­ties needs to be instal­led. Just copy the .exe file to your pre­fer­red path and remo­ve the file for unin­stal­ling it.

The uti­li­ties store some para­me­ters in the regi­s­try or in an ini-file. See the respec­ti­ve help file for details. Ear­lier ver­si­ons used the key „HKEY_CURRENT_USER\SOFTWARE\Michael Krä­mer Free­ware“ but I recent­ly chan­ged this to „HKEY_CURRENT_USER\SOFTWARE\DK8PP Free­ware\“. I’m sor­ry for any inconvenience.

All files are com­pres­sed with 7‑zip, which ensu­res inte­gri­ty by a built-in CRC32. If the file is cor­rup­ted by the down­load, 7‑zip should com­p­lain during unpacking. For some addi­tio­nal degree of file authen­ti­ci­ty, I added the MD5 hash codes for the com­pres­sed files. I agree that down­loading and run­ning exe­cu­ta­bles from unknown sources is gene­ral­ly not a good idea. I’m also reluc­tant to do that myself. Let me the­re­fo­re sug­gest the following:

  • Scan the down­loa­ded exe­cu­ta­ble with a local or online virus scanner.
  • Run the exe­cu­ta­ble in a vir­tu­al machine.
  • Review the pro­vi­ded source code and com­pi­le it yours­elf.
    I appre­cia­te if you report any errors that you find and I also value any sug­ge­sti­ons to impro­ve my pro­gram­ming style.

By the way, feel free to use and modi­fy the source code as you like. I don’t reser­ve any copy­rights. But if you dis­tri­bu­te modi­fied code, say that it is yours, not mine. I sim­ply want to avoid any lia­bi­li­ty issu­es. Life is too short to fight with hungry lawyers.

Some­ti­mes I recei­ve more or less mild com­p­laints for pro­gram­ming under Win­dows rather than Linux. Well, I had some expe­ri­ence with Linux in the late 90es. I then deci­ded to stay with Win­dows, sim­ply becau­se it works reli­ab­ly. Again, life is too short to lose time with imma­tu­re envi­ron­ments. I’m sure that Linux has impro­ved sin­ce the old days, but I will not chan­ge any more. I don’t use any sophi­sti­ca­ted tools, just the Win32 API and plain C, not even C++. The­re­fo­re the exe­cu­ta­bles should also run under Wine.

I/O Board mit RS485 Schnittstelle

Es hat mich mal wie­der in den Fin­gern gekrib­belt. Nach­dem wir die ver­gan­ge­nen zwei Jah­re nur mit unse­rem neu­en Haus beschäf­tigt waren, muss­te ich mal wie­der ein klei­nes Board entwickeln.

Ich habe ja wie­der mit dem Ama­teur­funk ange­fan­gen und zwei Trans­cei­ver von Icom gekauft. Die Anten­nen­an­la­ge lässt aller­dings sehr zu wün­schen übrig. Ich will ver­schie­de­ne Anten­nen auf­bau­en, für Kurz­wel­le vor­läu­fig nur Mono- und Dipo­le. Da nicht jede Anten­ne ein eige­nes Kabel bekom­men kann, wer­de ich also einen Anten­nen­um­schal­ter instal­lie­ren müs­sen, der von der Sta­ti­on aus elek­trisch schalt­bar sein soll. Sowas kann man fer­tig kau­fen oder auch sel­ber­bau­en, aber auch die gekauf­ten brau­chen eine Steuerung.

Zur Kom­mu­ni­ka­ti­on zwi­schen Anten­nen­um­schal­ter und Shack bie­tet sich die RS485 Schnitt­stel­le an. Sie setzt auf einer asyn­chro­nen seri­el­len Schnitt­stel­le auf und unter­stützt Lei­tungs­län­gen von vie­len hun­dert Metern (bis 1,2 km nach der Norm) bei Baud­ra­ten bis 12 MBd. Durch die Ver­wen­dung eines Lei­tungs­paars im Gegen­takt wird eine hohe Stör­si­cher­heit erreicht. Ein Lei­tungs­paar gestat­tet die Kom­mu­ni­ka­ti­on im Halb­du­plex-Mode, für Voll­du­plex sind zwei Lei­tungs­paa­re nötig. RS485 ermög­licht auch den Auf­bau eines Bus­systems, bei dem bis zu 32 Teil­neh­mer ange­schlos­sen wer­den kön­nen. Bei der hier geplan­ten Anten­nen­um­schal­tung könn­ten also meh­re­re Anten­nen­um­schal­ter über ein ein­zi­ges Lei­tungs­paar ange­schlos­sen werden.

Weil ich gera­de noch eini­ge Exem­pla­re des Mikro­con­trol­lers in der Kiste lie­gen hat­te, habe ich ein klei­nes Board mit dem ATtiny1634 und einem RS485-Trans­cei­ver gebaut. Hier die KiCad 3D-Vorschau:

ATTINY1634
Unter­sei­te des RS485 Moduls mit einem ATtiny1634.
Oberseite
Ober­sei­te des RS485 Moduls.

Da die Umschalt­re­lais des Anten­nen­schal­ters typi­scher­wei­se mit 12V arbei­ten, ist auf der Ober­sei­te ein ein­fa­cher Line­ar­reg­ler imple­men­tiert. Es pas­sen 3V- und 5V-Typen. Da der 1634 bei 3V nur bis 8 MHz getak­tet wer­den kann, habe ich auf dem Pro­to­ty­pen 5V-Reg­ler ein­ge­lö­tet. Damit läuft der Con­trol­ler mit bis zu 12 MHz. Hier ist der Schalt­plan, es gibt kei­ner­lei erwäh­nens­wer­te Besonderheiten.

In der Wahl des Kom­mu­ni­ka­ti­ons­pro­to­kolls ist man ziem­lich frei, aber war­um etwas eige­nes erfin­den, wenn es schon weit­ver­brei­te­te Stan­dards gibt. Ich habe mich für den Mod­bus ent­schie­den, der auch bei­spiels­wei­se bei der Kom­mu­ni­ka­ti­on mit PV-Wech­sel­rich­tern ver­wen­det wird. Es gibt ein schö­nes Uti­li­ty für Win­dows, QMod­Ma­ster, das Mod­bus-Nach­rich­ten sen­den und emp­fan­gen kann. Das war sehr hilf­reich bei der Imple­men­tie­rung des Mod­bus Pro­to­kolls in den ATtiny1634. Ich bin noch nicht kom­plett mit der Imple­men­tie­rung fer­tig, daher will ich die Soft­ware im Moment noch nicht hier ver­öf­fent­li­chen. Das hole ich nach, wenn’s fer­tig ist. Da die wesent­li­chen Din­ge aber bereits funk­tio­nie­ren, hier mal nur kurz der Ressourcenverbrauch: 

Pro­gram Memo­ry Usa­ge : 2892 bytes 17,7 % Full
Data Memo­ry Usa­ge : 85 bytes 8,3 % Full
EEPROM Memo­ry Usa­ge : 2 bytes 0,8 % Full

Dar­an wird sich im End­aus­bau nicht mehr viel ändern. Viel­leicht braucht er mit wei­te­ren Funk­tio­nen 25 – 30% Flash Spei­cher, aber die vor­han­de­nen 16 kB wer­den auf jeden Fall aus­rei­chen. Wenn genü­gend Platz bleibt, wer­de ich die Sen­de- und Emp­fangs­puf­fer etwas ver­grö­ßern, was dann den Daten­spei­cher Ver­brauch um ein paar Pro­zent anstei­gen las­sen wird. Auch hier wird das 1 kB SRAM alle­mal ausreichen.

Über ein 25m Kabel lief die Kom­mu­ni­ka­ti­on bei 38 kBd wie erwar­tet meh­re­re Stun­den feh­ler­frei, aller­dings kann QMod­Ma­ster auch lei­der nur eine Nach­richt pro Sekun­de abset­zen. Das ist also nicht wirk­lich ein hoher Durch­satz. Auf der PC-Sei­te ver­wen­de ich übri­gens einen „WaveSha­re USB TO RS232 RS485 TTL Indu­stri­al Iso­la­ted Con­ver­ter“, der bis­her zuver­läs­sig funktioniert.