Samstag, 2. Dezember 2017

RMS-Werte messen


Wie misst man den RMS (Root Mean Square) einer Wechselspannung ?

Der Effektivwert einer Spannung U ist definiert als diejenige Gleichspannung U_eff, die an einem Widerstand die gleiche Wärmemenge (Leistung) abgibt, wie die Wechselspannung U. Um den Effektivwert zu berechnen, berechnet man "einfach" die Fläche unter der Kurve, also das Integral über eine Periode, der Wechselspannung.

Es gibt eigentlich zwei "klassische" Methoden: Man nimmt einen "True RMS Konverter", den gibt es fertig als IC, etwa von Analog Devices, der eine dem Effektivwert der Spannung proportionale Gleichspannung erzeugt. Dazu wird die Eingangsspannung quadriert und der Mittelwert berechnet.

Oder man macht das digital, d.h. man erfasst die Spannung mit einem AD-Wandler und berechnet das Integral numerisch, berechnet also den Mittelwert des Absolutwerts. Die spannende Frage ist, welche Abtastrate braucht man. Handelt es sich um ein periodisches Signal, dann braucht man nicht besonders schnell abzutasten, die Abtastfrequenz kann durchaus auch niedriger als die Signalfrequenz sein (undersampling). Da letztlich ja nur der Mittelwert von Interesse ist, braucht man nur insgesamt genügend samples, um eine gute Näherung des tatsächlichen Werts zu erhalten. Außerdem kann es Probleme geben, wenn die Sample and hold-Schaltung zu langsam und ggf. nichtlinear ist.

Konkret geht es hier darum, eine sinusförmige Wechselspannung verhältnismäßig genau (besser als 1%) zu messen. Das Signal ist Bandpass-gefiltert, also gibt es keine Probleme mit Aliasing. Die Signalfrequenz ist 3 kHz, die (maximale) Abtastrate des verwendeten Arduino Due etwa 80kHz.

Aber wieviele Samples braucht man für welche Genauigkeit ? Ein einfaches Experiment soll Aufschluss geben. Ein Sinusgenerator erzeugt ein 3kHz-Signal, das an einen der analogen Eingänge des Arduino geht und mit 12 Bit Auflösung digitalisiert wird.


Es wird eine variable Anzahl von Samples aufgezeichnet, die Null-Linie berechnet (einfach der Mittelwert), quadriert, Mittelwert berechnet und wieder die Wurzel gezogen. Das gibt dann den Effektivwert. Um den Effekt verschiedener Abtastraten zu untersuchen, wird zunächst "ungebremst", dann mit einer variablen Verzögerung von 1-4msec gemessen. Das wird für unterschiedliche Anzahlen von samples (100 bis 2000 samples) wiederholt. In der Abbildung oben sieht man das Ergebnis. Dargestellt ist die Standardabweichung des RMS-Werts bei 20 aufeinanderfolgenden Messungen. 

Man sieht, dass die Standardabweichung mit steigender Anzahl von samples kleiner wird, zwischen etwa 1000 und 1500 samples scheint ein etwa konstanter Wert erreicht zu sein. Mit zunehmender Verzögerung zwischen den Samples wird das Ergebnis auch immer besser.

Die Verbesserung mit zunehmender Anzahl von samples ist leicht erklärbar: Da nicht über ganze Perioden gemessen wird, entstehen immer Fehler, die immer kleiner werden, je mehr samples betrachtet werden. Die Ursache des zweiten Effekts ist nicht so klar. Es könnte sein, dass der zeitliche Abstand zwischen zwei samples stärker schwankt, je größer der Abstand --> zufälligere Verteilung der Messpunkte. Möglicherweise kann sich aber auch bei längerem Abstand die S&H-Schaltung erholen .... Mal überlegen, wie man das rauskriegen könnte.

Montag, 25. April 2016

Temperatur messen ist meistens einfach ...


aber nicht immer.

Hier geht es darum, die Temperatur der Keramikleisten an einem Saugkasten zu messen. Da kommt man leider gar nicht gut ran, der rote Pfeil zeigt auf eine solche Leiste (das kleine graue "Ding" zwischen der blauen und der bräunlichen Kante (kann man kaum sehen). Das Problem dabei ist, dass auf dieser Leiste das Formiersieb (das hier im Bild am roten Pfeil schräg nach rechts oben verlaufende "Ding") läuft. Und zwar im Betrieb ziemlich schnell, da ranzukommen wäre gar keine gute Idee. Das ist übrigens die Leiste, an die man am besten rankommt, die anderen, zum Beispiel am blauen Pfeil, kann man hier im Bild überhaupt nicht erkennen ...

Um besser zu verstehen, was an einem solchen Saugkasten wirklich passiert, will ich die Temperaturen an mehreren Stellen messen, aber zunächst brauche ich ein Gefühl dafür, in welchem Bereich sich das ungefähr bewegt. Also ein Vorversuch. Im Prinzip ganz einfach, Kontaktthermometer mit langem Arm, an dem ein präziser, kleiner Fühler hängt. Gibt's bestimmt irgendwo zu kaufen, die Frage ist bloß wo und für wie viel.

Solche Thermometer mit einem 10cm langen Fühler gibt's an jeder Ecke, das hilft hier bloß nichts, man kommt nicht so nahe ran (es sei denn, man hat ernsthafte Ambitionen, vorzeitig aus dem Leben zu scheiden oder zumindest einen Arm zu opfern ...

Also selber basteln. Wie üblich ;-) Das Ergebnis:


Wunder der Globalisierung, das Material hat grade mal 20 € gekostet. Ein Miniatur Pt100, dazu ein Einbauinstrument zur Temperaturmessung und ein bisschen Kram aus der Bastelkiste. Das Interessante ist der Fühler selber. Die thermische Trägheit des Fühlers soll möglichst klein sein: Die Keramikleiste hat einen Querschnitt von vielleicht einem Quadratzentimeter und ist schön glatt poliert. Mit einem großen Fühler im Metallgehäuse kühlt man vermutlich eher die Leiste ab, als deren Temperatur zu messen, zumindest, wenn der thermische Kontakt gut ist und lang genug hält. Das ist aber gar nicht so einfach, da man das Ganze ziemlich freihändig einen Meter vom Körper entfernt möglichst ohne zu wackeln an die Leiste hält.

Um diesen Balanceakt zu erleichtern, eine spezielle Fühlerkonstruktion:

Der Messkopf (zum Größenvergleich die Pfote meines Katers) besteht aus einer dünnen Kupferscheibe (etwa 100µm dick, 10mm Durchmesser), auf der der PT100 (etwa 2x2x1mm) befestigt ist. Dieser Kopf ist mit einem Stückchen Silikonschlauch mit der Elektronik verbunden. Durch diese etwas elastische Kopplung ist es möglich, die Kupferscheibe vollflächig an die Leiste zu drücken, auch wenn man den richtigen Winkel nicht ganz trifft (man sieht ja nicht hin ...) und dabei eine möglichst große Kontaktfläche zu haben (dann kriegt man möglichst schnell Leiste und Fühler auf die möglichst gleiche Temperatur).

Da Silikon grundsätzlich schlecht zu kleben ist (hier zwar mit einem speziellen Silikonkleber, aber trotzdem ...), sollte man das mit der Elastizität nicht übertreiben, gedacht ist es ja, um einen Winkelfehler von vielleicht fünf Grad zu kompensieren. Die erste Version habe ich ein paar Ingenieuren überlassen, die den Messkopf prompt zerstört haben. Auf meine Frage, wieweit sie den Kopf gebogen haben, lautete die Antwort: "So weit, wie es ging". *arrrghhhhhhhh*


Montag, 11. April 2016

KI und so


IBM versucht ja seit einiger Zeit, mit dem Watson-Portfolio KI-Anwendungen in verscheidenen Branchen in den Markt zu bringen. Aktuell mit der Emotional Analysis API, einer Linguistik-Engine, die eine Persönlichkeitsanalyse aus einem Textmuster erzeugt.

So etwas gibt es ja schon lange, das kommerzielle Ziel ist (natürlich) effektivere Werbung, siehe den obigen Screenshot aus der Demo. Nur meistens funktioniert das nicht besonders gut. Um rauszufinden, ob es sich lohnt, Zeit zu investieren und gründlicher zu testen, wie gut das System funktioniert, habe ich mal mein letztes Paper analysieren lassen (eigentlich sollte man einen Text über Alltagsthemen verwenden, andererseits sind Industrie 4.0-Ansätze in der Papierindustrie heute ja ein Alltagsthema ;-)

