Project showcase

Plant Assistant © GPL3+

You can check on your plant with your smartphone to determine if it has enough water, fertillizer, sunlight, and if the air quality is good.

  • 2,494 views
  • 0 comments
  • 28 respects

Components and supplies

Apps and online services

About this project

Story:

Our project is using your smartphone to see if your plant has enough water, fertilizer, sunlight, and if the air quality, humidity and temperature are good in the room. If there is not enough water or fertilizer, it will automatically give more. We have a water tank with a water level meter, so we can see if there is still enough water in it to give to the plant. We did the same for the fertilizer. We have a soil moisture meter to know if the ground is too dry. We also used, for fun, a birthday card that plays music for the plant. We used an air quality sensor to know the air quality, a TPH sensor to know the temperature and humidity, and a sunlight sensor to know the light level in the room.

Ideation:

When we wanted to participate, we had to choose a topic, so we choose Health & Care. Then we started thinking what we could do first. We wanted to make a small conservatory, but that was too complicated, so we got the idea to make a plant automated.

Water level meter:

Fertilizer level meter:

Soil moisture meter:

Prints of the meters:

Code

Arduino program Arduino
Arduino program that controles all the sensors
#include <SoftwareSerial.h>
#include "ATT_IOT_FONA.h"
#include "ATT_MQTT.h"

#include "ATT_IOT_GPRS.h"
#include <SPI.h>

#define deviceId "x0Oq5Nf4rbnQZJC3YcWYzbJb"
#define clientId "vitronics_KJOcxvkQ"
#define clientKey "DGfg9VmT"

#define FONA_APN       "web.pro.be"
#define FONA_USERNAME  ""
#define FONA_PASSWORD  ""

#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 5
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);

ATTDevice Device(deviceId, clientId, clientKey);
#define httpServer "api.AllThingsTalk.io"       
#define mqttServer httpServer

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

#define voltageFlipPin1 6
#define voltageFlipPin2 5
#define sensorPin 1

#include "Arduino.h"
#include "SI114X.h"


SI114X SI1145 = SI114X();

Adafruit_BME280 bme;
unsigned long newTime;
unsigned long oldTime;  
int pinTemp = 15;
int pinPRES = 16;
int pinHUM = 17;
int pinSL = 18;
int aiQ = 19;
int pinGVS = 0;
int avg = 0;

int flipTimer = 1000;

int niveauPin =8;
int niveau = 0;
float xniveau = 0;
const int pinNiveauSensor = A3;

int niveauPin2 =7;
int niveau2 = 0;
float xniveau2 = 0;
const int pinNiveauSensor2 = A2;
int motorPin = 9;
int motorPin2 = 10;
int motorPin3 = 11;
int lamp = 12;
int kaart = 13;
int B = 0;
int water;
int TSetMest;
int wacht;
int delayStuur;

void callback(const char* topic, const char* payload, unsigned int length);

