Bernd Leitenbergers Blog

Nochmal 5 Tage durch die Crossplattform-Entwicklung

Ich hatte ja schon mal einen Teil 1 verfasst. der sich mit meinem Projekt einer Wetterstation beschäftigt. wer es noch nicht getan hat, dem rate ich diesen Teil zuerst zu lesen. Teil 2 knüpft nämlich daran an.

Ich habe mir das Ziel gesetzt eine eigene Wetterstation zu betreiben die automatisch eine Webseite aktualisiert und die Meßwerte dort laufend publiziert. Die Meßwetgeber stammen von Tinkerforge. Dazu gibt es auch einen separaten Testbericht. Die Steuerung erledigt ein Raspberry Pi. Er generiert auch die Bilder und die Webseite und lädt sie auf meinen Server hoch.

Stand Ende letzter Woche war, das die Anwendung im Prinzip lief, es aber noch einige Bugs auszuräumen gab und ich konkrete Pläne zur Verbesserung und Weiterentwicklung hatte. Auch war noch nicht geklärt ob ich die Charts selbst zeichne oder nicht eine Komponente nehme die Lazarus mitbringt.

Inzwischen hatte ich auch die Entwicklungskette im Griff: Die Entwicklung erfolgt zuerst auf einem Windows PC. Ohne Meßwertgeber geht dort die Hauptschleife mit einem Einlesen über einen Timer nicht, aber die war eigentlich auch erprobt und lief. Das Auswerten der Daten die auch auf die Disk geschrieben werden geht aber auch vom Windows PC aus. Danach wird das Programm von einem Raspberry PI 2 Model B übersetzt. Erst danach auf einen Raspberry Pi Model B+ (also mit nur einem CPU-Kern) überspielt. Das hat seinen Grund: Der Raspberry Pi 1 war nicht über Remote Desktop erreichbar, nur über Putty. Der Compiler läuft aber auf der grafischen Oberfläche. Zudem ist das Kompilieren auf dem Rechner mit nur 600 MHz und einem Kern ein echtes Geduldsspiel.

Tag 1

Das erste was ich erreichen wollte war, das die Versionen von Lazarus auf dem Windows PC und dem Raspberry Pi 2 die gleichen sind. Ich hatte es zwar fertig gebracht dort die Version 1.5 von Lazarus zu installieren (eigentlich eine Entwicklungsversion), aber der ignorierte einige wichtige Tasten wie []{} komplett. Ich suchte nach einer Alternative und schließlich fand ich eine Webseite, die die Kompilierung unter Windows von Lazarus 1.4 beschreibt. In einem mutigen Schritt ersetzte ich einfach die Anweisungen für die 1.5 Installation durch die dortigen und siehe da – es funktionierte. Wichtig war nur nun noch alle Pfade anzupassen die bisher auf die völlig veraltete Lazarus 0.93 Version zeigten. Auf dem Raspi 1 änderte ich nichts. Er hat viel weniger Rechenpower und RAM (schon beim Raspi 2 muss man die Swapdatei vergröbern)., Dort ließ ich den 0.93 Compiler. Das ist der einzige den man über die offizielle Pakte Verwaltung installiert bekommt. (Warum eine so veraltete Version?)

Der Sinn ist der: es gab schon in der letzten Version Probleme wenn ich das Projekt auf dem ARM lud. Eigenschaften bei Buttons waren der alten Version des dortigen Compilers unbekannt und eine Formatierung der X-Achse als Zeit wird in Version 0.93 und 1.4 völlig unterschiedlich geregelt und ergibt immer Fehler in einem der beiden Compiler. Es sollte also nur eine Version genutzt werden. Beim Raspi 2 lief nun auch die Version 1.4

Tag 2

Ich versuchte nochmal den Ansatz mit den mitgelieferten Charts. Sie sehen etwas besser aus als meine Grafiken. Nach Anpassung lief das Programm dann auch mehrere Stunden auf dem Raspi 2. Ich transferierte es auf den Raspi 1 und dort lief es über Nacht – alles kann doch so schön sein, dachte ich mir noch. endlich auf dem richtigen Weg, nun wird es sicher besser. Ich sah positiv in die Zukunft – bis morgen natürlich mein guter alter Bekannter Murphy an die Tür klopfte …

Tag 3

Damit ich auch eine Kontrolle habe, ob die Internetseite aktuell ist und somit ob nicht der Raspi abgestürzt ist, baute ich noch das Parsen der HTML-Vorlage von einigen Variablen ein, die dann folgende Tabelle ergeben:

Gemessen am 10:49:16
Letzte gemessene Temperatur: 24,9 Grad Celsius
Letzte gemessene Objekt-Temperatur: 23,2 Grad Celsius
Letzte gemessene Luftfeuchtigkeit: 36,3 Prozent relativ
Letzter gemessener Druck: 1017,5 hPa
Letze gemessene Helligkeit (Sensor misst nur maximal bis 900 Lux) 829,3 Lux

Während das Programm auf dem Raspi 2 problemlos lief, stürzte das kompilierte Programm auf dem Raspberry 1 sofort ab. Es erscheint nicht mal die Benutzeroberfläche. Wenn man es mit dem 0.93 Compiler übersetzt läuft es, stürzt aber beim Starten der Messung ab. Man erhält nur die Meldung dass der Debugger auch abgestürzt ist – auch ein Grund warum ich die 1.4 Version haben wolle. Wie ich noch von der Lehre an der DHBW weiß ist der Debugger bei den alten Versionen von Lazarus absturzgefährdet. So war der Fehler nicht einzukreisen. Auch Reboot half nichts. Ich nahm den Raspi 1 außer Betrieb und setzte den Raspi 2 ein. Der darf nun auch einen neuen Sensor unterstützen, der die Objekttemperatur misst. Auch der Raspi 2 macht ab und an Probleme. So beschwert er sich nach einem Reboot das er die Mrrko-SD-Karte nicht findet. Rausziehen und erneut reinstecken löst das Problem, nur warum bei einem Reboot wenn er vorher stundenlang lief? Ich verstehe bis heute nicht warum man bei der Pi-Foundation nicht die SD-Karten beibehalten konnte. Die sind nicht so fummelig, robuster und man bekommt sie auch leichter in den Steckplatz rein. Leider haben nun auch die neuen Raspberry B Modelle nur einen Mikro-SD Slot. Dafür aber auch vier USB-Ports wie der große Bruder.

Tag 4

Ein blick auf die Webseite am Morgen zeigt das der Raspi knapp 2 Stunden arbeitete und dann um halb vier nichts mehr ausgibt. Er reagiert auch nicht mehr auf Remote Desktop und Tastaturereignisse. Irgendwo ist noch ein Fehler in der Meßwerterfassung. Ich fasse mehr Routinen in Try -Except Blöcke, merke mir den Indes beim Start von Ausgaberoutinen (die Meßwerterfassung läuft über einen Timer weiter) und mache Ausgaben auf der Oberfläche. Es zeigt sich das die ARM Plattform anders reagiert als Windows. So gibt es einen Runtime Fehler 216 bei der Zeile:

MittlereHelligkeit := Gesamt / (Index+1)

zuerst denke ich an eine Division durch 0, aber das kann nicht sein, denn es wird ja 1 addiert. Der Fehler kommt dann auch vor bei einem Index von 9456. Noch rätselhafter ist die Nummer des Fehlers eigentlich für eine mathematisch nicht definierte Operation wie eine Wurzel aus einer negativen Zahl steht. Wenn man den Variablentyp durch eine double ersetzt, funktioniert die Zeile. Es gibt also keine implizite Umwandlung von Integer in Float wie bei Windows Version von Lazarus. Weitere Tests laufen über Stundenm melden dann aber einen Speicherzugriff auf der Oberfläche, während die Anwendung noch weiter läuft. So am Morgen des 5-ten Tages ein Fehler um 3:21, doch die Erfassung und Ausgabe läuft noch bis 6:52. Dann steigt der Raspi 2 aus. Alles sehr rätselhaft.

Wenn es einen Fehler gibt dann scheitert auch das folgende Kompilieren an internen Fehlern von Lazarus. da hilft nur eines, wie Paso Double schon 1985 in „Computerliebe“ dichtete „Schalt mich ein und schalt mich aus, die Gefühle müssen raus“ oder auf neudeutsch: „Wenn nichts mehr tut hilft nur Reboot“. Danach klappt’s auch mit dem Compiler. Aus demselben Lied: „Erste Regel für den Notfall am Computer: Null Emotionen“ ist auch ganz nützlich.

