ArduFarmBot Teil 2: IoT-Fernsteuerungsstation für Tomatenzucht
Komponenten
| Arduino Nano R3 | 1 |
| ESP8266 ESP-01 (WiFi) | 1 |
| DHT22 Temperatur/Luftfeuchte | 1 |
| LDR-Modul (KY-018) Helligkeit | 1 |
| Bodenfeuchtesensor (z. B. YL-69 / Hydrometer) | 2 |
| 2× 5 V Relaismodul (Pumpe, Lampe) | 2 |
| LCD I²C 20×4 | 1 |
| 3× Taster (Membran, 12 mm) + 3× LED | 3 |
| Widerstände: 10 kΩ, 2,2 kΩ, 1 kΩ, 220 Ω | je 1 |
| Arduino Nano Shield (Funduino) | 1 |
| Gehäuse (Kunststoffbox) | 1 |
Online-Dienste
- ThingSpeak API (kostenloser Cloud-Datenspeicher & Visualisierung)
Projektbeschreibung

Fortsetzung von ArduFarmBot Teil 1 (lokaler Automat). Teil 1: Sensoren (Temp, Luftfeuchte, Licht, Bodenfeuchte) → automatische Steuerung von Heizlampe & Wasserpumpe + manuelle Tasten.
Teil 2 fügt IoT hinzu: Sensordaten → ThingSpeak (Cloud). Webseite („Remote Control Page“) zeigt Daten near-realtime & erlaubt Fernsteuerung von Pumpe & Lampe.
Schritt 1: Stückliste (BOM)
Siehe Tabelle oben. Preise ca. 2017: Nano 7,50 €, DHT22 3,66 €, LDR 0,71 €, Bodenfeuchte 2×1,99 €, LCD I²C 13,99 €, ESP-01 5,96 €, Relais 2×5,80 €, Shield 7,28 €, Tastatur 6,65 €.
Schritt 2: Hardware-Ergänzung


Zur Local Station kommt nur der ESP8266 hinzu. Blockdiagramm zeigt alle Pin-Belegungen. Wichtig: ESP8266 läuft mit 3,3 V! RX des ESP (Pin 3 am Nano) darf nicht direkt an TX des Nano (5 V). Pegelwandler nötig – hier: Spannungsteiler 2,2 kΩ / 1 kΩ.
ESP an Nano Pin 2 (TX) & 3 (RX) via SoftwareSerial. Alternativ Hardware-Serial (Pin 0/1), aber beim Upload abstecken.
Summer (Buzzer) optional an Pin D17 (A3) für Kommunikationsfehler-Signal.
Test-Code für ESP-Setup: FC9DBPKIT682FY7.ino
Schritt 3: ESP8266 Verbindung

Reset-Funktion für CH_PD-Pin:
void reset8266() {
pinMode(CH_PD, OUTPUT);
digitalWrite(CH_PD, LOW); delay(300);
digitalWrite(CH_PD, HIGH);
Serial.println("8266 reset OK");
}
WLAN verbinden (Credentials im Code anpassen):
void connectWiFi() {
sendData("AT+RST\r\n", 2000, DEBUG);
sendData("AT+CWJAP=\"USERNAME\",\"PASSWORD\"\r\n", 2000, DEBUG);
delay(3000);
sendData("AT+CWMODE=1\r\n", 1000, DEBUG); // Station Mode
sendData("AT+CIFSR\r\n", 1000, DEBUG); // IP anzeigen
}
AT-Kommandos senden:
String sendData(String cmd, int timeout, bool debug) {
String resp = ""; esp8266.print(cmd);
long t = millis();
while (t + timeout > millis())
while (esp8266.available()) resp += (char)esp8266.read();
if (debug) Serial.print(resp);
return resp;
}
Schritt 4: Cloud-Speicher – ThingSpeak.com

