In der neuen Reihe “Mobile Geeks DIY” geht es, wie der Name schon vermuten lässt, um Hard- & Software-Projekte zum Selbermachen. Wikipedia definiert “DIY” so: “Der Begriff DiYourself kommt aus der englischen Sprache und bedeutet Mach es selbst. (…) Oftmals sind Spaß, Kreativität oder finanzielle Gründe der Anlass, Dinge selber zu fertigen.”

Paketzustellungsdetektor – Mobile Geeks DIY #1

In den ersten Teilen dieser Serie werden wir verschiedenste Projekte basierend auf der Arduino-Plattform (Wikipedia) umsetzen. Um die Projekte nachzubauen könnt ihr bei unseren Partnern Exp-Tech.de und PhysicalComputing.at die entsprechenden Bauteile direkt bestellen, diese sind verlinkt. Zum Programmieren wird einerseits die Arduino-Entwicklungsumgebung, zu finden auf arduino.cc, und teilweise die Programmiersprache Python (WICHTIG: Version 2.7) verwendet. Diese ist relativ einfach zu erlernen und auf vielen Betriebssystemen verfügbar (da OpenSource).

Im ersten Projekt bauen wir einen Paketzustellungsdetektor.

Idee

Ein Geek möchte natürlich immer sofort Bescheid wissen, wenn er ein neues Paket erhält. Dazu könnte er zwar die Internetseiten des Logistik-Unternehmens nutzen, jedoch dauert es immer etwas bis die Zustellung angezeigt wird und außerdem möchte der Geek sichergehen, dass das Paket wirklich bei ihm hinterlegt wurde.
Dafür kommt der Paketzustellungsdetektor zum Einsatz. Wenn der Postbote das Paket am festgelegten Ablageort hinterlässt, erhält der Geek sofort eine E-Mail. Außerdem wäre eine Überprüfung mit der Datenbank des Logistikunternehmens möglich, wodurch er Gewissheit hat, dass es sich bei dem abgelegten Gegenstand wirklich um sein Paket handelt.

Material

Umsetzung

Zusammensetzen der Bauteile

Im folgenden Schema könnt ihr den Projekt-Aufbau sehen.

Steckplatine MGDIY1

Der Force Sensitive Resistor (FSR) wird einerseits mit dem 3,3V-Port des Arduino verbunden. Außerdem wird er an dem anderen Anschluss mit dem ANALOG 0-Port des Arduinos und über einen 10kΩ-Widerstand mit dem GND-Port (Masse) verbunden.

Programmieren des Arduino

Der Arduino soll ständig den FSR abfragen und Mitteilung geben, sobald ein Grenzwert überschritten wurde, d.h. ein Gegenstand mit einem bestimmten Mindestgewicht auf dem Sensor abgestellt wurde. Der Computer kann dann die gewünschten Aktionen ausführen. Wird der Grenzwert wieder unterschritten, d. h. das Paket wieder aufgehoben, wird der Computer erneut informiert.
Zur Kommunikation zwischen Computer und Arduino verwenden wir die serielle Schnittstelle. Dazu muss der Arduino nur am USB-Port des Computers angeschlossen sein.

Ein Arduino-Programm hat den folgenden Grundaufbau:

void setup() {

}

void loop() {

}

Die Funktion setup() wird dabei genau ein Mal beim Starten des Programms ausgeführt. Die Funktion loop() hingegen wird immer wieder, solange bis das Programm beendet wird, ausgeführt. Außerdem können oberhalb dieser Funktionen bereits Variablen und Konstanten definiert werden.

Hier definieren wir die Variablen und Konstanten, die für den späteren Programmablauf notwendig sind:

#define FSR_GRENZWERT 15
#define ONBOARD_LED 13
#define FORCE_SENSOR 0  

int force_value = 0;
byte force_state = 0;

