Zunächst wurde die fertiggestellte Hardware mit einem einfachen Blink-Programm bespielt, um zu sehen, ob Programme einwandfrei auf den ESP8266 übertragbar sind.
Als nächstes sollten die analogen Werte des Sensors auf einem seriellen Monitor angezeigt werden. Dazu musste das Blink-Programm, welches am Anfang genutzt wurde, modifiziert werden. Der passende PIN A0 des ESP8266 musste am Sensor angeschlossen und im Programm als analoger Input definiert werden.
Nachdem der Sensor analoge Werte übermittelte, war es für die Funktionsweise der Bewässerungsanlage zu berücksichtigen, dass bestimmte Schwellenwerte dem Programm vorgegeben werden müssen, sodass das Programm erkennen kann, ob die Pflanze Wasser benötigt oder nicht.
Es wurden vier verschiedene Modi definiert, die je nach Schwellenwert aktiviert werden.
if(sensorValue>0 && sensorValue<340){
ledOff();
msg = "Sensor is full WET";
msg_id = 1;
} else if(sensorValue>=340 && sensorValue<=530) {
ledOff();
msg = "Sensor is wet";
msg_id = 2;
} else if(sensorValue>530 && sensorValue<1023) {
ledOn();
msg = "Sensor is DRY ";
msg_id = 3;
//pump();
} else {
ledOff();
msg = "Unexpected sensor value ";
msg_id = 4;
}
Anschließend wurde die Pumpe angeschlossen und in einem separaten Programm angesteuert. Nachdem die Funktionsweise der Pumpe und die Schwellenwerte des Sensors bekannt war, sollte nun das Programm von zuvor erweitert werden. Jedes Mal, wenn der Sensor meldet, dass die Pflanze trocken ist, sollte die Pumpe für 2 Sekunden angehen.
void pump(){
// Turn pump on for 2000s
int pumpPeriode = 2000;
if(minDelayOfPump < millis() - timeStamp1){
startingProcedure();
pumpOn();
delay(pumpPeriode);
pumpOff();
timeStamp1 = millis();
}
}
Damit die Erde der Pflanze das Wasser aufnehmen kann, wird gemessen wann die Pumpe das letzte Mal aktiviert wurde. Erst wenn eine bestimmte Pause vergangen ist, darf die Pumpe wieder aktiviert werden. Somit kann das Programm nach einer bestimmten Zeit entscheiden, ob die Wassermenge ausreicht oder nicht. Falls die Wassermenge nicht ausreicht, wird die Pumpe wieder aktiviert. Dieser Ablauf wiederholt sich solange, bis die Erde der Pflanze ausreichend Wasser aufgenommen hat.
Nun sollten die Werte des Sensors zusätzlich via MQTT übertragen werden können. Dazu sollte wieder ein separates Programm genutzt werden, um den Broker, den Port und das Topic testen zu können. Anschließend wurde die MQTT-Funktionalität mit in das vorherige Programm mit aufgenommen.
Durch kleinere Programme ließen sich die Funktionen separat testen, bevor zu einem größeren Programm zusammengefügt wurden. Dies hat mögliche Fehlerquellen seit dem Anfang der Umsetzung des Quellcodes ausschließen können.