Alle Sensordaten werden per updateDataThingSpeak() hochgeladen (Felder 1–6: Temp, Feuchte, Licht, Bodenfeuchte, Pumpenstatus, Lampenstatus).
void updateDataThingSpeak() {
startThingSpeakCmd();
cmd = msg;
cmd += "&field1=" + tempDHT;
cmd += "&field2=" + humDHT;
cmd += "&field3=" + lumen;
cmd += "&field4=" + soilMoist;
cmd += "&field5=" + pumpStatus;
cmd += "&field6=" + lampStatus;
cmd += "\r\n";
sendThingSpeakCmd();
}
Verbindungsaufbau:
void startThingSpeakCmd() {
cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP; cmd += "\",80";
esp8266.println(cmd); delay(2000);
if (esp8266.find("Error")) { Serial.println("START ERROR"); return; }
Serial.println("ThingSpeak Comm Started"); cmd = "";
}
Daten senden:
String sendThingSpeakCmd() {
esp8266.print("AT+CIPSEND="); esp8266.println(cmd.length());
if (esp8266.find(">")) {
esp8266.print(cmd); delay(500);
// Response lesen...
} else { esp8266.println("AT+CIPCLOSE"); return "error"; }
}
Basiert auf Tutorial von Michalis Vasilakis.
Schritt 5: Aktoren per Web steuern

ThingSpeak-Felder 7 & 8 als Befehlskanäle:
- Field 7: 1 = Pumpe AN, 0 = Pumpe AUS
- Field 8: 1 = Lampe AN, 0 = Lampe AUS
Schreiben per Browser: api.thingspeak.com/update?key=WRITE_KEY&field7=1
Lesen (letzter Wert): api.thingspeak.com/channels/CHANNEL_ID/fields/7/last
Funktion zum Abrufen:
int readLastDataField7() {
startThingSpeakCmd();
cmd = msgReadLastDataField7; cmd += "\r\n";
String msg = sendThingSpeakCmd();
return msg[7] - '0'; // ASCII zu Int
}
Befehle empfangen & ausführen:
void receiveCommands() {
field7Data = readLastDataField7();
if (field7Data == 1) { digitalWrite(PUMP_PIN, HIGH); pumpStatus = 1; }
else { digitalWrite(PUMP_PIN, LOW); pumpStatus = 0; }
showDataLCD(); delay(500);
field8Data = readLastDataField8(); // analog
if (field8Data == 1) { digitalWrite(LAMP_PIN, HIGH); lampStatus = 1; }
else { digitalWrite(LAMP_PIN, LOW); lampStatus = 0; }
showDataLCD(); delay(500);
}
Lokaler Tastendruck aktualisiert ebenfalls ThingSpeak-Felder 7/8 (Sync).
void aplyCmd() {
digitalWrite(PUMP_PIN, field7Data ? HIGH : LOW);
digitalWrite(LAMP_PIN, field8Data ? HIGH : LOW);
}
Koordination: Lokal vs. Remote vs. Auto
Priorisierung:
- Jeder Loop: Lokale Tasten prüfen (sofort)
- Alle ~20 s: Remote-Befehle von ThingSpeak abrufen (Polling)
- Alle ~75 s: Sensoren lesen, Auto-Steuerung ausführen, Daten hochladen (hat letzte Autorität)
long sampleTimingSeconds = 75;
long poolingRemoteCmdSeconds = 20;
long startTiming = 0, startRemoteCmdTiming = 0;
void loop() {
long elapsedRemote = millis() - startRemoteCmdTiming;
long elapsed = millis() - startTiming;
readLocalCmd(); showDataLCD();
if (elapsedRemote > poolingRemoteCmdSeconds * 1000) {
receiveCommands(); updateDataThingSpeak();
startRemoteCmdTiming = millis();
}
if (elapsed > sampleTimingSeconds * 1000) {
readSensors(); autoControlPlantation(); updateDataThingSpeak();
startTiming = millis();
}
}
Schritt 6: Eigene Webseite

ThingSpeak-Webseite ist funktional, aber nicht „schön“. Eigene responsive Webseite (HTML5/CSS3/JS) auf kostenlosem Byethost. Interagiert nur mit ThingSpeak:
- Lesen: Felder 1–4 (Sensoren), 5–6 (Aktor-Status)
- Schreiben: Felder 7–8 (Befehle)
- Bonus: Lokales Wetter via Yahoo API
Codes: FQOK9ENIT653YX5.zip (HTML/CSS/JS).
Schritt 7: Sensor-Aktor-Matrix (Entscheidungslogik)

