EmoPot: Smarter Blumentopf visualisiert Pflanzen-Gesundheit
Komponenten und Zubehör
| Arduino Nano R3 | × | 1 |
| DFRobot Gravity: Analog Soil Moisture Sensor | × | 1 |
| 0,96″ I2C OLED Display | × | 1 |
Benötigte Werkzeuge
- Lötkolben
- 3D-Drucker
Apps und Online-Dienste
- Arduino IDE
Über dieses Projekt
Ein smarter Blumentopf, der die „Emotion“ der Pflanze anzeigt 😜. Ein Bodenfeuchtesensor misst die Feuchtigkeit und der Topf zeigt dazu passende emotionale Ausdrücke. Pflanzen brauchen Wasser wie wir Essen – also ergibt das Sinn 😋. Ein spaßiges Projekt zum visuellen Monitoring der Bodenfeuchte.
Der Topf zeigt verschiedene Emotionen für unterschiedliche Feuchtigkeitslevel.
Nachbau lehrt:
- Bodenfeuchtesensor & analoges Einlesen per Arduino ADC
- Bilder/Animationen auf OLED darstellen
- Animationen auf OLED mit Arduino programmieren
Hardware-Aufbau
Topf mit Elektronikfach in Fusion 360 designt. Mit 3D-Drucker selbst druckbar. Ohne Drucker: beliebigen Topf + separate Elektronikbox.
Elektronik-Verdrahtung:
- Arduino A5 → OLED SCL
- Arduino A4 → OLED SDA
- Arduino A0 → Soil Moisture Sensor AO
Programmierung
Code wirkt umfangreich, ist aber simpel! Libraries am Anfang einbinden (evtl. installieren):
Adafruit_GFX.hAdafruit_SSD1306.h
Für jede Emotion & Animationsframe eine Funktion erstellt (sehr zeitaufwendig). Im setup() Display initialisieren. Im loop() Sensorwert einlesen sensorValue = analogRead(A0); und per Schwellenwerte die passende Emotion/Animation anzeigen.
Emotionen bei verschiedenen Feuchtigkeitsleveln (Videos)
Videos zeigen die verschiedenen emotionalen Ausdrücke (traurig, neutral, glücklich, weinend, verwirrt, blühend) bei steigender Feuchtigkeit.
Code (EmoPot)
#include
#include
#include
#include
#include
#define OLED_RESET 0
Adafruit_SSD1306 display(OLED_RESET);
int sensorValue = 0;
int xx = 40;
/****************************************** TRAURIG (SAD) ****************************************************/
// 13 Frames: frame01 ... frame121 (je 128 Bytes = 128x64 Bitmap)
// ... (Bitmap-Daten für alle Frames – sehr umfangreich, im Originalcode enthalten)
/****************************************** LÄCHELN (SMILE) **************************************************/
// 13 Frames: frame02, frame012, frame22 ... frame132
/****************************************** NEUTRAL **********************************************************/
// 9 Frames: frame03, frame013, frame23 ... frame83
/****************************************** BLÜHEND (BLUSHING) ***********************************************/
// 10 Frames: frame04, frame14, frame24 ... frame94
/****************************************** WEINEND (CRYING) *************************************************/
// 10 Frames: frame05, frame15, frame25 ... frame95
/****************************************** VERWIRRT (CONFUSED) **********************************************/
// 1 Frame: framec
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setFont(&FreeSans9pt7b);
display.setTextColor(WHITE);
display.setCursor(0, 0);
}
void loop() {
sensorValue = analogRead(A0);
if (sensorValue >= 80 && sensorValue < 250) { // LÄCHELN
display.clearDisplay(); display.drawBitmap(xx, 0, frame02, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame012, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame22, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame32, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame42, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame52, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame62, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame72, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame82, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame92, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame102, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame112, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame122, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame132, 48, 48, 1); display.display(); delay(30);
}
else if (sensorValue >= 250 && sensorValue < 350) { // BLÜHEND
display.clearDisplay(); display.drawBitmap(xx, 0, frame04, 48, 48, 1); display.display(); delay(50);
display.clearDisplay(); display.drawBitmap(xx, 0, frame14, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame24, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame34, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame44, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame54, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame64, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame74, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame84, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame94, 48, 48, 1); display.display(); delay(70);
}
else if (sensorValue >= 350 && sensorValue < 550) { // NEUTRAL
display.clearDisplay(); display.drawBitmap(xx, 0, frame03, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame013, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame23, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame33, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame43, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame53, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame63, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame73, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame83, 48, 48, 1); display.display(); delay(500);
}
else if (sensorValue >= 550 && sensorValue < 700) { // TRAURIG
display.clearDisplay(); display.drawBitmap(xx, 0, frame011, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame21, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame31, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame41, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame51, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame61, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame71, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame81, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame91, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame101, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame111, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame121, 48, 48, 1); display.display(); delay(100);
}
else if (sensorValue >= 700 && sensorValue < 800) { // WEINEND
display.clearDisplay(); display.drawBitmap(xx, 0, frame05, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame15, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame25, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame35, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame45, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame55, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame65, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame75, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame85, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame95, 48, 48, 1); display.display(); delay(70);
}
else { // VERWIRRT (außerhalb definierter Bereiche)
display.clearDisplay();
display.drawBitmap(xx, 0, framec, 48, 48, 1);
display.display();
delay(30);
}
}
Hinweis: Die vollständigen Bitmap-Arrays für alle Animationsframes sind im Originalcode enthalten, hier aus Platzgründen gekürzt.
Schaltplan
Custom Parts (3D-Druck)
STL-Dateien für den Topf mit Elektronikfach im Projektverzeichnis.
Herstellungsprozess
- Susquehanna Kernkraftwerk schließt planmäßige Wartung ab, nimmt Block 2 wieder in Betrieb
- Gabelstaplerunfälle verhindern: Wesentliche Sicherheitstipps für null Umkipper
- Atomuhr-Technologie reduziert Paketdiebstahl bei Online-Lieferungen
- KI-gestützte Geruchserkennung: Aryballes Technologie revolutioniert Business & Lieferketten
- Kritische Faktoren, die CNC-Fertigungskosten beeinflussen – Teil II
- 7 Schlüsselindikatoren: Zeit für ein Generator-Upgrade
- Warum maßgefertigte Teile in 4 Schlüsselbereichen Serienfertigungsteile überlegen sind
- 10 innovative DIY Open-Source-Projekte mit 3D-Druck
- Bagger erklärt: Typen, Einsatzbereiche & Auswahl des richtigen Modells für Ihr Projekt
- Branchen, die von 5-Achs-CNC-Bearbeitung profitieren: Effizienz & Präzision steigern