"sceptical and strict", "imaginative", "intrigued by new ideas" sind ja durchaus Attribute, die einer wissenschaftlichen Arbeit zu stehen. "unconcerned with helping others" folgt hoffentlich nur aus der sachlichen Natur einer solchen Veröffentlichung ;-)

Jedenfalls scheint das Ergebnis mehr als zufällig zu sein, ich werde wohl in den nächsten Wochen (theoretisch bin ich im Forschungssemester und habe Zeit für solche Sachen ;-) ein bisschen mehr Zeit mit diesem System verbringen.

Anwendungen gibt es dafür ja viele, von der Früherkennung von Problemen bei der Analyse von Besuchsberichten von Außendienstlern (das ist das, was mich am meisten interessieren würde) bis zur massenhaften Untersuchung von emails nach anderen Kriterien, vielleicht "Likely to be a terrorist".

Freitag, 3. Juli 2015

Mal was ganz anderes ....


ich habe heute aus aktuellem Anlass den Nachmittag über mit dem neuronalen Netz von google rumgespielt, das Bilder "träumen" kann .... cooler Stoff. Allerdings ging das nicht ganz ohne Probleme ab: Grundsätzlich schon so, wie in der Anleitung, aber nachdem endlich alles installiert war (also nach etwa zwei Stunden) stürzte python immer beim import von caffe mit einer segmentation violation ab.

Nach einigem suchen stellte sich raus, dass das daran liegt, dass die mit dem Betriebssystem (Mac OS X 10.10) mitgelieferte python Library (natürlich) nicht zur aktuellen, installierten python Version (2.7.10) passt. Abhilfe: Die System-Libraries ausser Gefecht setzen (/System/Library/Frameworks/Python.framework umbenennen und durch einen Link auf die aktuelle Version ersetzen, bei mir /usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/) und schon geht's.

Dafür funktioniert jetzt iPhoto nicht mehr, das will nämlich die alte Version *grrrr*

Mittwoch, 1. Oktober 2014

Ingestion rates


Im September gab es eine (durchaus interessante) Veranstaltung in Stuttgart, die mongoDB IoT european city tour. Thema war, ob (na ja, also natürlich "das") mongodb die ideale Basis für das Internet of Things sei. Dabei ergab sich die Gelegenheit, einen der Chief sonstwas Architects von mongodb zu fragen, warum (zum Geier) man denn eine (dokumentenorientierte) NoSQL-Datenbank braucht, um sehr einfach strukturierte Sensordaten zu speichern. Nach meiner unmassgeblichen Ansicht ist eine relationale Datenbank hier viel besser geeignet.

Die Antwort war: "Ingestion rate" (nach einigem Nachdenken kam dann noch "If you want to annotate your data ...", das ist ein guter Punkt, aber halt nur, wenn man das dann auch in unstrukturierter Form machen will. Und nach noch längerem Nachdenken "Open Source").

Also "Ingestion rate". Das Lieblingswort der NoSQL-Anbieter, wie mir scheint. Solche Aussagen wecken immer ganz schnell meine Neugier. Also habe ich die Zeit vor Semesterstart für einen kleinen Benchmark genutzt.

Das Szenario ist einfach: Eine Anzahl von Sensoren, die Daten liefern, beispielsweise 100 Sensoren, die ein paar Mal pro Sekunde einen Wert (etwa einen Ort oder eine Geschwindigkeit) liefern. Gespeichert wird für jede Messung die Zeit, der Wert, die Art des Werts und die ID des Sensors. Alles ints. Transaktionen brauchen wir hier eigentlich keine, da keine Werte geändert werden. Die einzigen Operationen sind das Anlegen neuer Datensätze und Lesen bereits bestehender.

Zunächst in einer mysql-Datenbank. Ein INSERT pro Wert, MyISAM-Engine. Kein Index. Dann mongoDB. Zunächst auch ein Wert pro insert, dann bulk-insert mit jeweils 1000 Werten. Auch ohne Index. In der Realität werden hier also die Zahlen schlechter (also langsamer) werden, denn ohne Index dauert es viel zu lang, die Daten zu finden.

Wenn man sich mal genauer überlegt, was man in diesem Fall eigentlich braucht, dann kommt man (hoffentlich) früher oder später darauf, dass eine Datenbank eigentlich overkill ist: Eine Zeitreihe kann man leicht in einer (Binär-) Datei speichern. Das Einfügen (also hier ja nur ein Anhängen) geht einfach. Suchen ist etwas schwieriger. Die typischen Abfragen in einem solchen System sind "Gib mir die Werte aus einem bestimmten Zeitintervall", beispielsweise den letzten zehn Sekunden usw.

Wenn hier jeweils die ganze Datei durchsucht werden muss, dann ist das viel zu langsam. Also braucht man einen Index. Da man in der Regel aber sowieso aggregierte Werte haben will, um die Darstellung auf unterschiedlichen Zeitskalen zu beschleunigen, ist das gar nicht so schwierig: Man speichert sowieso nicht nur die Originaldaten, sondern dazu noch Mittelwerte (und ggf. andere Verteilungsparameter) je Sekunde, Minute, Stunde, Tag usw. Wenn man hier jeweils noch die (ungefähre) Position dieses Intervalls in der grossen Datei mit den Originaldaten speichert, hat man eine Art B*-Baum für Zeitreihendaten. Der oberste Knoten sind die Monate(oder Jahre oder wasauchimmer). Auf der nächsten Ebene kommen die Tage, dann die Stunden, dann die Minuten, dann die Sekunden, dann die Daten. Sucht man die Daten für einen bestimmten Zeitpunkt, fängt man oben an, kommt so zum richtigen Tag, dann zur richtigen Stunde, zur Minute, zur Sekunde und schliesslich in die Datei, wo man einen Block oder so liest und die Daten hat. Programmieraufwand so in der Größenordnung von ein paar Tagen.

Das Ergebnis ist beeindruckend: MySQL und mongoDB liegen eher nah beieinander, MySQL etwa doppelt so schnell wie mongoDB. Beide in der Größenordnung (genauer ist das eh nicht, wir wollen ja nur ungefähre Zahlen haben) von 10.000 Datensätzen pro Sekunde.

Die "handgestrickte" Version mit Dateien (hier wurde nur der Index für die Sekunden realisiert, die oberen Ebenen wurden, da für die Performance irrelevant, weggelassen) schafft etwa 2 Millionen Datensätze pro Sekunde, also etwa 200 mal mehr als die Datenbanken !

Interessant ist hier, dass der bulk insert bei mongoDB praktisch keine Verbesserung bringt (bulk inserts scheinen ein schwieriges Thema zu sein, siehe etwa hier und hier).

Wenn man bei den Datenbanken noch Indices verwendet, muss man sehr ausfpassen, dass die Performance nicht in den Keller geht (siehe etwa hier).



Also: Wegen "Ingestion rate" braucht man keine NoSQL-Datenbank !



Üblicherweise kommt dann der Einwand, dass man NoSQL-Datenbanken leichter verteilen kann und so eine bessere Performance erzielen kann. Einen interesasanten Benchmark mit verteilten MySQL-Datenbanken, bei dem 15 Instanzen etwa 1 Million Datensätze pro Sekunde schaffen, gibt's hier.
Die schaffen etwa 150.000 pro Sekunde, was ganz gut zu meinen Messungen passt: Ich habe mein 4 Jahre altes Macbook verwendet, die hatten eine dicke Amazon Instanz. Passt.

Braucht man mehr Performance muss man in jedem Fall verteilen. Das ist dann aber schon ganz schön viel: Nehmen wir mal an, dass ein vernünftiger Rechner mit SSDs den zehnfachen Durchsatz wie mein altes Macbook schafft (das ist eher konservativ), dann wären das immerhin 20 Millionen Datensätze pro Sekunde .... die muss man erstmal haben.

Falls jeder Sensor pro Sekunde einen Datensatz liefert (das sind so übliche Szenarien, etwa auch bei der IoT-Veranstaltung die intelligenten Akkuschrauber von Bosch), dann sind das 20 Millionen Sensoren .....