Von den Charts habe ich mich wieder verabschiedet, weil sie durch die bis zu 3600 Meßwerte pro Tag „zittrig“ aussehen. Ich schreibe meine Grafikroutinen so um dass sie maximal 800 anzeigen, darüber Mittelwerte bilden und in jedem Falle noch ein 48-werte Mittel anzeigen. Die Skala passe ich dynamisch an, sodass sie X-Achse entweder bis morgens um 6, 12 18 oder 24 Uhr geht je nach Tageszeit. Nun sehen die Grafiken recht gut aus.

Tag 5

Einer der Fehler ist offensichtlich die Kommunikation mit den Bricklets. Die bricht öfters mit einem Kommunikationsfehler ab, wie ich nun bemerke. Die Unit hat einen Timeout von 2,5 s. Doch mein Timer holt jede Sekunde einen Wert ab. Das könnte eine Fehlerursache ab. Ich schalte den Timer zu Beginn der Meßwerterfassung ab und danach erst wieder ein. Erneut tritt ein neuer Fehler auf: diesmal wenn der Arrayzugriff auf ein nicht existentes Element zugreift – der Index wird offensichtlich nicht immer um Mitternacht auf 0 zurückgesetzt was auch die Fehler in den frühen Morgenstunden erklären kann. Wieder zeigt sich das der ARM Compiler irgendwie anders funktioniert, denn er bemängelt den Fehler in einer komplett anderen Zeile, die eine Datei lädt.

Ich baue nun in alle Routinen Ausgaben in eine Logdatei ein, nachdem ich schon seit Tag 4 die Objekttemperatur erfasst habe, die der neue Sensor als Zusatzmöglichkeit bietet taucht sie nun auch in den Ausgaben auf. Ein Versuch auch den Raspi 1 mit dem neuen Compiler zu beglücken scheitert. Immerhin gelingt mit einem neuen VNC.-Server eine Remote-Desktopverbindung. Die Verbindung zu dem Raspi 1 bleibt aber instabil und reist auch bei Putty immer wieder ab. Das ist kein Wlan-Pproblem sondern tritt auch auf wenn man ihn über Powerline anschließt. Zur Sicherheit, falls ich doch mal die Anwendung nicht unter der grafischen Oberfläche laufen lassen kann ersetze ich die TBitmaps durch BGRABitmaps die nicht auf der LCL beruhen. Damit könnte ich die Anwendung als Cronjob starten und zur Sicherung gegenüber Abstürze den Rechner ebenfalls über Cronjob regelmäßig neu booten. Das gilt zu diesem Zeitpunkt als letzter Backupplan.

Tag 6

Morgens der Blick auf die Webseite zeigt – der Raspi läuft noch. Ein Kontakt über remote Desktop geht ebenfalls. ein Blick ins Log zeigt nur Infomeldungen – na also es geht doch. Jetzt noch einige kleine Änderungen so führe ich auch mal die Chiptemperatur des Barometers mit, um zu sehen welchen Fehler das hat (angeblich sehr viel ungenauer als selbst der billigste Temperatursensor der nur auf 0,5 Grad genau ist) und das neue Programm um 12 Uhr überspielt. Immerhin ist der Raspi 2 nun über 18 Stunden am Stückl gelaufen und das neue startet wie die letzten Versuche auch ohne Fehler. Eigentlich müsste nach zwei tTgen ohne Probleme nun wieder ein Fehler kommen.

Soweit der Stand vom Samstag. Wie geht es weiter? Langfristig will ich den Raspi 1 wieder mit der Aufgabe betrauen. Ich brauche ihn sonst für nichts mehr.  Derzeit ersetzt er meinen Raspi 2 als Mediencenter (Openelec). Überlegenswert wäre auch die Messwerterfassung auf Callbacks umzustellen. Das wird in der Dokumentation als die bessere Möglichkeit für zyklische Abfragen beschrieben. Ich hielt das nicht für nötig, weil in Beispielen so was erschien wie der Anstieg des Lichtsensors, wenn man ihn mit einer Taschenlampe überstreift – dazu muss man im Millisekundenintervall messen und da sollte meine Messung einmal pro Sekunde wohl nicht zu viel sein. Aber nach den Kommunikationsproblemen denke ich wäre das eine Alternative. Leider melden sich Callbacks nur bei veränderten Werten nicht nach einer bestimmten Zeit. So müsste ich pro Meßgröße (derzeit 5) eine eigene Zeitbasis einführen, während ich bisher eine Zeitbasis für alle Meßwerte habe.

