DIY- IoT Projekt: Bauen Sie einen kostengünstigen Smart Planter

Vor ein paar Wochen habe ich beschlossen, eine Sukkulente für meinen Schreibtisch zu kaufen, nur weil sie einen positiven Einfluss auf die Umwelt hat. Falls Sie es noch nicht wissen: Der Anbau von Sukkulenten oder Kakteen kann Ihnen in mehrfacher Hinsicht zugute kommen: Sie tragen dazu bei, die Luft zu reinigen, die Luftfeuchtigkeit in den Räumen zu verbessern und der Umgebung frischen Sauerstoff zuzuführen

Nachdem ich ein paar Tage lang Lana (Ja, ich habe sie Lana genannt 💕) auf meinem Schreibtisch hatte, begann ich das Gefühl zu haben, dass etwas fehlte. Als leidenschaftlicher Maker und IoT Developer Advocate bei Ubidots Smart Planter “ für Lana zu erstellen Nach ein paar Tagen harter Arbeit und vielen Problemen beim Drucken hatte ich endlich dieses coole Ergebnis und ich wollte unbedingt meinen Prozess mit Ihnen teilen 🙆‍♀️💚:

Dieses Projekt wurde von einem früheren Projekt von Paul a Maker 👨‍💻 (3D-Druck, Elektronik, Software) , das ich vor Monaten verfolgt habe, und ich kann sagen, dass ich viele Tipps und Tricks von ihm gelernt habe. Wenn Sie Inspiration für Ihre Elektronikprojekte suchen, sollten Sie ihm folgen , vertrauen Sie mir.

Persönlich mag ich es wirklich, meine eigene Inspiration zu finden, indem ich den Projekten von jemand anderem folge. Ich finde sowieso immer eine Möglichkeit, meinen eigenen Stil hinzuzufügen, Credits zu geben und natürlich das Endergebnis zu teilen, damit andere Leute wie ich es bekommen können auch inspiriert. 🤓 🤓

Dieser Beitrag enthält eine Schritt-für-Schritt-Anleitung für mein Projekt sowie alle Ressourcen, die zum Nachbau des „ Smart Planter “ erforderlich sind.

Anforderungen

Schritt für Schritt

  1. 3D-Druck
  2. Verdrahtung
  3. Gehäuse
  4. NodeMCU ESP8266 programmieren
  5. Dashboard – Steuern und Überwachen
  6. Zusammenfassung

1. 3D-Druck

Meine Fähigkeiten zum Modellieren von 3D-Teilen sind etwas begrenzt (ich arbeite daran, weitere Projekte mit dem 3D-Drucker zu erstellen), aber es gibt eine offene Community namens Thingiverse , die unser Leben einfacher macht. Es ist eine florierende Design-Community zum Entdecken, Herstellen und Teilen von 3D-druckbaren Dingen. Nachdem ich mir viele Pflanzgefäß-Designs angeschaut hatte, beschloss ich, das folgende zu drucken:

Klicken Sie hier, um das Design herunterzuladen – thing:2857938

Dieses Design hat mir sehr gut gefallen, da es bereits ein IoT Pflanzgefäß war und die Lampe ein schönes und cooles Accessoire war. Im Grunde passte dieses Modell perfekt zu dem, was ich mir von Anfang an vorgestellt hatte:

  • Lampe für Fernbedienung.
  • Platz zum Platzieren elektronischer Komponenten zum Hinzufügen einiger Sensoren.

Allerdings war mir klar, dass der Platz für die Elektronik nicht für alle Funktionalitäten ausreichte, die ich einbauen wollte. Um dieses Problem zu lösen, habe ich das untere Teil zweimal gedruckt:

  • Weißes Teil : Zum Platzieren des NodeMCU ESP8266, der Sensoren und der Drähte.
  • Transparentes Teil : Zum Platzieren des NeoPixel-Rings.

Das Ergebnis ist das folgende Meisterwerk:

HINWEIS: Der NeoPixel-Ring ist für dieses Projekt nicht zwingend erforderlich, er war lediglich ein Accessoire, das es hübscher machte. Sie können auch nur ein Stück verwenden.

2. Verkabelung

Beziehen Sie sich entsprechend der in diesem Handbuch bereitgestellten Firmware auf das Diagramm und die Tabelle unten, um eine ordnungsgemäße Verbindung zwischen den verwendeten Komponenten herzustellen.

3. Gehäuse

Wenn die richtigen Kabelverbindungen bereits hergestellt sind, platzieren Sie alle Komponenten wie unten gezeigt im Pflanzgefäß:

Wie Sie sehen können, habe ich die NodeMCU in einem PCB-Steckbrett mit 10 rechtwinkligen Stiftleisten platziert. Die Idee bestand darin, die Verbindung mit den Sensoren herzustellen und etwas Platz für die Elektronik zu sparen. Ehrlich gesagt hätte ich die Kabel besser organisieren können. Die Idee bestand jedoch darin, eine maßgeschneiderte Leiterplatte für das Pflanzgefäß zu erstellen, in der alles eingebettet sein sollte. Außerdem habe ich das weiße Stück gebohrt, um die NeoPixel-Ringkabel hindurchzuführen. Zum Abschluss habe ich den NeoPixel-Ring mit der Spitze nach unten in die Unterseite geklebt und dann das transparente Teil auf das weiße geklebt, um das Licht zu verwischen. Am Ende hatte ich dieses tolle Ergebnis:

4. NodeMCU ESP8266 programmieren

ESP8266 arbeiten zu können , müssen Sie die ESP8266-Plattform mit dem vorkonfigurierten Arduino Board Manager . Wenn Sie nicht mit dem Hinzufügen einer Platine mit der Arduino IDE vertraut sind, finden Sie in diesem Artikel weitere Anleitungen .

2. Wählen Sie bei installierter ESP8266-Plattform das ESP8266-Gerät aus, mit dem Sie arbeiten. Im vorliegenden Fall arbeiten wir mit einem „ NodeMCU 1.0 “. Um Ihr Board aus der Arduino IDE auszuwählen, wählen Sie „Extras > Board „Generic ESP8266 Module““ .

Ubidots MQTTESP8266 herunter und installieren Sie sie . Eine ausführliche Erklärung zur Installation von Bibliotheken mithilfe der Arduino IDE finden Sie in dieser Anleitung .

4. Fügen Sie den folgenden Code in die Arduino IDE ein. Weisen Sie dann Ihr eindeutiges Ubidots TOKEN , SSID (WiFi-Name ) und Passwort des verfügbaren Netzwerks zu.

HINWEIS: Denken Sie daran, die richtigen Pins für die verwendeten Komponenten zuzuweisen, falls Sie einen anderen Anschluss als den oben angegebenen verwenden

GitHub-Repository