In der ersten Zeile legen wir den Grenzwert für den FSR fest, bei dem das Programm eine Mitteilung an den PC sendet. In der zweiten Zeile definieren wir den (digitalen) Port an dem die LED (die bereits auf dem Board angebracht ist) angeschlossen ist. In der dritten Zeile definieren wir den analogen Port, an dem der FSR angeschlossen ist.

In den beiden darauffolgenden Zeilen, initialisieren wir zwei Variablen: force_value undforce_stateforce_value ist vom Typ int, d.h. sie kann nur mit natürliche Zahlen belegt werden. force_state ist vom Typ byte, das ist eine natürliche Zahl von 0 bis 255. Inforce_value speichern wir (später) den aktuellen Wert des FSR zwischen; in force_stateob zur Zeit ein Paket auf dem FSR liegt oder nicht (Werte 0 (= Nein) oder 1 (= Ja)).

Gehen wir nun in die Funktion setup(). Diese soll genau zwei Dinge tun: Zum einen soll sie eine serielle Kommunikation(sleitung) mit dem Computer aufbauen (Z. 2). Zum anderen soll sie festlegen, dass es sich bei der ONBOARD_LED auf Port 13 um einen Ausgang handelt (Z. 3). Dies sieht im Programmcode wie folgt aus:

void setup() {
  Serial.begin(9600); // Startet die serielle Kommunikation mit 9600 Baud
  pinMode(ONBOARD_LED, OUTPUT); // Setzt den Pin ONBOARD_LED als einen Ausgang
}

(Alles hinter den doppelten Schrägstrichen in der jeweiligen Zeile ist ein Kommentar und wird vom Programm ignoriert.)

Nun zur loop()-Funktion. Deren Aufgabe ist es bei jedem Durchlauf den FSR abzufragen. Sollte der zurückgegebene Wert größer sein, als der vorhin definierte Grenzwert, wird über die serielle Schnittstelle eine Meldung an den Computer gesendet. Wenn der Grenzwert dann wieder unterschritten wurde, wird der PC erneut informiert, da das Paket nun wieder aufgenommen wurde.

void loop() {
  delay(1000);
  force_value = analogRead(FORCE_SENSOR);
  switch (force_state){
    case 0:
    if (force_value >= FSR_GRENZWERT)
    {
      force_state = 1;
      digitalWrite(ONBOARD_LED, HIGH);
      Serial.print("Paket abgelegt");
    }
    break;
    case 1: // Wurde Paket aufgenommen?
    if (force_value < FSR_GRENZWERT)
    {
      force_state = 0;
      digitalWrite(ONBOARD_LED, LOW);
      Serial.print("Paket aufgenommen");
    }
    break;
  }
}

Zeile. Beschreibung
2. Es wird eine Wartezeit pro Durchlauf von 1000 ms festgelegt, damit der FSR nicht zu häufig abgefragt wird.
3. Der Wert vom FSR wird mit der Funktion analogRead() ausgelesen. Dabei wird innerhalb der Klammern der analoge Port (den wir vorhin in der Konstante FORCE_SENSOR gespeichert hatten) angegeben. Den Rückgabewert der Funktion speichern wir in der Variable force_value.
4. switch steht für eine Bedingung. Dabei wird innerhalb der Klammern das zu unterscheidende Element angegeben – hier force_state.
5. Innerhalb von einem switch können die verschiedenen Fälle mit case unterschieden werden. Dabei wird jeweils hinter case der entsprechende Wert des zu unterscheidenden Elements angegeben. In diesem Fall wird der nachfolgende Code (Zeile 7-12) nur ausgeführt, wennforce_state den Wert 1 hat.
6. Hier befindet sich eine weitere Bedingung: Nur wenn der Wert des Drucksensors,force_value, größer oder gleich des definierten Grenzwerts ist, wird der nachfolgende Code ausgeführt (Zeile 7-11). Zeile 12 wird egal ob diese Bedingung erfüllt ist ausgeführt.
7.
8. Hier wird der Status, ob ein Paket auf dem Sensor liegt, force_state, auf 1 gesetzt, da der Grenzwert überschritten wurde.
9. Da ein Paket auf dem Sensor liegt, wird der digitale Ausgang ONBOARD_LED (die LED, die sich auf dem Arduino befindet) aktiviert. Die Funktion digitalWrite() erhält dabei als ersten Parameter den Port, als zweiten ob dieser aktiviert (HIGH) oder deaktiviert (LOW) sein soll.
10. In dieser Zeile wird über die serielle Schnittstelle die Meldung “Paket abgelegt” an den Computer gesendet.
11.
12. In dieser Zeile wird der aktuelle Funktionsdurchlauf abgebrochen, da die Verarbeitung abgeschlossen ist.

