Gestern ist wieder einmal ein heftiges Gewitter durch unsere Region gezogen und hinterließ seine Spuren auf dem Display des Gewitter-Monitors. Das war eine gute Gelegenheit, die letzten Software-Updates zu testen. Zur Zeit des Fotos lag das Maximum des Gewitters etwa 1 Stunde zurück. Die Trendanalyse über die letzten 45 Minuten (jetzt durch Pfeilsymbole unterstützt) zeigte, dass die Summe der Blitze pro Minute stark rückläufig war. Der Mittelwert der letzten 15 Minuten lag aber immer noch so hoch, dass alle drei Alarm-LEDs aktiviert waren.
Seitdem ich die Version 2 im Februar in Betrieb genommen hatte, gab es viele Gelegenheiten, die Funktion der Software im Detail zu testen. Allerlei Feinheiten mussten korrigiert werden. Besonders ärgerlich war ein Fehler in der Trendanalyse, der den Prozessor in eine Endlosschleife schickte, wenn die Zahl der Blitze pro Minute sehr hoch wurde. Außerdem gab es Ungereimtheiten mit der Anzeige des Maximums. Jetzt funktioniert aber alles so, wie es soll.
Die neue Software steht wie immer auf der Ressourcen-Seite zum Download bereit. Die neue Software benötigt die Smart I2C GLCD-Software ab Juni 2018. Sonst können die Pfeilsymbole nicht dargestellt werden.
Von Herrn Wolfgang Richter erreichte mich ein Foto. Er hat seinen Gewitter-Monitor in ein Gehäuse aus schwarzem ABS-Kunststoff (200 x 100 x 65 mm) gesetzt. Sehr schön ist die Antenne, die über dem Gerät schwebt. Vielen Dank für das Foto!
Herr Richter hat mich auch auf die Forschungen von Hans Baumer zu den sogenannten Sferics aufmerksam gemacht. Dabei handelt es sich um elektrische Entladungen in den Wolken, die ohne Lichterscheinungen von Blitzen einhergehen. Tatsächlich ist mir schon seit langem aufgefallen, dass der Gewitter-Monitor bei labilen Wetterlagen (feuchte und warme Luft) deutliche Aktivitäten anzeigt, und zwar schon lange bevor Gewitter zu beobachten sind. Hierbei handelt es sich wahrscheinlich um die genannten Sferics. Übrigens habe ich die Empfindlichkeit des Geräts so eingestellt, dass die Alarmlevel (rote Leuchtdioden) erst dann aktiviert werden, wenn tatsächliche Gewitter im Umkreis von einigen hundert km registriert sind. Zur Kontrolle eignet sich die sehr informative Website Blitzortung.org.
Erstens … wollte ich für den Gewitter-Monitor Pfeilsymbole haben, die die Trendanalyse unterstützen. Ein oder zwei Pfeil nach oben oder unten – so schwer kann das doch nicht sein. Herausgekommen ist ein weiterer Zeichensatz, Font #7, mit einigen Symbolen. Der neue Zeichensatz mit einer Höhe von 12 Pixeln wird auch im User-Dokument beschrieben.
Bei Gelegenheit werden noch ein paar Symbole dazu kommen.
Außerdem wurde der Startup-Screen, der sich nach dem Anlegen der Betriebsspannung zeigt, erweitert. Neben der Software-Versionsnummer und Datum werden der Display-Typ mit der Anzahl der Pixel in horizontaler Richtung, die I2C-Puffergröße und Adresse und die aktuelle Helligkeitseinstellung (0 …. 10) präsentiert. Übrigens lässt sich der Startup-Screen unterdrücken durch Abschalten des Verbose-Mode.
Abgesehen von diesen Erweiterungen und zwei kleinen Bugfixes wurde die Software nicht mehr verändert. Das Display hat sich als recht zuverlässig erwiesen.
Zweitens … ist der erste Satz Platinen (für Display Typ 3 mit 4 Zoll Diagonale) bereits verbaut und tut in verschiedenen Anwendungen seinen Dienst. Deshalb musste ich neue Platinen bestellen. Bei der Gelegenheit habe ich das Layout noch einmal überarbeitet. Die Platine ist etwas kleiner geworden. Es gibt ein Befestigungsloch, das mit dem entsprechenden Loch der Display-Platine fluchtet. Bei der Gelegenheit habe ich den PNP-Transistor für die Steuerung der Beleuchtung ausgetauscht. Der eher seltene BC636 wurde durch den Standard-Transistor BC327 ersetzt.
Und drittens … gibt es eine erweiterte Arduino-Library zur Ansteuerung des Displays. Die Bibliothek glcd_functions_avr ist speziell für die kleinen 8Bit-AVR-Prozessoren (z. B. ATmega168 oder ATmega328) gedacht, wie sie im Arduino Nano oder Uno zum Einsatz kommen. Dort hat man oft das ärgerliche Problem, dass der beschränkte RAM-Speicher (1 oder 2k Byte) nicht ausreicht. Das hat zwar mit dem Display erst einmal nichts zu tun. Aber wenn man viele Texte im Programm verwalten und auf dem Display anzeigen möchte, dann wird RAM-Speicherplatz sehr schnell eng. Deshalb ist es sinnvoll, konstante Texte im viel größeren ROM-Speicher zu halten. Dazu gibt es die zusätzlichen Funktionen draw_pgm_str(), draw_center_pgm_str() und draw_radj_pgm_str(). Diese Funktionen übernehmen Texte direkt aus dem Programmspeicher, so dass dafür kein RAM „verbraucht“ wird.
Diese zusätzlichen Funktionen machen aber nur Sinn für die kleinen AVR-Prozessoren. Deshalb sollten alle anderen Arduinos (z.B. mit STM32, ESP32, etc.), die wesentlich mehr RAM-Speicher zur Verfügung haben, die normale Library glcd_functions verwenden.
Die neuen Gerber-Files, Software und Dokumente sind auf der Ressourcen-Seite verfügbar.
Übrigens: Da ich jetzt einen kleinen Vorrat an Platinen habe, gebe ich gerne Einzelstücke zum Selbstkostenpreis ab. Einfach per E-Mail melden.
Der Arduino-Kurs hat drei weitere Module bekommen. In „LC-Display“ geht es um den Anschluss eines einfachen LC-Display, so dass Texte und Daten ausgegeben werden können. Das Modul „Bits und Bytes“ behandelt die Eingabe über externe Taster. Zusammen mit dem Display wird daraus ein Reaktionszeit-Tester. Das dritte Modul, das neu dazu gekommen ist, bearbeitet Timer und Interrupts. So lassen sich quasi-parallele Aufgaben unabhängig voneinander ausführen.
Das Smart-I2C Graphic Display kommt bei verschiedenen Projekten zum Einsatz. Neulich begegneten uns zwei Probleme, die zu kleinen Erweiterungen der Funktionalität führten.
Rechts-bündige Texte ausgeben
Manchmal ist es hilfreich, Texte rechtsbündig auszugeben. Das ist zum Beispiel nützlich, wenn man mehrere Zahlenwerte untereinander positionieren möchte.
Also wurde die Firmware für das Display noch einmal geöffnet und um die Funktion draw_radj_str() erweitert. Der zugehörige Command-Token ist 37. Damit gibt es jetzt drei Funktionen zur Text-Ausgabe, wie in Smart I2C GLCD Instruction Set_v1-1 erläutert:
Das folgende Beispiel zeigt einen Arduino-Sketch, der die drei Text-Funktionen verwendet und die Ausgabe produziert, die hier als Beitrags-Bild zu sehen ist.
In der setup()-Funktion werden die drei Texte ausgegeben. In der loop()-Funktion wird dann gezeigt, wie man z.B. eine Zahl in die untere, rechte Ecke des Displays setzt. Dazu wird die Zahl mit itoa() in einen String konvertiert, der dann mit draw_radj_str() ausgegeben wird.
Die neue Firmware für das I2C GLCD und das Instructions-Dokument stehen auf der Ressourcen-Seite bereit. Auch die Arduino-Bibliothek wurde angepasst.
Texte aus dem Programm-Speicher ausgeben
Ein notorisches Problem der 8-Bit AVR-Prozessoren ist der sehr limitierte RAM-Speicherplatz. Zum Beispiel hat der ATmega328 nur 2 kByte RAM an Board. Die üblichen Funktionen zur Textausgabe, z.B. draw_str(„Dieses ist Text“); haben den Nachteil, dass der Text erst in das RAM kopiert wird, bevor er zur Ausgabe gelangt. Das ist für konstante Texte, wie sie z.B. als Titel-Texte, Menü-Items oder Beschriftungen häufig zum Einsatz kommen, nicht sinnvoll und führt schnell zu Engpässen im RAM-Speicher.
Zum Glück gibt es die Möglichkeit, Texte direkt aus dem Flash-Programm-Speicher auszugeben. Davon hat der ATmega eine ganze Menge zu bieten. Wenn man mit dem Atmel-Studio in C arbeitet, sieht das etwa so aus:
* Funktion to plot a zero-terminated string from program memory
*/
voidglcd_draw_pgm_str(constchar*my_str)
{
charmy_char;
i2c_start_wait(GLCD_ADDR+I2C_WRITE);
i2c_write(GLCD_DRAW_STR);
do{
my_char=pgm_read_byte(my_str);
i2c_write(my_char);
++my_str;
}while(my_char>0);
i2c_stop();
};
...
constcharstr_title[]PROGMEM="Dieses ist ein Titel-Text";
glcd_draw_pgm_str(str_title);
...
Dieses Beispiel geht davon aus, dass die I2C-Funktionen bereit stehen. Ich verwende üblicherweise die I2C-Master-Bibliothek von Peter Fleury (siehe http://jump.to/fleury).
Natürlich klappt das auch mit dem Arduino. Die entsprechenden Funktionen zur Textausgabe aus dem Programm-Speicher wurden in die GLCD-Bibliothek arduino_glcd_functions aufgenommen und heißen draw_pgm_str(), draw_center_pgm_str() und draw_radj_pgm_str(). Die Anwendung ist damit sehr einfach, wie das folgende Beispiel zeigt:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <Wire.h>
#include <glcd_functions.h>
#include <avr/pgmspace.h>
constcharstr_title[]PROGMEM="Dieses ist ein Titel-Text";
glcd gd(0x20);// creates an instance of the Graphic LCD
...
gd.draw_pgm_str(str_title);// plots a string from program memory
...
Die Arduino-Bibliothek mit den neuen Funktionen zur Textausgabe ist – wie immer – auf der Ressourcen-Seite verfügbar.
Bleibt noch zu erwähnen, dass diese Methode natürlich nur für Texte und Strings klappt, die als Konstante definiert werden können und sich im Laufe des Programms nicht ändern. Und dass das Problem des limitierten RAM-Speichers eine AVR-8-Bit-Eigenart ist. Sobald man mit grösseren Prozessoren, z.B. den STM32-Prozessoren oder gar dem Raspberry Pi unterwegs ist, sind solche Klimmzüge zur Text-Ausgabe nicht mehr notwendig.
Ich hoffe, die neuen Funktionen sind hilfreiche. Kommentare und Rückmeldungen sind sehr willkommen.
Der Gewitter-Monitor mit graphischer Anzeige war ein Projekt, das ich im Jahr 2014 fertig gestellt hatte. Seit dem habe ich das Gerät immer wieder einmal im Einsatz, und es tut gute Dienste. Inzwischen ist es aber an der Zeit für etwas Modell-Pflege. Rechtzeitig vor der nächsten Gewitter-Saison stelle ich hier die neue Version 2 vor.
Version 2 verwendet im Kern einen Arduino, wodurch das Programmieren und Flashen vereinfacht wurde. Das I2C-Smart Graphic LCD ermöglicht ansprechende Graphiken. Dazu gibt es eine vollständig neu entwickelte Software mit vielen neuen Features, z.B. einen mehrstufigen Alarm-Level, eine Trend-Analyse und ein Konfigurations-Menü.
Bewährtes Design mit neuen Funktionen
Das Grundprinzip des Gewitter-Monitors bleibt bestehen und wird hier kurz zusammengefasst.
Wer Radiohören noch aus den Zeiten von Mittelwelle und Langewelle kennt, der weiß, dass Gewitter-Blitze als störendes Krachen im Lautsprecher zu hören waren. Seit dem Umstieg auf Frequenzmodulation oder gar digitale Verfahren ist das aus unserem Radio-Alltag verschwunden. Das Prinzip eignet sich aber nach wie vor, um Gewitter-Blitze zu beobachten und zu registrieren.
Die hier vorgestellte Schaltung arbeitet mit zwei Langewelle-Empfängern, die auf einer freien Frequenz (ungefähr 100kHz) ständig in den Äther hören. Sobald ein Signal erfasst wird, wird es von einem Mikrocontroller untersucht. Typisch für Blitze sind schnell ansteigende Flanken (im Lautsprecher als „Knacken“ vernehmbar), die mit Hilfe des Analog-Digital-Converters (ADC) im Mikrocontroller selektiert und vermessen werden. Die Software sammelt die Anzahl der registrierten Blitze und die Summe der Pegel, die für jeden Blitz erreicht werden. Die Daten werden dann auf einem graphischen Display angezeigt. Das Display zeigt nicht nur die aktuell gemessenen Werte, sondern auch den Verlauf über die letzten Stunden. Die Daten erlauben die Analyse des Alarm-Levels, der über Leuchtdioden angezeigt werden. Darüber hinaus gibt es eine Trend-Analyse, um abzuschätzen, wie sich die Gewitteraktivitäten entwickeln werden.
Der analoge Schaltungsteil des vorherigen Gewitter-Monitors mit AM-Empfängern und der Peak-Detection-Schaltung hat sich bewährt und wurde übernommen. Die einzige Veränderung bezieht sich auf die Zeitkonstante der Peak-Detection, was weiter unten beschrieben wird.
Es gibt aber drei wesentliche Neuerungen:
(1) Die erste Veränderung trägt dem Feedback von einigen Nachbauten Rechnung. Basierend auf der zunehmenden Popularität des Arduino-Frameworks habe ich mich entschlossen, den ATmega-Prozessor im DIL-Gehäuse durch einen Arduino Nano zu ersetzen. Ich muss zugeben, dass ich für meine Entwicklungen lieber direkt mit den AVR-Prozessoren arbeite. Die Arduino-Boards waren bisher immer gross, teuer und unhandlich für die Entwicklung von eigenständigen Geräten. Mit der Verfügbarkeit des kleinen und preisgünstigen Arduino Nano-Boards hat sich das aber verändert. Die kleine Platine hat ein komplettes Kernsystem für den ATmega-Prozessor an Board, was den Aufbau vereinfacht. Es bleibt der Nachteil, dass der Arduino im Vergleich zu einem „nackten“ ATmega-Prozessor relativ strom-hungrig ist, da die Peripherie, z.B. das USB-Interface und die eingebaute Leuchtdiode, immer unter Spannung stehen. Da der Gewitter-Monitor aber wahrscheinlich nicht mit Batterie-Strom betrieben wird, ist dieser Nachteil verschmerzbar.
(2) Die zweite Veränderung bezieht sich auf das Graphik-Display. Bei dem vorher verwendeten ST7920 gab es Beschaffungsprobleme für die SPI-Variante. Außerdem fand ich die u8glib-Bibliothek unhandlich. Was lag also näher als eines der gut verfügbaren KS0108-Displays einzusetzen und mit dem Smart-I2C-Interface zu kombinieren, das an anderer Stelle beschrieben ist (siehe Universelles I2C-Interface für Graphik-LCD). Konkret habe ich mich für das 4-Zoll Display (Typ 3) entschieden, dass mit einer Auflösung von 192 x 64 Pixeln bei ansprechender Größe neue Möglichkeiten eröffnet. Das Graphik LCD-Display ist z.B. bei eBay unter dem Stichwort 4″ 192×64 Graphic LCD Modul Display in verschiedenen Farben erhältlich.
(3) Und schließlich war es an der Zeit, die Software komplett zu überarbeiten. Der neue Gewitter-Monitor hat einige neue Funktionen bekommen, speziell zur Analyse des Alarm-Status und der Trend-Entwicklung. Außerdem lässt sich das neue System flexible konfigurieren über ein Menü zur Einstellung der wichtigsten Parameter. Die Software wurde komplett in der Arduino-Entwicklungsumgebung geschrieben und kann mit dem vorhandenen USB-Interface des Arduinos in den Programmspeicher übertragen werden. Ein separater AVR-Programmer ist dafür nicht notwendig.
Die Schaltung
Der neue Gewitter-Monitor besteht aus dem Antennen-Modul, das wie oben beschrieben ohne Veränderung von der vorherigen Version übernommen wurde, und dem Hauptteil, das für die Auswertung und Anzeige zuständig ist. Das Antennen-Modul wird über ein 6-poliges Flachband-Kabel mit dem Hauptteil verbunden.
Hier arbeitet ein AM-Empfänger mit dem TA7642 und einem Ferritstab als magnetische Antenne. Der Ferritstab hat eine Richtwirkung mit engen aber stark ausgeprägten Minima in Richtung der Ferritstab-Achse. Deshalb werden zwei Empfänger eingesetzt, die senkrecht zueinander stehen. So wird eine lückenlose Abdeckung von 360 Grad erreicht.
Der Hauptteil des Gerätes verwendet, wie oben beschrieben, einen Arduino Nano und das Smart-I2C-Graphic-Display.
Das Signal vom Antennen-Modul wird mit einem Transistor (BC549C) verstärkt und dann an die Peak-Detection-Schaltung mit dem Operationsverstärker MCP602 geführt. Diese Schaltung folgt ansteigen Flanken sehr schnell und lässt das Signal dann langsam abfallen. So wird es möglich, mit dem naturgemäß relativ langsamen ADC die kurzen Blitz-Impulse sicher zu erfassen. Die Funktionsweise der Peak-Detection lässt sich mit dem Oszilloskop beobachten.
Im Gegensatz zum vorherigen Gewitter-Monitor wurde die ADC-Abtast-Frequenz erhöht auf 2000 Hz pro Kanal. Entsprechend konnte die Zeitkonstante der Peak-Detection-Schaltung reduziert werden (10nF statt vorher 100nF). Dadurch erreicht das neue System eine etwa 10-fach höhere zeitliche Auflösung. Ereignisse, die vorher als ein einziger Blitz registriert wurden, können jetzt in mehrere diskrete Blitze aufgelöst werden.
Rechts oben im Schaltplan befindet sich die Spannungsversorgung für das Antennen-Modul. Die Empfangs-Empfindlichkeit der TA7642-ICs lässt sich über die Versorgungsspannung einstellen. Die Schaltung verwendet eine Band Gap-Referenz (TL431), die exakte 2.5V produziert, und einen Emitterfolger mit einem weiteren BC549C. Mit einem Trimmer kann der gewünschte Spannungswert gewählt werden. Ich habe die besten Erfahrungen mit 1.6V gemacht, gemessen am Eingang des Antennenmoduls (vor der Diode).
Für die Bedienung des Geräts sind drei Tasten verfügbar, die mit Select, Down und Up bezeichnet sind. Die Tasten befinden sich zusammen mit den Leuchtdioden für die Anzeige des Alarm-Levels und der Blitz-Erkennung auf einer kleinen Platine, die hier als Front-Panel bezeichnet wird.
Die Spannungsversorgung der Schaltung geschieht über ein externes Stecker-Netzteil, das mindestens 7V liefern sollte. Der Strombedarf ist abhängig von der eingestellten Beleuchtungsstärke des Displays und liegt maximal bei 150mA. Intern arbeitet ein Festspannungsregler. Zwar hat der Arduino einen eigenen 5V-Regler an Board, den man auch zur Versorgung der anderen Schaltungsteile heranziehen könnte. Ich habe mich aber für eine separate Versorgung entschlossen, weil der Regler auf dem Arduino bei größeren Eingangsspannungen vom Stecker-Netzteil (in meinem Fall 12V) und Strömen oberhalb von 100mA durchaus recht warm werden.
Damit ist die Schaltung beschrieben. Durch den Einsatz des integrierten Arduino Nano-Boards ist der Aufbau überschaubar. Dazu trägt auch die Tatsache bei, dass der Audio-Verstärker, der in der vorherige Version vorhanden war, hier weggelassen wurde. Es hat sich gezeigt, dass beim laufenden System keine Notwendigkeit besteht, das Signal akustisch auszugeben.
Vollständig neue Software
Der Umstieg auf Arduino und das Smart-I2C-GLCD erforderte eine vollständige Überarbeitung der Software. Das Grundprinzip ist aber weitgehend gleich geblieben.
Die Software besteht aus 4 Modulen:
GewitterMonitor_v2.ino ist das Hauptprogramm mit den setup() und loop()-Funktion und der Timer-getriebene Interrupt-Routine
GewitterMonitor_graphs.ino beinhaltet die Funktionen zur Anzeige auf dem Display
GewitterMonitor_stats.ino beherbergt die Statistik-Funktionen
GewitterMonitor_config.ino ist für die Verwaltung der Konfiguration zuständig.
Zusätzlich benötigt das Programm die Arduino-Bibliothek für das Graphik-Display glcd_functions. Um erfolgreich zu kompilieren, muss sich der glcd_functions-Folder im librariers-Ordner der Arduino-Sketche befinden – – wie bei Arduino üblich.
Alle Dateien sind auf der Ressourcen-Seite zum Download verfügbar. Für die glcd_functions-Bibliothek muss darauf geachtet werden, dass die Version vom 21-Feb-2018 (oder neuer) benötigt wird.
Kernstück der Software ist die Interrupt-Routine im Hauptprogramm. Diese Routine wird durch einen Timer-Interrupt 4000 mal pro Sekunde aufgerufen und liest wechselweise die ADC-Kanäle 0 und 1 ein. Das bedeutet, dass die Ausgänge vom Antennen-Modul wie oben beschrieben 2000 mal pro Sekunde abgefragt werden. Wenn sich zwei aufeinanderfolgende Werte um einen bestimmten Wert unterscheiden, wird dieses als Erkennung einer ansteigenden Flanke gewertet und entsprechend ein Blitz registriert. Der Schwellwert zur Blitzerkennung ist ein wichtiger Parameter des Systems, der sich konfigurieren lässt. Kleinere Werte bedeuten höhere Empfindlichkeit aber auch höhere Anfälligkeit gegen Störsignale. Größere Werte bedeuten geringere Empfindlichkeit. Als Default-Wert wird 150 eingesetzt, was bei dem Wertebereich des ADC von 1024 also etwa 15% Ausschlag entspricht. Damit habe ich die besten Erfahrungen gemacht.
Wenn der Trigger für die Blitzerkennung ausgelöst wurde, ermittelt das Programm den Maximalwert des Blitzes. Für jede Minute speichert das Programm die Anzahl der Blitze (flash_cnt) und die Summe der gemessenen Blitz-Maxima (flash_sum) in einem Array ab. Die Werte der letzten 150 Minuten stehen zur Anzeige zur Verfügung.
4 verschiedene Alarm-Level
Der Alarm-Level soll Auskunft geben, wie stark oder möglicherweise gefährlich die derzeitige Gewitter-Aktivität ist. Diese Information mag den interessierten Wetterbeobachter erfreuen oder hilfreich sein, um z.B. ein geplantes Picknick im Freien zu verschieben oder eine windanfällige Markise einzufahren.
Das System kennt 4 verschiedene Alarm-Level. Der Alarm-Level 1 schaltet die Display-Beleuchtung ein. Die Idee ist, dass das Gerät bei geringer Gewitteraktivität selbstständig um Aufmerksamkeit bittet. Die folgenden Alarm-Level 2 bis 4 werden über die drei roten Leuchtdioden als aufsteigende Reihe angezeigt.
Für die Berechnung des Alarm-Levels werden die Daten der letzten 15 Minuten herangezogen, sofern nichts anderes eingestellt wurde. Das Zeitfenster für die Auswertung des Alarm-Levels (alarm window) ist wiederum ein Parameter, den der Anwender konfigurieren kann. Der Default-Wert von 15 Minuten kann zwischen 5 und 60 Minuten gewählt werden.
Die Datenbasis für den Alarm-Level ist das Array mit den Summenwerten der Blitze pro Minute (flash_sum). Das Programm erlaubt zwischen zwei verschiedenen Algorithmen zu wählen. Entweder wird der Durchschnittswert (average) der Summenwerte berechnet, oder es wird der Maximalwert (max) gesucht. Durchschnittswerte sind robuster gegen einzelne Ausreißer, aber sie reagieren auch träger auf Veränderungen. Hier muss man Erfahrung sammeln, um zu schauen, was sich am Besten eignet. Für meinen Einsatz bevorzuge ich die Durchschnittsberechnung. In jedem Fall liefert das Programm einen Wert, entweder Durchschnitt oder Maximum, der dann mit einem Alarm-Schwellwert verglichen wird. Wird der Schwellwert übertroffen, dann wird der Alarm-Level 1 ausgelöst. Die anderen Alarm-Level verhalten sich entsprechend einer geometrischen Reihe:
Durchschnitt oder Maximum > Schwellwert: Alarm-Level 1
Durchschnitt oder Maximum > 2 * Schwellwert: Alarm-Level 2
Durchschnitt oder Maximum > 4 * Schwellwert: Alarm-Level 3
Durchschnitt oder Maximum > 8 * Schwellwert: Alarm-Level 4
Man kann leicht erkennen, dass es bei einem Alarm-Level 4 wirklich gewaltig kracht und das Gewitter in direkter Nähe ist.
Der Schwellwert des Alarm-Levels (alarm threshold) lässt sich ebenfalls konfigurieren. Man kann sowohl den gewünschten Algorithmus (Durchschnitt oder Maximum) als auch den Wert selber wählen. Als Default-Wert verwendet das System die Durchschnitts-Methode bei einem Schwellwert von 50.
Ich muss an dieser Stelle erwähnen, dass ich aufgrund der winterlichen Wetterlage bisher noch keine praktische Erfahrung mit den Alarm-Leveln sammeln konnte. Sicherlich wird es im Laufe des Sommers den einen oder anderen Software-Update geben.
Anzeige und Bedienung
Nach diesen Erklärungen sind das Display und die Bedienelemente hoffentlich einleuchtend.
Das 4-Zoll Display macht den Hauptteil der Frontseite aus. Es gibt dort zwei Bereiche: Auf der rechten Seite werden die aktuellen Messdaten für die laufende Minute gezeigt. Count steht für die Anzahl der registrierten Blitze in dieser Minute, und Sum für den Summenwerte über die gemessenen Maxima. Der Sekundenzähler unten in Bild läuft immer von 0 bis 60. Sobald die Minute voll ist, werden die aktuellen Daten übernommen und in den Verlauf eingefügt, der dabei um eine Reihe (= eine Minute) nach links verschoben wird.
Im rückblickenden Verlauf steht jede vertikale Linie für die Summe der Blitze während einer Minute. Am oberen Rand ist die Zeit-Skala angedeutet. Die kleinen Striche stehen für jeweils 15 Minuten, und der etwas größere Strich für eine Stunde. Man muss beachten, dass die vertikale Achse automatisch skaliert wird, um auch den größten gemessenen Wert sinnvoll abbilden zu können. Wenn z.B. der größte gemessene Wert 350 ist, dann wird die Skala bis 500 skaliert, usw.
Die gepunktete vertikale Linie zeigt das Zeitfenster für die Berechnung des Alarm-Levels. Alle Werte zwischen der gepunkteten Linie und dem rechten Rand (der aktuellen Zeit) werden für die Berechnung der Alarm-Level herangezogen. Wenn man im Konfigurations-Menü das Zeitfenster anders einstellet, wandert die gepunktete Linien an ihren neuen Platz.
Oben links im Display wird das Maximum (max) und der Durchschnittswert (avg) für das aktuelle gewählte Zeitfenster angezeigt.
Die restlichen Bedienelemente sind schnell erklärt. Die beiden gelben Leuchtdioden oben leuchten kurz auf (200 msec), sobald ein Blitz registriert wurde. Mit den beiden gelben Tasten lassen sich die Graphik-Bildschirme durchschalten. Man kann entweder die Anzeige der Summen oder die Anzeige der Anzahl der Blitze wählen. Schließlich ist die rote Taste ist für das Konfigurations-Menü vorgesehen.
Die Beleuchtung der Anzeige schaltet sich nach einiger Zeit ab, sofern kein Alarm-Level gesetzt ist. Wenn der neugierige Zeitgenosse trotzdem die aktuellen Daten sehen möchte, genügt ein Druck auf eine der Tasten, womit die Beleuchtung für 2 Minuten aktiviert wird.
Trend-Analyse
Interessanter als der Verlauf der letzten Minuten oder Stunden ist eigentlich das, was kommt. Wird das Gewitter noch stärker werden oder zieht es ab? In die Zukunft schauen kann der Gewitter Monitor natürlich nicht. Aber die Daten der Vergangenheit geben Anhaltspunkte. Zu dem Zweck habe ich eine Trend-Analyse in das Programm aufgenommen. Genaugenommen wird eine lineare Regression nach der Methode der kleinsten Quadrate über die Werte der letzten 45 Minuten (Regressions-Zeitfenster) berechnet und angezeigt. Die resultierende Gerade kann ansteigen oder abfallen, was sich in einem positiven oder negativen Steigungs-Koeffizienten erkennen lässt. Dieser Wert wird angezeigt – allerdings nur, wenn der Korrelations-Koeffizient grösser als 0.5 ist und somit einen sinnvollen Zusammenhang zeigt. Positive Werte bedeuten also, dass die Gewitter-Aktivität in den letzten 45 Minuten zugenommen hat, während negative Werte die Abnahme anzeigen. Wenn die Messwerte durchgängig bei 0 liegen oder wild streuen, so dass die Statistik keinen Trend erkennen lässt, dann wird im Display nur „–.-“ angezeigt.
Die Trend-Analyse kann jederzeit mit den Up– oder Down-Tasten dazu geschaltet werden. Die beiden gelben Tasten laufen hintereinander 4 verschiedene Darstellungen durch:
Zeitverlauf der Summenwerte (Flash Sum)
Zeitverlauf der Summenwerte zusätzlich mit Trend-Analyse (Flash Sum + Trend)
Zeitverlauf der Anzahl der Blitze pro Minute (Flash Count)
Zeitverlauf der Anzahl der Blitze pro Minute mit Trend-Analyse (Flash Count + Trend)
Auch hier gilt die oben gemachte Bemerkung, dass ich bisher noch keine Erfahrung mit dieser Funktion sammeln konnte. Der Sommer wird möglicherweise Software-Updates bringen.
Konfiguration
Wie oben beschrieben gibt es die Möglichkeit, die wichtigsten System-Parameter zu konfigurieren und an den Aufstellungsort und die Anwender-Vorlieben anzupassen. Ein langer Druck (> 3 sec) auf die rote Select-Taste führt in das Konfigurations-Menü.
Die Auswahl des gewünschten Parameters erfolgt über die Up– and Down-Tasten. Dann führt ein Druck auf die rote Select-Taste in die Einstellung für den gewählten Wert.
Mit den Up– und Down-Tasten kann der gewählte Werte verändert werden. Ein weiterer Druck auf Select übernimmt den neuen Wert und führt zurück zum Menü. Mit der Anwahl des letzten Eintrags, Exit, verlässt man das Konfigurations-Menü.
Alle Parameter haben Default-Werte, die bei dem ersten Programmstart eingestellt werden. Diese Werte haben sich bisher als eine gute Wahl während des Testbetriebs herausgestellt.
Hier eine kurze Zusammenfassung der Konfigurations-Parameter mit ihren Default-Werten
Trigger threshold ist die minimale Schrittgröße zwischen zwei aufeinander folgenden Messwerten, um eine ansteigende Flanke als Blitz zu interpretieren. Kleine Werte erhöhen die Empfindlichkeit aber auch die Anfälligkeit gegenüber Störsignalen.
Default-Wert: 150
Alarm window ist die Anzahl der letzten, verstrichenen Minuten, die zur Berechnung des Alarm-Levels herangezogen werden.
Default-Wert: 15
Alarm threshold selektiert den Algorithmus (Durchschnitt oder Maximum) und den Schwellwert für das Setzen der Alarm-Levels. Alarm-Level 1 wird beim Überschreiten des einfachen Schwellwertes aktiviert, Alam-Level 2 beim doppelten Wert, usw.
Default-Wert: Avg 50
Display light setzt die Helligkeit des Displays. Die Werte reichen von 0 (= 0%, aus) bis 10 (= 100%, maximale Helligkeit).
Default-Wert: 8
Startup screen selektiert die Graphik, die nach dem Einschalten des Geräts gezeigt wird. Mögliche Werte sind:
– Flash Sum
– Flash Sum + Trend
– Flash Count
– Flash Count + Trend
Default-Wert: Flash Sum
Es bleibt noch zu erwähnen, dass alle Konfigurations-Parameter im EEPROM des Prozessors abgelegt werden. Damit bleiben die eingestellten Parameter auch nach dem Abschalten (oder beim Überwintern im Bastelkeller) erhalten – wie es sich für eine Anwendung dieser Art gehört.
Aufstellung und Einstellung
Zum Schluss ein paar Tips für die Inbetriebnahme. Das Gerät empfängt die magnetische Komponenten der elektromagnetische Schwingungen von Blitzen. Zum Glück sind die magnetischen Störfelder im Haus meist weniger stark ausgeprägt als die elektrischen Felder. Trotzdem reagiert das Gerät empfindlich auf Störsignale von manchen Schaltnetzteilen. Das ist natürlich insbesondere relevant für das Stecker-Netzteil, mit dem das Gerät betrieben wird. Hier gibt es deutliche Unterschiede. Im Zweifelsfall ist es keine schlechte Idee, etwas mehr Geld zu investieren. In meinem Fall steht das Gerät in einer Fensterecke, die sich ein bisschen abseits von den anderen Geräten befindet.
Es kann sinnvoll sein, das Gerät an eine Erdung (z.B. Wasserleitung, Heizung, etc.) anzuschliessen. In meinem Fall konnte ich dadurch den Störpegel deutlich reduzieren und die Empfindlichkeit weiter erhöhen. Das sollte aber nicht unbedingt notwendig sein.
Für die erste Inbetriebnahme sollte die Versorgungsspannung des Antennen-Moduls am Trimpoti auf 1.6V eingestellt werden. Für die Software empfehlen sich die Default-Parameter wie oben beschrieben. Nach dem Einschalten – und in Abwesenheit von Gewittern – sollten die Blitz-Indikatoren nicht aufleuchten. Wenn es gelegentlich ein Signal gibt, dann ist das normal und kommt wahrscheinlich von technischen Geräten. In jedem Fall sollten die Werte aber deutlich unter der Schwelle für den ersten Alarm-Level liegen.
Zum Testen der Funktion nehme ich eine alte 9V-Batterie, die ich mit einem etwa 30 cm langen Drahtstück ein paar Mal kurz schließe. Wenn ich das in etwa 20 bis 30 cm Entfernung von der Antenne mache, sollte das Gerät dies als Blitze registrieren. Wenn das geklappt hat, ist alles in Ordnung und man kann entspannt auf die nächste gewittrige Wetterlage warten.
Es gibt zwei Optionen, die Empfindlichkeit zu verändern. Zuerst kann man mit dem Trimmpoti die Antennen-Spannungsversorgung vergrößern (höhere Empfindlichkeit) oder verkleinern (geringere Empfindlichkeit). Als zweite Option, und besonders um unerwünschte Störsignale heraus zu filtern, kann der Konfigurations-Parameter Trigger Threshold verkleinert (höhere Empfindlichkeit) oder vergrößert (geringere Empfindlichkeit) werden. Tatsächlich ist eine sehr große Empfindlichkeit gar nicht wünschenswert. In Sommernächten kann das Gerät Reichweiten von vielen 100 km erreichen. Dann ist es fraglich, ob man sich ein Gewitter in den fernen Alpen anzeigen lassen möchte.
Zum Schluss
Ich hoffe, dass der neuen Gewitter Monitor v2 das Interesse des einen oder anderen Bastlers weckt. Wie immer freue ich mich über Rückmeldungen, Kommentare, Vorschläge oder Ideen. Natürlich bin ich auch gerne bereit, bei der Beschaffung von Komponenten zu unterstützen oder Prozessoren zu programmieren.
Die Software hat ein gewisses Mass an Komplexität erreicht – und wird sicherlich allerlei Fehler enthalten. Auch hierzu sind Rückmeldungen willkommen. Ich gehe davon aus, dass es bei Gelegenheit Updates geben wird, die – Arduino sei Dank – über die USB-Schnittstelle sehr einfach eingespielt werden können.
Die Software für dieses Projekt kann von der Ressourcen-Seite herunter geladen werden.
3D-Druck ist populär, und Drucker für den Heimgebrauch sind billiger geworden. Für den Elektroniker hat diese Technik viel zu bieten: Mechanische Kleinteil wie z.B. Gehäuse, Zahnräder, Seilrollen und ähnliches können im Handumdrehen selbst hergestellt werden. Das klingt so gut, dass es an der Zeit ist, die Technik selbst auszuprobieren.
Um es vorweg zu nehmen: Im Handumdrehen geht bei der 3D-Druckerei gar nichts. Der Weg vom Modell zum fertigen Produkt ist weit. Aber die Resultate können überzeugen!
Geeetech Prusa I3 X
Für meine ersten Versuche bestellte ich mir einen Bausatz der chinesischen Firma Geeetech, basierend auf dem quelloffenen FDM 3D-Drucker Prusa I3, ein einfaches und zuverlässiges Konzept, das sich bewährt hat. Geeetech ist einer von vielen Herstellern, die Prusa I3-Nachbauten anbieten.
Etwa eine Woche nach der Bestellung kam das Paket an. Es enthielt auf zwei Styropor-Lagen verteilt eine Unzahl von kleinen und großen Bauteilen, die alle gut geordnet und sorgfältig durchnummeriert waren. Per Email erreicht mich ein Link zu der PDF-Bauanleitung auf dem Geeetech-Server.
Für den Zusammenbau sollte man sich Zeit nehmen. Laut Geeetech ist der Nachbau in 11 Stunden möglich. Davon würde ich abraten. Ich selbst habe 5 Tage benötigt, wobei ich jeden Tag 3 oder 4 Stunden investieren konnte. Die englischsprachige Anleitung ist gut gemacht und erklärt die Schritte mit vielen Bildern. Darüber hinaus gibt es einen Satz von YouTube-Videos, die alles ausführlich zeigen.
Der Rahmen des Geräts besteht im Wesentlichen aus 8 mm starken, schwarzen Acrylplatten. Die Teile sind exakt geschnitten. Ob das schwarz-glänzende „Klavierlack-Finish“ für den Einsatz in der Werkstatt optimal ist, sei dahingestellt. Die Schrauberei ging bei guter Passgenauigkeit der Teile zügig voran. Zum Glück sind viele der Kleinteile in der Überzahl enthalten, so dass es kein Problem war, wenn ein kleines Schräubchen nicht mehr auffindbar war.
Allerdings scheinen einige Details ständig überarbeitet zu werden, so dass es immer wieder Abweichungen zwischen den Bildern und den tatsächlich vorhandenen Bauteilen gab. Insgesamt benötigte der Zusammenbau aktives Mitdenken und ein gutes technisches Verständnis. Leider fehlt eine gute Übersichtsbeschreibung des Gerätes mit Markierung der einzelnen Komponenten (in früheren Zeiten gab es so etwas als „Explosions-Zeichnung“), so dass ich streckenweise Bauteile zusammensetzte, ohne ihre Rolle zu verstehen. Wenn man dann etwas falsch zusammengesetzt hat, ist das aber kein Problem, weil alle Komponenten verschraubt sind und wieder gelöst werden können.
Es gab eine Hürde, die ich nach Bauanleitung nicht lösen konnte: Die Z-Achse machte Probleme. Während die X- (links/rechts) und Y- (vorne/hinten) Achsen durch Zahnriemen gesteuert werden, was auf Anhieb gut funktionierte, wird die Z-Achse (oben/unten) durch Gewindestangen bewegt. Nach dem ersten Zusammenbau saßen die Gewindestangen so fest, dass sie sich absolut nicht mit den Motoren drehen ließen. Die 8 mm Führungslöcher in den entsprechenden Plastikteilen waren genau auf Größe geschnitten und ließen der M8-Stange keine Luft. Zur Behebung des Problems wurden die Löcher direkt am Schlitten und an der oberen Platte auf 10 mm aufgebohrt.
Da die Gewindestange jetzt keinen zuverlässigen Halt mehr hatte, setzte ich zur Stabilisierung auf die obere Platte jeweils ein Kugellager mit 8 mm Innendurchmesser. Dadurch war eine reibungsfreie Lagerung bei präziser Führung gewährleistet. Ähnliche Ansätze mit 3D-gedruckten Konstruktionen werden in den Foren diskutiert (Stichwort z axis wobble fix). In meinem Fall fiel die Wahl auf Sperrholz, weil ich eine Lösung brauchte, bevor der Drucker funktionsfähig war.
Außerdem hatte eine der beiliegenden Gewindestangen einen deutlichen Schlag und wurde durch eine Stange besserer Qualität aus dem Baumarkt ersetzt. Mit einigen wenigen Tropfen harz-freiem Öl an der Gewindemuffe auf der Gewindestange lief der Antrieb dann reibungsfrei.
Zum Abschluss wurde alle Komponenten elektrisch verbunden durch eine Vielzahl von Steckverbindungen – genau nach Bauanleitung. Wieder musste ich mich damit auseinander setzten, dass einige Details der Controller-Platine von der Beschreibung abwichen. Trotzdem war alles logisch und nachvollziehbar angeordnet.
Inbetriebnahme
Geeetech stellt ein zweites Dokument bereit, das User Manual, das die Inbetriebnahme und das Fine Tuning beschreibt. Bevor es zum Einschalten ging, musste die zugehörige Software auf dem steuernden PC installiert werden. Geeetech verwendet Repetier Host, ein gut etabliertes Open Source-Programm. Tatsächlich verlief die Installation auf meinem Windows 10-PC völlig problemlos.
Dann kam der spannende Moment: Strom ein! Aber kein Grund zur Aufregung. Die Verbindung zwischen PC und Controller-Board funktionierte sofort, und die Drucker-Funktionen ließen sich gut steuern. Vom PC aus lassen sich alle Achsen manuell ansteuern. So konnte ich auch die problematische Z-Achse ausprobieren und nachjustieren, bis es reibungslos lief.
Dann aber gab es Probleme beim Heizen des Extruders. Zwischenzeitlich zeigte das Geräte die „MINTEMP“-Fehlermeldungen, was bedeutet, dass der Thermistor einen Temperaturwert unter 19 Grad erfasst. Anscheinend hatte der Thermistor im Alu-Block des Extruders keinen zuverlässigen Kontakt mit dem Board. Eine genauere Analyse ergab, dass die kleinen Steckverbinder am Alu-Block keine stabile Verbindung hatten. Die Kontakte befinden sich unter gelben Klebeband und sind deshalb nicht so leicht zu finden. Nachdem ich sie mit einer Zange nachgedrückt hatte, lief alles nach Plan. Das Klebeband habe ich inzwischen durch zwei Kabelbinder ersetzt. Übrigens konnte ich meinem Impuls, die Verbindungen mit dem Lötkolben dauerhaft zu machen, widerstehen. Das Problem dabei ist, dass die Lötstellen bei Temperaturen oberhalb von 200 Grad nicht halten. Also lieber klemmen!
Zum Schluss musste noch das Druckbett nivelliert werden, was nach der Anleitung gut machbar war.
Dann konnte es losgehen. Geeetech legt 3 Meter gelbes Filament in den Karton. Der erste Versuch, einen runde Scheibe zu produzieren, die als *.stl-File auf dem Geeetech-Server bereitsteht, war weitgehend erfolgreich. Prima. Was kommt als nächstes?
Tool Chain
Sinn und Zweck des Druckers in meinem Elektronik-Labor ist es, nützliche Kleinteile für meine elektrischen Geräte zu produzieren. Der nächste Schritt ist also eine Software, die die Erstellung solcher Bauteile am PC ermöglicht. Meine Wahl fiel auf FreeCAD, ein beeindruckendes, wenn auch leider nicht ganz fehlerfreies Programm, um 3-dimensionale Objekte zu designen. Auch dieses Programm braucht etwas Einarbeitungszeit. Zum Glück gibt es sehr hilfreiche YouTube-Tutorials, die die Grundlagen gut erklären. Man sollte sich aber Zeit nehmen.
Die Ausgaben von FreeCAD sind nicht ohne weiteres mit dem Drucker kompatible. Die Körper sind z.B. mit papier-dünnen Wänden definiert und nicht „wasserdicht“ (mannigfaltig). In der Regel muss noch ein Mesh erzeugt werden, das die Körper füllt. Zwar kann FreeCAD auch diesen Schritt übernehmen. Ich habe aber besser Erfahrungen mit dem ebenfalls freien Programm Meshmixer von Autodesk gemacht. Dort lässt sich über die Funktionen edit -> solid fill ein Körper erzeugen, der dann direkt vom Repertier Host importiert und zum Druck geschickt werden kann.
Ein weiteres praktisches Problem ergab sich dadurch, dass manches Mal der erste gedruckte Layer nicht recht auf der Alu-Fläche des Druckbettes halten wollte. Wenn der erste Layer nicht stabil liegt, dann endet der Druck über kurz oder lang im Chaos. Das ist ein viel diskutiertes Thema in den Internet-Foren. Dort fand ich auch Abhilfe: Eine Schicht Tesa Abdeckband für Maler (wieder aus dem Baumarkt meines Vertrauens), das ohne Lücke oder Überlapp auf die Alu-Platte geklebt wird, erhöht die Haftung. Wenn die Nivellierung stimmt, dann hält die erste Schicht absolut fest. Das Band ist Verbrauchsmaterial und musste nach ein paar Ausdrucken erneuert werden.
Endlich 3D drucken!
So, jetzt konnte es endlich losgehen. Als eines der ersten Objekte produzierte ich Halter für das Graphik LCD-Display, mit dem ich oft arbeite, so dass das Display bei meinen Experimenten nicht mehr lose auf dem Arbeitstisch liegen muss. Für eine bessere Druckqualität habe ich die Druckgeschwindigkeit etwas heruntergesetzt. Auch mit der Temperatur des Extruders kann man experimentieren. Die Zahl der Parameter zur Feinabstimmung ist groß und braucht Geduld und Experimentierfreude. Das Resultat ist dann aber wirklich sehr schön und ein wohlverdienter Lohn der Mühe!
Es ist sehr erfreulich, wenn man dann das fertigen Bauteil vom Druckbett löst und ohne weitere Bearbeitung – keine Löcher bohren, keine Ausschnitte nachfeilen – an das Display schraubt.
Fazit
Der Geeetech Prusa I3 X ist gut geeignet für den Einstieg in die 3D-Druckerei. Der Bausatz ist durchdacht und bietet gute Qualität, wenn auch einige Details angepasst werden müssen. Die Bauanleitung beantwortet nicht alle Fragen, so dass Mitdenken, technisches Verständnis und gelegentliches Stöbern in einschlägigen Foren gefordert sind.
Der Einstieg in das Thema benötigt viel Zeit. Es ist sicherlich kein Consumer-Produkt, das nach Aufstellen und Einschalten bereits gute Ergebnisse produziert. Hier sind mehr Investitionen vom Anwender gefragt. Wenn man die Hürden aber genommen hat, dann eröffnet der Drucker enorme Möglichkeiten und belohnt den Anwender mit guter Qualität.
Mehr gedruckte Objekte werden folgen!
Download
FreeCad und konvertiertes STL-File für den Display-Halter: DisplayHalter
Wer mit Elektronik arbeitet, muss unweigerlich Fehler suchen. Das gehört einfach dazu. Es gibt sicherlich kein Projekt, das von der Idee bis zum Prototypen fehlerfrei funktioniert. Meistens kann man mit schrittweisem Vorgehen die Fehler einigermaßen gezielt lokalisieren und beseitigen. Jetzt ist mir aber ein verstecktes Problem begegnet, dass mich an der Weltordnung der Elektronik zweifeln ließ.
Es ging um eine Schaltung mit zwei ATmega-Prozessoren, die als Master und Slave über den I2C-Bus miteinander im Gespräch sind. Soweit so gut. Erst einmal funktionierte auch alles wie geplant, aber dann gab es sporadische Ausfälle. Sporadisch, also nicht gezielt reproduzierbar, ist hier das Stichwort. Mal lief die Schaltung für Stunden ohne Probleme, und dann war plötzlich der I2C-Bus weg. Der Slave-Prozessor reagierte nicht mehr. Ein anderes Mal wollte die Schaltung schon nach dem Einschalten nicht so, wie sie sollte.
Zuerst einmal wurde gemessen. Das Oszilloskop zeigte ein vernünftiges I2C-Signal am Takt und auf der Datenleitung. Dann wurde die Software auf den Kopf gestellt. Stürzt die Slave-Software ab? Wo hängt die Geschichte? Aber ohne Ergebnisse. Eine regelmäßige blinkende LED wurde eingebaut, und als nach Stunden reibungsloser Tätigkeit der Fehler wieder auftauchte, zeigte die LED, dass der Slave nach wie vor sein Programm abarbeitete und auf Input wartete. Auch ein Austausch des Prozessors gegen ein fabrik-neues Exemplar brachte keine nachhaltige Besserung. Verflixt!
Als ich dann die laufende Platine in die Hand nahm, merkte ich, dass mechanische Spannungen, z.B. leichtes Verdrehen der beiden Seiten, den I2C-Bus wieder belebten. Also ein Lötproblem? Genaue Inspektion der Lötpunkte und Nachlöten aller I2C-involvierten Leitungen halfen immer noch nicht weiter. Mein Frustrationslevel erreichet den Siedepunkt. Ich legte die Platine zur Seite und baute einen zweiten Prototype, der für das Projekt sowieso gebraucht wurde. Und siehe da, diese zweite Platine arbeitet bis heute tadellos. Meine Elektroniker-Welt war halwegs wieder zurecht gerückt.
Aber natürlich war das Problem damit noch nicht behoben. Tage später setzte ich mich noch einmal an die fehlerhafte Platine. Dabei zog ich den Slave-Prozessor aus der Fassung, um ihn mit einem Software-Update zu versorgen. Und dann fiel es mir wie Schuppen von den Augen: Pin 27 der IC-Fassung sah irgendwie anders aus, als die anderen Pins. Genauer hingeschaut konnte ich erkennen, dass der innere Ring im Pin-Anschluss fehlte. Aha, eine fehlerhafte IC-Fassung! Ich steckte den Prozessor noch einmal in die Fassung und konnte mit einem Multimeter erkennen, dass Pin 27 nur gelegentlich Kontakt zum Chip hatte. Und tatsächlich: Bei diesem Pin handelt es sich um die Datenleitung des I2C-Bus.
Da es sich um „nur“ um einen Prototypen handelte, wurde zur Fehlerbehebung der Pin des Prozessors direkt in der Fassung verlötet. Seit dem läuft die Platine tadellos.
Sporadische, nicht reproduzierbare Fehler brauchen Geduld und hohe Frustrationstoleranz. Um so schöner ist es, wenn der Fehler dann doch gefunden wird.
Ein Kollege sagte einmal: Wenn du frustriert bist, dann bist du dabei, etwas zu lernen! In diesem Sinne: Viel Erfolg beim Aufbau der nächsten Schaltung!
Kürzlich wurden in der Zeitschrift Elektor Mini-Oszilloskope besprochen. Es sind einfache Geräte, die im Kern einen Mikrocontroller mit schnellem Analog-Digital-Converter (ADC) aufweisen und mit einem einfach Display versehen sind. Die Ergebnisse sind durchaus beachtlich. Durch diesen Bericht animiert stellte ich mir die Frage: Kann man so etwas mit ganz einfachen Mitteln machen? Wie weit kommt man mit dem Arduino Nano, basierend auf einem ATmega32 mit 16MHz Taktfrequenz und einem I2C Graphic-LCD?
Die Frage lässt sich nur durch einen Test-Aufbau beantworten. Von Anfang an war klar, dass es kein „konkurrenzfähiges“ Produkt werden soll. Die getesteten Mini-Oszilloskope sind so günstig zu kaufen, zum Teil als Bausatz, dass es keinen Sinn macht, ein vergleichbares Gerät selbst zu entwickeln. Hier geht es also um das Prinzip. Und wie immer gibt es dabei viel zu lernen.
Vorüberlegungen
Der ATmega32 hat einen ADC auf dem Chip, der bereits mit einer sample-and-hold Schaltung ausgerüstet und somit für die Erfassung dynamischer Spannungsverläufe gut geeignet ist. Die Grundidee ist ganz einfach: Ein regelmäßiger Timer-Interrupt liest mit Hilfe des ADC den aktuellen Spannungswert am Eingang ein. Mit einer Trigger-Logik wird festgestellt, ob ein (einstellbarer) Schwellwert (trigger threshold) überschritten wurde. Wenn das der Fall ist, erfolgt die Datensammlung in ein Array. Sobald das Array gefüllt ist, wird es als Kurve auf dem Display ausgegeben.
Die Auflösung des ADC beträgt 10 Bit, also Werte von 0 bis 1023, was mehr als genug ist für diese Anwendung. Tatsächlich ist das Display mit seinen vertikalen 64 Pixeln, also 6 Bit, der beschränkende Faktor. Im Programm wird die Auflösung in zwei Stufen reduziert. Zuerst einmal wird nur das höherwertige Byte des ADC ausgelesen. Das lässt sich einfach machen, indem das Flag for left adjusted result (ADLAR) gesetzt wird. Es bleiben also 8 Bit. Diese Auflösung wird für die Trigger-Logik verwendet. Für die Anzeige der Kurve auf dem Display wird der Wert dann noch einmal um 2 Bit nach rechts verschoben, wodurch der verbleibende Wertebereich 0 bis 63 beträgt und somit gut auf das Display passt.
Der ADC arbeitet hier mit der internen Spannungsreferenz des ATmega von knapp 1.1V, wodurch der Messbereich festgelegt ist. Für diese einfache Anwendung habe ich auf eine analoge Verstärkung oder Aufbereitung des Signals, wie es für ein praktisch einsetzbares Oszilloskop unabdingbar wäre, verzichtet.
Eine kritische Frage ist die errechbare Geschwindigkeit des Daten-Samplings, ein wichtiges Qualitätsmerkmal jedes digitalen Oszilloskops. Der ADC des ATmega ist von einfacher Bauweise. Deshalb sollte man keine zu großen Ansprüche stellen. Der ADC wird mit einem internen Takt versorgt, der mit einem Vorteiler aus dem Systemtakt generiert wird. Das ATMEL Datenblatt empfiehlt Taktraten zwischen 50 und 200 kHz. Außerdem kann man dort erfahren, dass eine Umwandlung 13 Taktzyklen benötigt. Bei 200 kHz würde eine Umwandlung also 65µsec benötigen, was einer Sampling-Frequenz von 15 kHz entspricht. Geht es schneller? Das Datenblatt erwähnt, dass höhere Taktraten möglich sind, wenn man nicht die volle Auflösung von 10 Bit benötigt. Da in dieser Anwendung nur die höheren 8 Bit verwendet werden, habe ich mich für eine Taktrate von 500 kHz entschieden. Dadurch sinkt die Umwandlungszeit auf 26µsec, entsprechend 38kHz. Tatsächlich läuft die Abfrage des ADC mit einem Interrupt von 20kHz, was sich in den Experimenten als eine stabile Frequenz erwiesen hat. Man sollte aber nicht unterschätzen, dass der Prozessor damit unter signifikanter Systemlast steht.
Hardware
Der Aufbau ist minimalistisch und lässt sich schnell auf eine Steckbrett zusammen setzen. Im Zentrum stehen der Arduino Nano und das Graphik-Display, die über den I2C-Bus miteinander verbunden werden. Alle Details zum Graphik-Display sind an anderer Stelle beschrieben (Universelles I2C Interface für Graphik LC-Displays) Die Stromversorgung kommt über den USB-Port des Arduino. Das zu messende Eingangssignal gelangt über einen Kondensator an den Analog-Port A0 des Arduino. Ein lineares 100kOhm-Poti fügt eine feste Gleichspannung hinzu, womit die vertikale Position eingestellt werden kann. Für die interne ADC Spannungsreferenz wird noch ein 100nF-Kondensator gegen Masse am Referenz-Pin benötigt.
Eine LED am digitalen Port D6 dient als Anzeige des Trigger-Modus. Schließlich gibt es noch vier Tasten an den digitalen Ports D2 bis D5, über die die horizontale Zeitachse und der Trigger-Level eingestellt werden können. Damit ist der Aufbau auch schon beschrieben.
Software
Der Arduino-Sketch sieht komplizierter aus als er ist. Allerdings habe ich für die Steuerung von Interrupt und ADC nicht die Arduino-Funktionen gewählt, sonder die ATmega-Register direkt angesprochen. So war es möglich, das enge Timing besser unter Kontrolle zu halten. Zum Glück ist all das innerhalb der Arduino-IDE ohne Probleme möglich.
Eine zentrale Funktion ist die Interrupt-Service-Routine (ISR), die mit 20kHz aufgerufen wird. In dieser Routine wir der ADC ausgelesen und gleich wieder gestartet für den nächsten Durchlauf. Darauf folgt die Trigger-Logik und bei gesetztem Trigger das Abspeichern der Daten im Array für die Anzeige. Im zweiten Teil der ISR werden die vier Tasten (im Programm-Code etwas hochtrabend als keyboard bezeichnet) abgefragt und entprellt. Es gibt sogar eine einfache Tasten-Repeat-Funktion.
Die Sampling-Frequenz lässt sich über die Tastatur herunter regeln, was einer langsameren Zeitachse entspricht. Die Tabelle sar_table enthält die möglichen Einstellungen. Die derzeitige Software erlaubt 7 verschiedene Werte. Die ISR läuft in jedem Fall mit 20kHz. Für langsamere Einstellungen werden mehrere ADC-Werte gemittelt wie in der Tabelle angegeben (interrupts per sample).
Die setup()-Funktion erledigt alle Systemeinstellung und zeichnet die statischen Elemente auf den Bildschirm. Die loop()-Funktion schließlich wartet auf das Signal von der Interrupt-Routine, dass Daten zur Anzeige bereitstehen, und erledigt dieses mit der glcd-Funktion draw_function(). Die Software ergänzt den Kurven-Verlauf mit einem Raster aus gepunkteten Linien. Außerdem werden im Hauptprogramm mögliche Aktivitäten des Keyboards ausgewertet.
Für die Datenanzeige gibt es noch eine erwähnenswerte Besonderheit. Bevor ein neuer Kurvenzug gezeichnet werden kann, muss vorher der bestehende, „alte“ Kurvenzug gelöscht werden. In einer ersten Version des Programmes hatte ich dazu den Bildschirm vollständig gelöscht, was allerdings ein deutlich sichtbares Flackern zur Folge hatte. Eleganter geht das mit zwei Datenarrays. Eines enthält die vorherigen, „alten“ Daten und wird zum Löschen benutzt, während das zweite die aktuellen, „neuen“ Daten hat. Mit jedem Durchlauf wird zwischen den beiden Datenarrays hin- und hergeschaltet. Mit dieser Logik ist die Anzeige weitgehend frei von Flackern.
Anwendung
Die Anzeige ist einfach zu lesen. Die vertikalen, gepunkteten Linien sind das Raster für die Zeitachse. Die horizontale, gepunktete Linie zeigt den aktuelle Trigger-Wert. Am rechten Rand des Bildschirms befinden sich die eingestellten Parameter: der Trigger-Wert und die Zeitachse. Der Wert für die Zeitachse ist die Dauer eines Raster-Feldes in msec.
Zu beachten ist, dass das Gerät nur dann aktiv wird, wenn der Trigger eine ansteigende Flanke erkannt hat. Es gibt also keinen Auto-Modus wie bei anderen Geräten, in dem auch ohne Trigger der Signalverlauf angezeigt wird. Die LED, die bei jedem Trigger kurz aufleuchtet, erweist sich als ein gutes Hilfsmittel.
Fazit
Das kleine Oszilloskop macht sich in der Praxis erstaunlich gut, sofern die vergleichsweise niedrige Abtastrate kein Problem ist. Frequenzen von einigen 100Hz lassen sich sehr gut darstellen. Auch bei 2000Hz (entspricht 10 Datenpunkte pro Schwingung) bekommt man noch einen brauchbaren Eindruck der Signalform. Darüber ist aber kein sinnvolles Arbeiten mehr möglich. Ein schnellerer ADC wäre wünschenswert. Auch die vertikale Auflösung des Displays setzt klare Grenzen. Trotzdem ist es beeindruckend, was mit diesem geringen Materialaufwand und der einfachen Software machbar ist.
Das Smart I2C Graphic LCD kommt inzwischen öfter am Arduino zum Einsatz, wodurch Arduino-Projekte leicht mit graphischen Ausgaben bereichert werden können.
Hier ein einfaches Beispiel: Ein Analogwert – in diesem Fall ein Potentiometer zwischen Masse und Betriebsspannung – wird mit dem ADC ausgelesen und als horizontaler Balken angezeigt.
Hardware
Für diese Demo verwende ich einen Arduino Nano. Der Aufbau lässt sich schnell auf einer kleinen Lochraster-Platine realisieren. Die Stromversorgung kommt vom USB-Anschluss des Arduinos und versorgt auch gleich das Display mit 5V. Wir brauchen vier Anschlüsse zum Display: +5V, Masse und die beiden I2C-Anschlüsse SCL und SDA. Das Potentiometer wird mit dem analogen Port A0 des Arduino verdrahtet. Damit ist der Aufbau fertig.
Software
Um das GLCD über den Arduino anzusprechen, wird eine Bibliothek gebraucht, die die Graphik-Funktionen bereitstellt. Die glcd-Bibliothek besteht aus 3 Dateien im Ordner glcd_functions:
glcd_functions.cpp beinhaltet den Programm-Code für die Graphik-Funktionen. Die Logik ist sehr einfach. Im Prinzip werden die Parameter, z.B. Koordinaten der Linien und Rechtecke, übernommen und mit den entsprechenden Instruktions-Token an die I2C-Schnittstelle gesendet.
glcd_functions.h ist die zugehörige Header-Datei und beinhaltet die Definitionen der Graphik-Funktionen
keywords.txt listet die Schlüsselwörter der Bibliothek, so dass sie im Arduino-Editor farblich markiert werden
Der Folder glcd_functions mit diesen drei Dateien wird in den Folder libraries der Arduino-Umgebung kopiert. Damit ist alles vorbereitet.
Im eigentlichen Programm für diese Beispiel, es ist der Sketch glcd_demo.ino, wird ganz am Anfang die glcd-Bibliothek mit dem entsprechenden #include-Statement eingebunden. Außerdem wird eine Instanz des Graphik-Displays als globale Variable initiiert. Dabei wird die I2C-Adresse, in diesem Fall hexadezimal 20, übergeben. Damit sind alle Graphik-Funktionen verfügbar.
1
2
3
#include <glcd_functions.h>
glcd my_gd(0x20);//instance of the graphic display
Für den Bar-Graphen gibt es eine Datenstruktur bar_graph, die alle wichtige Daten zusammenfasst, z.B. Koordinaten der linken, oberen Ecke, Länge und Breite, und der aktuell angezeigte Wert. Dazu sind zwei Funktionen vorhanden: draw_bar_graph_frame() zeichnet einen Ramen mit einer Skala von 0 bis 100. Diese Funktion wird ganz am Anfang im setup()-Block aufgerufen. Die zweite Funktion refresh_bar_graph() erzeugt dann den Balken mit dem aktuellen Wert, der vom ADC kommt. Diese Funktion wird im loop()-Block aufgerufen. Schließlich sorgt der Aufruf von delay(100) dafür, dass die Loop etwa 10 mal pro Sekunde durchlaufen wird.
Neben den verschiedenen Zeichenfunktionen zeigt dieses Beispiel auch die Möglichkeiten, die Hintergrund-Beleuchtung zu steuern, wie es z.B. zum Stromsparen bei Batterie-Betrieb notwendig sein kann. Solange der ADC-Wert unverändert bleibt, wird nach Ablauf einer voreingestellten Zeit (verwaltet mi dem Zähler delay_cnt) das Display mit der Funktion dim_on() dunkel geschaltet. Sobald sich der ADC-Wert verändert, wird die Display-Beleuchtung mit dim_off() wieder auf ihren ursprünglichen Wert zurück gesetzt.
Fazit
Dieses Beispiel soll zeigen, dass das Display sehr einfach in eine Arduino-Anwendung einzubinden ist. Der Aufwand für Hardware und Software ist gering und eröffnet viele Möglichkeiten für ansprechende Darstellungen.
Das Graphik-Display „Smart I2C-GLCD“ hat inzwischen eine ganze Reihe Anwendungsgebiete gefunden. Dabei sind einige neue Funktionen hinzugekommen, z.B. das Zeichnen von gepunkteten Linien oder die Ausgabe von negativen Zahlen. Durch den größeren Funktionsumfang war der Instruktions-Interpreter aber nicht mehr effizient und musste verbessert werden.
Zur Erinnerung: Das Graphik-Display empfängt Instruktionen über das I2C-Interface. Das erste Byte jeder Datensendung ist das Command-Token und bestimmt, welche Funktion ausgeführt werden soll. Z.B steht 17 für das Zeichnen einer Linie oder 32 für die Ausgabe eines Zeichens. Im bisherigen Programm gab es eine Switch/Case-Konstruktion, die sich durch die Liste der möglichen Instruktion-Tokens hindurch hangelte, bis der passende Token gefunden wurde. Dort wurde dann in die entsprechende Graphik-Funktion verzweigt. Das funktionierte gut mit 5 oder 10 möglichen Tokens, macht aber keinen Sinn mehr für die derzeitige Liste von über 30.
Wie geht es besser? Die Idee ist ganz einfach: Eine Tabelle, die für jeden Token einen Zeiger auf die zugehörige Graphik-Funktion. Mit Hilfe dieser Tabelle kann der Instruktions-Token als Index genutzt werden, um ohne Schleifen direkt den jeweiligen Tabellen-Eintrag zu finden.
Allerdings benötigt der Instruktionsinterpreter nicht nur den Zeiger auf die zugehörige Funktion, sondern auch die Anzahl der Parameter, die zum Ausführen der Funktion benötigt werden. Die Graphik-Funktion draw_char() braucht nur einen Parameter, eben das zu zeichnende Zeichen, während die Funktion draw_line() 5 Parameter benötigt, die Koordinaten des Start- und Endpunktes und der Modus. So ergibt sich eine Tabelle mit zwei Spalten: dem Zeiger auf die zugehörige Graphik-Funktion und der Anzahl der Parameter.
Die Sprache C macht den Umgang mit Zeigern nicht gerade einfach. Auch nach vielen Jahren Programmierpraxis ist die zugehörige Syntax immer wieder verwirrend. Zum Glück konnte ich noch meinen alten „Kernighan & Ritchie“ im Regal finden (meine Ausgabe ist von 1986). Dieses immer wieder erstaunliche Buch zeigt die zugehörige Syntax.
Und so ist der neue Instruktions-Interpreter entstanden. Das Kernstück, die zweidimensionale Tabelle, wird mit Hilfe einer Struktur definiert.
1
2
3
4
typedefstruct{
void(*cmd_func)(void);
int8_t parm_count;
}cmd_entry_t;
Die Formulierung void (*cmd_func)(void) ist ein Platzhalter für die Zeiger auf die jeweiligen Graphik-Funktion. Die Instruktions-Tabelle ist ein Array von der oben definierten Struktur. Sie wird gleich mit den entsprechenden Einträgen initialisiert:
1
2
3
4
5
6
7
8
9
10
cmd_entry_t cmd_table[]={
{cmd_ignore,0,},// 0
{cmd_glcd_on,0,},// 1
{cmd_glcd_off,0,},// 2
{cmd_set_display_light,1,},// 3
{cmd_set_dim_on,0,},// 4
{cmd_set_dim_off,0,},// 5
{cmd_set_i2c,1,},// 6
...
};
Natürlich müssen die Funktionen, die in der Tabelle auftauchen, entsprechend definiert sein. Hier sind die Funktions-Prototypen gezeigt, die üblicherweise in einer #include-Datei stehen:
1
2
3
4
5
6
7
8
9
// command function prototypes
voidcmd_ignore(void);
voidcmd_glcd_on(void);
voidcmd_glcd_off(void);
voidcmd_set_display_light(void);
voidcmd_set_dim_off(void);
voidcmd_set_dim_on(void);
voidcmd_set_i2c(void);
...
Im Instruktions-Interpreter wird das Command-Token über das I2C-Interface eingelesen, der Wertebereich überprüft, und wenn der passt die entsprechende Funktion aufgerufen.
1
2
3
4
5
6
7
8
9
cmd_token=I2C_fetch_byte();// get instruction token
if(cmd_token<sizeof(cmd_table)/sizeof(cmd_entry_t)){// range check
parm_buffer[i]=I2C_fetch_byte();// if yes, get parameters
(*cmd_table[cmd_token].cmd_func)();// and call graphic function
}else{
cmd_show_error();// if not, show error
};
parm_buffer[] ist ein globales Array, in dem der aktuelle Command-Token und die zugehörigen Parameter abgelegt werden. Dieses Array wird von den Graphik-Funktionen genutzt, um die jeweilige Aktion zu steuern. Als Beispiel wird hier die Funktion cmd_draw_line() gezeigt, die die zugehörige Graphik-Funktion zum Zeichnen einer Linie aufruft:
1
2
3
4
/* cmd_draw_line - plots a straight line -----------------------*/
Nach einigen Versuchen funktioniert der neue Instruktions-Interpreter ganz hervorragend. Das Programm ist damit deutlich kürzer und effizienter geworden.
Die neue Software ist bei den Ressourcen zu finden unter Smart I2C Display, Firmware