/* RGB Smart Planter integriert mit Ubidots zur Überwachung und Steuerung. Dieser Code funktioniert für: 1) Lesen von zwei Sensoren: DHT11 und Bodenfeuchte. 2) Veröffentlichen Sie Sensormesswerte auf Ubidots . 3) Abonnieren Sie mehrere Variablen zur Fernsteuerung. Erforderliche Bibliotheken: - Ubidots ESP8266 MQTT - ( ubidots / ubidots -mqtt-esp) - Adafruit NeoPixel - (https://github.com/adafruit/Adafruit_NeoPixel) - DHT - (https:// github.com/adafruit/DHT-sensor-library) Erstellt von: Maria Hernández – IoT Developer Advocate @ Ubidots Überarbeitung: José García – Development & Support Manager @ Ubidots /*************** ************************* * Bibliotheken einschließen ********************** ******************/ #enthalten<Adafruit_NeoPixel.h> #enthalten<stdio.h> #enthalten<map> #include „DHT.h“ #include „ Ubidots ESPMQTT.h“ /************************************** ****** * Pins definieren ************************************/ #define LIGHTPIN D1 // Digitaler Pin für LED-Lampe. #define DHTPIN D5 // Digitaler Pin für DHT-Sensor. #define NEOPIXELSPIN D6 // Digitaler Pin für NeoPixel Ring. #define MOISTUREPIN A0 // Analoger Pin für Feuchtigkeitssensor. /**************************************** * Konstanten definieren ****** **********************************/ #define TOKEN „BBFF-xxxxxxxxxx“ // Weisen Sie Ihr Ubidots TOKEN zu. #define WIFINAME „xxxxxxxxxx“ // Weisen Sie Ihre SSID zu. #define WIFIPASS „xxxxxxxxxx“ // Weisen Sie Ihr WLAN-Passwort zu. #define DEVICE „planter“ // Ubidots Device Label. #define VAR_PUB_1 "temperatur" // Ubidots -Variablenbezeichnung für die Veröffentlichung von Daten. #define VAR_PUB_2 „humidity“ #define VAR_PUB_3 „soil-feuchtigkeit“ #define VAR_PUB_4 „heat-index“ #define VAR_SUB_1 „light-1“ // Ubidots -Variablenbezeichnung zum Abonnieren von Daten; \ // Diese Variablen müssen bei Ubidots erstellt werden. #define VAR_SUB_2 "light-2" #define NUMPIXELS 12 // 12 Bit NeoPixel Ring // Kommentieren Sie den von Ihnen verwendeten Typ aus #define DHTTYPE DHT11 // DHT 11 //#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 //#define DHTTYPE DHT21 // DHT 21 (AM2301) typedef enum { rot, grün, blau, gelb, weiß, schwarz } NeoPixelColor; // R, G, B uint8_t myColors[][6] = {{250, 0, 0}, // Rot. {0, 255, 0}, // Grün. {0, 0, 255}, // Blau. {255, 255, 0}, // Gelb. {255, 255, 255}, // Weiß. {0, 0, 0}}; // Schwarz. const uint8_t numberOfVariables = 2; // Anzahl der Variablen für das Abonnement. char *variableLabels[numberOfVariables] = {VAR_SUB_1, VAR_SUB_2}; // Variablenbezeichnung für das Abonnement. Float-Wert; // Eingehenden Wert speichern. int lastValue; bool bottomLight; // Flag zur Steuerung der Bedingungen für das untere Licht. unsigned long initTime; // Speichere die Initialisierungszeit. const long SECONDS_TO_RECONNECT = 180000; // Zeitraum zum erneuten Verbinden der MQTT-Verbindung. // Vergleichsfunktor mit Kartenfunktionen. struct cmp_str { bool Operator()(char const *a, char const *b) const { return strcmp(a, b) < 0; } }; // Deklaration der Kartenfunktion. typedef std::function<void()> Funktionstyp; typedef std::map<const char *, FunctionType, cmp_str> mapTopicSubscription; /**************************************** * Instanzen definieren ****** **********************************/ Ubidots -Client(TOKEN); Adafruit_NeoPixel Pixel(NUMPIXELS, NEOPIXELSPIN, NEO_GRB + NEO_KHZ800); DHT dht(DHTPIN, DHTTYPE); mapTopicSubscription ubiSubTopic; /**************************************** * Hauptfunktionen ****** **********************************/ void setup() { initTime = millis(); // Initialisierungszeit speichern Serial.begin(115200); pinMode(LIGHTPIN, OUTPUT); // Pin-Modus deklarieren // Definiert die zugeordneten Funktionen zur Behandlung des Abonnementereignisses. ubiSubTopic[VAR_SUB_1] = &subscriptionHandler1; ubiSubTopic[VAR_SUB_2] = &subscriptionHandler2; Kunde. ubidots SetBroker("industrial.api. ubidots .com"); // Legt den Broker richtig für das // Geschäftskonto fest. client.setDebug(true); // Übergeben Sie einen boolschen Wert „true“ oder „false“, um Debug-Meldungen zu aktivieren. client.wifiConnection(WIFINAME, WIFIPASS); // WLAN-Verbindung herstellen. client.begin(callback); dht.begin(); // Initialisiert den DHT-Sensor. pixels.begin(); // Initialisiert NeoPixel Ring. pixels.clear(); // Alle Pixelfarben auf „Aus“ setzen. // Erstellt ein Abonnement mit definierten Variablen. Kunde. ubidots Subscribe(DEVICE, VAR_SUB_1); Kunde. ubidots Subscribe(DEVICE, VAR_SUB_2); } void loop() { // Stellt das Abonnement mit definierten Variablen wieder her, wenn die Verbindung unterbrochen wird oder alle 3 Minuten. if (!client.connected() || abs(millis() - initTime) > SECONDS_TO_RECONNECT) { initTime = millis(); client.reconnect(); Kunde. ubidots Subscribe(DEVICE, VAR_SUB_1); Kunde. ubidots Subscribe(DEVICE, VAR_SUB_2); } client.reconnect(); // Werte für Temperatur, Luftfeuchtigkeit und Bodenfeuchtigkeit lesen.a float Moisture = dht.readHumidity(); Float-Temperatur = dht.readTemperature(); int SoilMoisture = analogRead(MOISTUREPIN); // Hitzeindex in Celsius berechnen (isFahreheit = false). float heatIndexC = dht.computeHeatIndex(temperatur, feuchtigkeit, false); // Überprüfen Sie, ob Lesevorgänge fehlgeschlagen sind, und beenden Sie den Vorgang vorzeitig (um es erneut zu versuchen). if (isnan(humidity) || isnan(temperature)) { Serial.println(F("Fehler beim Lesen vom DHT-Sensor!")); } // Steuert die Farben von NeoPixel basierend auf den Temperaturwerten. if (bottomLight) { if (inRange(temperature, 0, 16)) colorWipe(blue, 50); if (inRange(temperature, 16, 21)) colorWipe(green, 50); if (inRange(temperature, 21, 26)) colorWipe(gelb, 50); if (inRange(temperature, 26, 40)) colorWipe(red, 50); } // Fügt Variablen hinzu, die in Ubidots veröffentlicht werden sollen. client.add(VAR_PUB_1, Temperatur); client.add(VAR_PUB_2, Luftfeuchtigkeit); client.add(VAR_PUB_3, SoilMoisture); client.add(VAR_PUB_4, heatIndexC); // Veröffentlicht alle dem definierten Gerät hinzugefügten Variablen. Kunde. ubidots Publish(DEVICE); client.loop(); Verzögerung (1000); } /**************************************** * Abonnementfunktionen ***** ***********************************/ // Funktion, die ausgeführt werden soll, wenn var_sub_1 seinen Status ändert. void subscriptionHandler1() { if (value == 1) { Serial.println("Pflanzgefäßlampe eingeschaltet."); digitalWrite(LIGHTPIN, HIGH); } else { Serial.println("Pflanzgefäßlampe ausgeschaltet."); digitalWrite(LIGHTPIN, LOW); } }; // Funktion, die ausgeführt werden soll, wenn var_sub_2 seinen Status ändert. void subscriptionHandler2() { if (value != lastValue) { if (value == 1) { Serial.println("Pflanzgefäß-Unterlicht eingeschaltet."); for (int i = 0; i < 3; i++) { colorWipe(red, 50); colorWipe(grün, 50); colorWipe(blau, 50); }; colorWipe(weiß, 200); BottomLight = true; } else { Serial.println("Pflanzgefäß-Unterlicht ausgeschaltet."); colorWipe(weiß, 50); colorWipe(schwarz, 200); bottomLight = false; } } lastValue = value; }; /**************************************** * Hilfsfunktionen ****** **********************************/ // Gibt ein int mit der Länge eines char zurück int strLen(char *s) { int l = 0; while (*s != '\0') { s++; l++; } return (l); } // Rückruf zur Bearbeitung des Abonnements void callback(char *topic, byte *payload, unsigned int length) { char *variableLabel = (char *)malloc(sizeof(char) * 30); getVariableLabelTopic(topic, variableLabel); // Speichert das Variablenlabel. value = btof(Nutzlast, Länge); // Speichert den Wert der abonnierten Variablen. executeCases(variableLabel); // Führt den Funktionshandler für die // abonnierte Variable aus. free(variableLabel); // Freier Speicher. } // Analysiere das empfangene Thema, um die Variablenbezeichnung zu extrahieren. void getVariableLabelTopic(char *topic, char *variableLabel) { sprintf(variableLabel, ""); for (int i = 0; i < numberOfVariables; i++) { char *resultLv = strstr(topic, variableLabels[i]); if (resultLv != NULL) { uint8_t len ​​= strlen(resultLv); char result[100]; uint8_t i = 0; for (i = 0; i < len - 3; i++) { result[i] = resultLv[i]; } result[i] = '\0'; snprintf(variableLabel, strLen(result) + 1, „%s“, result); brechen; } } } // Von einem Array von Zeichen in einen Gleitkommawert umwandeln. float btof(byte *payload, unsigned int length) { char *demo_ = (char *)malloc(sizeof(char) * 10); for (int i = 0; i < length; i++) { demo_[i] = payload[i]; } return atof(demo_); } // Führt die jeweilige „Subscription Function“ basierend auf dem empfangenen Wert aus. voidexecuteCases(char *variableLabel) { if (ubiSubTopic.find(variableLabel) != ubiSubTopic.end()) { mapTopicSubscription::iterator i = ubiSubTopic.find(variableLabel); (i->second)(); } } // Füllt NeoPixel-Ringpixel nacheinander mit Farbe. void colorWipe(NeoPixelColor color, int wait) { int r, g, b; r = myColors[color][0]; g = myColors[color][1]; b = myColors[color][2]; for (int i = 0; i < pixels.numPixels(); i++) { pixels.setPixelColor(i, r, g, b); pixels.show(); Verzögerung (warten); } } // Überprüft, ob der empfangene Wert im erwarteten Bereich liegt bool inRange(float x, int low, int high) { return ((x - low) > 0 && (high - x) >= 0); }