Da die restlichen Zeilen ähnlich den Zeilen 5-12 sind, hier nur eine kurze Zusammenfassung der Unterschiede:
13. Hier wird, wenn force_state = 1 ist, der folgende Code (Z. 14-20) ausgeführt (siehe Z. 6-12).
14. Wenn der Wert vom FSR wieder kleiner ist als der Grenzwert, dann…
16. … wird force_state gleich 0 gesetzt.
17. … die LED deaktiviert.
18. … über die serielle Schnittstelle die Meldung “Paket aufgenommen” ausgegeben.
20. … der Funktionsdurchlauf abgebrochen.

Damit ist das Programm für den Arduino fertiggestellt und wir können es auf den Arduino übertragen. Dazu wird der Arduino zuerst mit einen freien USB-Anschluss des Computers verbunden. Dann wird durch einen Klick auf das UPLOAD-Symbol im Arduino-Fenster die Übertragung gestartet.

Arduino-Upload MGDIY1

Wenn die Übertragung fertig ist und erfolgreich war (was ihr am unteren Rand des Arduino-Fensters erkennen könnt), könnt ihr den seriellen Monitor aufrufen und euer Programm testen.

Serieller Monitor MGDIY1

Drückt einfach mal das obere, runde Ende des Drucksensors zusammen und schaut, ob der serielle Monitor eine Meldung vom Arduino empfängt. Wenn ihr wieder loslasst, sollte erneut eine Meldung erscheinen.

Auswertung am PC mit Python

Nun zur Auswertung der vom Arduino gesammelten Daten am Computer. Zur Programmierung verwenden wir die Sprache Python in Version 2.7 (!). Außerdem benötigen wir das Modul pyserial, das ihr hier herunterladen und installieren könnt. Alles weitere dazu findet ihr auf der Website des Projekts.

Um zu Starten öffnen wir die Python IDLE, die ihr nach der Installation auf eurem PC vorfinden solltet. Nach einem Tastendruck von STRG + n (Windows) oder CMD + n (Mac) öffnet sich ein neues, leeres Fenster, in das wir nun den Programmcode schreiben.

Zuerst muss das eben installierte Modul importiert werden, damit wir die Funktionen in unserem Programm verwenden können:

import serial 

Nun soll das Programm eine Verbindung mit dem Arduino über den seriellen Port herstellen. Dazu initialisieren wir die Verbindung:

arduino = serial.Serial('SERIELLEN_PORT_AENDERN',baudrate=9600,timeout=1) 

In dieser Zeile weisen wir dem Objekt arduino eine serielle Verbindung über den seriellen PortSERIELLEN_PORT_AENDERN mit einer Baud-Rate von 9600 und einer maximalen Wartezeit (timeout) von 1 Sekunde zu. Hierbei müsst ihr aber SERIELLEN_PORT_AENDERN durch den seriellen Port eures Arduinos am Computer ersetzen.

