tag:blogger.com,1999:blog-84404824681543792252024-03-06T00:01:07.671-08:00Fundstücke<a href="http://www.tillh.de">Mein</a> Blog zu Projekten, Erkenntnissen, Technologien. Derzeit vor allem über das Internet der DingeTill Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comBlogger24125tag:blogger.com,1999:blog-8440482468154379225.post-60234539082642964052017-12-02T08:12:00.001-08:002017-12-02T08:12:31.620-08:00RMS-Werte messen<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm_A-u-5Q1Z6kaTrPQUv1MQHxuVPh3dTaIwNMo4OPtwQ3MOfVVJPiBI-cIB7_i4Lw5XcY-1M-7d_Ul-T4AKZUI5LJRgK7LCYjcCpZMGub1nmQbTblQcoypyTN3kaGNXf8zfPcl3JF-t3Q/s1600/rms2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="451" data-original-width="687" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm_A-u-5Q1Z6kaTrPQUv1MQHxuVPh3dTaIwNMo4OPtwQ3MOfVVJPiBI-cIB7_i4Lw5XcY-1M-7d_Ul-T4AKZUI5LJRgK7LCYjcCpZMGub1nmQbTblQcoypyTN3kaGNXf8zfPcl3JF-t3Q/s400/rms2.png" width="400" /></a></div>
<br />
Wie misst man den RMS (<a href="https://de.wikipedia.org/wiki/Effektivwert">Root Mean Square</a>) einer Wechselspannung ?<br />
<br />
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.<br />
<br />
Es gibt eigentlich zwei "klassische" Methoden: Man nimmt einen "True RMS Konverter", den gibt es fertig als IC, etwa von <a href="http://www.analog.com/media/en/technical-documentation/data-sheets/AD536A.pdf">Analog Devices</a>, der eine dem Effektivwert der Spannung proportionale Gleichspannung erzeugt. Dazu wird die Eingangsspannung quadriert und der Mittelwert berechnet.<br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidfeZ7cbS2snStYdcT5CYQrFaTBWYM6i27EvWuGAXaXOclNPTiOdUVInCKqG7ka5myKVdMJsx_CppaOCPWhf5crdQZmeaXUnTbf4Q8_2vtugKralUZqCfba0e0tXkxqTzEJrQCKf2lEvc/s1600/IMG_1265.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1200" data-original-width="1600" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidfeZ7cbS2snStYdcT5CYQrFaTBWYM6i27EvWuGAXaXOclNPTiOdUVInCKqG7ka5myKVdMJsx_CppaOCPWhf5crdQZmeaXUnTbf4Q8_2vtugKralUZqCfba0e0tXkxqTzEJrQCKf2lEvc/s400/IMG_1265.JPG" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
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. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
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.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
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.</div>
<br />Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-10257770134925091172016-04-25T02:42:00.002-07:002016-04-25T05:24:10.017-07:00Temperatur messen ist meistens einfach ...<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibGAiN7Nx1RXu0AMzLnSv4EbCi5SYBchof5F5xLwE9OptwvgnZ1nWAUjuxXyHbeqq2V-1CtHLrGppvggq0RkE4u5snqeHA442_LJ6tlhoc34XHhShdwEKXRLdsYymZES7WqAG7Xiy2Nd4/s1600/Saugkasten_klein.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibGAiN7Nx1RXu0AMzLnSv4EbCi5SYBchof5F5xLwE9OptwvgnZ1nWAUjuxXyHbeqq2V-1CtHLrGppvggq0RkE4u5snqeHA442_LJ6tlhoc34XHhShdwEKXRLdsYymZES7WqAG7Xiy2Nd4/s640/Saugkasten_klein.jpg" width="640" /></a></div>
<br />
aber nicht immer.<br />
<br />
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 ...<br />
<br />
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.<br />
<br />
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 ...<br />
<br />
Also selber basteln. Wie üblich ;-) Das Ergebnis:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUZKNdSpFnWcycSJet9nwebkSxw7rb5PE2aHo8GqFw3GIb58yuOBXDVNEzYXKYxFOnqYaTifv15DjJBGLNRDKFglGdarPNHr266jykY0SwQRd14KjrMCTBZMDJlJu2PhPOrghKg-43z4s/s1600/Messgeraet.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="426" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUZKNdSpFnWcycSJet9nwebkSxw7rb5PE2aHo8GqFw3GIb58yuOBXDVNEzYXKYxFOnqYaTifv15DjJBGLNRDKFglGdarPNHr266jykY0SwQRd14KjrMCTBZMDJlJu2PhPOrghKg-43z4s/s640/Messgeraet.jpg" width="640" /></a></div>
<br />
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.<br />
<br />
Um diesen Balanceakt zu erleichtern, eine spezielle Fühlerkonstruktion:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKN09xWoesjqStgN5jK7LjsZPYX0WOP8i7Jw3tBhKo2p3i1cVe7eYBtLgzzqfkrHTqzquYpownz2xBcqhLAX-S7-yTrIy9cPFaPYQ0O1mDuBXuUr5z68y8NMcsjnPBmvRtG79ulqTmfRc/s1600/MesskopfKater_klein.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKN09xWoesjqStgN5jK7LjsZPYX0WOP8i7Jw3tBhKo2p3i1cVe7eYBtLgzzqfkrHTqzquYpownz2xBcqhLAX-S7-yTrIy9cPFaPYQ0O1mDuBXuUr5z68y8NMcsjnPBmvRtG79ulqTmfRc/s640/MesskopfKater_klein.jpg" width="640" /></a></div>
<br />
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).<br />
<br />
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*<br />
<br />
<br />Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-44137817628027136122016-04-11T02:04:00.001-07:002016-04-25T05:24:24.981-07:00KI und so<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7jWr052srlYSXa1J_GqvSFaf97h9VJxwQsrGB-gjOTcmJgWPv2iTY9UOb1DKPeT12PoHcERdi4gvAXRgOxWp3JwVtYtvZ96gIJDr7dBjZ_pHm3vj4LRf8HZHsv5QlndBfdBHbKFhCtpE/s1600/Bildschirmfoto+2016-04-11+um+10.52.02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="302" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7jWr052srlYSXa1J_GqvSFaf97h9VJxwQsrGB-gjOTcmJgWPv2iTY9UOb1DKPeT12PoHcERdi4gvAXRgOxWp3JwVtYtvZ96gIJDr7dBjZ_pHm3vj4LRf8HZHsv5QlndBfdBHbKFhCtpE/s640/Bildschirmfoto+2016-04-11+um+10.52.02.png" width="640" /></a></div>
<br />
IBM versucht ja seit einiger Zeit, mit dem Watson-Portfolio KI-Anwendungen in verscheidenen Branchen in den Markt zu bringen. Aktuell mit der <a href="http://www.alchemyapi.com/api/emotion-analysis">Emotional Analysis API</a>, einer Linguistik-Engine, die eine Persönlichkeitsanalyse aus einem Textmuster erzeugt.<br />
<br />
So etwas gibt es ja schon lange, das kommerzielle Ziel ist (natürlich) effektivere Werbung, siehe den obigen Screenshot aus der <a href="https://watson-pi-demo.mybluemix.net/">Demo</a>. 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 <a href="http://www.atiner.gr/papers/TEN2015-1721.pdf">letztes Paper</a> analysieren lassen (eigentlich sollte man einen Text über Alltagsthemen verwenden, andererseits sind Industrie 4.0-Ansätze in der Papierindustrie heute ja ein Alltagsthema ;-)<br />
<br />
"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 ;-)<br />
<br />
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.<br />
<br />
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".Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-34484277640163282642015-07-03T06:53:00.004-07:002015-07-03T06:53:58.579-07:00Mal was ganz anderes ....<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq7JFSTONoIq6RGgQ-yaqPjCXRSW3KqLb8a3FssecYkORvSe5qTHvMy0Lil2VHwPRdVfDhPSpoCNJtX748X9PvPjWMT-I2B23UgDMH-9NXi41MWdhwgZfW2JbcnCR0X31VRGpAmR1iTkY/s1600/Download.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="424" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq7JFSTONoIq6RGgQ-yaqPjCXRSW3KqLb8a3FssecYkORvSe5qTHvMy0Lil2VHwPRdVfDhPSpoCNJtX748X9PvPjWMT-I2B23UgDMH-9NXi41MWdhwgZfW2JbcnCR0X31VRGpAmR1iTkY/s640/Download.jpeg" width="640" /></a></div>
<br />
ich habe heute aus aktuellem Anlass den Nachmittag über mit dem neuronalen <a href="http://googleresearch.blogspot.ch/2015/06/inceptionism-going-deeper-into-neural.html">Netz</a> 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 <a href="https://github.com/google/deepdream">Anleitung</a>, aber nachdem endlich alles installiert war (also nach etwa zwei Stunden) stürzte python immer beim import von <a href="http://caffe.berkeleyvision.org/">caffe</a> mit einer segmentation violation ab.<br />
<br />
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.<br />
<br />
Dafür funktioniert jetzt iPhoto nicht mehr, das will nämlich die alte Version *grrrr*Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-11915275213816183082014-10-01T05:01:00.001-07:002014-10-01T05:12:12.262-07:00Ingestion rates<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjvXufV7YBSZ9pj4AVe0XjDsXxG82UouoK3UW2CRdP8tFCiHZZ5GYSUySUFFJmdvlJwjANWISyQfjq5YEI64IYT42QWUSCKo-IFlPk9bEVpQO8POrEOHfK3in4RLWaLtvB6byVO3dKguk/s1600/Bildschirmfoto+2014-10-01+um+13.10.19.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjvXufV7YBSZ9pj4AVe0XjDsXxG82UouoK3UW2CRdP8tFCiHZZ5GYSUySUFFJmdvlJwjANWISyQfjq5YEI64IYT42QWUSCKo-IFlPk9bEVpQO8POrEOHfK3in4RLWaLtvB6byVO3dKguk/s1600/Bildschirmfoto+2014-10-01+um+13.10.19.png" height="388" width="640" /></a></div>
<br />
Im September gab es eine (durchaus interessante) Veranstaltung in Stuttgart, die <a href="http://www.mongodb.com/">mongo</a>DB <a href="http://www.mongodb.com/lp/event/iot-euro-city-tour-stuttgart">IoT european city tour</a>. 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.<br />
<br />
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").<br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
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 !<br />
<br />
Interessant ist hier, dass der bulk insert bei mongoDB praktisch keine Verbesserung bringt (bulk inserts scheinen ein schwieriges Thema zu sein, siehe etwa <a href="http://cfc.kizzx2.com/index.php/slow-batch-insert-with-mongodb-sharding-and-how-i-debugged-it/">hier</a> und <a href="https://blog.compose.io/better-bulking-for-mongodb-2-6-and-beyond/">hier</a>).<br />
<br />
Wenn man bei den Datenbanken noch Indices verwendet, muss man sehr ausfpassen, dass die Performance nicht in den Keller geht (siehe etwa <a href="http://stackoverflow.com/questions/6783212/how-to-load-100-million-records-into-mongodb-with-scala-for-performance-testing">hier</a>).<br />
<br />
<br />
<br />
Also: Wegen "Ingestion rate" braucht man keine NoSQL-Datenbank !<br />
<br />
<br />
<br />
Ü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 <a href="http://www.tesora.com/blog/ingesting-over-1000000-rows-second-mysql-aws-cloud">hier</a>.<br />
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.<br />
<br />
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.<br />
<br />
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 .....<br />
<br />
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 <a href="https://www.mapr.com/blog/loading-time-series-database-100-million-points-second#.VCvljCnD9Sc">hier</a>.<br />
<br />
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 !<br />
<br />
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.<br />
<br />
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.<br />
<br />
Bleibt "Open Source". Ist MySQL auch. Zumindest die Community Edition. Wie bei mongoDB auch.<br />
<br />
Was bleibt also von den Argumenten übrig ?<br />
<br />
Nix.<br />
<br />
Den Quellcode der verwendeten Programme gibt's <a href="http://www.tillh.de/mongo_bench.tar">hier</a>.Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-15138998764545068262014-07-02T08:04:00.001-07:002014-07-02T08:04:34.096-07:00Wie in der guten alten Zeit ...<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirf3hkTjyjUSbx746iW5zMnxYuxwyhqWGxLqScq_zYxyc7FhKrjsvN20XUBv3DeQ9vLBU0ok9OJJZMERvEtjuoztkXBE_qp_RS-jFIV0kZPmCyEKDGo7oqO-emRvxjCdVHTBLSXGfFewg/s1600/Bildschirmfoto+2014-07-02+um+16.53.36.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirf3hkTjyjUSbx746iW5zMnxYuxwyhqWGxLqScq_zYxyc7FhKrjsvN20XUBv3DeQ9vLBU0ok9OJJZMERvEtjuoztkXBE_qp_RS-jFIV0kZPmCyEKDGo7oqO-emRvxjCdVHTBLSXGfFewg/s1600/Bildschirmfoto+2014-07-02+um+16.53.36.png" height="148" width="640" /></a></div>
<br />
Von Intel gibt es ganz neu einen sehr schicken - na ja, was eigentlich - sagen wir mal <a href="http://www.intel.com/content/www/us/en/nuc/nuc-kit-de3815tykhe.html">Barebone</a> (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.<br />
<br />
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.<br />
<br />
Bleibt die Frage nach dem Betriebssystem. Linux natürlich. In diesem Fall <a href="http://lubuntu.net/">Lubuntu</a>, 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.<br />
<br />
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 .....<br />
<br />
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:<br />
<br />
In Zeile 102 einfach True statt False, dann läuft der Installer munter weiter .... wer bremst verliert ;-)Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-30716066148481837522014-07-02T04:43:00.000-07:002014-07-02T04:43:23.437-07:00Und noch ein Versuch<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGGY0YF-nO-hutp29newmQ0bm_Q9hQ3Xnw7Pb3xlU9wE6sFE0K1pItfVg2dap_pQFy7yV75R47SLEaMDDb6XSsgq0Ctl1RFpwX3jOjTT5UzrYc1cjv1I2eqZH9z6Pviu1RtRhShYvOXqg/s1600/IRSensor.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGGY0YF-nO-hutp29newmQ0bm_Q9hQ3Xnw7Pb3xlU9wE6sFE0K1pItfVg2dap_pQFy7yV75R47SLEaMDDb6XSsgq0Ctl1RFpwX3jOjTT5UzrYc1cjv1I2eqZH9z6Pviu1RtRhShYvOXqg/s1600/IRSensor.jpg" height="320" width="300" /></a></div>
<br />
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.<br />
<br />
Da ich sowieso einen <a href="https://www.sparkfun.com/datasheets/Sensors/Temperature/SEN-09570-MLX90614.pdf">IR-Temperatursensor</a> ausprobieren wollte, war das die Gelegenheit. Auch hier war das nicht besonders kompliziert, der <a href="http://bildr.org/2011/02/mlx90614-arduino/">Beispielcode</a> 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.<br />
<br />
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.<br />
<br />
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 <a href="http://support.fluke.com/raytek-sales/Download/Asset/9250315_ENG_D_W.PDF">Emissivität </a>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 <a href="http://www.optris.com/temperature-measurement-metal">sehr viel heisser ist</a> 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.<br />
<br />
Fazit: Geht, aber zu teuer. Den nächsten Versuch machen wir mit Ultraschallsensoren. Nächstes Mal ;-)Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-86645149988754455592014-06-24T11:25:00.002-07:002014-06-24T11:25:51.251-07:00Eine sezierte Maus ...<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXFTKA7Xf0ArpdFIDktYmL87wlJflnB0kdhuuKKModTGVrUbE15rGUUT8gpmshcRq9uVCXT-kmA1paWRCHOSjgH6PEGY_u0IzqeQsPy5_4GmWKJDhC-WGB7lMFhvATB_N-dT3WO4RBQYI/s1600/DSC_0053.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXFTKA7Xf0ArpdFIDktYmL87wlJflnB0kdhuuKKModTGVrUbE15rGUUT8gpmshcRq9uVCXT-kmA1paWRCHOSjgH6PEGY_u0IzqeQsPy5_4GmWKJDhC-WGB7lMFhvATB_N-dT3WO4RBQYI/s1600/DSC_0053.jpg" height="214" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both;">
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. </div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Nämlich dann, wenn man keine "Bilder" fotografieren will, sondern nur ein paar Helligkeitswerte unterscheiden muss.</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
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 ;-)</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
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.</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Wir sind natürlöich nicht die ersten, die sich mit dem Innenleben einer Maus beschäftigt haben, wir sind nach dieser <a href="http://wiki.edwindertien.nl/doku.php?id=modules:opticalmouse">Anleitung</a> vorgegangen, da die Jungs dort den Code freundlicherweise schon an den auch in unserer Maus vorhandenen Kamerachip <a href="http://www.efo.ru/components/avago/catalog/files/pdf/5988-9774EN.pdf">ANDS2610</a> angepasst hatten. Funktionierte auch (beinahe wider Erwarten) sofort.</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
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.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglnvm7jnJiJkphblQHg2ICnd8yGALa_kf8JQ1yNmFtYNo-0ZZa0BBGh_TSmvjGVo-_sxMEPvNiPzJV6jPZ9uz8qVFdKVKpnUKnhyphenhyphenvNofhhPggZp4hydBfwFg0-_6O1CQ3GeGeqXvs2hv0/s1600/DSC_0056.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglnvm7jnJiJkphblQHg2ICnd8yGALa_kf8JQ1yNmFtYNo-0ZZa0BBGh_TSmvjGVo-_sxMEPvNiPzJV6jPZ9uz8qVFdKVKpnUKnhyphenhyphenvNofhhPggZp4hydBfwFg0-_6O1CQ3GeGeqXvs2hv0/s1600/DSC_0056.jpg" height="214" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
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.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbXFOmAXtS41z_V2CitXwZK8imBXNp6xeztp9lf-O04C_547vSYD1rz50-yXUOyjsbbJmV1V1NnYG-681FyxCVekX6zdV9-6JbHyck_5sjwN9mxiuyJlboCQL3kkMsZ6tKoptZ1WrVFig/s1600/DSC_0062.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbXFOmAXtS41z_V2CitXwZK8imBXNp6xeztp9lf-O04C_547vSYD1rz50-yXUOyjsbbJmV1V1NnYG-681FyxCVekX6zdV9-6JbHyck_5sjwN9mxiuyJlboCQL3kkMsZ6tKoptZ1WrVFig/s1600/DSC_0062.jpg" height="214" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Funktioniert ! Im Labor. Schau mer mal, wie das dann aussieht, wenn der Sensor in die Stosstange des Autos eingebaut ist.</div>
<br />Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-29217056924904092802014-05-10T05:17:00.002-07:002014-05-10T05:17:24.239-07:00So sehen Probleme aus ...<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaCa8GFCZjGGV7vzjq5GQwvFQFmV6TtkoYOaYHl8HZBW4NMzEb49RUHDqzr2aslbCMLKUcSJoWhB1EiH9IVvjKoiONd35Yp1cuzT7dVD7c6sB_L5k0TdLRgTSuVvqkOI_f_73Es3CeQi4/s1600/SCR01.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaCa8GFCZjGGV7vzjq5GQwvFQFmV6TtkoYOaYHl8HZBW4NMzEb49RUHDqzr2aslbCMLKUcSJoWhB1EiH9IVvjKoiONd35Yp1cuzT7dVD7c6sB_L5k0TdLRgTSuVvqkOI_f_73Es3CeQi4/s1600/SCR01.PNG" height="260" width="320" /></a></div>
<br />
Das ist die Versorgungsspannung des Roboter-Controllers. Man sieht, wie der Regler zu schwingen anfängt. Und das gefällt dem Gyrosensor gar nicht.<br />
<br />
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 <a href="http://www.ebay.de/itm/MPU6050-GY-521-Sensor-3-Achse-Gyroscope-Acce-lerometer-AVR-fuer-Arduino-Multiwii-/171251337157?ssPageName=ADME:L:OC:DE:3160">günstig</a> und auch entsprechende <a href="http://playground.arduino.cc/Main/MPU-6050">Beispielprogramme</a>. 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 ....<br />
<br />
Heute bin ich endlich dazu gekommen, dem Problem auf den Grund zu gehen (morgen ist Julius wieder hier und will den Roboter mitnehmen).<br />
<br />Die Motoren erzeugen lustige Störsignale, die den Spannungsregler zum fröhlichen mitschwingen anregen. Oh oh ....<br />
<br />
Motoren mit einem (MKT-) Kondensator entstört, schluckt die tiefen Frequenzen gut weg, aber der HF-Müll bleibt:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSnNcoWE7VHF_M9O4SXP0Y3O3iQbIZQvoeDGLNN65zfsIPUdlIw-smpBqLO6FsDjmp2JKI7oEF_HZ1veLG9UhYIb7imnyf0_TK812365kSDB48YAfY9ATzcsfBS0PFVMBN8zoBfHQE-QY/s1600/SCR05.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSnNcoWE7VHF_M9O4SXP0Y3O3iQbIZQvoeDGLNN65zfsIPUdlIw-smpBqLO6FsDjmp2JKI7oEF_HZ1veLG9UhYIb7imnyf0_TK812365kSDB48YAfY9ATzcsfBS0PFVMBN8zoBfHQE-QY/s1600/SCR05.PNG" height="260" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
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 :-(</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
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.</div>
<br />Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-30656082810524731152014-02-28T03:28:00.000-08:002014-02-28T02:45:11.810-08:00Ein einfacher Robotor entsteht ....<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYcq-JFcJXe01t7f3tecQocrJCDzYTdlFpDOm8Lh2HVBKNmUn_JzjRg8xdPWXDOwSrl8ppKHWNgOablkLsOIxtcvlZ2K5CPvFhSzHDB8SS1hfEO18kQ0maLQnkf3j2tyh4H6VQ-0NBYSc/s1600/Julius.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYcq-JFcJXe01t7f3tecQocrJCDzYTdlFpDOm8Lh2HVBKNmUn_JzjRg8xdPWXDOwSrl8ppKHWNgOablkLsOIxtcvlZ2K5CPvFhSzHDB8SS1hfEO18kQ0maLQnkf3j2tyh4H6VQ-0NBYSc/s1600/Julius.jpg" height="320" width="239" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
aber wozu bloß ??<br />
<br />
Man braucht bekanntlich Motiv, Gelegenheit und Mittel zur Umsetzung.<br />
<br />
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 <a href="http://www.processing.org/">Processing</a>. Das machen wir in der WI in Heidenheim <a href="http://wi2.dhbw-heidenheim.de:8001/">so</a>. Eine vielversprechende Variante ist das Scripting von Spielen, etwa <a href="http://pragprog.com/book/ahmine/learn-to-program-with-minecraft-plugins">so</a>. Der Ansatz, um den es hier geht, ist die Verwendung von Robots. Durch <a href="http://www.lego.com/en-us/mindstorms/?domainredir=mindstorms.lego.com">Lego Mindstorm</a> 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.<br />
<br />
Verwendet haben wir einen Bausatz, den es etwa bei ebay für wenig Geld gibt, etwa <a href="http://www.ebay.de/itm/SainSmart-4WD-Drive-Aluminum-Mobile-Car-Silver-Robot-Platform-4-Arduino-Motor-DE-/320969267864?pt=Wissenschaftliche_Ger%C3%A4te&hash=item4abb425a98">hier</a>. Der liegt seit gut einem Jahr bei mir rum und wartet auf Zuwendung. Bisher erfolglos. Aber da kam in Gestalt eines <a href="http://www.schule-bw.de/schularten/gymnasium/bogy/ueber/info/">Bogy</a>-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.<br />
<br />
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.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTd5BvaXFtaeNeI-HP7cHYbz6EKJ-f2MnWHwUwGKL51YSaiFsjHLcoLVgEESCrx_VcGsRjEnsrKA93apXchkMDQZhqFZWw9zSDK0_QfCdDB9m2hijICjxkwQ3eZz0U_ags7bfVcrQzvEE/s1600/RoboFaehrt.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTd5BvaXFtaeNeI-HP7cHYbz6EKJ-f2MnWHwUwGKL51YSaiFsjHLcoLVgEESCrx_VcGsRjEnsrKA93apXchkMDQZhqFZWw9zSDK0_QfCdDB9m2hijICjxkwQ3eZz0U_ags7bfVcrQzvEE/s1600/RoboFaehrt.jpg" height="214" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
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 <a href="http://de.wikipedia.org/wiki/Pulsweitenmodulation">PWM</a>, 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.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Ein Roboter, der nur auf dem freien Feld fahren kann, wird schnell langweilig. Deshalb kommt am dritten Tag ein <a href="http://www.seeedstudio.com/wiki/index.php?title=Ultra_Sonic_range_measurement_module">Ultraschallsensor</a> dazu, der Hindernisse erkennen kann. Der ist schnell integriert, bloss was tut man, wenn man ein Hindernis erkennt ? Zunächst mal nix:</div>
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/8GDKrHn8Bv0" width="420"></iframe>
<br />
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.<br />
<br />
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:<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/W1z_SXDgWnU" width="420"></iframe>
<br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
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 <a href="http://cgi.ebay.de/ws/eBayISAPI.dll?ViewItem&item=171251337157&ssPageName=ADME:L:OC:DE:3160">Gyro-Sensor</a>, der hoffentlich rechtzeitig geliefert wird.</div>
<br />
<br />
<u>Julius</u>: 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<br />
meine Berufserkundung nochmal machen könnte, würde ich wieder kommen.<br />
<br />
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.<br />
<br />
PS: Der Sensor kam leider nicht mehr rechtzeitig hier an.Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-67123170038744445542014-01-17T03:19:00.000-08:002014-01-17T03:19:00.476-08:00Warum Thermostaten interessant sind ....<div>
oder: Warum gibt google mehr als 3 Milliarden Dollar für einen Hersteller von Thermostaten aus ?</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
Glaubt man etwa der <a href="http://www.faz.net/aktuell/wirtschaft/netzwirtschaft/google/fuer-ueber-drei-milliarden-dollar-google-kauft-rauchmelder-firma-nest-12750875.html">FAZ</a>, 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.“<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
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 ?</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Blödsinn !</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
</div>
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. <a href="http://iotresearch.blogspot.de/2013/09/feuchtesensor.html">Solche Sensoren</a> setzt man etwa im industriellen Umfeld zur <a href="http://www.tillh.de/Sensor.html">Optimierung der Produktionsabläufe</a> 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.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidk0r34pO20F18kjby9AoCXCXfoCqqVUDTYlUh-b9QNLR6DK1lAkyquxLrtxxhCsSQb2yEz0WfhaqHZ8kxXjsp0wewnCeMty34Rpi9_S7mz9TX50eb0TUFQQNvNUn2QMgGSlxI9m_ixWY/s1600/AusschnittTempBuero.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidk0r34pO20F18kjby9AoCXCXfoCqqVUDTYlUh-b9QNLR6DK1lAkyquxLrtxxhCsSQb2yEz0WfhaqHZ8kxXjsp0wewnCeMty34Rpi9_S7mz9TX50eb0TUFQQNvNUn2QMgGSlxI9m_ixWY/s1600/AusschnittTempBuero.png" height="348" width="640" /></a><br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
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 ....<br />
<br />
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.<br />
<br />
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 ....<br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<br />Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-84504228201946478252014-01-15T05:24:00.001-08:002014-01-16T06:18:09.837-08:00Wie 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." (<a href="http://de.wikipedia.org/wiki/Idempotenz">wikipedia</a>). 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.<br />
<br />
Um das anschaulicher zu machen, habe ich eine "Lampe" gebaut:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<span 1em="" margin-left:="" margin-right:=""><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqp-bzxlotBnnFrBAgRRougS2SNxrHiTpWMxHOB4bNw9uToziK4FEFImRAGMiVpQh3n-G7FFhTQNzXlr9UR5rrnKLKOiwWoSQ0fo-TKx1uGClPRQHDmRulNuWhKz8IW6_KZzHtCWigvwQ/s1600/Basis.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqp-bzxlotBnnFrBAgRRougS2SNxrHiTpWMxHOB4bNw9uToziK4FEFImRAGMiVpQh3n-G7FFhTQNzXlr9UR5rrnKLKOiwWoSQ0fo-TKx1uGClPRQHDmRulNuWhKz8IW6_KZzHtCWigvwQ/s320/Basis.jpg" height="320" width="200" /></a></span></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Dazu gibt es einen Schalter, genauer gesagt einen Taster</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj43WfzcmWb6_QnJoloD88cGk0COB26qK1ub8RDVobG-_7ZuM-bEdPeywnpz7LK-ne9AgdQQdBdVpUORVVd9Vo1hiGwhnu7zQzyoFbxkASj8kjcH5hNP3flhzbNTweA2uU3YMqCCks-Yjg/s1600/Taster.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="background-color: #999999;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj43WfzcmWb6_QnJoloD88cGk0COB26qK1ub8RDVobG-_7ZuM-bEdPeywnpz7LK-ne9AgdQQdBdVpUORVVd9Vo1hiGwhnu7zQzyoFbxkASj8kjcH5hNP3flhzbNTweA2uU3YMqCCks-Yjg/s320/Taster.jpg" height="179" width="320" /></span></a></div>
<br />
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.<br />
<br />
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.<br />
<br />
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").<br />
<br />
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).<br />
<br />
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.<br />
<br />
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.<br />
<br />
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".<br />
<br />
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 ?<br />
<br />
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.<br />
<br />
Man muss die Anwendung so konstruieren, dass kein Schaden entsteht, wenn eine Nachricht mehrfach empfangen wird. Das ist Idempotenz.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: sans-serif; font-size: x-small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv64OA3NNsre31mVptlVdPAoElTAzA8Ll-uk8UwEpURZe_j9hyphenhyphenXJ0wXmjegco0-ndWZeUU1_mRlKdp49NWfr1PKVTmF8158Bw_lQnqfgWCVox3GdZ_y56zLiMSIMxYjcZwFd5MIm1Ddsw/s1600/Schalter.jpg" imageanchor="1" style="background-color: #999999; margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv64OA3NNsre31mVptlVdPAoElTAzA8Ll-uk8UwEpURZe_j9hyphenhyphenXJ0wXmjegco0-ndWZeUU1_mRlKdp49NWfr1PKVTmF8158Bw_lQnqfgWCVox3GdZ_y56zLiMSIMxYjcZwFd5MIm1Ddsw/s320/Schalter.jpg" height="318" width="320" /></a></span></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
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).<br />
<br />
<br />
Nächste Woche werde ich das in der Vorlesung ausprobieren, mal schauen, ob dieses Konzept so besser verständlich ist.<br />
<br />
Realisiert wurde das System mit ZigBee zur Übertragung, hierfür wurden XBee-Module der Firma <a href="http://www.digi.com/xbee/">Digi</a> 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.<br />
<br />
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 ....Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-29547318712602139672013-10-24T07:43:00.000-07:002016-04-25T05:15:48.349-07:00Erster Praxistest der Sensoren<div class="separator" style="clear: both; text-align: center;">
<a href="http://backend.tillh.de/wp-uploads/2013/10/BasisKehl.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://backend.tillh.de/wp-uploads/2013/10/BasisKehl.jpg" height="480" width="640" /></a></div>
<br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
Unser erster Versuch geht über 4 Wochen. Bei 85 Grad und gut 30 Prozent relativer Feuchte. Damit kann man schon ganz komfortabel Mahlzeiten zubereiten ;-)<br />
<br />
Aber zumindest bisher funktioniert alles. Am 24. haben wir die Sensoren installiert und bis heute keine (schlechten) Nachrichten bekommen.<br />
<br />
<strong>Update:</strong> Eine Woche vorbei und alles noch OK.Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-37778667959010823502013-10-17T11:36:00.000-07:002013-11-16T11:46:28.373-08:00Wie lang hält die Batterie ....<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi767ds6QzuTxcgJRKAOr6-R13m3TUbsb-OO3ZCK4IqiYcQufNoLt3yleAtVZa4OF3YV_anSSe5uPo8BJFxi6-2O6bWT8e4TKiAG4H4Tsi0yarcRaBhHP5k2vN71ZhoQp6d567gBJEflbY/s1600/Bildschirmfoto+2013-11-16+um+20.30.49.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="182" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi767ds6QzuTxcgJRKAOr6-R13m3TUbsb-OO3ZCK4IqiYcQufNoLt3yleAtVZa4OF3YV_anSSe5uPo8BJFxi6-2O6bWT8e4TKiAG4H4Tsi0yarcRaBhHP5k2vN71ZhoQp6d567gBJEflbY/s320/Bildschirmfoto+2013-11-16+um+20.30.49.png" width="320" /></a></div>
Grau mein Freund ist alle Theorie ....<br />
<br />
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).<br />
<br />
Nach etwa sechs Wochen ist die Spannung von anfänglich etwa knapp 4,2 Volt auf gut 3,7 Volt gefallen.<br />
<br />
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.<br />
<br />
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.<br />
<br />
<br />
<br />Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-47213839869265077992013-09-22T13:11:00.000-07:002016-04-25T05:17:52.115-07:00Vergleichstest der Sensoren<div class="separator" style="clear: both; text-align: center;">
<a href="http://backend.tillh.de/wp-uploads/2013/10/BasisDaten.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://backend.tillh.de/wp-uploads/2013/10/BasisDaten.jpg" height="310" width="640" /></a></div>
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
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 ;-)Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-54185669199054504222013-09-20T07:34:00.000-07:002016-04-25T05:18:57.994-07:00Die Basisstation<div class="separator" style="clear: both; text-align: center;">
<a href="http://backend.tillh.de/wp-uploads/2013/10/BasisAufbau.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://backend.tillh.de/wp-uploads/2013/10/BasisAufbau.jpg" height="424" width="640" /></a></div>
<br />
Die Basis besteht aus einem <a href="http://www.raspberrypi.org/">Raspberry Pi</a>, einem <a href="http://en.wikipedia.org/wiki/XBee">XBee-Modul</a> 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 <a href="http://www.adafruit.com/products/801">Pi Plate Kit von Adafruit</a> aufgebaut.<br />
<br />
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.Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-36172580829588095672013-08-22T06:35:00.000-07:002013-12-06T06:36:56.382-08:00Dynamische Messung der Stromaufnahme<div class="MsoNormal">
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.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Die Stromaufnahme des Arduino im sleep-mode (powerDown,
ADC_OFF, BOD_OFF) beträgt statisch gemessen ca. 40 µA (direkte Strommessung,
Philips PM 2503).</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span lang="EN-GB" style="mso-ansi-language: EN-GB;">Konfiguration:
Arduino Fio, XBee Series 2, LiPo Akku 850 mAh, LowPower V. 1.30 </span><a href="https://github.com/rocketscream/Low-Power"><span lang="EN-GB" style="mso-ansi-language: EN-GB;">https://github.com/rocketscream/Low-Power</span></a><span lang="EN-GB" style="mso-ansi-language: EN-GB;">)<o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Die dynamischen Messungen wurden als Spannungsmessungen über
einem 1 Ω 1% Widerstand mit einem HP 54200A Digitaloszilloskop ausgeführt.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
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.</div>
<div class="MsoNormal">
<br /></div>
<!--[if gte mso 9]><xml>
<o:DocumentProperties>
<o:Template>Normal.dotm</o:Template>
<o:Revision>0</o:Revision>
<o:TotalTime>0</o:TotalTime>
<o:Pages>1</o:Pages>
<o:Words>185</o:Words>
<o:Characters>1057</o:Characters>
<o:Company>BA Heidenheim</o:Company>
<o:Lines>8</o:Lines>
<o:Paragraphs>2</o:Paragraphs>
<o:CharactersWithSpaces>1298</o:CharactersWithSpaces>
<o:Version>12.0</o:Version>
</o:DocumentProperties>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
</o:OfficeDocumentSettings>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:Zoom>0</w:Zoom>
<w:TrackMoves>false</w:TrackMoves>
<w:TrackFormatting/>
<w:HyphenationZone>21</w:HyphenationZone>
<w:PunctuationKerning/>
<w:DrawingGridHorizontalSpacing>18 pt</w:DrawingGridHorizontalSpacing>
<w:DrawingGridVerticalSpacing>18 pt</w:DrawingGridVerticalSpacing>
<w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
<w:DisplayVerticalDrawingGridEvery>0</w:DisplayVerticalDrawingGridEvery>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:DontGrowAutofit/>
<w:DontAutofitConstrainedTables/>
<w:DontVertAlignInTxbx/>
</w:Compatibility>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="276">
</w:LatentStyles>
</xml><![endif]-->
<!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Normale Tabelle";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;}
</style>
<![endif]-->
<!--StartFragment-->
<!--EndFragment--><br />
<div class="MsoNormal">
Zunächst wurde der Stromverbrauch des Arduino-Boards ohne
XBee-Modul gemessen:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGfYyR7LZkOdNk6zjd7ehfVFjZxK4Bg4wzohQZOcPpJIURVz_Yk4QkmcIkg83816XoytvbxMwMDLJV0We6tB2BdASXyaSerVQJs0f75Qma4_ZNzF7deIF0gL868I8zbIl7iIBvDwbMiJs/s1600/p1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGfYyR7LZkOdNk6zjd7ehfVFjZxK4Bg4wzohQZOcPpJIURVz_Yk4QkmcIkg83816XoytvbxMwMDLJV0We6tB2BdASXyaSerVQJs0f75Qma4_ZNzF7deIF0gL868I8zbIl7iIBvDwbMiJs/s320/p1.jpg" width="320" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
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.</div>
<div class="MsoNormal">
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.</div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<!--[if gte mso 9]><xml>
<o:DocumentProperties>
<o:Template>Normal.dotm</o:Template>
<o:Revision>0</o:Revision>
<o:TotalTime>0</o:TotalTime>
<o:Pages>1</o:Pages>
<o:Words>81</o:Words>
<o:Characters>466</o:Characters>
<o:Company>BA Heidenheim</o:Company>
<o:Lines>3</o:Lines>
<o:Paragraphs>1</o:Paragraphs>
<o:CharactersWithSpaces>572</o:CharactersWithSpaces>
<o:Version>12.0</o:Version>
</o:DocumentProperties>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
</o:OfficeDocumentSettings>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:Zoom>0</w:Zoom>
<w:TrackMoves>false</w:TrackMoves>
<w:TrackFormatting/>
<w:HyphenationZone>21</w:HyphenationZone>
<w:PunctuationKerning/>
<w:DrawingGridHorizontalSpacing>18 pt</w:DrawingGridHorizontalSpacing>
<w:DrawingGridVerticalSpacing>18 pt</w:DrawingGridVerticalSpacing>
<w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
<w:DisplayVerticalDrawingGridEvery>0</w:DisplayVerticalDrawingGridEvery>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:DontGrowAutofit/>
<w:DontAutofitConstrainedTables/>
<w:DontVertAlignInTxbx/>
</w:Compatibility>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="276">
</w:LatentStyles>
</xml><![endif]-->
<!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Normale Tabelle";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;}
</style>
<![endif]-->
<!--StartFragment-->
<!--EndFragment--></div>
<div class="MsoNormal">
Daraufhin wurde die Stromaufnahme mit XBee-Modul gemessen.</div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ84YUCKcSuy18IenwpjquHh2jFXSzCv0iq3NrUCGbVuoQFFp6b05psQiqte40CLw6cMG_kNnHgyvjKOFhdVrvIl1bu1yjIUSNsd39RnuovL2irqzFFzv1eRtmyOsHcddy7I4WoKz-nUo/s1600/p2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ84YUCKcSuy18IenwpjquHh2jFXSzCv0iq3NrUCGbVuoQFFp6b05psQiqte40CLw6cMG_kNnHgyvjKOFhdVrvIl1bu1yjIUSNsd39RnuovL2irqzFFzv1eRtmyOsHcddy7I4WoKz-nUo/s320/p2.jpg" width="320" /></a></div>
<div class="MsoNormal">
Da das XBee-Modul mindestens etwa 3 Sekunden „wach“ blieb<a href="http://www.blogger.com/blogger.g?blogID=8440482468154379225#_ftn1" name="_ftnref" style="mso-footnote-id: ftn;" title=""><span class="MsoFootnoteReference"><span style="mso-special-character: footnote;"><!--[if !supportFootnotes]-->[1]<!--[endif]--></span></span></a>,
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.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
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.</div>
<div class="MsoNormal">
Dies führt zu folgenden Betriebsdauern:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDXEWdaSBY9pxidOSArVl6Of0xSTQITqOeUbW01g2AhC1SqMQQRgxrleAI-EvltUF88c4lmXN00f0MXWd-wyJlpN1i3iVw5RVTQWQBD2MdVVQhKlkIZ-OGi5FaVSPpEkJjB0mEhFAPB94/s1600/p3.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="257" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDXEWdaSBY9pxidOSArVl6Of0xSTQITqOeUbW01g2AhC1SqMQQRgxrleAI-EvltUF88c4lmXN00f0MXWd-wyJlpN1i3iVw5RVTQWQBD2MdVVQhKlkIZ-OGi5FaVSPpEkJjB0mEhFAPB94/s640/p3.gif" width="640" /></a></div>
<div class="MsoNormal">
<br />
<!--[endif]--><!--[if gte mso 9]><xml>
<o:OLEObject Type="Embed" ProgID="Excel.Sheet.8" ShapeID="_x0000_i1025"
DrawAspect="Content" ObjectID="_1321705227">
</o:OLEObject>
</xml><![endif]--></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
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.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;">/**<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;">* Short sleep cycles to measure power consumption<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;">* essentially a fast blink with sleep during off time<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;">**/<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<br /></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;">#include "LowPower.h"<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<br /></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;">char c = 'A';<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<br /></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;">const int XBEE_WAKE = 7;<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<br /></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;">void setup() {<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span>Serial.begin(9600);<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;"> </span>// Send
XBee to sleep, never wake it up<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span>digitalWrite(XBEE_WAKE,HIGH); // just in case<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;"> </span>// XBee
pins are clamped internally<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span>pinMode(XBEE_WAKE,INPUT);<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;">}<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<br /></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;">void loop () {<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span>LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span>digitalWrite(13, HIGH);<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;"> </span>// Send
to XBee Module<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;"> </span>// first
wake it up<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span>pinMode(XBEE_WAKE,OUTPUT);<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span>digitalWrite(XBEE_WAKE,LOW);<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;"> </span>// wait
a little bit<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span>delay(100);<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span>Serial.print(c);<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span>Serial.flush();<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;"> </span>// wait
a little bit and send XBee to sleep again<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span>delay(100);<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span>digitalWrite(XBEE_WAKE,HIGH); // just in case<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;"> </span>// XBee
pins are clamped internally<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span>pinMode(XBEE_WAKE,INPUT);<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<br /></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<br /></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span lang="EN-GB" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: EN-GB;"><span style="mso-spacerun: yes;">
</span></span></b><b style="mso-bidi-font-weight: normal;"><span style="font-family: "Courier New"; font-size: 10.0pt;">delay(100);<o:p></o:p></span></b></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span style="font-family: "Courier New"; font-size: 10.0pt;"><span style="mso-spacerun: yes;"> </span>digitalWrite(13, LOW);<o:p></o:p></span></b></div>
<div class="MsoNormal">
<!--[if gte mso 9]><xml>
<o:DocumentProperties>
<o:Template>Normal.dotm</o:Template>
<o:Revision>0</o:Revision>
<o:TotalTime>0</o:TotalTime>
<o:Pages>1</o:Pages>
<o:Words>126</o:Words>
<o:Characters>723</o:Characters>
<o:Company>BA Heidenheim</o:Company>
<o:Lines>6</o:Lines>
<o:Paragraphs>1</o:Paragraphs>
<o:CharactersWithSpaces>887</o:CharactersWithSpaces>
<o:Version>12.0</o:Version>
</o:DocumentProperties>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
</o:OfficeDocumentSettings>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:Zoom>0</w:Zoom>
<w:TrackMoves>false</w:TrackMoves>
<w:TrackFormatting/>
<w:HyphenationZone>21</w:HyphenationZone>
<w:PunctuationKerning/>
<w:DrawingGridHorizontalSpacing>18 pt</w:DrawingGridHorizontalSpacing>
<w:DrawingGridVerticalSpacing>18 pt</w:DrawingGridVerticalSpacing>
<w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
<w:DisplayVerticalDrawingGridEvery>0</w:DisplayVerticalDrawingGridEvery>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:DontGrowAutofit/>
<w:DontAutofitConstrainedTables/>
<w:DontVertAlignInTxbx/>
</w:Compatibility>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="276">
</w:LatentStyles>
</xml><![endif]-->
<!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Normale Tabelle";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;}
</style>
<![endif]-->
<!--StartFragment-->
<!--EndFragment--></div>
<div class="MsoNormal" style="margin-left: 1.0cm;">
<b style="mso-bidi-font-weight: normal;"><span style="font-family: "Courier New"; font-size: 10.0pt;">}<o:p></o:p></span></b></div>
<div class="separator" style="clear: both; text-align: center;">
<!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]--><!--[if gte mso 9]><xml>
<o:DocumentProperties>
<o:Template>Normal.dotm</o:Template>
<o:Revision>0</o:Revision>
<o:TotalTime>0</o:TotalTime>
<o:Pages>1</o:Pages>
<o:Words>269</o:Words>
<o:Characters>1538</o:Characters>
<o:Company>BA Heidenheim</o:Company>
<o:Lines>12</o:Lines>
<o:Paragraphs>3</o:Paragraphs>
<o:CharactersWithSpaces>1888</o:CharactersWithSpaces>
<o:Version>12.0</o:Version>
</o:DocumentProperties>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
</o:OfficeDocumentSettings>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:Zoom>0</w:Zoom>
<w:TrackMoves>false</w:TrackMoves>
<w:TrackFormatting/>
<w:HyphenationZone>21</w:HyphenationZone>
<w:PunctuationKerning/>
<w:DrawingGridHorizontalSpacing>18 pt</w:DrawingGridHorizontalSpacing>
<w:DrawingGridVerticalSpacing>18 pt</w:DrawingGridVerticalSpacing>
<w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
<w:DisplayVerticalDrawingGridEvery>0</w:DisplayVerticalDrawingGridEvery>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:DontGrowAutofit/>
<w:DontAutofitConstrainedTables/>
<w:DontVertAlignInTxbx/>
</w:Compatibility>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="276">
</w:LatentStyles>
</xml><![endif]-->
<!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Normale Tabelle";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;}
</style>
<![endif]-->
<!--StartFragment-->
<!--EndFragment--></div>
<div style="mso-element: footnote-list;">
<!--[if !supportFootnotes]--><br clear="all" />
<hr align="left" size="1" width="33%" />
<!--[endif]-->
<br />
<div id="ftn" style="mso-element: footnote;">
<div class="MsoFootnoteText">
<a href="http://www.blogger.com/blogger.g?blogID=8440482468154379225#_ftnref" name="_ftn1" style="mso-footnote-id: ftn;" title=""><span class="MsoFootnoteReference"><span style="mso-special-character: footnote;"><!--[if !supportFootnotes]-->[1]<!--[endif]--></span></span></a> 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.</div>
</div>
</div>
<div class="MsoNormal">
<br /></div>
Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-5533198734909212272013-08-10T07:43:00.000-07:002013-11-12T04:01:23.239-08:00AD7714 - die SoftwareDer <a href="http://www.analog.com/en/analog-to-digital-converters/ad-converters/ad7714/products/product.html" title="AD7714">AD7714</a> - 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.<br />
<br />
Angebunden wird er über die <a href="http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus" title="SPI">SPI</a>-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).<br />
<br />
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<br />
<br />
SPI.setDataMode(SPI_MODE2);<br />
<br />
Der AD7714 liefert (und erwartet) die Daten MSB first, das wird mit<br />
<br />
SPI.setBitOrder(MSBFIRST);<br />
<br />
definiert. Bleibt noch die Taktrate, wir haben es nicht allzu eilig und nehmen<br />
<br />
SPI.setClockDivider(32);<br />
<br />
das müssten 500kHz sein.<br />
<br />
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.<br />
<br /><br /><table><tbody>
<tr><th>Code</th><th>dezimal</th><th>Register</th></tr>
<tr><td>000</td><td>0</td><td>Communications Register</td></tr>
<tr><td>001</td><td>16</td><td>Mode Register</td></tr>
<tr><td>010</td><td>32</td><td>Filter High Register</td></tr>
<tr><td>011</td><td>48</td><td>Filter Low Register</td></tr>
<tr><td>100</td><td>64</td><td>Test Register</td></tr>
<tr><td>101</td><td>80</td><td>Data Register</td></tr>
</tbody></table>
<br />
Die Codes 110 und 111 sind die Calibration Registers und im Moment uninteressant.<br />
<br />
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).<br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
Als nächstes muss das Mode-Register konfiguriert werden, dazu zunächst Mode-Register für einen Schreibzugriff auswählen 0x14 (20)<br />
<br />
Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-82754808976154854162013-05-12T12:00:00.000-07:002013-11-16T12:01:51.504-08:00Hobel sind Präzisionsinstrumente ....<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdae6hvwsV71d0iFWISp-XZqf7BMSEPemLa06xH2LQH4bnmyhIT6LEnbowq8G4YVGx8uTKEZLP1ZqtU-LvPikFI_li4cbfNFFekVD1VcDt2FoFZtiKk3aMbhsCdvaJlRll3_AOt-Zuk-eI/s1600/Hobel.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdae6hvwsV71d0iFWISp-XZqf7BMSEPemLa06xH2LQH4bnmyhIT6LEnbowq8G4YVGx8uTKEZLP1ZqtU-LvPikFI_li4cbfNFFekVD1VcDt2FoFZtiKk3aMbhsCdvaJlRll3_AOt-Zuk-eI/s320/Hobel.jpg" width="320" /></a></div>
<br />
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.<br />
<br />
<br />
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. <a href="http://haus-renovieren.blogspot.de/2013/03/nein-kein-sarg.html">Voila</a> !<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuDEkXqvOpNJ5SAeeQUqS5ckUnO2aCHNp5pYMenJcH00nWsRi9h_b3a6exMeYb7S4sLOZA5dZLDzrEpRRefUG0lY0I3wuQzetBVUvxpOdlgMLF05akyIvSjd6RRRHaSx1_90deOn5OUIyj/s1600/DSC_0110.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="249" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuDEkXqvOpNJ5SAeeQUqS5ckUnO2aCHNp5pYMenJcH00nWsRi9h_b3a6exMeYb7S4sLOZA5dZLDzrEpRRefUG0lY0I3wuQzetBVUvxpOdlgMLF05akyIvSjd6RRRHaSx1_90deOn5OUIyj/s320/DSC_0110.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both;">
In einer ausgeglichen temperierten Werkstatt reicht das aus, in einem <a href="http://haus-renovieren.blogspot.de/2012/11/einhunderteinundfunfzig.html">feuchten Keller</a> nicht :-( Dabei ist nicht einmal der tatsächliche Wert entscheidend, sondern die Schwankungen. Aber wie vermeidet man die ?</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
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.</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
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:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCOpxv3WPb1Pv6KXHy8DrG693s7oy9CXLxcUsdltfdq0W6PpJntKkFrP4nCf2OWXwyxitZrrsbFMcMDASV13jr2hNQWS2n0NLe8mT5SKTFIZR27R3ue2IKFyz4x7Y5yOfbSjgHNF-f6c0r/s1600/DSC_0114.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCOpxv3WPb1Pv6KXHy8DrG693s7oy9CXLxcUsdltfdq0W6PpJntKkFrP4nCf2OWXwyxitZrrsbFMcMDASV13jr2hNQWS2n0NLe8mT5SKTFIZR27R3ue2IKFyz4x7Y5yOfbSjgHNF-f6c0r/s320/DSC_0114.jpg" width="320" /></a></div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Vermutlich bin ich einer der wenigen Menschen mit einer beleuchteten Werkzeugkiste ;-)</div>
<div class="separator" style="clear: both;">
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.</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Idee gut, Ergebnis leider nicht überzeugend: Bringt etwa 0,2 Grad und knapp 3 Prozent weniger Luftfeuchtigkeit .... Nächster Versuch.</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Vielleicht erstmal messen .... also eine kontinuierliche Messung von Temperatur und Luftfeuchtigkeit installiert. Für die "normalen" Anwendungen arbeiten wir ja mit <a href="http://haus-renovieren.blogspot.de/2011/11/der-kleine-hat-geschwisterchen-bekommen.html">Datenloggern</a>, 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. </div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Normalerweise hätte ich das zähneknirschend akzeptiert. Aber da ich zur Zeit sowieso gemeinsam mit einem <a href="http://www.zm-technik.de/">Startup</a> 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</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Ein <a href="http://8devices.com/carambola">Carambola</a> Board und ein <a href="http://www.conrad.de/ce/de/product/505671/Digitaler-Feuchte-Temperatur-Sensor-HYT-IST-AG-HYT-221-18-0-100-rF-02-C-40-125-C;jsessionid=CC64E01CD4F91F8A2F76BC0261973DFB.ASTPCEN11">Feuchtesensor</a> 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.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTMVp3UupV7cApb9iE0jYfkDp8j81PENbL-B_AMMi4HDb-ygKTOQE5ThfZDbouULE8uFYUl9IOvMrgSfRjPgHZbrWc8idQ8AHbaoVcemrt-wGOcKzHH6fcQVTdO32da-qdtHmMz4RfowaI/s1600/DSC_0153.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTMVp3UupV7cApb9iE0jYfkDp8j81PENbL-B_AMMi4HDb-ygKTOQE5ThfZDbouULE8uFYUl9IOvMrgSfRjPgHZbrWc8idQ8AHbaoVcemrt-wGOcKzHH6fcQVTdO32da-qdtHmMz4RfowaI/s320/DSC_0153.jpg" width="320" /></a></div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Hoch interessant, was man mit geeigneten Sensoren alles messen kann ....</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyMShycH9x1A9fT1FJSt9jzItSZDsfW9v-eSXEj2AsPd7w4BUp2BWNnTV_ApZ_d5j5SM9Y9oVrGBTOPlKAXDhpaLYv_-mImUiX7TM3VwuVqsR-vGcdglbrYwxOFDeUYQEAk_vAg3OGInvh/s1600/Bildschirmfoto+2013-05-12+um+20.29.45.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="188" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyMShycH9x1A9fT1FJSt9jzItSZDsfW9v-eSXEj2AsPd7w4BUp2BWNnTV_ApZ_d5j5SM9Y9oVrGBTOPlKAXDhpaLYv_-mImUiX7TM3VwuVqsR-vGcdglbrYwxOFDeUYQEAk_vAg3OGInvh/s320/Bildschirmfoto+2013-05-12+um+20.29.45.png" width="320" /></a></div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
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 ...</div>
<div class="separator" style="clear: both;">
Wenn drei Erwachsene (?) mit aller Hingabe an Bumerangs basteln, sieht das noch mal ganz anders aus:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjabUBT2Ewnz2IYeKPN_dCa_SEBLXy5IgIWdjfBWbE9rtttgsLp7GK8LPu_LgbgLzGtoC_hZtanaMQPWp3GPSmKIZGod15KeU-T6epeJhW_LXKykjgCqL7hJPl0XXlCA_3GHgMkFzff9ck-/s1600/Bildschirmfoto+2013-05-12+um+20.32.14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="205" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjabUBT2Ewnz2IYeKPN_dCa_SEBLXy5IgIWdjfBWbE9rtttgsLp7GK8LPu_LgbgLzGtoC_hZtanaMQPWp3GPSmKIZGod15KeU-T6epeJhW_LXKykjgCqL7hJPl0XXlCA_3GHgMkFzff9ck-/s320/Bildschirmfoto+2013-05-12+um+20.32.14.png" width="320" /></a></div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
3,6% in nicht mal einer halben Stunde ! Big Data ist was Feines ....</div>
<div class="separator" style="clear: both;">
Wer sich selber den aktuellen Stand anschauen will, findet den (wenn ich nicht grade an der Hardware bastle) <a href="http://wi2.dhbw-heidenheim.de:3000/">hier</a>.</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Conclusio</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
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 !</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Zweitens: </div>
<div class="separator" style="clear: both;">
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).</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Drittens:</div>
<div class="separator" style="clear: both;">
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). </div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
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 !</div>
Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-54973679801202719302013-05-04T12:56:00.000-07:002016-04-25T05:20:20.524-07:00Feuchtesensor<div class="separator" style="clear: both; text-align: center;">
<a href="http://backend.tillh.de/wp-uploads/2013/10/SensorDetail.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://backend.tillh.de/wp-uploads/2013/10/SensorDetail.jpg" height="424" width="640" /></a></div>
<br />
Für die Messung der Luftfeuchtigkeit und der Temperatur verwenden wir einen <a href="http://www.ist-ag.com/eh/ist-ag/resource.nsf/imgref/Download_DHHYT939_E2.0.pdf/$FILE/DHHYT939_E2.0.pdf">HYT939</a> Sensor der Firma<a href="http://www.ist-ag.com/"> IST</a>. Der ist zwar ziemlich teuer, hat aber eine exquisite Performance, spezifiziert ist er mit +/-1,8% Fehler bei der Feuchte (bei einer Wiederholgenauigkeit von 0,2%) und +/- 0,2K bei der Temperatur. So wie es aussieht, halten die Sensoren das auch ein.<br />
<br />
Die Anbindung an einen Controller (hier ein Arduino FIO) ist simpel, da I2C-Schnittstelle:<br />
<br />
Source (vollständiger Quellcode bei <a href="https://github.com/TillHaenisch/Sensor">Github</a>):<br />
<br />
// HYT 939 Humidity Sensor Address<br />
#define I2C_SENS 0x28<br />
<br />
Wire.beginTransmission(I2C_SENS);<br />
// send MR command --> write address of sensor<br />
Wire.write(I2C_SENS);<br />
Wire.endTransmission();<br />
<br />
// wait til sensor data available<br />
delay(100);<br />
<br />
Wire.beginTransmission(I2C_SENS);<br />
Wire.requestFrom(I2C_SENS,4);<br />
unsigned char data[4];<br />
<br />
while(Wire.available()) {<br />
data[i++] = Wire.read();<br />
}<br />
humidity = data[0];<br />
humidity &= 0x3f;<br />
humidity *= 255;<br />
humidity += data[1];<br />
<br />
double dHumidity = 100.0/16384.0*humidity;<br />
<br />
temp = data[2];<br />
temp *= 255;<br />
temp += data[3];<br />
temp /= 4;<br />
double dTemp = 165.0/16384.0*temp-40;<br />
<br />
Ein weiterer Vorteil dieses Moduls ist der niedrige Standby Verbrauch von < 1 µA (sleep) und wenigen µA während der Messung.<br />
<br />
Durch das runde Gehäuse mit Keramikmembran ist auch die Montage sehr einfach. Deshalb. Trotz des Preises (etwa 40 € als Einzelstück) lohnt sich das in Summe.<br />
<br />
Ergänzung: Die Faktoren zur Umrechnung finden sich in den <a href="http://www.ist-ag.com/eh/ist-ag/resource.nsf/imgref/Download_AHM_E2.0[smallpdf.com]ROEGER.pdf/$FILE/AHM_E2.0[smallpdf.com]ROEGER.pdf">Application Notes</a>Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-79817144786281869602013-01-29T08:03:00.000-08:002013-11-16T11:12:35.708-08:00Reichweitentest der ZigBee Module<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiawoqCuqJxCRin_mDNaaObNLsJ88S3xReLFGksTPdc-HtpD7e5oI18Nly87pIMuLGBSuS-6vsOhAA0p4e3RYZ9Da4TL_7nbAjb-77D321fkK4mZGf4mGt1laIxiUWhcmySf5Z7LNXnzM4/s1600/Bildschirmfoto+2013-11-14+um+16.55.18.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="99" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiawoqCuqJxCRin_mDNaaObNLsJ88S3xReLFGksTPdc-HtpD7e5oI18Nly87pIMuLGBSuS-6vsOhAA0p4e3RYZ9Da4TL_7nbAjb-77D321fkK4mZGf4mGt1laIxiUWhcmySf5Z7LNXnzM4/s320/Bildschirmfoto+2013-11-14+um+16.55.18.png" width="320" /></a></div>
<br />
Da zunächst nicht ganz klar war, wie die Reichweite der Sensoren innerhalb einer (im wesentlichen aus Metall bestehenden) Papiermaschine sein würde, war der erste Vorversuch ein simpler Ausleuchtungs-/ Reichweitentest. In der Abbildung sind einige der Messpositionen gezeigt. Zunächst wurden normale XBee-Module mit Drahtantennen verwendet (ein Unterschied zu Chipantennen war nicht erkennbar). Es wurde eine Reihe von Messungen über einen Zeitraum von mehreren Minuten ausgeführt, angegeben sind jeweils Mittelwerte. Die Werte sollten nur als Anhaltspunkt angesehen werden, eine exakte Messung müsste systematischer ausgeführt werden. Da das Ziel aber nicht eine genaue Ausleuchtungsmessung dieser einen Maschine war, sondern es darum ging, eine Idee von den im Allgemeinen erzielbaren Reichweiten zu erhalten, reicht diese grobe Art der Messung hier aus.<br />
<br />
<br />
Von Messposition 1 aus wurde zuerst die Dämpfung horizontal in
Maschinenrichtung erfasst (Position 2 – FS). Im Anschluss wurde von Messposition 1 aus die Dämpfung zu Position 3 (TS)
erfasst. Dies entspricht nahezu der maximalen Distanz innerhalb der
Trockenpartie diagonal durch die Sektion. Hier wurde eine Signaldämpfung von -20 bis -25 dB ermittelt --> kein Problem.
Als zweites Datenset wurde die Dämpfung im Übergang von innerhalb der
Trockenpartie nach aussen erfasst. Dazu wurde auf Höhe der Messposition 1 auf
TS der Empfänger ausserhalb der Trockenpartie (auf PM Boden) platziert. Der Sender wurde – zunächst bei geöffneten Haubentüren – auf Messposition 3
positioniert. Danach wurden die Haubentüren (TS) nacheinander geschlossen um
Auswirkungen auf die Dämpfung zu erkennen. Hier wurde eine Dämpfung von etwa -35 (Haubentüren offen) bis -55 dB ermittelt, das ist an der Grenze einer verläßlichen Datenübertragung.Als letztes wurde noch die Dämpfung mit stärkeren Modulen (XBEE Pro) und Stabanttennen vom
Haubeninneren bis in die Warte geprüft. Anfangspunkt war die Positionierung des Senders in Position 2 und des
Empfängers im nächstgelegenen Wartenraum. Im Anschluss wurde die Dämpfung erfasst, wenn die Distanz erhöht wird. Dazu
wurde der Sender auf Position 1 platziert. Hier wurde eine Dämpfung von -25 bzw. -35 dB gemessen.Insgesamt sind die Ergebnisse sehr ermutigend. Im Gegensatz zu den
Erwartungen reduziert die metallische Umgebung das Signal wesentlich weniger
als beispielsweise Stahlbetonkonstruktionen.
Es kann eindeutig gefolgert werden, dass sich der Sender mit geringer
Sendeleistung für den Einsatz eignet. Somit können die Ziele Kompaktheit des
Sensors, Einzelkosten, Einsatzdauer voraussichtlich mit reduziertem Aufwand
erreicht werden.<br />
<br />
<br />
<br />
<div class="column">
</div>
<span style="font-family: 'Dotum-WinCharSetFFFF-H2'; font-size: 12.000000pt;">
</span>Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-32568211049284386842013-01-24T11:06:00.000-08:002013-11-16T11:12:54.049-08:00In der Papiermaschine ...<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgimdzhQPuOO5GqeFBdlBwVEXDwAJT4x0NvjsTPnHBt0wTuExRKi7NIfYIEPjqDB0ri5YJ9YJp0Bvgp1DeBrSyaqXlS7fbZ51uO0L2YDCi72cXii7l_v7hjUuLjPY4sAdh9zpOnaqtm3bo/s1600/PMDreck.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgimdzhQPuOO5GqeFBdlBwVEXDwAJT4x0NvjsTPnHBt0wTuExRKi7NIfYIEPjqDB0ri5YJ9YJp0Bvgp1DeBrSyaqXlS7fbZ51uO0L2YDCi72cXii7l_v7hjUuLjPY4sAdh9zpOnaqtm3bo/s320/PMDreck.JPG" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
ist dann doch alles etwas anders aus. Schmutziger zum Beispiel ;-) Lauter, heißer und vor allem viel mehr Metall um einen rum ...<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLcTjwfunF8ckxc3W93qdWRptebirSrh3_FzvaopBGdm74Yg8Y-ogDCowjdRmHcu8yMCoxXotf5wz9G8xHOk64_vrEj5FS1FEso7IVhY867_kPcUCNasQWnHUlhH0x_dR8kvs45KWKf7Q/s1600/PMMetall.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLcTjwfunF8ckxc3W93qdWRptebirSrh3_FzvaopBGdm74Yg8Y-ogDCowjdRmHcu8yMCoxXotf5wz9G8xHOk64_vrEj5FS1FEso7IVhY867_kPcUCNasQWnHUlhH0x_dR8kvs45KWKf7Q/s320/PMMetall.JPG" width="240" /></a></div>
<br />
Um zu testen, wie sich die XBee-Module in dieser Umgebung verhalten, haben wir eine einfache Reichweitenmessung (letztlich fast nichts anders als der Reichweitentest der von Digi gelieferten <a href="http://www.digi.com/support/kbase/kbaseresultdetl?id=2125">Software</a>) durchgeführt: Ein Sensormodul (ein Standard-Xbee mit einem simplen Temperatursensor) sendet Daten an eine Basisstation, dort wird die Signalstärke (RSSI) ausgewertet:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipeuro54UcNgo9Iy_sdDuMMqAQl1Xe2XzP0pMzNwiCXQyACYHvWrzU0uFCWWCP_4W3gyN-RlK_1EL2Su8-PUilBKmzYj-xuCzgn8asYM6BhTFL3l3sCaDJFjwztukx1jhGVH8dBqxiGtU/s1600/PMLaptop.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipeuro54UcNgo9Iy_sdDuMMqAQl1Xe2XzP0pMzNwiCXQyACYHvWrzU0uFCWWCP_4W3gyN-RlK_1EL2Su8-PUilBKmzYj-xuCzgn8asYM6BhTFL3l3sCaDJFjwztukx1jhGVH8dBqxiGtU/s320/PMLaptop.JPG" width="240" /></a></div>
<br />
Man erkennt das lose rumhängende XBee-Modul am USB-Kabel ... aber es ist ja schließlich nur der erste Versuch, der klären soll, ob sich weiterer Aufwand überhaupt lohnt: Wenn die Reichweite nur ein paar Meter beträgt, wird das Projekt umgehend wieder eingestampft.<br />
<br />
Aber damit nicht alles "frei verdrahtet" aussieht, haben wir wenigstens den Sensor in ein Kästchen eingebaut:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMbuVGQshLiWq35nWv7YlJ4giK4lJlP6XANIwkN81Vd4KWbn4WiIIwgUkxiVM_GbUQ-uP73ov1jdxMxgwNJdY6JzP2S_S7mvSZR7WFgGsjz7L3PByji6SYxzM0Nzl98vY4e4TAQwd4Brs/s1600/PMSensor.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMbuVGQshLiWq35nWv7YlJ4giK4lJlP6XANIwkN81Vd4KWbn4WiIIwgUkxiVM_GbUQ-uP73ov1jdxMxgwNJdY6JzP2S_S7mvSZR7WFgGsjz7L3PByji6SYxzM0Nzl98vY4e4TAQwd4Brs/s320/PMSensor.JPG" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
Der hat inzwischen einen Ehrenplatz auf meinem Schreibtisch ;-)<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-52433454479062735302012-11-16T07:48:00.000-08:002013-11-16T11:13:08.753-08:00Architektur des Sensornetzes<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvK3p4KOs-ESl2semnEN2DUo2uihLSpQBYKDcdiqKAc-8qK5FRVBMYjXWchmQ8ycGOOUUw2MJvdZNnAQbNA-CawdcfbeFxABG4iA-SCF0X9ZuwnSQCEI9HkHkJhNHWUlYkH820Bghpmqo/s1600/Overview.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvK3p4KOs-ESl2semnEN2DUo2uihLSpQBYKDcdiqKAc-8qK5FRVBMYjXWchmQ8ycGOOUUw2MJvdZNnAQbNA-CawdcfbeFxABG4iA-SCF0X9ZuwnSQCEI9HkHkJhNHWUlYkH820Bghpmqo/s320/Overview.png" width="320" /></a></div>
Die einzelnen Sensoren kommunizieren über <a href="http://en.wikipedia.org/wiki/ZigBee">ZigBee</a>, verwendet werden Module der Firma <a href="http://www.digi.com/products/wireless-wired-embedded-solutions/zigbee-rf-modules/zigbee-mesh-module/xbee-zb-module">Digi</a>. ZigBee hat hier zwei entscheidende Vorteile gegenüber WLAN:<br />
<br />
Erstens handelt es sich um ein <a href="http://en.wikipedia.org/wiki/Mesh_networking">Mesh-Netz</a>, dessen Routing-Topologie sich nach Bedarf anpasst. Dies ist wichtig, da die Sensoren in verschiedenen Umgebungen eingesetzt werden, deren Funkabdeckung wechseln kann. Die Umgebung ist hier besonders kritisch zu sehen, da der zunächst geplante Einsatzort die Trockenpartie einer Papiermaschine ist, im wesentlichen eine sehr große Menge von Stahl, der von einer praktisch dichten Aluminiumhaube umgeben ist. Kann ein einzelner Sensor die Basisstation nicht erreichen, ist dies kein Problem, andere Sensoren können die Daten weiterleiten. Ist also etwa ein Sensor nicht zu erreichen, wird einfach zwischen diesen und den letzten erreichbaren ein weiterer Sensorknoten installiert. Da die Sensoren batteriebetrieben sind, ist dies praktisch kein Aufwand.<br />
<br />
Zweitens kann mit ZigBee vergleichsweise leicht ein geringer Stromberbrauch realisiert werden. Die meiste Zeit sind die Module im Ruhezustand und werden nur gelegentlich zur Datenübertragung aufgeweckt. Für den Stromverbrauch letztlich entscheidend, ist die Minimierung der Dauer des aktiven Zustands. Man kann zwar mit hoch optimierten Systemen (dazu siehe etwa Benedikt Ostermeier et al, Connecting Things
to the Web using Programmable Low-power WiFi Modules, WoT '11 Proceedings of
the Second International Workshop on Web of Things, Article No. 2, ACM, 2011) durchaus auch mit WLAN eine regelmäßige Datenübertragung bei Batteriebetrieb erreichen, aber ZigBee ist hier bereits "by design" schneller.<br />
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Als Sensoren für Temperatur und Luftfeuchtigkeit werden Sensoren vom Typ <a href="http://iotresearch.blogspot.de/2013/09/feuchtesensor.html">HYT939</a> verwendet. Diese bieten eine hohe Genauigkeit bei einfacher Anbindung und einfachem Einbau. Die Vorverarbeitung der Daten erfolgt durch einen Arduino FIO, der von einer LiPo-Batterie versorgt wird.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Die Daten werden von den Sensoren zu einer <a href="http://iotresearch.blogspot.de/2013/09/die-basisstation.html">Basisstation</a> (ein Raspberry Pi mit Funkinterfaces und einem LCD-Display) übertragen, die diese lokal speichert und eine grobe Auswertung zur Zustandsdiagnose durchführt. Diese Basisstation bietet ein WLAN-Interface, um Anzeigegeräte anzubinden. Die Darstellung der Daten erfolgt auf einem Smartphone oder Tablet.</div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCTBdZE6hCp9EgupBRZb3SLHTiC7AP-qcY38byJ7DS0Vgr5JFkzODVoMTNKJZ0FmtGBUNnWylU3IU5RNckzTbndLaxofhwHhFfNJy805KipcrP0V4pmGtiEtmPWJZ0rN0DNgtxFgycpRg/s1600/UI.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="226" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCTBdZE6hCp9EgupBRZb3SLHTiC7AP-qcY38byJ7DS0Vgr5JFkzODVoMTNKJZ0FmtGBUNnWylU3IU5RNckzTbndLaxofhwHhFfNJy805KipcrP0V4pmGtiEtmPWJZ0rN0DNgtxFgycpRg/s320/UI.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="MsoNormal">
Dadurch ist eine ständige Überwachung der Betriebsparameter durch die Maschinführer leicht möglich. In einer späteren Ausbaustufe sollen die Daten per UMTS-Modem direkt zur Erstellung von Analysen bereitgestellt werden.</div>
<div class="MsoNormal">
<br /></div>
<!--EndFragment-->Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.comtag:blogger.com,1999:blog-8440482468154379225.post-9165333048317760562012-09-20T11:23:00.000-07:002013-11-16T11:25:51.797-08:00Worum es hier geht ....Aus einer Unterhaltung (bei einigen Bierchen, aber da entstehen manchmal die besten Ideen) mit meinem Freund <a href="http://www.zm-technik.de/">Dominik Mai</a> entstand die Idee, meine Interessen und Erfahrungen (Internet der Dinge, Meßtechnik - das klingt jetzt vielleicht für einen Wirtschaftsinformatiker etwas seltsam, aber ich bin von Haus aus Physiker und habe mir mein Studium durch die Entwicklung von medizinischer Meßtechnik finanziert) und seine (Papiermaschinen, innovative Produkte) zu verbinden und ein Low Cost Sensornetz für den Einsatz im industriellen Umfeld, insbesondere eben in Papiermaschinen zu entwickeln.<br />
<br />
Das klingt jetzt zunächst mal vielleicht nicht besonders spannend, die Technologien dafür gibt's ja schließlich schon länger, aber erstens ist die Umgebung dort alles andere als freundlich (heiß, naß, abrasiv) und zweitens sind die verfügbaren Systeme viel zu teuer.<br />
<br />
Unser Ziel ist: 100 Euro pro Sensorknoten (zuzüglich dem eigentlichen Sensor), 500 für die Basisstation, 4-6 Wochen kontinuierlicher Betrieb ohne externe Stromversorgung, Installation/Konfiguration des Systems und Auswertung der Daten ohne IT-Expertenwissen. Das ist bei kleinen Stückzahlen sportlich. Und war vor ein paar Jahren sicherlich nicht möglich.<br />
<br />
<br />
Ob es heute möglich ist, werden wir sehen. Die Zukunft ist es in jedem Fall.<br />
<br />Till Hänischhttp://www.blogger.com/profile/11539143849901965737noreply@blogger.com