Update: Green finger IoT

08/10/2017.Henrik.0 Likes.0 Comments

So if you have read my last post for project Green Finger you know what it's about. I have now performed a total rebuild to make it work better and also made it in to an IoT device. Totally necessary for watering some plants don't you think?

The update

So what have changed? Well it now uses a WeMos D1 V2 mini (ESP8266 Wifi) instead of the Arduino Nano for the built in WiFi and compact size, the motor driver have been scraped and replaced with just two transistor, the voltage splitter have also been scraped and everything is powered with a random micro-USB phone charger.

The down side with the WeMos is that it only have one analogue pin and the sensors uses analogue pins. This was overcome by connecting both sensors to the one pin and having diods to prevent back current and messed up readings, this also resulted in some further problems because of the diods nature resulting in messed up readings once again. But by adding some delay between checking each plants this was corrected and I was getting good values.

You will have to test out what values that are right for your plants, the once in the code is good for me(basil and salad). You can set different levels for when the plants are to be watered and if they are to be held at a certain level(just be moist all the time) or maybe get to dry out a bit and then get a proper watering, it's up to you and your plants.

I won't attach the database structure or websites for the logging and displaying, but it's not that complicated to figure out so you can probably sort it out your self (or strip the logging part from the code, up to you). But you can check out my readings here: Green Finger

I'm attaching a parts list, some pictures of my system and the code below(note that the code isn't optimised in any way and probably contains unused stuff and things).

The stuff

/**
 * Project: Green Finger WiFi
 * Self watering system
 * Author: Henrik Norberg
 * E-mail: henrik@dbhn.se
 */

#include <ESP8266WiFi.h>

const char* ssid = "Your WiFi Name";
const char* password = "WiFi Password";

WiFiClient client;

// motor one
int pump1 = D1; //Trigger pin for Pump 1
int pump2 = D2; //Trigger pin for Pump 2

int mostureSensor = A0; //Both mosture sensors on same pin

int triggerSens1 = D7; //Power on/off sensor 1 to prevent corrotion
int triggerSens2 = D8; //Power on/off sensor 2 to prevent corrotion

//Moisture levels

int lowLevel = 0;

// Sensor states, 0 = Needs chacking, 1 = Ok or too dry/missing
int sensor1 = 0;
int sensor2 = 0;
int sensorValue = 0;
int numSensors = 2; //Numbers of sensors

int i = 0; //Counter

int delayShort = 300000; //Delay between waterings when dry. Default: 300000 = 5min

int interval = 10800000; //Delay between waterings when dry. Default: 10800000 = 3h

// Tracks the time since last event fired
unsigned long previousMillis=0;

int watering = 0; //Tell server if watering occured

void setup() {
	// Serial Begin so we can see the data from the mosture sensor in our serial input window. 
  Serial.begin(115200);
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Print the IP address
  Serial.print("Use this URL : ");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");

 // set all the motor control pins to outputs
  pinMode(pump1, OUTPUT); //pump 1
  pinMode(pump2, OUTPUT); //pump 2

  pinMode(triggerSens1, OUTPUT); //Trigger 1
  pinMode(triggerSens2, OUTPUT); //Trigger 2
}