Den serielle Port des Arduinos am Computer könnt ihr leicht ermitteln: Zuerst trennt ihr die USB-Verbindung von Arduino und Computer. Dann öffnet ihr die Arduino-Software und geht in der Menüleiste auf Tools > Serieller Port. Merkt euch alle Elemente der erscheinenden Liste. Nun schließt ihr das Menü wieder und steckt den Arduino an den Computer. Öffnet erneut das Menü und vergleicht die Liste mit der, die ihr euch gemerkt habt. Es sollte(n) ein/zwei neue(s) Element(e) vorhanden sein. Nun notiert euch das neue Element, welches mit /dev/tty beginnt (Mac) bzw. das welches die höchste Nummer am Ende stehen hat (Win). Dieses fügt ihr dann anstelle vonSERIELLEN_PORT_AENDERN ein.

Jetzt soll unser Programm auf Nachrichten vom Arduino warten und eventuell empfangene ausgeben.

while True: nachricht = arduino.readline() print(nachricht) 

Zeile. Beschreibung
1. while True bedeutet, dass der nachfolgende, eingerückte Programmcode unendlich oft ausgeführt werden soll.
2. arduino.readline() wartet auf eine Nachricht vom Arduino und speichert diese dann in der Variable nachricht
3. print() gibt das in Klammern stehende, also die Nachricht, auf dem Bildschirm aus.

Um zu testen, ob das Programm wirklich funktioniert, ladet euer Arduino-Programm nochmals auf den Arduino (siehe oben), startet aber nicht den seriellen Monitor. Stattdessen startet ihr, nachdem das Programm auf dem Arduino gestartet ist, das Python-Programm auf eurem Computer (MenüRun > Run Module oder eventuell Taste F5). Sollte nun bei Druck auf den Sensor die Meldung “Paket abgelegt” auf dem Bildschirm (Python-Shell) erscheinen, läuft alles korrekt.
Um das Programm jetzt wieder zu beenden muss ein sog. KeyboardInterrupt gesendet werden (Tastenkombination: ctrl + c (Mac), Strg + c (Windows)).

rbehebung

Python

Die angegebenen rmeldungen sind jeweils nur die letzte Zeile der Meldung.

ImportError: No module named serial 

Wahrscheinlich hast du pyserial nicht (korrekt) installiert. Lade es erneut von der Homepage herunter und probiere es noch einmal.

NameError: serial is not definied 

Du hast die Zeile import serial ganz oben im Programmcode vergessen.

serial.serialutil.SerialException: could not open port <...>: [Errno 2] No such file or directory: '<...>' 

(<…> = beliebig)
Prüfe noch einmal ob du den Arduino angeschlossen hast und das Arduino-Programm läuft. Auch darf der serielle Monitor der Arduino-Software nicht geöffnet sein. Sollte das Problem weiterhin bestehen, wiederhole die Schritte zur Bestimmung des seriellen Ports.

KeyboardInterrupt 

Diese (r-)Meldung erscheint sobald du einen KeyboardInterrupt (s.o.) an dein Python-Programm sendest. Das bedeutet nicht, dass ein r im Programmcode vorliegt.

Programmcode-Download

Der gesamte Programmcode steht für euch als Download unter folgenden Links zur Verfügung.

Quelle

Idee & Umsetzung basierend auf: Riley, Mike: Das intelligente Haus. 1. Auflage, Köln: O’Reilly, 2012.

Fortsetzung – Mobile Geeks DIY #2

In der nächsten Ausgabe von MobileGeeks DIY geht es dann um die Verarbeitung der vom Arduino gesendeten Nachrichten mit dem Computer / Python. Dies könnte z. B. das Versenden einer E-Mail o.ä. sein. Auch kann das Programm eine Liste führen, wann Pakete abgelegt und wieder aufgenommen wurden. Ihr seht: Es gibt endlos viele Möglichkeiten, was man alles mit dem Arduino/diesem Projekt machen kann. Wenn ihr selber noch Ideen habt, schreibt mir doch einfach eine kurze Nachricht (Kontaktformular s.u.).

Fragen, Kritik, Vorschläge

Wie hat euch die erste Ausgabe von Mobile Geeks DIY gefallen?
Ich freue mich auf eure Fragen, Kritik, Vorschläge und Feedbacks! Schreibt mir eine Nachricht im folgenden Kontaktformular.

