Saturday, 24 February 2018

Herb Box Eco System

About this project

Since my plants do always suffer from too much or less water and I like to put a lot of herbs into my dishes, I decided to create a custom irrigation system. The box for my herbs should be configurable and work automatically or manually. Therefore an interface to a website exists to enable a setup and show the humidity in a nice chart. The last step was the integration of voice control to ask Amazon Alexa for humidity, switch a plant growing lamp on/off, and start the irrigation, if automation is deactivated. Click here for find the result.
I started with the technical part of the project and bought an Arduino. After some tutorials, i was firm with the software and controlling the Arduino. I ordered a wifi controller, some moisture sensors, pumps, a plant growing lamp and additional required hardware (relais shield to separate the circuts for the lamp and pumps from the Arduino, some wires and beech wood for the frame). The Arduino code of the result is provided in this tutorial, beside some information of how to use the components in your projects. The website/api code is not provided (unless the demand is very high ;) ).

 

 

 

Step One: Moisture Sensor

The first milestone was to read the humidity with my Arduino. The moisture sensor YL-69 was easy to connect with the Arduino. You need to connect he VCC pin to a GPIO pin (in my example pin 06), ground to ground and the A0 to an analog pin (in my example pin A1) of the Arduino.


Tutorial: Soil Humidity Sensor
 
byte vccPin = 6;
byte dataPin = A1;
void setup() {
 pinMode(vccPin, OUTPUT);
 digitalWrite(vccPin, LOW);
 Serial.begin(9600);
 while (!Serial);
}
int readHumidity() {
 digitalWrite(vccPin, HIGH);
 delay(500); // you need to test how long you pre-power before measurement
 int value = analogRead(dataPin);
 digitalWrite(vccPin, LOW);
 return 1023 - value;
}
void loop() {
 Serial.print("HumidityLevel (0-1023): ");
 Serial.println(readHumidity()); 
 delay(10000);
}

 

 

Step Two: Relay for Pumps and Lamp