Das Programm wurde noch um eine weitere Funktion erweitert, sodass es auch möglich ist die Pumpe via MQTT zu aktivieren.
/**
*
* brief: read values from water-sensor and send via WiFi to an application
* date: 05.07.2019
* project: CvO/Informatik/DDI3_µC
*/
//#include <WiFi.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
/********************************************************/
// Update these with values suitable for your network.
const char* ssid = "HIER DER NETZWERK NAME";
const char* password = "HIER DAS PASSWORT DES NETZWERKS";
/********************************************************/
const char* mqtt_server = "broker";
const char* mqttTopicPlant = "topic1";
const char* mqttTopicValues = "topic2";
const int port = 1883;
/********************************************************/
char* msg = ""; // msg to the broker
int msg_id = 0;
int msg_id_temp = 0;
int MOTOR = 14;
unsigned long timeStamp1 = 0, timeStamp2 = 0, minDelayOfPump = 20000;
WiFiClient espClient;
PubSubClient client(espClient);
/********************************************************/
/* SETUP */
/********************************************************/
void setup() {
pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output
pinMode(MOTOR, OUTPUT);
pinMode(A0, INPUT);
Serial.begin(115200); // initialize serial communication at 115200 bits per second
startingProcedure(); // blinking BuildIn_LED as starting procedure
setup_wifi();
client.setServer(mqtt_server, port);
client.setCallback(callback);
timeStamp1 = millis();
timeStamp2 = millis();
}
/********************************************************/
/* MAIN LOOP */
/********************************************************/
// the loop routine runs over and over again forever:
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
sensorStates(sensorValue);
delay(1000);
}
/********************************************************/
/********************************************************/
/* PROCESS */
/********************************************************/
void sensorStates(int sensorValue){
if(sensorValue>0 && sensorValue<340){
ledOff();
msg = "Sensor is full WET";
msg_id = 1;
} else if(sensorValue>=340 && sensorValue<=530) {
ledOff();
msg = "Sensor is wet";
msg_id = 2;
} else if(sensorValue>530 && sensorValue<1023) {
ledOn();
msg = "Sensor is DRY ";
msg_id = 3;
//pump();
} else {
ledOff();
msg = "Unexpected sensor value ";
msg_id = 4;
}
if(minDelayOfPump < millis() - timeStamp2){
timeStamp2 = millis();
statusCheckOfPlant(msg_id, sensorValue);
}
if(msg_id != msg_id_temp){
msg_id_temp = msg_id;
statusCheckOfPlant(msg_id, sensorValue);
}
}
void statusCheckOfPlant(int msg_id, int sensorValue){
sendDataToBroker(sensorValue);
// DRY?
if(msg_id == 3){
//Turn pump on
pump();
}
}
void sendDataToBroker(int sensorValue){
// Serial
Serial.println(msg);
Serial.println(sensorValue);
// MQTT
client.publish(mqttTopicPlant, msg);
sendSensorValueViaMqtt(sensorValue);
}
/********************************************************/
/* Pump */
/********************************************************/
void pump(){
// Turn pump on for 2000s
int pumpPeriode = 2000;
if(minDelayOfPump < millis() - timeStamp1){
startingProcedure();
pumpOn();
delay(pumpPeriode);
pumpOff();
timeStamp1 = millis();
}
}
void pumpOn(){
ledOn();
// pump on
analogWrite(MOTOR, 512);
}
void pumpOff(){
ledOff();
// pump off
analogWrite(MOTOR, 0);
}
/********************************************************/
/* LED */
/********************************************************/
void ledOn(){
digitalWrite(LED_BUILTIN, LOW); // turn the LED on (HIGH is the voltage level)
delay(250);
}
void ledOff(){
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(250);
}
// blinking procedure when device is switched on
void startingProcedure(){
ledOn();
ledOff();
ledOn();
ledOff();
}
/********************************************************/
/* MQTT */
/********************************************************/
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
char receivedPayload[length];
/*Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");*/
for (int i = 0; i < length; i++) {
//Serial.print((char)payload[i]);
receivedPayload[i] = (char) payload[i];
}
Serial.println();
// Received Message
int receivedMessage = atoi(receivedPayload);
if(receivedMessage==1){
Serial.print("MESSAGE: ");
Serial.println(receivedMessage);
pump();
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("outTopic", "hello world");
//client.publish(mqttTopicPlant, "hello world!");
client.subscribe(mqttTopicPlant);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void sendSensorValueViaMqtt(int sensorValue){
// Publish int (auch hier wieder char array)
String pi_str = String(sensorValue);
char pi_buff[pi_str.length()+1];
pi_str.toCharArray(pi_buff, pi_str.length()+1);
client.publish(mqttTopicValues, pi_buff);
}