5. Überprüfen Sie Ihren Code in der Arduino IDE. Dazu sehen Sie in der oberen linken Ecke unserer Arduino IDE das „ Häkchen “-Symbol; Wählen Sie es aus, um Ihren Code zu bestätigen.

6. Laden Sie den Code in Ihr „NodeMCU 1.0“ . Wählen Sie dazu das „ Rechtspfeil“ -Symbol neben dem „ Häkchen “-Symbol.

7. Um die Konnektivität des Geräts und die gesendeten Daten zu überprüfen, öffnen Sie den seriellen Monitor , indem Sie das „ Lupe “-Symbol in der oberen rechten Ecke der Arduino IDE auswählen, um die Konnektivitätsprotokolle logs die Antworten vom Ubidots Server anzuzeigen.

8. Nach einigen Sekunden der Initialisierung erstellt der bereitgestellte Code automatisch ein neues Gerät in Ihrem Ubidots -Konto. Gehen Sie zum Gerätebereich Ihres Ubidots Kontos . Sie sollten sehen, dass neue Geräte automatisch erstellt werden:

Geben Sie das Gerät „ Planter “ ein und sehen Sie sich die konfigurierten Variablen für die Datenübertragung an:

9. Erstellen Sie dann zwei neue Rohvariablen, um das Abonnement einzurichten und die Lichter fernzusteuern. Klicken Sie dazu auf „Variable hinzufügen > Rohvariable “ und weisen Sie die im Code definierte Variablenbezeichnung zu. Für den bereitgestellten Beispielcode lauten die zu erstellenden Variablenbezeichnungen „light-1“ und „light-2“ .