Aber in der Tat, es gibt Anwendungsfälle, wo man so viele hat (etwa bei TelCos). Dann sind verteilte Dateisysteme notwendig, ein schönes Beispiel mit 100 Millionen Datensätzen pro Sekunde gibt's hier.

Also nochmal: Wegen Ingestion rates braucht man keine NoSQL-Datenbank ! Zumindest in einem IoT-Szenario, bei komplexen Dokumenten mag das wohl sein. Haben wir hier aber nicht ! Nein !

Bleibt also noch das Argument mit der Annotation. Bei Sensordaten kann man hier zwei Grenzfälle sehen: Bei Massendate die Annotation mit Events. Das also aus anderen Quellen stammende oder durch Auswertungen erzeugte Informationen über besondere Ereignisse (etwa die Überschreitung von Grenzwerten oder die Clusterung von Daten) hinzugefügt werden. Das geht mit relationalen Datenbanken natürlich hervorragend. Einfach eine zusätzliche Tabelle angelegt, die per Fremdschlüssel auf die entsprechenden Datensätze verweist.

Der andere Grenzfall wären meistens manuell erstellte, in jedem Fall aber unstrukturierte Daten in unvorhersehbarer Form. Die kann man tatsächlich gut in NoSQL-Datenbanken speichern. Die Frage ist, was bringt das ? Unstrukturierte Daten auszuwerten ist, insbesondere wenn man überhaupt nicht weiss, worum es sich handelt, gar nicht so einfach. Da bleibt eigentlich nur eine Volltextsuche, semantische Textanalyse usw. Das kann man aber auch mit einer relationalen Datenbank gut machen, wenn man diese Annotationen als BLOB speichert.

Bleibt "Open Source". Ist MySQL auch. Zumindest die Community Edition. Wie bei mongoDB auch.

Was bleibt also von den Argumenten übrig ?

Nix.

Den Quellcode der verwendeten Programme gibt's hier.

Mittwoch, 2. Juli 2014

Wie in der guten alten Zeit ...


Von Intel gibt es ganz neu einen sehr schicken - na ja, was eigentlich - sagen wir mal Barebone (heisst NUC - Next Unit of Computing). Der ist wohl eigentlich für Kassensysteme oder Infoterminals gedacht: Sehr niedriger Stromverbrauch, sehr niedrige Rechenleistung, ohne mechanische Teile, also lüfterlos, 4GB Flash intern, VGA-Anschluss und, man höre und staune: eine serielle Schnittstelle.

Also ideal für embedded-Anwendungen wie das NBS. Die ideale Basisstation. Bisher war das ja ein Raspberry Pi mit einem LCD-Display, aber wenn man den Aufwand für das Gehäuse, Netzteil usw. mitrechnet, dann ist die Intel-Kiste ein Schnäppchen: Ohne RAM für etwa 140 Euro, insgesamt also etwa 180.

Bleibt die Frage nach dem Betriebssystem. Linux natürlich. In diesem Fall Lubuntu, ein Ubuntu für Systeme mit wenig Resourcen. Also nix wie los. Aber da gibt es ein Problem: Ich möchte natürlich keine separate Festplatte installieren, sondern das Betriebssystem auf das interne Flash packen.

Leider sagt Lubuntu bei der Installation aber, dass es mindestens 4,3 GB braucht *grrr* Das eigentliche Image braucht nämlich nur 2.3 GB. In den Anleitungen im Netz findet man überall, dass man die Größenberechnung patchen soll. Das hat bestimmt mal mit irgendeiner Version funktioniert .....

Die Lösung ist aber einfach: Letztlich muss man nur den Installer dazu bringen, trotz vermeintlich zu knappem Platz weiter zu machen. Und das erreicht man, indem man die Fehlerbehandlung dieses Problems (siehe oben, im File ubi-prepare.py) aehm, sagen wir mal, modifiziert:

In Zeile 102 einfach True statt False, dann läuft der Installer munter weiter .... wer bremst verliert ;-)

Und noch ein Versuch


Die Bewegungserkennung mit der-Maus-Kamera funktionierte im Labor zwar sehr gut, unterm dunklen Auto in der Tiefgarage allerdings nicht mehr. Zumindest ohne Beleuchtung wird das wohl nichts.

Da ich sowieso einen IR-Temperatursensor ausprobieren wollte, war das die Gelegenheit. Auch hier war das nicht besonders kompliziert, der Beispielcode funktionierte sofort. Beeindruckend ist die Auflösung, eine Hand in einem halben Meter davorgehalten erkennt der Sensor sofort, die Hauttemperatur wird mit etwa 30 Grad gut gemessen. Der einzige Hinderungsgrund, den Sensor für das Bewegungserkennungsprojekt einzusetzen, ist der Preis, etwa 20 Euro.

Da die Inbetriebnahme viel schneller ging, als gedacht, haben wir noch ein bisschen mit dem Sensor experimentiert: Unterschiedliche Materialien haben eine unterschiedliche Emissivität. Soll etwa die Temperatur einer (auch Infrarot spiegelnden) Metalloberfläche gemessen werden, wird das mit dieser Art Sensor schwierig.

Zum experimentieren verwendeten wir ein Stück Aluminium, auf der einen Seite blank poliert, auf der anderen mattschwarz lackiert. Man kann natürlich bei der Berechnung der Temperatur die Emissivität einstellen (sowohl beim verwendeten Sensor als auch bei dem als Kontrolle verwendeten IR-Thermometer), das löst aber das Problem nicht: Die von der Umgebung (in diesem Fall vom Experimentator) ausgehende Strahlung wird von der Metalloberfläche reflektiert. Man muss also sehr genau aufpassen, welche Temperatur man misst. Das ist kein (allzu grosses) Problem, wenn das zu messende Objekt sehr viel heisser ist als die Umgebung (die Temperatur geht in der vierten Potenz in die Sensorspannung ein), bei ähnlicher Temperatur (bei uns etwa 30 Grad Umgebung vs. gut vierzig Grad am Messobjekt) ist das praktisch aussichtslos.

Fazit: Geht, aber zu teuer. Den nächsten Versuch machen wir mit Ultraschallsensoren. Nächstes Mal ;-)

Dienstag, 24. Juni 2014

Eine sezierte Maus ...



kann mehr Freude machen als man denkt, Mikroschalter, Lichtschranken und vor allem eine Kamera. Zwar beschränkt in der Auflösung (typischerweise 18x18 Pixel, schwarzweiss, also nix für die Videokonferenz) aber manchmal ist das ja von Vorteil. 

Nämlich dann, wenn man keine "Bilder" fotografieren will, sondern nur ein paar Helligkeitswerte unterscheiden muss.

Im Rahmen unserer Summerschool "physical computing" hatte ein Student die Idee, den Kofferraum seines Autos berührungslos zu öffnen. Heißt durch Gesten, in diesem Fall mit dem Fuß, weil die Hände in dieser Situation ja oft bereits belegt sind. Den Auto-spezifischen Teil (wie öffnet man den Kofferraum, wie sorgt man dafür, dass das nur im Stillstand passiert usw.) hatte er sich schon überlegt, aber die Erkennung der Geste war noch ein ungelöstes Problem. Also genau das richtige für uns ;-)

Nach einer Weile brainstorming kam die Idee auf, dieses Problem optisch zu lösen, nicht mit einer Webcam, das wäre zwar einfach, aber man braucht eine ganze Menge Rechenleistung, sondern mit der Kamera aus einer optischen Maus und einem (stromsparenden und schnell bootenden) Arduino.

Wir sind natürlöich nicht die ersten, die sich mit dem Innenleben einer Maus beschäftigt haben, wir sind nach dieser Anleitung vorgegangen, da die Jungs dort den Code freundlicherweise schon an den auch in unserer Maus vorhandenen Kamerachip ANDS2610 angepasst hatten. Funktionierte auch (beinahe wider Erwarten) sofort.

Man muß eigentlich nicht viel tun: Die Maus ihres Gehäuses entledigen und die beiden Leitungen der seriellen Schnittstelle zwischen dem Optik-Chip und dem Controller in der Maus auftrennen und mit zwei Ports eines Arduino-Controllers verbinden. Fehlt noch die Stromversorgung, die auch der Arduino übernimmt, das war's.


Im ersten Versuch liest der Arduino nur die Daten vom Kamera-Chip und überträgt die dann per serieller Schnittstelle an den angeschlossenen PC. Dort läuft ein Processing-Sketch, der die Daten grafisch darstellt und auswertet. Im Versuchsaufbau ersetzt ein schwarzer Laptop-Deckel den Asphalt des Parkplatzes, die wischende Hand wird problemlos erkannt: Der Processing-Sketch berechnet pro Bild (zwanzig pro Sekunde) die mittlere Helligkeit und daraus dann einen gleitenden Mittelwert über hundert Bilder. Ist die Abweichung des aktuellen Bildes größer als eine Schwelle, ist was passiert.


Funktioniert ! Im Labor. Schau mer mal, wie das dann aussieht, wenn der Sensor in die Stosstange des Autos eingebaut ist.

Samstag, 10. Mai 2014

So sehen Probleme aus ...


Das ist die Versorgungsspannung des Roboter-Controllers. Man sieht, wie der Regler zu schwingen anfängt. Und das gefällt dem Gyrosensor gar nicht.

Aber zurück zu den Anfängen. Wie im letzten Beitrag beschrieben wollten wir den Roboter um einen Gyrosensor ergänzen, um eine exakte Drehung machen zu können. An sich eine einfache Sache, es gibt solche Sensoren günstig und auch entsprechende Beispielprogramme. Also flugs  den Sensor an einen Arduino angeschlossen, Testprogramm ausprobiert, geht. Eingepackt und an Ostern kurz in den Roboter eingebaut. Und dann die böse Überraschung: Geht nicht. Genauer gesagt funktionierte der Gyro-Sensor, solange die Motoren nicht liefen (Arduino über USB versorgt), sobald die Motoren mitliefen, ging gar nichts mehr, Sensor reagierte nicht mehr, Roboter drehte sich fröhlich im Kreis. Oh oh ....

Heute bin ich endlich dazu gekommen, dem Problem auf den Grund zu gehen (morgen ist Julius wieder hier und will den Roboter mitnehmen).

Die Motoren erzeugen lustige Störsignale, die den Spannungsregler zum fröhlichen mitschwingen anregen. Oh oh ....

Motoren mit einem (MKT-) Kondensator entstört, schluckt die tiefen Frequenzen gut weg, aber der HF-Müll bleibt:

Die saubere Lösung wäre vermutlich ein großer keramischer Kondensator (so in der Art 0,22 µF), hab ich aber leider nicht da :-( Oder andere Motoren. Hab ich auch nicht :-(

Weitere Verzweiflungstaten wie Leitungen zum Sensor möglichst kurz machen, die Pull-Up-Widerstände am I2C-Bus auf 2k2 runtersetzen und den Motor nur mit 2/3 Gas laufen lassen führen immerhin dazu, dass der Sensor nicht sofort ausfällt, sondern im Mittel eine halbe Minute oder so mitspielt. Schön ist das nicht, aber für eine kurze Vorführung ausreichend.

Freitag, 28. Februar 2014

Ein einfacher Robotor entsteht ....



aber wozu bloß ??

Man braucht bekanntlich Motiv, Gelegenheit und Mittel zur Umsetzung.

Wie bringt man Schülern (und angehenden Studenten) die Freuden der Programmierung näher ? Mit den"klassischen" Methoden, Beispielen aus Mathematik oder einfacher String-Verarbeitung klappt das heute eher nicht mehr. Ansätze, die ganz gut funktionieren, sind etwa die Verwendung von grafischen Beispielen, etwa mit Processing. Das machen wir in der WI in Heidenheim so. Eine vielversprechende Variante ist das Scripting von Spielen, etwa so. Der Ansatz, um den es hier geht, ist die Verwendung von Robots. Durch Lego Mindstorm populär gemacht ist die Verbindung von virtueller Programmierung und physikalischer Welt eine spannende Sache. Um tatsächlich in die (technische) Programmierung einzusteigen und genügend Potential für spätere Projekte zu haben, sollte die Plattform möglichst leistungsfähig und auch durchaus auch etwa anspruchsvoll sein. Schließlich geht es ja darum, die begabten Schüler zu fördern und zu motivieren.

Verwendet haben wir einen Bausatz, den es etwa bei ebay für wenig Geld gibt, etwa hier. Der liegt seit gut einem Jahr bei mir rum und wartet auf Zuwendung. Bisher erfolglos. Aber da kam in Gestalt eines Bogy-Praktikanten das ideale Versuchskaninchen zu mir ;-) Der ist für eine Woche da und so ergab sich auch unmittelbar das Projekt: Herauszufinden, ob es gelingt, ohne Vorkenntnisse in einer Woche einen irgendwie sinnvoll funktionierende Roboter aufzubauen, der das Potential hat, auch anspruchsvollere Projekte zu realisieren.

Der erste Tag: Auspacken, Teile sichten und Zusammenbauen. Die erste Hürde: Keine Anleitung, sondern selber denken. Am ersten Abend ist alles zusammen und der Roboter fährt geradeaus.

Am zweiten Tag geht's daran, mehr als nur geradeaus zu fahren. Das heisst, die beiden Seiten mit unterschiedlichen Geschwindigkeiten anzusteuern. Das geht im Prinzip zwar einfach per PWM, aber hier ist mehr Erklärung und auch Programmierung (Erstellen von Funktionen usw) und auch ausprobieren gefragt. Ergebnis: Der Robo kann schnell oder langsam, vorwärts oder rückwärts und auch (etwas eingeschränkt) Kurven fahren. Problem ist die eher schlechte Haftung der Reifen am Boden und die Tatsache, dass beide Motoren jeder Seite gemeinsam angesteuert werden (der Motortreiber hat nur zwei Kanäle). Hier ist zu überlegen, ob man nicht etwas aufrüstet um mehr Power zu bekommen.

Ein Roboter, der nur auf dem freien Feld fahren kann, wird schnell langweilig. Deshalb kommt am dritten Tag ein Ultraschallsensor dazu, der Hindernisse erkennen kann. Der ist schnell integriert, bloss was tut man, wenn man ein Hindernis erkennt ? Zunächst mal nix:

Ein Hindernis zu umgehen, ist schon etwas komplizierter. Dazu braucht man erstmal eine Strategie. Unsere ist, es ein Stückchen weiter zu probieren, d.h. ein Stück zurück zu fahren, dann etwas zur Seite und den nächsten Versuch zu machen. So tastet man sich langsam an einem Hindernis entlang und kommt hoffentlich irgendwann daran vorbei.

Das stellte sich aber als erheblich schwieriger heraus, als erwartet: Beim Fahren enger Kurven drehen die Räder leicht durch. Dadurch ist der Winkel am Ende der Kurve unbestimmt. Manchmal geht das gut:


Manchmal (das zeigen wir nicht ;-) leider nicht. Um das zu verbessern braucht man letztlich eine Rückmeldung über die tatsächlich erfolgte Bewegung: Eine Steuerung ("Motor rechts 500 msec  drehen lassen") reicht nicht, wir brauchen eine Regelung ("So lange drehen, bis wir einen Winkel von 90 Grad zur vorigen Richtung haben"). Dazu aber zunächst mal eine Möglichkeit, die tatsächliche Lage zu messen. Das geht am einfachsten mit einem Gyro-Sensor, der hoffentlich rechtzeitig geliefert wird.


Julius: Auch aus meiner Sicht war das ganze Projekt sehr spannend und interessant, da man immer dazulernte und es nie zu schwer war. Wenn wir ein Problem hatten, haben wir immer eine Lösung gefunden, wenn es auch oft eine sehr kreative und unerwartete war. Zum Schluss schaue ich freudig auf die zurückliegende Woche und hoffe noch weitere Sensoren etc. an dem Roboter anbringen zu können, um mich immer an dieses Erlebnis zu erinnern und noch mehr über die Programmierung zu lernen. Das Programmieren ist durchaus eine Berufsaussicht für mein späteres Leben, und wenn ich
meine Berufserkundung nochmal machen könnte, würde ich wieder kommen.

Schon am ersten Tag, als wir den Roboter ohne Anleitung zusammenbauen sollten, standen wir vor unserem ersten Problem. Mit Fachkenntnis und (etwas) Glück lösten wir dieses relativ schnell und konnten alles (ohne Kurzschluss :-))verkabeln. Als wir am zweiten Tag vor dem Problem standen, dass die Geschwindigkeit des Roboters sich nur beim Rückwärtsfahren verändern ließ, fanden wir leider keine Lösung außer ihn rückwärts fahren zu lassen. Das Hauptproblem wurde die Tage später immer deutlicher: Die Räder drehten mal durch und mal nicht, zudem waren die Batterien immer schwächer und brachten nicht die selbe Leistung wie am Anfang. Durch wechseln der Batterien wurde der Roboter wieder leistungsstark. Das Programm musste ich aber auch wieder umschreiben, da er die Kurven weiter fuhr als bisher.

PS: Der Sensor kam leider nicht mehr rechtzeitig hier an.

Freitag, 17. Januar 2014

Warum Thermostaten interessant sind ....

oder: Warum gibt google mehr als 3 Milliarden Dollar für einen Hersteller von Thermostaten aus ?

Glaubt man etwa der FAZ, dann „scheint [Nest Labs] zwar auf Thermostate und Feuermelder fokussiert zu sein, aber es ist nicht abwegig, dass Google diese Technologie mit der Zeit auf andere Geräte überträgt“, denn „Die Automatisierung von Haushalten ist eine der größten Geschäftsmöglichkeiten, wenn man vom allgegenwärtigen Internet redet, das alles verbinden wird.“

Das klingt ja alles nett, aber die Hausautomatisierung wurde schon vor fünf Jahren als die kommende Technologie gepriesen, die dem Internet der Dinge zum Durchbruch verhelfen würde. Wer erinnert sich noch an den intelligenten Kühlschrank, der automatisch Milch nachbestellt oder Rezepte vorschlägt ?

Blödsinn !

Es geht (google) nicht darum, zu erkennen, ob jemandem der Toast anbrennt, oder welche Lieblingstemperatur der Durchschittsamerikaner im Wohnzimmer hat. Worum es wirklich geht, wird klar, wenn man sich die Daten eines Temperatursensors mal genauer anschaut. Solche Sensoren setzt man etwa im industriellen Umfeld zur Optimierung der Produktionsabläufe ein. Die Abbildung zeigt Daten, die solche Sensoren in meinem Büro über ein paar Tage aufgenommen haben (hier zwei, einer neben meinem Schreibtisch - rot und einer auf dem Besuchertisch - grün). Auf der Zeitachse entsprechen die größeren Striche jeweils einem Tag, die kleineren jeweils 6 Stunden.



Von links nach rechts erkennt man zunächst einen ganz normalen Arbeitstag: Ich komme gegen 8 Uhr ins Büro, die Temperatur steigt schnell an. Im Lauf des Vormittags geht immer mal wieder die Tür auf und zu, kurz vor Mittag gehe ich schnell ein Brötchen holen (die Temperatur fällt kurz ab), dann mache ich die Tür zu, um in Ruhe zu essen (die Temperatur steigt an), dann mache ich wieder auf, falls Studenten zu mir wollen, Temperatur fällt und schwankt dann ein bisschen, wenn jemand vorbeiläuft. Gegen 16 Uhr  ein kurzer Gipfel wegen hektischer Bewegung beim Aufbruch, dann Feierabend: Die Temperatur fällt langsam wieder ab. Gegen 18 Uhr kommt die Putzfrau, kurze Schwankung.

Am nächsten Tag ein interessanteres Bild: Am späten Vormittag bin ich kurz in einer Besprechung, der Temperaturanstieg hat eine leichte "Delle", kurz vor Mittag kriege ich Besuch. Der sitzt am Gästetisch, dort (grüne Kurve) steigt die Temperatur plötzlich an. Danach gehe ich in Ruhe essen, bin gut anderthalb Stunden weg. Gegen 17 Uhr Feierabend, etwas später dann wieder die Putzfrau.

Am Samstag ist niemand da, am Sonntag vormittag komme ich kurz vor neun ins Büro um in Ruhe zu arbeiten. Man sieht (bis auf die kleine Schwankung gegen halb elf, da war ich auf der Toilette) einen ruhigen, ungestörten Vormittag. Gegen Mittag dann Feierabend.

Man sieht: Nichts, was man mit einer Überwachungskamera nicht auch sehen könnte. Aber deren Daten wären viel schwieriger auszuwerten. Und ausserdem wäre eine Kamera zumindest in Deutschland verboten. Aber einen Thermostaten braucht man halt ....

Kombiniert man das mit ein paar anderen Daten (vielleicht noch die Helligkeit, braucht man zur Steuerung der Jalousie, Stromverbrauch) und ein paar Informationen aus dem Internet (welche Website besuche ich grade, wonach suche ich denn so) kann man die Bewegungs- und Kommunikationsdaten, die man aus dem GPS-Empfänger und den Mobilfunk-Verbindungsdaten hat, schön anreichern.

Mit einem Thermostaten kann man den Teil des (Privat-) Lebens untersuchen, den man mit anderen (legalen) Mitteln nicht sieht. Und man sieht schon im Büro ziemlich viel ....


Mittwoch, 15. Januar 2014

Wie erklärt man Idempotenz ?

"Man bezeichnet ein Element einer Menge (also auch eine Funktion), das mit sich selbst verknüpft wieder sich selbst ergibt, als idempotent." (wikipedia). Dass es sich hierbei um eine der zentralen Anforderungen bei der Programmierung verteilter Systeme handelt, und dass das ganz erhebliche Auswirkungen auf Architektur und Entwurf solcher Systeme hat, ist (nach meiner Erfahrung) für Studenten nicht grade leicht verständlich.

Um das anschaulicher zu machen, habe ich eine "Lampe" gebaut:


Dazu gibt es einen Schalter, genauer gesagt einen Taster


Bei jedem Druck auf den Taster (ganz klein, rechts an der Platine) ändert sich der Zustand der Lampe: Ist sie aus, dann geht sie an, ist sie an, dann geht sie aus.

Soweit ganz einfach. Der Taster sendet eine Nachricht ("wurde gedrückt") an den Empfänger, der schaltet entsprechend hin und her. Kompliziert wird das dadurch, dass die Übertragung über Funk erfolgt. Die Übertragung ist deshalb nicht verläßlich. Insbesondere haben die Module nur eine beschränkte Reichweite. Vergrössert man den Abstand weit genug, gehen Nachrichten verloren.

Steht die Lampe in einem Raum und der Schalter in einem anderen, weiss man nach dem Drücken der Taste nicht mehr sicher, ob die Nachricht angekommen, die Lampe also an oder aus ist. Dies wäre nur der Fall, wenn jede Nachricht genau einmal zugestellt würde ("exactly once").

Das ist aber nicht realisierbar: Ein Ansatz wäre, dass der Empfänger eine Bestätigung schickt, wenn er die Nachricht erhält. Kommt diese beim ursprünglichen Absender an, weiss er, dass die Nachricht erfolgreich zugestellt wurde und damit, ob das Licht jetzt an oder aus ist. Er kennt also den Zustand der Lampe ("shared state", beide sind sich einig darüber, ob die Lampe brennt oder nicht).

Aber was passiert, wenn die Bestätigung nicht ankommt ? Wenn die Nachricht tatsächlich nicht angekommen ist, könnte sie ein weiteres Mal gesendet werden. Aber eben das läßt sich nicht feststellen, denn das Ausbleiben der Bestätigung könnte mehrere Ursachen haben: Entweder ist die ursprüngliche Nachricht verloren gegangen, oder die Nachricht ist zwar angekommen, aber der Empfänger ist abgestürzt, bevor er die Bestätigung schicken konnte oder die Bestätigung ist verloren gegangen. Je nachdem, welche Ursache vorliegt, ist die Lampe an oder aus, der Taster (Absender) weiss es nicht.

Wie ließe sich dieses Problem lösen ? Man könnte die Bestätigung bestätigen. Kommt diese an, ist alles OK, aber wenn nicht, gibt es verschiedene Ursachen usw.

So wird das Problem also nicht zufriedenstellend gelöst, da zumindest die letzte Nachricht in einer Kommunikation nicht verlässlich übertragen werden kann. Deshalb kann man nicht vermeiden, dass eine Nachricht gelegentlich entweder verloren geht, oder mehrfach übertragen wird. Es gibt nur "at most once" oder "at least once".

