Aufgabe war es die physischen Aspekte von Sensoren und Aktuatoren zu erkunden, und die dazugehörige Software von Embedded über Kommunikation und Protokolle bis zur Nutzerschnittstelle zu entwickeln.
Es war Frühling, die Stadt blühte endlich wieder in all den schönen Farben auf. Vögel zwitscherten und machten sich gerade auf die Suche nach Nahrung, als wir einen Eisvogel in voller Pracht sichteten!
Komplett euphorisiert wurde eine weitere Vogelapp aufs Smartphone geladen, die uns die heimischen Vögel näherbringen sollte. Doch die App wurde nie wieder angefasst. Was für eine Schande …
Was können wir drei IoT-Studenten denn tun, um die Vögel, die so frei über unseren Köpfen Kreisen endlich besser kennenzulernen?
Natürlich ein Vogelhäuschen bauen mit Fütterung auf Knopfdruck und eine Kamera, die bei einer “motion detection” ein Bild von dem Vogel auf unsre Webseite hochlädt … oder?
Code
Arduino
Unser Arduino Code ist nach der Prämisse “Keep the low-end simple” aufgebaut. Das Programm ist darauf ausgelegt, die aus dem Node.js Backend gesendeten Befehle zu empfangen und basierend auf dem empfangenden Befehl zu entscheiden welche Aktion ausgeführt werden soll.
Ablauf
Zunächst verbindet sich der Jeweilige NodeMCU mit dem eingetragenen Wi-Fi des Nutzers. Sobald eine Verbindung mit dem Wi-Fi besteht, verbindet sich der NodeMCU via MQTT mit dem Backend. Dabei hat jeder NodeMCU einen eigenen Topic auf dem er seine Befehle erhält. Sobald in dem jeweiligen Topic ein Befehl eingeht Parsed der NodeMCU seine Daten aus dieser Nachricht.
Beispiel Nachricht Motor:
-1500,500,1
Die empfangene Nachricht besteht aus 3 Parametern:
Parameter 1. (-1500) : Gibt die anzufahrende Position für den Stepper, oder anders gesagt die Laufweite für diesen Befehl an.
Parameter 2. (500) : Gibt die Geschwindigkeit an mit der sicher der Stepper zu der anzufahrenden Position bewegen soll.
Parameter 3. (1) : Gibt den Modus an welcher ausgeführt werden soll. (1 Motorsteuerung)
Beispiel Nachricht Sensor:
0,0,0
Hierbei wird über Parameter 3 der Modus 0 aufgerufen. Der Modus 0 dient dazu den DHT11 abzufragen und dessen Werte per MQTT an den Webserver zu verschicken.
RaspberryPi
Unser Raspberry Pi läuft mit dem aktuell Raspbian OS. Die Bewegungs- erkennung läuft mit Python3 und der Bildverarbeitungs Libary opencv. Zusätzlich zu dem Python3 Script benutzen wir noch ein Node.js Script welches die geschossenen Bilder auf den Webserver hochlädt. Bei de Scripts werden über einen PM2 Loadbalancer lokal auf dem Raspberry Pi verwaltet, um die bestmögliche Performance zu erreichen.
Vogelerkennung
Die Bewegungsänderungen stellen wir wie folgt fest. Das Script überwacht konstant den Video-Stream der Rasp. Cam, dieser Stream wird zunächst in Schwarzweißbild umgewandelt, um eine bessere Performance zu erreichen. Danach wird das Bild mit dem vorher aufgenommen Bild verglichen. Die Unterschiede der einzelnen Bilder werden zu einer Fläche zusammengefasst. Diese Fläche wird danach berechnet. Dieser Flächenwert benutzen wir, als Schwellwert um das Bild aufzunehmen, das später auf dem Webserver landet. Wird der Schwellwert überschritten speichert das Script das aktuelle Bild und schickt einen HTTP Request an das parallel laufende Node.js Script. Dieses Script übernimmt die Aufgabe das Bild mit den nötigen Metadaten auszustatten und danach mit einem Form-Data Objekt zu binden und an den Webserver zu verschicken.
Webserver
Unser Webserver ist ein gemieteter Ubuntu Webserver bei dem Cloud-Anbieter unserer Wahl. Auf Diesem Webserver wird unser Node.js Backend gehostet wie auch das Frontend. Ebenso läuft auf diesem Server ein MosquittoMQTT Broker um unsere MQTT Verbindungen sicherzustellen.
Das Node.js Backend besteht aus einem Express Webserver welcher all unsere API Endpunkte verwaltet. Ebenso ist er für die Verwaltung unserer Datenbanken verantwortlich.
Image Database: Diese Datenbank speichert alle Daten bezüglich Bilder ab. Eingehende Bilder werden im Filesystem des Servers abgelegt & der jeweilige Pfad mit Bildherkunft und Zeitstempel in der Datenbank abgelegt. Wenn nun das Frontend Bilder anfragt, werden keine Blobs mit den Bilddaten verschickt, sondern nur der jeweilige Eintrag in der Datenbank die Bilder werden nachträglich über das src Attribut des img Tag vom Filesystem abgefragt.
Temperature Database: Diese Datenbank speichert alle eingehenden Temperatur Abfragen der jeweiligen NodeMCU’s. Nach dem Befehl für die Temperatur Abfrage wartet das Backend auf die Antworten der einzelnen NodeMCU’s über MQTT. Sobald eine Antwort erhalten wurde, wird diese mit einem Zeitstempel & einem identifier in die Datenbank eingepflegt. Identifier & Zeitstempel brauchen wir später im Frontend um die jeweiligen Daten eindeutigen Parteien zuordnen zu können.
CAD
Funktion
Im Behälter wird das Vogelfutter aufbewahrt. Das Innenleben des Behälters ist so konstruiert, dass das Futter problemlos, zu jedem Füllstand zur Spirale gelangt. Wird die Spirale einer Torsion gegen den Uhrzeigersinn ausgesetzt, führt das dazu, dass das Futter entlang des Rohrs wandert und Finals durch dessen Öffnung ausgeworfen wird. Nach einigen Versuchen wurde der Winkel für eine ideale Futterbeförderung auf 30° (zum Boden des Vogelhäuschens) festgelegt sowie Erhebungen auf der Oberfläche der Spirale angebracht. Um ein ruhigen- und sauberen Rundlauf der Förderspirale zu gewährleisten, wird diese zwischen zwei Rillenkugellager gelagert. Die Rillenkuggellager sind mittels Presspassungen im Deckel des Rohrs und dem Behälter koaxial zueinander verbaut. Der Drehmoment wird vom Nema 17 Schrittmotor über die Kupplung zur Spirale übertragen. Der Nema Schrittmotor weist einen Haltemoment von 16 Ncm auf und wird über die Schrittmotoren Halterung am Behälter befestigt.
Das RaspberryPi 3b+ sowie das Breakoutboard, befinden sich im Unterkasten. Dort sind auch Lüftungsschlitze integriert, die eine zu heiße Umgebungstemperatur verhindern sollen. Die RaspberryPi Cam v1, ist am Flansch des Rohrs in einer Einkerbung angebracht und wir durch die Kamerabdeckung vor Witterung geschützt.
Montage
Die Montage der Bauteile ist ziemlich simpel. Zuerst führt man den Flansch des Rohrs in die Kreistasche des Holzbretts ein und verschraubt diese anhand den drei M12 Sechskantschrauben miteinander. Im Anschluss müssen die Rillenkugellager in die Passungen des Behälters und des Rohrdeckels eingepresst werden. Nachdem die Kugellager an ihrer Position sitzen, wird der Behälter auf den halb-offenen Teil des Rohrs gesteckt. Ist der Behälter auf das halb-offene Ende des Rohrs aufgesteckt, kann dieser mit drei langen M6 Schrauben mit dem Holzgehäuse verschraubt werden. Zwischen dem Behälter und dem Holzgehäuse finden die Distanzbuchsen ihren Platz. Anschließend wird die Spirale in das Rohr eingeführt und der Deckel des Rohrs aufgesteckt. Nun sollte die Spirale im Rohr verdreht werden können. Ist dies der Fall, wird der Schrittmotor in seiner vorgesehenen Halterung eingeschraubt. Nun wird die Kupplung auf die Antriebswelle des Schrittmotors gesteckt und mit einer M3 Schraube befestigt. Dabei ist darauf zu achten, dass sich die Mitnahmefläche der Antriebswelle in richtiger Position befindet, sodass eine Drehmomentübertragung stattfinden kann. Dasselbe gilt für die Spirale. Zuerst wird die Schrittmotorhalterung an den Behälter mittels vier M6 Senkkopfschrauben verschraubt und im Anschluss die Kupplung mit der Spirale. Dabei ist darauf zu achten, dass anstatt eine M3 Schraube, eine M6 Gewindeschraube über die Kerbe auf der Unterseite des Behälters, den weg zur Kupplung findet. Nun wird die RaspberryPi Cam in die Freifläche des Rohrs angebracht und mit der Kameraabdeckung verschraubt und im Anschluss mit dem RaspberryPi 3b+ über das Datenkabel verbunden.
Ist soweit alles korrekt montiert, wird das RaspberryPi 3b+, wie das Breakoutboard an deren vorgesehene Stelle im Unterkasten angebracht und mit Strom versorgt. Finals wird der Unterkasten mittels vier M6 Zylinderkopfschrauben mit dem Behälter verschraubt.
Ressourcensparendes konstruieren
Um beim 3-D Druck möglichst viel Filament zu sparen, wurden bestimmte Bereiche mit niedrigen Bauteilbelastungen hohl konstruiert. So ist zum Beispiel ein großer Bereich des Behälters hohl. Dadurch verringerten wir bei dem Behälter den Filamentverbrauch um knapp die Hälfte und die Druckzeit um ein drittel!
Frontend
Das Frontend wurde ganz klassisch mit HTML/CSS/Javascript gestaltet. Wenn man auf die Seite: https://www.vogel-feeder.de geht, sieht man zunächst drei Panels, die für jedes Gruppenmitglied angelegt wurden. Auf diesen Panels gibt es zwei Buttons und ein Dropdown Menü, sowie Temperatur und Luftfeuchtigkeits-Anzeigen die im oberen linken Eck der Seite über “Parameter Aktualisieren” aktualisiert werden können. Mit dem Button “Nachfüllen” ist es möglich, bei der jeweiligen Person das Futter für die Vögel nachzufüllen. Dazu ist in dem Dropdown-Menü eine Futterart auszuwählen. Über den Button “Charts” kann man den Verlauf der Temperatur und Luftfeuchtigkeit exakt einsehen. Scrollt man auf der Seite ein wenig runter stößt man auf die Galerie, in der jedes Bild hochgeladen wird, das die jeweiligen Vogelhäuser schießen. Es ist auch möglich diese über einen “delete” Button zu löschen.
Breakoutboard
Um so platzsparend & sauber wie möglich unsere Elektronik unterzubekommen, entschlossen wir uns ein Breakoutboard eigens für unsere Zwecke zu löten. Das Board verfügt über 2 Female Pin Head Sockel, um den NodeMCU und den Stepperdriver jederzeit ohne Probleme von dem Board zu lösen. Der DHT11 und der Stepper wie auch die 12v Versorgung für den Stepper wurden über JST-Steckverbindungen realisiert. Somit können einzelne Bauteil ganz einfach per Plug-and-play ausgetauscht werden. Mit einer Boardgröße von 30 mm auf 50 mm ist der doch sehr kleine Footprint perfekt um ein Kabelchaos zu vermeiden.
Die 12 V Spannungsversorgung des Steppers verfügt zusätzlich noch eine parallel geschalteten 100 µF Kondensator, um die meist etwas unzuverlässigen Netzteile auszugleichen. Er verhindert kurzzeitige Spannungsverluste und ist daher super um falsche Steps zu vermeiden.
Hinterlasse einen Kommentar