void setup() {
  pinMode(niveauPin, OUTPUT);
  pinMode(niveauPin2, OUTPUT);
  pinMode(motorPin, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(lamp, OUTPUT);
  pinMode(kaart,OUTPUT);
  pinMode(voltageFlipPin1, OUTPUT);
  pinMode(voltageFlipPin2, OUTPUT);
  fonaSS.begin(19200);
  Serial.begin(57600);
  
  digitalWrite(motorPin, HIGH);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(lamp, HIGH);
  while (!SI1145.Begin()) {
    delay(1000);
  }

  bool status;
    
    // default settings
    status = bme.begin();
    
  while(!Serial && millis() < 2000);                       // Make sure you see all output on the monitor. After 2 sec, it will skip this step, so that the board can also work without being connected to a pc  
  
    while (! Device.InitGPRS(fonaSS, FONA_RST, F(FONA_APN), F(FONA_USERNAME), F(FONA_PASSWORD))) {
        Serial.println("Retrying FONA");
    }
    Serial.println(F("Connected to Cellular!"));
    delay(2000);                                            // wait a few seconds to stabilize connection
  
    while(!Device.Connect(httpServer))                    // connect the device with the IOT platform.
        Serial.println("retrying");
    Device.AddAsset(pinTemp, "temperature", "rotary switch",false, "{\"type\": \"integer\", \"minimum\": -10.0, \"maximum\": 50.0}");     // data input to Allthingstalk app
    Device.AddAsset(pinPRES, "presure", "rotary switch",false, "{\"type\": \"integer\", \"minimum\": 0, \"maximum\": 1200}");
    Device.AddAsset(pinHUM, "vochtigheid", "rotary switch",false, "{\"type\": \"integer\", \"minimum\": 0, \"maximum\": 100}");
    Device.AddAsset(niveauPin, "niveau", "rotary switch",false, "{\"type\": \"integer\", \"minimum\": 0, \"maximum\": 100}");
    Device.AddAsset(niveauPin2, "niveau Mest", "rotary switch",false, "{\"type\": \"integer\", \"minimum\": 0, \"maximum\": 100}");
    Device.AddAsset(pinGVS, "GV", "rotary switch",false, "{\"type\": \"integer\", \"minimum\": 0, \"maximum\": 100}");
    Device.AddAsset(pinSL, "licht sensor", "rotary switch",false, "{\"type\": \"integer\", \"minimum\": 0, \"maximum\": 1000}");
    Device.AddAsset(aiQ, "lucht qualiteit", "rotary switch",false, "{\"type\": \"integer\", \"minimum\": 0, \"maximum\": 3}");
    Device.AddAsset(motorPin, "motor1", "light emitting diode", true, "boolean");
    Device.AddAsset(motorPin2, "motor2", "light emitting diode", true, "boolean");
    Device.AddAsset(motorPin3, "motor3", "light emitting diode", true, "boolean");
    Device.AddAsset(lamp, "lamp", "light emitting diode", true, "boolean");
    Device.AddAsset(kaart, "kaart", "light emitting diode", true, "boolean");
    while(!Device.Subscribe(callback, mqttServer, 1883))                          // make certain that we can receive message from the iot platform (activate mqtt)
        Serial.println("retrying");
}

void loop() {
  int x = bme.readTemperature();    // measure temperature from TPH meter
  Device.Send(String(x), pinTemp);
  delay(1000);

  int y = bme.readPressure() / 100.0F;   // measure pressure from TPH meter
  Device.Send(String(y), pinPRES);
  delay(1000);
  
  int z = bme.readHumidity();   // measure humidity from TPH meter
  Device.Send(String(z), pinHUM);
  delay(1000);

  digitalWrite(niveauPin, HIGH);        //  water level meter activates
  xniveau = analogRead(pinNiveauSensor);    // measure water level
  delay(5);
  
  digitalWrite(niveauPin, LOW);   //  water level meter deactivates
  
  xniveau = (xniveau*5.0)/1023.0;     // from analoge to value from 0-100
  if(xniveau<1.20){
    niveau = 0;
  }
  else if (xniveau<2.20){
    niveau = 10;
  }
  else if(xniveau<2.70){
    niveau = 25;
  }
   else if(xniveau<3.30){
    niveau = 50;
  }
  else if(xniveau<5){
    niveau = 100;
  }
  Device.Send(String(niveau),niveauPin);
  delay(1000);
  digitalWrite(niveauPin2, HIGH);   //  fertillizer level meter activates
  xniveau2 = analogRead(pinNiveauSensor2);  // measure fertillizer level
  delay(5);
  
  digitalWrite(niveauPin2, LOW);  //  fertillizer level meter deactivates
  
  xniveau2 = (xniveau2*5.0)/1023.0; // from analoge to value from 0-100
  if(xniveau2<1.40){
    niveau2 = 0;
  }
  else if(xniveau2<3.80){
    niveau2 = 50;
  }
  else if(xniveau2<5){
    niveau2 = 100;
  }
  Device.Send(String(niveau2),niveauPin2);
  delay(1000);
  setSensorPolarity(true);    // activated soil moisture sensor
  delay(flipTimer);
  
  int val1 = analogRead(sensorPin);   // measure of soil moisture
  delay(flipTimer);
   
  setSensorPolarity(false);   // switch polarity of the soil moisture sensor
  delay(flipTimer);
   
  // invert the reading
  int val2 = 1023 - analogRead(sensorPin);  // measure of soil moisture
  //
  reportLevels(val1,val2);    // compare 2 values
  Device.Send(String(avg),pinGVS);
  delay(1000);
  
  int B = SI1145.ReadVisible();   // sunlight measuring
  Device.Send(String(B),pinSL);
  delay(1000);
  
  Device.Process(); 
}

void setSensorPolarity(boolean flip){   // activate or switch polarity of the soil moisture sensor
  if(flip){
    digitalWrite(voltageFlipPin1, HIGH);
    digitalWrite(voltageFlipPin2, LOW);
  }else{
    digitalWrite(voltageFlipPin1, LOW);
    digitalWrite(voltageFlipPin2, HIGH);
  }
}

void reportLevels(int val1,int val2){   // compare 2 values
  
  avg = (val1 + val2) / 2;
  avg=map(avg,0,1000,0,100);
  
}

void callback(const char* topic, const char* payload, unsigned int length) 
{ 
  String msgString(payload);                              //convert to string object, so we can easily compare and modify the string.
  int* idOut = NULL;
  idOut = &motorPin;

  idOut = &motorPin2;

  idOut = &motorPin3;

  idOut = &lamp;

  idOut = &kaart;
  int pinNr = Device.GetPinNr(topic, strlen(topic));
    
  Serial.print("Payload: ");                            //show some debugging.
    Serial.println(msgString);
    Serial.print("topic: ");
    Serial.println(topic);
    Serial.print("pin: ");
    Serial.println(pinNr);
    
    if (pinNr == motorPin)                      //check for which asset we received an actuator so that we can perform the correct actuation.
    {
        msgString.toLowerCase();                            //to make certain that our comparison later on works ok (it could be that a 'True' or 'False' was sent)
        if (msgString == "false") {
            digitalWrite(motorPin, LOW);//change the led
            Device.Send(String("true"),motorPin);
            delay(1000);
            digitalWrite(motorPin, HIGH);
            digitalWrite(motorPin2, LOW);
            delay(20000);
            digitalWrite(motorPin2, HIGH);
            digitalWrite(motorPin3, LOW);
            delay(21000);
            digitalWrite(motorPin3, HIGH);   
            idOut = &motorPin;                                
        }
        else if (msgString == "true") {
            digitalWrite(motorPin, HIGH);
            idOut = &motorPin;
        }
    }

  if (pinNr == motorPin2)                      //check for which asset we received an actuator so that we can perform the correct actuation.
    {
        msgString.toLowerCase();                            //to make certain that our comparison later on works ok (it could be that a 'True' or 'False' was sent)
        if (msgString == "false") {
            digitalWrite(motorPin2, LOW);                      //change the led    
            idOut = &motorPin2;                                
        }
        else if (msgString == "true") {
            digitalWrite(motorPin2, HIGH);
            idOut = &motorPin2;
        }
    }
    if (pinNr == motorPin3)                      //check for which asset we received an actuator so that we can perform the correct actuation.
    {
        msgString.toLowerCase();                            //to make certain that our comparison later on works ok (it could be that a 'True' or 'False' was sent)
        if (msgString == "false") {
            digitalWrite(motorPin3, LOW);                      //change the led    
            idOut = &motorPin3;                                
        }
        else if (msgString == "true") {
            digitalWrite(motorPin3, HIGH);
            idOut = &motorPin3;
        }
    }

    if (pinNr == lamp)                      //check for which asset we received an actuator so that we can perform the correct actuation.
    {
        msgString.toLowerCase();                            //to make certain that our comparison later on works ok (it could be that a 'True' or 'False' was sent)
        if (msgString == "false") {
            digitalWrite(lamp, LOW);                      //change the led    
            idOut = &lamp;                                
        }
        else if (msgString == "true") {
            digitalWrite(lamp, HIGH);
            idOut = &lamp;
        }
    }

    if (pinNr == kaart)                      //check for which asset we received an actuator so that we can perform the correct actuation.
    {
        msgString.toLowerCase();                            //to make certain that our comparison later on works ok (it could be that a 'True' or 'False' was sent)
        if (msgString == "false") {
            digitalWrite(kaart, LOW);                      //change the led    
            idOut = &kaart;                                
        }
        else if (msgString == "true") {
            digitalWrite(kaart, HIGH);
            idOut = &kaart;
        }
    }

    
  if(idOut != NULL)                                       //also let the iot platform know that the operation was succesful: give it some feedback. This also allows the iot to update the GUI's correctly & run scenarios.
    Device.Send(msgString, *idOut);  
}

Schematics

Waterlevelmeter Shematic
this is the schematic for a waterlevelmeter we created to know if there is still enough water to give for the plant
Iotopia print apudbkjrls
Waterlevelmeter Board
This is the print we created here you can see wich components we used
Iotopia print 2 cdku93vl0m

Comments

Similar projects you might like

Arduino Bluetooth Basic Tutorial

by Mayoogh Girish

  • 454,938 views
  • 42 comments
  • 239 respects

Home Automation Using Raspberry Pi 2 And Windows 10 IoT

Project tutorial by Anurag S. Vasanwala

  • 285,543 views
  • 95 comments
  • 672 respects

Security Access Using RFID Reader

by Aritro Mukherjee

  • 229,398 views
  • 38 comments
  • 236 respects

OpenCat

Project in progress by Team Petoi

  • 196,006 views
  • 154 comments
  • 1,363 respects
Add projectSign up / Login