Bestätigungen sind also für diesen Fall nicht geeignet. So wird die Grundannahme, dass mit einem solchen Protokoll (wie es etwa TCP realisiert) eine verläßliche Übertragung von Nachrichten, die den Zustand ändern, möglich ist, erschüttert. Doch wie löst man das jetzt ?

Man betrachtet den Eingang einer Bestätigung nicht als verläßliche Bestätigung, sondern schickt eine Nachricht, falls nicht innerhalb einer bestimmten Zeitspanne eine Bestätigung eintrifft, einfach nochmal ("at least once"). Oder man überträgt gleich die Nachricht immer wieder. Dazu braucht man natürlich andere Nachrichten, mit unserem Beispiel würde die Lampe ständig an und aus geschaltet werden.

Man muss die Anwendung so konstruieren, dass kein Schaden entsteht, wenn eine Nachricht mehrfach empfangen wird. Das ist Idempotenz.


Im Bild sieht man einen Schalter, der zwei Zustände hat (an und aus) und den aktiven Zustand immer wieder (im Beispiel alle 200 Millisekunden) überträgt. Diese Nachricht (entweder "An" oder "Aus") kann beliebig oft übertragen werden, der Empfänger ist, sobald er mindestens eine (aktuelle) Nachricht erhält, im richtigen Zustand. Ist die Lampe an, und es wird nochmal "An" empfangen, passiert nichts (unerwünschtes).


Nächste Woche werde ich das in der Vorlesung ausprobieren, mal schauen, ob dieses Konzept so besser verständlich ist.

Realisiert wurde das System mit ZigBee zur Übertragung, hierfür wurden XBee-Module der Firma Digi verwendet. Das würde natürlich auch mit anderen Übertragungstechniken funktionieren, aber diese Module sind sehr bequem zu verwenden, die Funktionen, die man hier braucht, sind schon eingebaut: Im einen Fall wird der Zustand eines digitalen Eingangs bei jeder Änderung übertragen, im anderen Fall werden die Eingänge in einem festen Zeitintervall abgetastet und übertragen.

Für den Empfänger bräuchte man an sich nur ein bisschen Logik (im Taster-Betrieb ein Flip-Flop, das den aktuellen Zustand speichert und eine Erkennung mit entsprechender Logik, die erkennt, welche Betriebsart grade vorliegt, das wird durch einen weiteren Eingang mit entsprechend fixem Wert festgelegt). Das liesse sich leicht diskret ohne Controller realisieren, wenn nicht ... die XBee-Module mit 3.3 Volt arbeiten würden ... Man bräuchte also auch noch Level-Shifter. Und da ich den Arduino grade rumliegen hatte ....

Donnerstag, 24. Oktober 2013

Erster Praxistest der Sensoren



Den Dauertest auf dem Schreibtisch haben die Sensoren gut überstanden, trotz gelegentlicher Übertragungsstörungen (ich vermute Interferenzen mit dem jeweiligen WLAN, dazu später mehr) lief das System stabil.

Aber die "echte" Welt ist doch etwas anderes. Die Umgebungsbedingungen in einer Papiermaschine sind für Elektronik-Komponenten schon außerhalb des normalen Consumer-Bereichs. Es gibt natürlich von praktisch allen Komponenten MILSPEC-Versionen oder solche für den Automotive Bereich, aber für eine Low Cost Anwendung ist das natürlich keine Lösung. Jetzt sind sie in einer echten Papiermaschine, die Basis steht in der Warte neben dem System zur Produktionssteuerung.

Unser Vorteil ist, daß wir keine lange Lebensdauer brauchen. Also sollte etwa die Alterung von Kondensatoren kein ernstes Thema sein. 85 Grad halten auch die "normalen" Typen aus und das ist ziemlich genau das Klima, in dem wir sie betreiben. Mehr Sorgen machen mir die Batterien. Die LiPos in den Sensoren sollten mit diesen Umgebungsbedingungen gut klar kommen. Aber im Router haben wir normale Alkaline Batterien verbaut. Da ist es schon eher fraglich, ob die durchhalten.

Unser erster Versuch geht über 4 Wochen. Bei 85 Grad und gut 30 Prozent relativer Feuchte. Damit kann man schon ganz komfortabel Mahlzeiten zubereiten ;-)

Aber zumindest bisher funktioniert alles. Am 24. haben wir die Sensoren installiert und bis heute keine (schlechten) Nachrichten bekommen.

Update: Eine Woche vorbei und alles noch OK.

Donnerstag, 17. Oktober 2013

Wie lang hält die Batterie ....

Grau mein Freund ist alle Theorie ....

Also messen. Und zwar in der endgültigen (na ja ... zumindest mal für dieses Jahr) Konfiguration. Arduino FIO, Standard-XBee, LiPo-Akku mit 850 mAh, Messung alle 4 Sekunden, Datenübertragung einmal pro Minute, keine Routing-Funktion in den Sensorknoten, Pin-Sleep-Mode, d.h. die XBee-Module werden vom Arduino einmal pro Minute per Hardware aufgeweckt (das ist der größte Unterschied zur "endgültigen" Version, bei der werden die XBee-Module den Arduino wecken, um ZigBee-Routing zu ermöglichen. Aber eins nach dem anderen).

Nach etwa sechs Wochen ist die Spannung von anfänglich etwa knapp 4,2 Volt auf gut 3,7 Volt gefallen.

Gehen wir mal davon aus, dass wir dann weniger als die Hälfte der Kapazität verbraucht haben. Eine genaue Abschätzung ist schwierig, da üblicherweise für LiPos nur Entladekurven bei hohen Strömen publiziert werden. Die würden uns allerdings wenig nutzen, da solche Messungen idR nicht bei den für uns relevanten Temperaturen von 80-95 Grad durchgeführt würden.

Gehen wir also mal davon aus, dass wir dann noch die Hälfte der Kapazität haben, sind wir was die Akkus betrifft auf der sicheren Seite.



Sonntag, 22. September 2013

Vergleichstest der Sensoren


Um einen Eindruck von der Genauigkeit - genauer gesagt von der Abweichung der Sensoren untereinander, die absolute Genauigkeit ist gar nicht so einfach zu messen - habe ich die Sensoren in einen luftdichten Koffer gepackt und eine Weile gewartet.

Bis auf den Sensor 5 (links unten) liegen alle recht nah beieinander. Der liegt knapp 1 Grad unter den anderen. Berücksichtigt man die Abhängigkeit der relativen Feuchte von der Temperatur stimmt die Luftfeuchtigkeit zwischen den Sensoren sehr gut überein, das ist der Wert, der relevant ist. Absolut gleiche Werte für die Temperaturen sind nicht zu erwarten, da die Umgebung unterschiedliche Temperaturen hat. Dazu müsste man eine Klimakammer verwenden, das war mir aber zu aufwendig.

Da für die geplante Anwendung im wesentlichen die Abweichung der Werte und nicht der Absolutwert von Interesse ist und eine Genauigkeit von 2% locker reicht folgt: Test bestanden.

Interessant wäre natürlich die Genauigkeit bei den später relevanten Umgebungsbedingungen (etwa 85 Grad bei 20-30% relativer Feuchte). Aber das läßt sich ohne Klimaschrank tatsächlich kaum prüfen. Im Feldversuch haben wir dann ja einen sehr großen Klimaschrank mit vielen eingebauten Sensoren zum testen ;-)

Freitag, 20. September 2013

Die Basisstation


Die Basis besteht aus einem Raspberry Pi, einem XBee-Modul und einer Echtzeituhr (da das Modul im Betrieb keine Netzwerkverbindung hat und die aufgenommenen Daten später mit anderen Daten synchronisiert werden müssen). Das XBee-Modul ist über die serielle Schnittstelle des Raspberry Pis angebunden. Das alles ordentlich auf einem Pi Plate Kit von Adafruit aufgebaut.

Was im Bild fehlt, ist das Display, ein 20x4 LCD-Display mit I2C-Schnittstelle. Was ausserdem fehlt, ist der 3.3 Volt Spannungsregler: Der Raspberry Pi liefert nur 50mA, das reicht für ein Standard XBee-Modul (wie im Bild). Wird ein XBee-PRO-Modul verwendet, reicht das bei weitem nicht aus. Die Entwicklungsversion (im Bild) läuft mit einem normalen Modul, also ist der separate Regler nicht nötig, in der Produktionsversion natürlich schon. Da hat das XBee-Modul auch eine externe Antenne.