Sollte ein Programm rmeldungen ausgeben, welche nicht durch den Abschnitt rbehebung gelöst werden konnten, bitte immer die vollständige rmeldung, den Programmcode, sowie (wenn möglich) die Schritte zur Reproduktion des rs mit angeben, damit ich auf eure Probleme besser eingehen kann.

Unsere Partner

Mobile Geeks DIY wird freundlich unterstützt von ExpTech.de und PhysicalComputing.at. Schaut doch mal bei ihnen vorbei!

Freue mich auch über Emails: lindholm (punkt) matthias (at) gmail (Punkt) com!

Newsletter abonnieren

RSS-Icon Immer auf dem Laufenden bleiben? Dann abonniere unseren RSS-Feed!
Kategorien DIY

Über Matthias Lindholm

Author Avatar
Blogger, Podcaster, Webdesigner aus Berlin, Deutschland und Los Angeles, USA
  • DevSibwarra

    Vielleicht sollte man im text erwähnen, dass man für eine höhere Messgenauigkeit die Formel im Datasheet konsultieren sollte um die korrekten Widerstände für die korrekte Beschaltung des Drucksensores anwenden sollte.

    Zudem wäre es wohl auch nicht verkehrt, dass es eventuell probleme geben könnte die Daten über ein 10m langes USB Kabel zu senden :D Also vielleicht ein Ausblick auf gewisse Verbesserungen (in kombination mit zukünftigen DIY?) die man selbst vornehmen könnte. Denkbar wäre z.B. es mit einer Batterie zu kombinieren (das würde allerdings modifikationen am programm benötigen um den Energieverbrauch zu senken) und dann über ein RFM01/02/12 (433MHz Funkmodule die es für 3€ oder so gibt) mit dem PC verbinden (benötigt dann 2 µCs natürlich).

    • Matthias Lindholm

      Hi! Danke für dein Feedback.
      Eine Erweiterung mit Netzteil/Batterien ist schon auf der Planungsliste; genauso wie die Nutzung von Funkmodulen (geplant sind xBee). Da die Konfiguration von bspw. xBee’s aber relativ komplex ist, habe ich das erstmal etwas nach hinten verschoben. Kommt aber noch :-)

      Mit der Formel im Datasheet hast du vollkommen recht. Werde ich dann noch mit nachreichen; ist halt nur schwierig, wenn nicht alle vom gleichen FSR ausgehen. Wie oben schon gesagt, richtet sich das erstmal eher an die Einsteiger.

      Wenn du noch weitere spannende Projektvorschläge hast, immer her damit!

      • Kevin Kleebusch

        Also einen Vorschlag hätte ich da spontan schon, bloß dürfte das nicht so leicht umzusetzen sein. Wir haben an unserem Haus keine Klingel. Da wäre es extrem spannend wenn man eine günstige Webcam in Verbindung mit einem Bewegungsmelder dazu bringen könnte das Bild der Haustür an den Rechner zu senden, bei dem dann ein Popup mit dem Bild erscheint. Natürlich dürfte das mit der Stromversorgung schwieriger werden, man müsste ein Programm am Rechner für das Popup schreiben, es muss das Bild per Funk übertragen werden der dann noch durch Wände muss also sollte er ausreichend stark sein usw. Aber die Idee würde mir sehr zusagen und so etwas dann selbst zu bauen ist bestimmt gut für das Ego ;)

        PS: Wie viel sollte man für das hier erklärte DIY Finanziell einplanen für alle Komponenten?

        • Matthias Lindholm

          Behalte ich im Hinterkopf und setze es auf die Wunschlisten. Über ein ähnliches Szenario habe ich auch schon mal nachgedacht.

          –> Kosten
          Ich hab jetzt im Artikel die ungefähren Preise eingefügt. Ein Gesamtpreis ist schwer festzulegen, da man manche (Bau)teile (Widerstände, USB-Kabel, …) evtl. schon besitzt.

  • http://twitter.com/RobLogist Rob.Logist

    finde dieses DIY tutorial ziemlich “speziell”. Fuer die meisten wird es nicht interessant sein.

    Wenn DIY solltet ihr euch bisschen populäreren DIY-Themen wenden, die auch von der Mehrheit der Leser umgesetzt werden können. Beispiele sind hier DIY-Heimkino Boxen (die normalen sind nämlich extrem ueberteuert) oder DIY-Beamer

    • http://www.mobilegeeks.de/ Sascha Pallenberg

      wobei dann die Frage ist wieviele denn ein Kino im Hause haben :)
      Keine Panik, es kommen noch mehr Anwendungsbereiche und Projekte

    • Matthias Lindholm

      Solltest du eine Anleitung für ein DIY-Beamer finden, immer her damit :-)
      Ich glaube aber nicht, dass man da im Eigenbau wirklich günstiger UND besser (Qualität, (Aussehen), Langlebigkeit, …) kommt. Außerdem wäre das von der Komplexität eher nicht passend. Es hat ja auch seinen Grund warum Beamer ein bisschen (mehr) Geld kosten; sonst würde ja jeder den Beamer selber bauen, wenn’s so einfach wäre :-)

      –> finde dieses DIY tutorial ziemlich “speziell”

      Es geht ja auch nicht nur um diesen speziellen Anwendungsbereich. Die Artikel sollen auch zum Weiterdenken und zum Entwickeln von eigenen Ideen anregen, z.B. wie man den Drucksensor noch einsetzten könnte. Wenn du Ideen hast, schreib mir einfach eine Nachricht.

      Aber wie @nbnde:disqus schon schrieb, kommen auch noch andere Projekte.

      • http://twitter.com/RobLogist Rob.Logist

        es gibt riesige DIY Beamer Communities. https://www.google.com/search?q=DIY+beamer&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:de:official&client=firefox-a
        Deswegen wunderte es mich, warum dies noch nicht behandelt wurde. Oder was auch toll ist wäre ein DIY HTPC aufbau inkl. XBMC 12 Einrichtung

        • Matthias Lindholm

          OK, danke! Wusste ich noch nicht.
          Das war ja gerade erstmal der erste Artikel der Serie; da folgende noch weitere.
          Ein Projekt mit XMBC 12 ist in Planung.

          • http://twitter.com/RobLogist Rob.Logist

            Genial toll! finde es auch eine tolle Idee mit der DIY Rubrik. Der Artikel war auch spannend nur er war für mich technikaffinen, aber programmier unerfahrenen Leser ein bisschen abschreckend. DIY soll ja zum nachbauen anregen! Aber natürlich war es ein toll geschriebener Artikel und bei Zeiten werde ich mich dransetzen :)

  • http://twitter.com/Falcon2045 Severin Lochinger

    Nett geschriebenes DIY… Aber mir reicht dann doch die “Pakete” App aus dem Play Store. Genauer brauch ich es nicht…

  • http://twitter.com/DukNukem DukNukem

    Daumen Hoch!

    Das ist auf jeden Fall ein guter Start in die Kategorie und ich freue mich von weiteren Projekten zu lesen. Eventuell komme ich irgendwann auch mal dazu das nachzubauen.

    Schauen wir mal, was noch alles kommt. Ich persönlich fände auch noch Hardware Hacks und ähnliches sehr toll. Es ist immer interessant zu sehen, was man aus manchen dingen noch herausholen kann.

    Der Raspberry Pi wird dann bestimmt auch bald in dieser Kategorie oder im Forum auftauchen. Finde ich super.

    Auf was man meiner Meinung auch noch achten sollte ist, dass die Projekte auch gewisse preisliche Grenzen nicht sprengen. So lassen die sich auch von vielen Nachbauen und man muss sich nicht ärgern, wenn es unbenutzt in der Ecke verstaubt.

    PS: Sagt euch http://www.tinkerforge.com etwas?

Trackbacks & Pingbacks