void loop() {
	unsigned long currentMillis = millis();

	delay(1000);
	if ((unsigned long)(currentMillis - previousMillis) >= interval) {
		digitalWrite(pump1, LOW);
		digitalWrite(pump2, LOW);  
		sensor1 = 0;
		sensor2 = 0;
		Serial.println("Sensors set to 0");
		delay(1000);
		watering = 0;
		lowLevel = 650; //Set default moisture low limit
		while (sensor1 == 0){			
			Serial.println("Sensor 1 on");
			digitalWrite(triggerSens1, HIGH);
			// read the input from sensor1:
			mCheck();
			Serial.println(sensorValue);
			digitalWrite(triggerSens1, LOW);
			Serial.println("Sensor 1 off");
			if (sensorValue >= lowLevel && sensorValue <= 800 ){ 
lowLevel = 500; //Change moisture low limit so the plant gets more water 
Serial.println("Sensor 1 too dry, watering."); 
// turn on motor 
digitalWrite(pump1, HIGH); 
delay(2000); 
// now turn off motors 
digitalWrite(pump1, LOW); 
watering = 1; 
delay(delayShort); 
} 
else if (sensorValue >= 801) {
				sensor1 = 1; 
				Serial.println("Sensor 1 too dry or missing.");

			}
			else {
				sensor1 = 1; 
				Serial.println("Sensor 1 - Moisture OK!");

			}
			Serial.println("\nStarting connection to server..."); 
			/** 
			An explanation for my server logging and it's security.

			The logging works by having a server with an SQL-database setup and a site that the ESP sends data to(or it just opens a webadress basicly).
			The url have a security key and the watering data. The security key is for hopefully preventing "unwelcomed" data entries, if the key don't match one in the database then the connection is killed.
			As a extra precaution the site for the data entry have a randomly generated name and can be placed where ever on the server.

			*/
			if (client.connect("www.domain.com", 80 //Your website

				WiFi.printDiag(Serial);
				String data = "swifty=RandomKey" //Generate a random key 
					+  (String) + "&plant=1" //What plant that it concerns
					+  "&value=" +(String) sensorValue //Moisture level
					+ "&water=" + (String) watering; //Was the plant watered? 0/1

				client.println("POST /randomsitename.php HTTP/1.1"); //The site name, get a random name for this also
				client.println("Host: www.domain.com");                 
				client.println("Content-Type: application/x-www-form-urlencoded"); 
				client.print("Content-Length: "); 
				client.println(data.length());
				client.println();
				client.print(data);

				Serial.println("\n");
				Serial.println("My data string im POSTing looks like this: ");
				Serial.println(data);
				Serial.println("And it is this many bytes: ");
				Serial.println(data.length());       
			}     
			if (client.connected()) { 
				client.stop();	// DISCONNECT FROM THE SERVER
			}
		}
		i=0;
		while (i<=600) { 
//Wait 10min for better readings 
delay(1000); 
Serial.println(i); 
i++; 
} 
lowLevel = 650; //Set default moisture low limit 
watering = 0; 
while (sensor2 == 0){ 
// read the input from sensor2: 
digitalWrite(triggerSens2, HIGH); 
Serial.println("Sensor 2 on"); 
mCheck(); 
Serial.println(sensorValue); 
digitalWrite(triggerSens2, LOW); 
Serial.println("Sensor 2 off"); 
if (sensorValue >= 650 && sensorValue <= 800){ 
lowLevel = 550; //Change moisture low limit so the plant gets more water 
Serial.println("Sensor 2 too dry, watering."); 
// turn on motor 
// set speed out of possible range 0~255 
digitalWrite(pump2, HIGH); 
delay(2000); 
// now turn off motors 
digitalWrite(pump2, LOW); 
watering = 1; 
delay(delayShort); 
} 
else if (sensorValue >=801) {
					sensor2 = 1; 
					Serial.println("Sensor 2 too dry or missing.");
				}
			 else {
				sensor2 = 1; 
				Serial.println("Sensor 2 OK!");
			  }
			  Serial.println("\nStarting connection to server..."); 
			if (client.connect("www.domain.com", 80)){

				WiFi.printDiag(Serial);
				String data = "swifty=RandomKey"
					+  (String) + "&plant=2"
					+  "&value=" +(String) sensorValue
					+ "&water=" + (String) watering;

				client.println("POST /randomsitename.php HTTP/1.1"); 
				client.println("Host: www.domain.com");                 
				client.println("Content-Type: application/x-www-form-urlencoded"); 
				client.print("Content-Length: "); 
				client.println(data.length());
				client.println();
				client.print(data);

				Serial.println("\n");
				Serial.println("My data string im POSTing looks like this: ");
				Serial.println(data);
				Serial.println("And it is this many bytes: ");
				Serial.println(data.length());       
			}     
			if (client.connected()) { 
				client.stop();	// DISCONNECT FROM THE SERVER
			}
		}    
		delay(400);
		Serial.println("Done, sleep");
		previousMillis = currentMillis;
	}
}

void mCheck(){ //Universal sensor checking
	i = 0;
	sensorValue = 0;
	delay(500);
	while (i<=10) { //"Purge" the diode
		delay(1000);
		analogRead(mostureSensor);
		Serial.println(i);
		i++;
	}
	i=0;
	sensorValue = analogRead(mostureSensor);
	Serial.println(sensorValue);

  return;
}

The Future

In future development I would like to make it possible to remote control it for adjusting watering levels etc., add a water level detector to the water tank (so it don't try to water if there isn't any water, maybe also add a visual indicator for this), pritty up the wires running from the housing, add a room temperature/hygrometer sensor.

Downloads

SelfWatering_rev4_WiFi.zip
Categories: Projekt

All rights reserved © Design by HN