Donnerstag, 22. August 2013

Dynamische Messung der Stromaufnahme

Um die Belastung der Batterie unter realen Bedingungen zu messen, wurde der Stromverbrauch des Gesamtsystems in einer dem Zustand bei der tatsächlichen Messung ähnlichen Konfiguration bestimmt. Die Messungen wurden ohne Sensor durchgeführt, da verschiedene Sensoren einen unterschiedlichen Stromverbrauch haben. Falls der Sensor keine erhebliche Stromaufnahme oder (insbesondere) eine erhebliche Anlaufzeit benötigt, ist dieser für die folgende Betrachtung zu vernachlässigen.

Die Stromaufnahme des Arduino im sleep-mode (powerDown, ADC_OFF, BOD_OFF) beträgt statisch gemessen ca. 40 µA (direkte Strommessung, Philips PM 2503).

Konfiguration: Arduino Fio, XBee Series 2, LiPo Akku 850 mAh, LowPower V. 1.30 https://github.com/rocketscream/Low-Power)

Die dynamischen Messungen wurden als Spannungsmessungen über einem 1 Ω 1% Widerstand mit einem HP 54200A Digitaloszilloskop ausgeführt.

Um zu prüfen, ob die Stromaufnahme, insb. des XBee-Moduls beim Einschalten einen höheren Peak als während des Betriebs hat, wurde eine Kontrollmessungen mit einem analogen Speicheroszilloskop (HP1741A) durchgeführt, die keine Anzeichen dafür lieferten.


Zunächst wurde der Stromverbrauch des Arduino-Boards ohne XBee-Modul gemessen:

Dazu wurde der Controller 15msec in den sleep Modus versetzt, dann über die Standard-delay-Funktion 100msec gewartet. Die Stromaufnahme des Controllers beträgt etwa 5mA.
Die sleep-Dauer scheint nicht ganz der Angabe von 15msec zu entsprechen, sondern eher etwa 20msec zu betragen. Bei Bedarf sollte dies durch eine genauere Messung geklärt werden. Die Messung wurde bei längeren sleep-Dauern wiederholt, um eine erhöhte Stromaufnahme bei längerer Dauer auszuschließen. Dafür ergab sich kein Anhaltspunkt.

Daraufhin wurde die Stromaufnahme mit XBee-Modul gemessen.

Da das XBee-Modul mindestens etwa 3 Sekunden „wach“ blieb[1], wurde im Versuch eine sleep-Dauer von 8 Sekunden (der Maximalwert) verwendet. Die Abbildung zeigt, dass die Stromaufnahme jetzt etwa 40 mA beträgt. Dies deckt sich mit statischen Messungen (Digital- und Analog-Voltmeter) und ist auch plausibel. Man erkennt eine leicht erhöhte Stromaufnahme zu Beginn (etwa 3 mA mehr Stromverbrauch für etwa 300 msec). Auch dies ist plausibel. In einer Messung (von etwa 50, kein Bild) erschienen einzelne Datenpunkte, die einen höheren Stromverbrauch zu Beginn andeuten könnten, diese konnten aber durch Messungen mit einem analogen Speicheroszilloskop nicht verifiziert werden und werden deshalb als Artefakte (etwa Einstreuung des benachbarten PCs oder Lötstation) interpretiert. Bei Bedarf sollte eine präzise Messung – etwa per analoger Integration und Mittelung – durchgeführt werden. Der hierfür nötige Aufwand scheint aber nur gerechtfertigt, falls Probleme mit überlasteten Batterien auftreten.

NB: Die Messungen wurden insbesondere durchgeführt, da ein Testaufbau mit einem Arduino-Leonardo und XBee-Shield bei weitem nicht die erwartete Betriebsdauer erzielte, sondern nur gut eine Woche aus 4 Standard-Mignon-Zellen. Dies rührte aber, wie zu Beginn der Messungen klar wurde, vom Ruhestrom des Spannungsreglers des XBee-Shields, der bei etwa 10 mA lag. Dies würde dann zu einer Batteriekapazität von etwa 10 Tagen x 24 Stunden x 10 mA = 2400 mAh (plus die eigentlich nötige Stromaufnahme von Board und XBee-Modul, die bei etwa 1 mA im Mittel liegt und damit vernachlässigbar ist), also einem plausiblen Wert.
Dies führt zu folgenden Betriebsdauern:


Quellcode des Programms zur Messung mit XBee-Modul. Für die Messung ohne XBee-Modul wurde der entsprechende Code auskommentiert und die Zeit im Aufruf von powerDown auf 15Ms gesetzt.

/**
* Short sleep cycles to measure power consumption
* essentially a fast blink with sleep during off time
**/

#include "LowPower.h"

char c = 'A';

const int XBEE_WAKE = 7;

void setup() {
  Serial.begin(9600);
  // Send XBee to sleep, never wake it up
  digitalWrite(XBEE_WAKE,HIGH); // just in case
  // XBee pins are clamped internally
  pinMode(XBEE_WAKE,INPUT);
}

void loop () {
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
    digitalWrite(13, HIGH);
  // Send to XBee Module
  // first wake it up
  pinMode(XBEE_WAKE,OUTPUT);
  digitalWrite(XBEE_WAKE,LOW);
  // wait a little bit
  delay(100);
  Serial.print(c);
  Serial.flush();
  // wait a little bit and send XBee to sleep again
  delay(100);
  digitalWrite(XBEE_WAKE,HIGH); // just in case
  // XBee pins are clamped internally
  pinMode(XBEE_WAKE,INPUT);


    delay(100);
    digitalWrite(13, LOW);
}



[1] Vermutlich wurde das so konfiguriert, prüfen ! Ist aber nicht so kritisch. Letztlich sollte per Versuch – aufwendig – geklärt werden, wie lange das Modul mindestens wach bleiben muß, um eine verlässliche Übertragung zu gewährleisten. 3 Sekunden sind meiner Erinnerung nach der default und realistisch.

Samstag, 10. August 2013

AD7714 - die Software

Der AD7714 - ein 24 Bit Sigma-Delta-Wandler mit integrierter Signalaufbereitung - ist ein toller Chip (und wenn man bedenkt, wie aufwendig es wäre, all diese Funktionen selbst aufzubauen, nicht mal teuer), aber leider gibt es (bisher) keine Beispiele im Web, wie man ihn an einen Arduino anbindet, das ist nämlich nicht ganz trivial. Also los.

Angebunden wird er über die SPI-Schnittstelle. Da ich nur einen SPI-Chip verwende, wird das /CS-Signal (Pin 19) nicht verwendet, sondern fest auf low gelegt. So braucht man nur drei Leitungen, MISO (Daten vom Wandler, Pin 21), MOSI (Daten vom Arduino, Pin 22) und SCK (Takt, Pin 1).

SPI ist kein "absoluter" Standard, sondern ein de-facto-Industriestandard, heisst, es gibt verscheidene Ausprägungen. Deshalb muss zunächst festgelegt werden, wie die Daten übertragen werden: Zunächst der SPI-Mode, der festlegt, welche Polarität das Taktsignal hat und welche Flanke zur Signalübernahme dient. Wir nehmen  Mode 2, das bedeutet Takt ist aktiv low und die Daten werden bei der fallenden Flanke übernommen. Das wird chipseitig durch die entsprechenden Pins festgelegt (POL, Pin 4 auf high) und Arduino-seitig durch

SPI.setDataMode(SPI_MODE2);

Der AD7714 liefert (und erwartet) die Daten MSB first, das wird mit

SPI.setBitOrder(MSBFIRST);

definiert. Bleibt noch die Taktrate, wir haben es nicht allzu eilig und nehmen

SPI.setClockDivider(32);

das müssten 500kHz sein.

Der Zugriff auf die internen Register erfordert zunächst die Auswahl des zu schreibenden oder zu lesenden Registers. Dies geschieht durch Schreiben des Communication Registers. Dieses legt in den unteren drei Bits den Kanal des Wandlers fest. Wir verwenden nur einen Kanal, den aber differentiell an AIN1 und AIN2, dieser hat den Code 100 (also 4 dezimal). Das nächste Bit definiert, ob gelesen oder geschrieben wird, 1 bedeutet Lesen (also 8 dezimal).  Die nächsten drei Bits geben das Register an, auf das als nächstes zugegriffen werden soll.