The next goal was to install a relay shield (4 relais) for separating the circuits of the lamp, pumps and Arduino. The Arduino runs on 5V, the pumps use 12V and the plant growing lamp 230V. The shield needs to be connected to the 5V and Ground pins on the Arduino. Each relay further needs a GPIO pin of your choice to switch on and off. Lastly, you can use a jumper for VCC JC to VCC on the shield, or use an extra battery (which would be best, but i don't have any battery inside my project, yet).
It is important to understand, that my shield switches "On" with "LOW" on the pin. As soon as my pin is defined as OUTPUT, it automatically switched to active. In the code you should always switch to INPUT and LOW, if you want the relay to be off. By default, the Arduino pins are INPUT and LOW.


Tutorial: Relay Shield
Information: Why relay OUTPUT + LOW = Active?
 
 
byte pump1 = 11;
byte pump2 = 10;
void setup() {
 Serial.begin(9600);
 while (!Serial);
 pinMode(pump1, OUTPUT); // variant low/high
 digitalWrite(pump2, LOW); // variant input/output
}
void loop() {
 digitalWrite(pump1, HIGH); // pump1 deactivated
 pinMode(pump2, INPUT); // pump2 deactivated
 delay(1000);
 digitalWrite(pump1, LOW); // pump1 activated
 pinMode(pump2, OUTPUT);  // pump2 activated
 delay(1000);
}

Step Three: WiFi with ESP-01

Connecting the espressif ESP8266 ESP-01 to the Arduino for WiFi was the most difficult part. It took me hours to get the wifi running in my script.
The ESP is connected to: VCC = 3.3V, GND = GND, CH_PD = 3.3V, TX = Pin 02, RX = Pin 03. For productive usage, you should use at least a level converter from 5V to 3.3V for the pin 02 and pin 03, too. In my case, it worked fine.
Similar to the Arduino, the ESP-01 is another microcontroller. If you want both controllers to communicate, you have to use serial communication. The Arduino UNO uses by default the pins 01 and 02 for RX and TX. But they are also used for USB debugging and therefore it's suggested to include SoftwareSerial.h and define custom pins.
 
 
#include <SoftwareSerial.h>
SoftwareSerial espSerial(3,2); // RX, TX
void setup() {
 Serial.begin(9600);
 espSerial.begin(115200); // switch to 9600 after AT+UART_DEF=9600,8,1,0,0
 while (!Serial);
}
void loop() {
 if (espSerial.available()) {
   Serial.write(espSerial.read());
 }
 if (Serial.available()) {
   espSerial.write(Serial.read());
 }
}



Running the script above, you can enter AT-commands into the serial monitor and see the results. Serial communication is prone to failure, therefore i decreased the communication baud rate used by the ESP from 115200 to 9600.
Tutorial: ESP8266 + Arduino | Tutorial: General ESP8266 (german)


The script uses HTTP 1.0, because with HTTP 1.1 the bytes are part of the response. It's important to take care about the line breaks for the command to be send after AT+CIPSEND. If they are wrong, you will receive a byte send error.
 
 
#include <SoftwareSerial.h>
SoftwareSerial espSerial(3,2); // RX, TX
const char* ssid = "<YOUR-WIFI-SSID>";
const char* pass = "<YOUR-WIFI-PASSWORD>";
void setup() {
 Serial.begin(9600);
 espSerial.begin(9600);
 while(!Serial);
 while(!connectToWiFi());
 // request website and print result
 if (httpRequest("my.server.com", "/site/subsite/index.php")) {
   while (espSerial.available()) { Serial.write(espSerial.read()); }
 }
}
void loop() { // run over and over
 if (espSerial.available()) {
   Serial.write(espSerial.read());
 }
 if (Serial.available()) {
   espSerial.write(Serial.read());
 }
}
bool connectToWiFi() {
 delay(2000;)
 espSerial.setTimeout(3000);
 while (espSerial.available()) Serial.write(espSerial.read());
 Serial.println(F("[ESP] Connecting to WiFi"));
 espSerial.println(F("AT+CIPSTATUS=2"));
 if (!espSerial.find("OK")) {
   espSerial.setTimeout(10000);
   Serial.println(F("[ESP] Reset Module"));
   espSerial.println(F("AT+RST")); if (!espSerial.find("ready")) { Serial.println(F("[ESP] Reset failed")); return false; }
   Serial.println(F("[ESP] Set CWMode"));
   espSerial.println(F("AT+CWMODE=1")); if (!espSerial.find("OK")) { Serial.println(F("[ESP] Mode failed")); return false; }
   Serial.println(F("[ESP] Connect to Router"));
   espSerial.print(F("AT+CWJAP=\""));
   espSerial.print(ssid);
   espSerial.print(F("\",\""));
   espSerial.print(pass);
   espSerial.println("\"");
   if (!espSerial.find("OK")) { Serial.println(F("[ESP] WiFi connection failed")); return false; }
 }
 espSerial.setTimeout(3000);
 Serial.println(F("[ESP] WiFi is connected"));
 return true;
}
bool httpRequest(String server, String site) {
 String cmd = "";
 cmd += "GET " + site + " HTTP/1.0\r\n";
 cmd += "Host: " + server + "\r\n";
 cmd += "Connection: close";
 int cmdLength = cmd.length() + 4;
 // Serial.println(cmd);
 espSerial.print(F("AT+CIPSTART=\"TCP\",\""));
 espSerial.print(server);
 espSerial.println(F("\",80"));
 if (!espSerial.find("OK")) { Serial.println(F("[ESP] TCP Connection Error")); return false; }
 espSerial.print(F("AT+CIPSEND="));
 espSerial.println(cmdLength);
 if (!espSerial.find(findGT)) { Serial.println(F("[ESP] Send State Error")); return false; }
 espSerial.print(F("GET "));
 espSerial.print(site);
 espSerial.print(F(" HTTP/1.0\r\n"));
 espSerial.print(F("Host: "));
 espSerial.print(server);
 espSerial.print(F("\r\n"));
 espSerial.print(F("Connection: close\r\n"));
 espSerial.println();
 if (!espSerial.find(":")) { Serial.println(F("Bytes not sent")); espSerial.print(F("AT+CIPCLOSE")); return false; }
 char status[32] = {0};
 espSerial.readBytesUntil('\r', status, sizeof(status));
 if (strcmp(status, "HTTP/1.1 200 OK") != 0) { Serial.print(F("[ESP] Unexpected response: ")); Serial.println(status); return false; }
 if (!espSerial.find("\r\n\r\n")) { Serial.println(F("[ESP] Invalid response")); return false; } // Skip HTTP headers
 // if (!espSerial.find(\r\n)) { Serial.println(F("[ESP] Bytes not found")); return; } // skip bytes (for http 1.1)
 return true;
}

Step Four: The Wooden Box

The frame was planned to store all electronics and three herb pots from the supermarket. I measured the sizes of all components and structured the positions. Four moisture sensors, two pumps, the Arduino + shield, a 4x relay shield and an USB plug and some wires need to fit in the box. It was made out of beech wood, to make it strong and last waterdrops without additional glaze.



The circles were sawn out with jig saw on a self made jig saw table. The plant mounts are glued inside the circles with hot glue. The sides of the box are glued by wood glue (D3 for water resistance). Besides the eletronic, i didn't use any screws or nails beside the lower panel fixing.



For more, Visit Arduino Project Hub

No comments:

Post a Comment