Komplexe Bedingungen → Matrix (18 Zeilen × 10 Spalten). Spalten 0–7: Sensorzustände (Boden: trocken/mittel/nass; Licht: dunkel/hell; Temp: kalt/mittel/heiß). Spalten 8–9: Pumpe, Lampe.
boolean SDf[18][10] = {
{1,0,0, 0,1, 0,0,1, 1,0}, // trocken, dunkel, kalt → Pumpe AN
{1,0,0, 0,1, 0,1,0, 1,0},
{1,0,0, 0,1, 1,0,0, 1,1},
{1,0,0, 1,0, 0,0,1, 1,0},
{1,0,0, 1,0, 0,1,0, 1,0},
{1,0,0, 1,0, 1,0,0, 0,1},
{0,1,0, 0,1, 0,0,1, 0,0},
{0,1,0, 0,1, 0,1,0, 0,0},
{0,1,0, 0,1, 1,0,0, 0,1},
{0,1,0, 1,0, 0,0,1, 0,0},
{0,1,0, 1,0, 0,1,0, 0,1},
{0,1,0, 1,0, 1,0,0, 0,1},
{0,0,1, 0,1, 0,0,1, 0,0},
{0,0,1, 0,1, 0,1,0, 0,0},
{0,0,1, 0,1, 1,0,0, 0,1},
{0,0,1, 1,0, 0,0,1, 0,0},
{0,0,1, 1,0, 0,1,0, 0,1},
{0,0,1, 1,0, 1,0,0, 0,1}
};
Funktion defSensorStatus() prüft jede Zeile: Wenn Sensorzustände (Array snsSts[8]) mit Zeile matchen → Aktoren setzen. Auch für Loggen genutzt.
Excel-Datei: F2HWXBYITA8WIN1.xlsx
Schritt 8: Code-Optimierung
- Display: Standardmäßig AUS. Taster „Sensors Read“ toggelt Anzeige (aktualisiert Werte, greift nicht in Regelung ein).
- Initial-Setup: Beim Start zeigt LCD Schwellenwerte (KALT, TROCKEN, FEUCHT, DUNKEL, Pumpenzeit, Scan-Intervall, SW-Version). Start per „Sensors“-Taste.
- Logbuch im EEPROM: Jeder Zyklus speichert Sensorzustände (8 Bit) + Pumpe + Lampe (2 Bit) = 10 Bit pro Eintrag. Funktion
storeDataLogEEPROM(). - Modulare Dateien:
communication.ino(ESP/ThingSpeak),stationCredentials.h(Keys/Channel-ID). - PROGMEM: Konstanten in Flash statt RAM (
const PROGMEM byte DHTPIN = 5;+#include <avr/pgmspace.h>). Debug-Prints auskommentieren.
Schritt 9: MJRovai Home Farm – Fotos


… weitere Wachstumsphasen bis zur Ernte.
Schritt 10: Fazit & Ausblick

Projekt hilft beim Einstieg in Elektronik, IoT, Robotik. Teil 3 folgt (Rezept: Tomatensauce-Pasta). Buch „ArduFarmBot, the Book!“ auf Amazon: 3 Teile (Local → IoT/ThingSpeak → NodeMCU/Blynk), mit Fritzing-Plänen, GitHub-Code, YouTube-Videos.
Blog: MJRoBot.org
Code-Dateien (GitHub)
FTUT5VIIT67U8ME.ino(Main)FWMIPSSIT67U8MG.ino(Communication)FJPGZNKIT67U8MK.ino(Sensoren)FQH3X9VIT67U8NA.ino(Aktoren)F15MY4YIT67U8NB.ino(Logik/Matrix)FVU64X1IT67U8NC.h(Credentials)FZ057E3IT67U8P5.h(Konstanten)
Schaltplan

Herstellungsprozess
- Aufkommende Trends in der IoT-Implementierung: Insights & Strategien
- Arduino-gesteuerte 6-Shot-Getränkemischstation – Bauen Sie Ihren eigenen Cocktail-Automaten
- Multi-Position Temperatursensor-System für Smart-Home-Integration
- MotionSense: Smarte Einbruchserkennung mit Arduino & ESP8266
- 3D-Drucker Brandschutz: Intelligentes Sensorsicherheitssystem
- Web-fähigen IoT-Messer mit Arduino, Yaler und IFTTT bauen
- Arduino-basierte abstoßende Magnetschwebung: Einfache Schaltung & DIY-Anleitung
- Fortgeschrittener ferngesteuerter Greifer-Roboter für präzises Handling
- Hochleistungs-Datenlogger für Arduino-Wetterballons
- CoroFence Thermaldetektor: PIR-Sensor & IoT-Integration mit Panasonic GridEye