Auch die Indexeite bedarf noch etwas Aufhübschung. Danach wäre das Projekt auf der Raspiplattform abgeschlossen, dann ginge es an das Auswertuen unter Windoes über Tage hinweg.

Resümee

Es geht, aber es war nicht wenig Arbeit. Allerdings gehöre ich zu den Leuten die Gene Kranz Einstellung teilen: „Failure Is Not an Option „.  Aufhören kam also nie in Frage. Wenn jemand anders das angehen will, dann würde ich ihm aber ein paar Tipps geben die ich gezogen habe:

Kein Kit kaufen sondern Basisbrick, Feuchtigkeits-, Ir-Temperatur und Drucksensor. Das Gehäuse ist Schrott und nicht dicht, der Lichtsensor ist schon mit Schatten übersteuert und das LCD-Display braucht man für eine Station für draußen nicht.

Überlegen was als Rechner eingesetzt wird. Tinkerforge bietet einen ähnlichen Kleinstrechner den „Red Brick“ an. Diesem soll man einfach Programme zum ausführen übergeben können. Allerdings denke ich klappt das gut nur bei Skriptsprachen oder Bytecode (Java, .net). Den Ansatz für kompilierte Sprachen wie C oder Delphi den Windows x86 Code crosszucompilieren halte ich für sehr fehlerträchtig und langsam, läuft schließlich auf eine Emulation heraus. ARM Programme sind übrigens signifikant (etwa um ein Drittel bis zur Hälfte) länger als x86 Programme.

Wenn man sich nicht damit auseinandersetzen will kann man einen ausgedienten PC nehmen oder einen der sowieso dauernd an ist (viele haben ja inzwischen eigene Mediaserver oder NAS daheim, der kann dann auch noch die Wetterstation betreuen. Da hat dann aber ein Problem mit der Witterung. Wenn man genügend Geld hat, kann man auch Intel NUC nehmen. Der kleinste Intel DN2820FYKH NUC-Kit (Intel Celeron Prozessor N2820) kostet knapp 149 Euro ohne Platte und Speicher. Mit 4 GB (für Windows) und einer 2,5 Zoll Platte ist man dann bei etwa 250 Euro. Das ist verglichen mit einem Raspberry, einer SD-Karte und einem Netzteil zwar etwa 190 Euro teurer aber man kann die Programm 1:1 von einem Desktop übernehmen. Wenn er sowieso ins Netz eingebunden ist (muss er ja wegen dem zyklischen Aktualisieren der Webseite) kann man ihn auch noch für andere Dinge nutzen. Nur muss man dann den Ruhezustand deaktivieren. Der Komfort hat einen Preis, jeder muss entscheiden wie viel ihm seine Arbeitszeit selbst wert ist.

Lazarus hat mich unter Windows überzeugt. Das Projekt hat sich in den letzten Jahren deutlich weiterentwickelt und holt gegenüber Delphi deutlich auf. Einige Sachen sind sogar besser gelöst, so wird der Suchpfad angepasst wenn man eine Datei aus einem Verzeichnis aufnimmt – so brauche ich von den Bibliotheken von Tinkerforge mehr als eine Datei. Vor allem kann man mit dem Packlage anchordockingdn endlich das angenehme Verhalten von angedockten nicht wirr herumliegenden Fenstern einstellen.

Ich habe mal auf dem Pi 2 das Lazarusverzeichnis gezippt und hoffe das so auf dem Pi 1 doch noch installieren zu können. Wenn das klappt könnte ich es eigentlich als Download für alle zur Verfügung stellen – dann müsste keiner mehr den Compiler aus den Quellen selbst erstellen.

Die mobile Version verlassen