CodedezimalRegister
0000Communications Register
00116Mode Register
01032Filter High Register
01148Filter Low Register
10064Test Register
10180Data Register

Die Codes 110 und 111 sind die Calibration Registers und im Moment uninteressant.

Das oberste Bit des Communication Registers ist das /DRDY muss beim Schreiben immer 0 sein, beim Lesen liefert es den Wert des /DRDY-Pins (low, wenn Daten gelesen werden können).

Zur Initialisierung des AD7714 wird zunächst das Filter konfiguriert, das durch Schreiben von 4 (Kanal AN1+AN2, Schreibzugriff) + 32 (Filter High Register) = 36 (0x24) ausgewählt wird.

Im Filter-Register werden im oberen Byte einige Parameter konfiguriert, hier unipolare Operation, 24 Bit Auflösung der zu lesenden Daten, Current Boost (da wir mit hoher Verstärkung und hohem Takt arbeiten) und ohne Clock Disable. Dies ergibt 1110 für die oberen 4 Bit. Die unteren 4 Bit sind die höherwertigen Bits des Filter-Teilers. Die niedrigste Filterfrequenz ergibt sich mit dem Teiler 4000 (0xfa0), nämlich fCLOCK/128/4000 = 4,8 Hz. Da die Zeitkonstante des zu messenden Temperatursignals sicher länger ist, ist die Genauigkeit umso besser, je niedriger die Filterfrequenz.

Also zunächst das Filter High-Register auswählen (0x24), dann die Werte schreiben (0x4f), dann das Filter-Low-Register auswählen (0x34) und das untere Byte (0xa0) schreiben.

Als nächstes muss das Mode-Register konfiguriert werden, dazu zunächst Mode-Register für einen Schreibzugriff auswählen 0x14 (20)

Sonntag, 12. Mai 2013

Hobel sind Präzisionsinstrumente ....


und vor allem wenn sie aus Holz sind sehr empfindlich. Ein gut eingestellter Hobel nimmt grade mal ein Hundertstel dicke Späne ab. Das bedeutet aber auch, dass die Geometrie des Hobels in eben dieser Größenordnung stimmen muss. Leider verändert Holz seine Größe mit der Luftfeuchtigkeit, Holz arbeitet eben.


Um diesen und anderen Unbillen zu trotzen, schützt man empfindliche Werkzeuge üblicherweise durch eine Werkzeugkiste (oder einen Schrank, der ist aber erheblich schlechter zu transportieren). Am besten eine möglichst dichte, die Feuchtigkeit gar nicht erst eindringen läßt. Voila !


In einer ausgeglichen temperierten Werkstatt reicht das aus, in einem feuchten Keller nicht :-( Dabei ist nicht einmal der tatsächliche Wert entscheidend, sondern die Schwankungen. Aber wie vermeidet man die ?

Die erste Idee war eine Heizung: Im Inneren der Werkzeugkiste angebracht, erhöht sie erstens die Temperatur (und senkt damit die relative Feuchtigkeit) und sorgt zweitens durch Konvektion durch die unvermeidlichen Lecks in der Hülle der Werkzeugkiste für einen Abtransport der eingedrungenen Feuchtigkeit. Doch wie ? Zu viel Heizleistung ist ja auch eher kontraproduktiv, wegen Energieverschwendung und dann viel zu warmen und zu trockenen Werkzeugen, die sich dann beim ersten Kontakt mir der Umgebung verziehen. Also nur ein paar Watt.

Nach längerer (na ja, so lang war das gar nicht) Überlegung die Lösung: Ein LED-Streifen von 2m Länge liefert die grob überschlagen nötige Heizleistung:

Vermutlich bin ich einer der wenigen Menschen mit einer beleuchteten Werkzeugkiste ;-)
Sieht - ehrlich gesagt - auch etwas dekadent aus, wenn man den Deckel aufmacht, vielleicht stelle ich irgendwann mal auf eine inverse Kühlschrankbeleuchtung um: Leuchtet nur, wenn der Deckel zu ist.

Idee gut, Ergebnis leider nicht überzeugend: Bringt etwa 0,2 Grad und knapp 3 Prozent weniger Luftfeuchtigkeit .... Nächster Versuch.

Vielleicht erstmal messen .... also eine kontinuierliche Messung von Temperatur und Luftfeuchtigkeit installiert. Für die "normalen" Anwendungen arbeiten wir ja mit  Datenloggern, aber für diesen Zweck ist das zu mühsam: Alle paar Tage in den Keller gehen, den Windows-Rechner hochfahren um die Auswertesoftware zu starten, Daten runterladen, in Excel transferieren usw. Das dauert insgesamt etwa eine halbe Stunde, zu viel für die regelmäßige Verwendung. 

Normalerweise hätte ich das zähneknirschend akzeptiert. Aber da ich zur Zeit sowieso gemeinsam mit einem Startup an einer Lösung zur industriellen Datenerfassung bastle, stapeln sich die Sensoren, Controller, Funkmodule usw. sowie auf meinem Schreibtisch also musste eine professionelle Lösung her

Ein Carambola Board und ein Feuchtesensor mit digitalem Ausgang liefern nach etwa einem Tag fluchen über die I2C tools unter Linux (die nämlich exakt nicht den I2C Bus unterstützen sondern nur so etwas ähnliches und deshalb zu einem Tag verschärftem debugging und bare metal Programmierung führen - dazu demnächst mehr) ein System, das die Temperatur und Luftfeuchtigkeit in meiner Werkzeugkiste misst und (mehr oder weniger - auch dazu demnächst mehr) live ins Internet bringt.

Hoch interessant, was man mit geeigneten Sensoren alles messen kann ....

Man sieht sehr schön, wie ich etwa am 27.4. am späten Nachmittag kurz zum Basteln in den Keller gegangen bin, die Feuchtigkeit steigt um gigantische 0,4% innerhalb weniger Minuten ...
Wenn drei Erwachsene (?) mit aller Hingabe an Bumerangs basteln, sieht das noch mal ganz anders aus:

3,6% in nicht mal einer halben Stunde ! Big Data ist was Feines ....
Wer sich selber den aktuellen Stand anschauen will, findet den (wenn ich nicht grade an der Hardware bastle) hier.

Conclusio

Erstens: Die Luftfeuchtigkeit konnte durch den Einsatz eines modernen Controllers mit WLAN-Interface nicht nur beobachtet, sondern um etwa 10% gesenkt, die Schwankungen erheblich reduziert werden. Insbesondere dadurch, dass der Controller und vor allem das WLAN-Interface so viel Strom verbrauchen, dass die Heizleistung zu eben diesem Effekt führt. Arduino und ZigBee, sie leben hoch !

Zweitens: 
Es ist inzwischen mit minimalem Aufwand (etwa 50 Euro und ein Tag Arbeit) möglich, sich einen "Internet-Kühlschrank" oder eben eine Internet-Werkzeugkiste zu bauen, ohne Experte zu sein (Ich bin Wirtschaftsinformatiker, kein E-Technik-Ingenieur).

Drittens:
Die Datenlogger, die wir bisher zur Messung von Temperatur und Feuchtigkeit verwendet hatten, zeigen die Temperatur recht genau (paar Zehntel Grad), aber die Feuchtigkeit zwar untereinander konsistent, aber absolut um etwa 6% zu niedrig an (ich traue den einzeln kalibrierten Luxus-Sensoren mit garantierter Maximalabweichung von 2% mehr als den China-Billigteilen. Fairerweise muss man aber auch sagen, dass hier der Sensor etwa soviel gekostet hat, wie der komplette Datenlogger). 

PS: Die allererste Idee zur Lösung des beschriebenen Problems war die Regulierung der Luftfeuchtigkeit durch wasseraufnehmende Salze, gibt's in jedem Baumarkt für wenig Geld, muss man aber regelmäßig kontrollieren und auswechseln. Nicht eben elegant. Wenn nichts anderes hilft, werde ich darauf zurück kommen, aber so leicht gebe ich nicht auf !