Wenn die Variablen erfolgreich erstellt wurden, sollten Sie das folgende Ergebnis erhalten:

5. Dashboard – Steuerung und Überwachung

Nachdem alles bereits integriert ist, ist es an der Zeit, die Daten der Geräte in einem Dashboard . dient das dashboard

1. Um Ihr erstes dashboard , gehen Sie zum Dashboard Registerkarte (Daten → Dashboards ) . Wählen Sie dann oben rechts das Pluszeichen (+) und dann den gewünschten Widget-Typ aus. dashboards wie das folgende zu erstellen

Mehr über Ubidots Dashboards : Anwendungs-Branding: Benutzerdefinierte Stile für Ihre dashboards und Widgets

Ubidots ermöglicht es jedem Benutzer, seine Daten sehr intuitiv zu verwalten, sodass jeder sie so individuell anpassen kann, wie er möchte. Falls Sie mehr wissen möchten, empfehle ich Ihnen dringend, einen Blick auf die folgenden Leitfäden zu werfen:

2. Ubidots unterstützt bereits integrierte Ereignisse, damit Sie Ereignisse, Warnungen und Benachrichtigungen basierend auf Ihren Sensor- und Aktordaten senden können.

Sehen Sie sich die Art der unterstützten Veranstaltungen an und erfahren Sie, wie Sie die einzelnen Veranstaltungen einrichten:

  1. E-Mail-Benachrichtigungen
  2. SMS-Benachrichtigungen
  3. Webhook-Ereignisse – erfahren Sie mehr
  4. Telegrammbenachrichtigungen
  5. Slack-Benachrichtigungen – erfahren Sie mehr
  6. Sprachanrufbenachrichtigungen – erfahren Sie mehr
  7. Zurück zur normalen Benachrichtigung – erfahren Sie mehr
  8. Geofence-Benachrichtigungen – erfahren Sie mehr

6. Zusammenfassung

Nach ein paar Stunden Basteln und Codieren (und einer Menge Kaffee) habe ich diesem Smart Planter Leben eingehaucht:

Wie ich eingangs erwähnt habe, habe ich das gemacht, weil ich nicht nur eine neue Schreibtischdekoration wollte, sondern weil ich auch das Gefühl hatte, dass etwas für Lana fehlte, wollte ich meine eigene Art der Kommunikation mit ihr über IoT und Daten erfinden. Wenn Sie andere Möglichkeiten zur Kommunikation mit Ihren Pflanzen wünschen, können Sie diese über MIDI Sprout . Das ist cool, oder? 🤩

Dies ist nur die V0 des Smart Planter und es gibt ein paar Dinge, die ich verbessern möchte, wie zum Beispiel das Design, die Elektronikorganisation mit einer benutzerdefinierten Leiterplatte und die Integration mit anderen Diensten wie Google Assistance, Alexa und Twitter.

Ich hoffe, es hat Ihnen genauso gefallen wie mir. Wenn Sie Kommentare oder Fragen zum Projekt haben, können Sie sich gerne an uns wenden! Ich bin völlig offen für konstruktives Feedback, um diese Art von Projekten zu verbessern und sie mit Ihnen zu teilen. 😁💚

Weitere nützliche IoT Projekte: