Constance
Published

Self Watering Flower Pot

This system keeps my plant automatically/remotely nurtured/nourished and is convenient for my busy lifestyle.

BeginnerShowcase (no instructions)20 hours271
Self Watering Flower Pot

Things used in this project

Hardware components

Photon
Particle Photon
×1
0.96" OLED 64x128 Display Module
ElectroPeak 0.96" OLED 64x128 Display Module
×1
Gravity: I2C BME680 Environmental Sensor
DFRobot Gravity: I2C BME680 Environmental Sensor
×1
Grove - Dust Sensor(PPD42NS)
Seeed Studio Grove - Dust Sensor(PPD42NS)
×1
Grove - Air quality sensor v1.3
Seeed Studio Grove - Air quality sensor v1.3
×1
Capacitor 470 µF
Capacitor 470 µF
×1
DC motor (generic)
×1
Grove - Relay
Seeed Studio Grove - Relay
×1
Software Adafruit.IO Dashboard
×1
software corel draw
×1

Story

Read more

Schematics

Fritzing Diagram

Once the project was completed, the OLED was removed from the breadboard and attached to the back of the wooden encasement.

Code

L14_04_PlantWater.ino

C/C++
This system will automatically water my plant by reading the moisture level from the moisture sensor. A manual button has also been created in AdafruitIO; I can water my plant remotely if necessary.
/*
 * Project L14_04_PlantWater
 * Description: Watering system using
 * Adafruit.io to document changes
 * Author: Constance
 * Date:  11/9/2020
 */


    #include <Air_Quality_Sensor.h>
    #include "credentials.h"
    #include <Adafruit_MQTT.h>
    #include "Adafruit_MQTT/Adafruit_MQTT.h" 
    #include "Adafruit_MQTT/Adafruit_MQTT_SPARK.h" 
    #include "Adafruit_MQTT/Adafruit_MQTT.h" 
    #include "Adafruit_BME280.h"    
    #include <Adafruit_SSD1306.h>//OLED Library
    

    #define OLED_RESET D4
    Adafruit_SSD1306 display(OLED_RESET);
    const int pinMoisture = A2;
    int moistureRead;
    String DateTime , TimeOnly ;
    char currentDateTime [25] , currentTime [9];
    AirQualitySensor airSensor(A0);
    const int pinDust = A4;
    
    unsigned long duration;
    unsigned long starttime;
    unsigned long sampletime_ms = 30000;//sampe 30s ;
    unsigned long lowpulseoccupancy = 0;
    float ratio = 0;
    const int RELAY = D10;
    
    Adafruit_BME280 bme;

    float varTempC;
    float varPressPA;
    float varHumidRH;
    float varTempF;
    float varPressPAinHG;
    int varAirQuality;
    float varDust;
    float concentration = 0;

    int status;


    /************ Global State (you don't need to change this!) ***   ***************/ 
    TCPClient TheClient; 

    // Setup the MQTT client class by passing in the WiFi client and MQTT server and login details. 
    Adafruit_MQTT_SPARK mqtt(&TheClient,AIO_SERVER,AIO_SERVERPORT,AIO_USERNAME,AIO_KEY); 



    /****************************** Feeds ***************************************/ 
    // Setup Feeds to publish or subscribe 
    // Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname> 
    Adafruit_MQTT_Subscribe feedvarbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/FeedButton"); //pulling from
    Adafruit_MQTT_Publish feedvartemperature = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/FeedTemperature");  //sending to
    Adafruit_MQTT_Publish feedvarhumidrh = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/FeedHumidity");  //sending to
    Adafruit_MQTT_Publish feedvarpressurepainhg = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/FeedPressure");  //sending to
    Adafruit_MQTT_Publish feedvarmoistureread = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/FeedMoisture");  //sending to
    Adafruit_MQTT_Publish feedvarairquality = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/FeedAirQuality");  //sending to
    Adafruit_MQTT_Publish feedvardust = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/FeedDust");  //sending to
    
    /************Declare Variables*************/
    unsigned long last, lastTime;
    int buttonValue;    
    const int buttonPin = D7;
    

void setup() {
    Serial.begin(9600);

    //Air Quality Setup
    delay(100); //wait for Serial Monitor to startup

    Serial.println("Waiting sensor to init...");
    delay(20000);
  
  if (airSensor.init()) {
    Serial.println("Sensor ready.");
  }
  else {
    Serial.println("Sensor ERROR!");
  }

    //OLED setup 
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
  // init done 
    display.display();
    delay(2000); // Pause for 2 seconds
    display.clearDisplay();    
    display.display();
    delay(2000);

    pinMode(pinMoisture,INPUT);
    sync_my_time () ; // Ensure the Argon clock is up to date

    pinMode(pinDust,INPUT);
    starttime = millis();//get the current time;
    

    status = bme.begin(0x76); //intialize BME
   if(status==false){
    Serial.printf("failed to open BME");
   }

    // Setup MQTT subscription for onoff feed.
    //mqtt.subscribe(&TempF);
    mqtt.subscribe(&feedvarbutton);
    

    pinMode(RELAY,OUTPUT);//WATERPUMP INITIALIZED
}

void loop() {
      MQTT_connect();
      pingMQTT();
      getBMEData();
      getCurrentTime();    
      getMoisture();
      getAirQuality();
      getDust();
      displayOLEDData();
      publishData();
      getButtonData();  
    
}

    // Function to connect and reconnect as necessary to the MQTT server.
    // Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
    int8_t ret;
    
    // Stop if already connected.
    if (mqtt.connected()) {
        return;
    }
    
    Serial.print("Connecting to MQTT... ");
    
    while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
        Serial.println(mqtt.connectErrorString(ret));
        Serial.println("Retrying MQTT connection in 5 seconds...");
        mqtt.disconnect();
        delay(5000);  // wait 5 seconds
    }
    Serial.println("MQTT Connected!");
}

void pingMQTT(){
    if ((millis()-last)>120000) {
        Serial.printf("Pinging MQTT \n");
        if(! mqtt.ping()) {
            Serial.printf("Disconnecting \n");
            mqtt.disconnect();
        }
        last = millis();
    }
}

void getButtonData(){
    Adafruit_MQTT_Subscribe *subscription;
    while ((subscription = mqtt.readSubscription(3000))) {
        if (subscription == &feedvarbutton) {
            buttonValue = atoi((char *)feedvarbutton.lastread);
            Serial.printf("buttonValue%i\n",buttonValue);
            if(buttonValue==1) {
                digitalWrite (RELAY, HIGH); //turn pump on
                delay(1000);
                digitalWrite(RELAY,LOW);
            }
            
                   

        }
    }
}

    //BME FUNCTIONS
void getBMEData(){
    //Read value from sensors
    varTempC = bme.readTemperature();
    varPressPA = bme.readPressure()/100.0; 
    varHumidRH = bme.readHumidity();
    //convert Celsius to F 
    varTempF = ((varTempC*9)/5)+32;
    //convert pascuals to inHg..inches of mercury
     varPressPAinHG = (varPressPA/33.86);
   
}

    //OLED FUNCTIONS: display info from BME
void displayOLEDData(){
      display.clearDisplay();    
      display.setTextSize(1);             // Normal 1:1 pixel scale
      display.setTextColor(WHITE);        // Draw white text
      display.setCursor(0,0);             // Start at top-left corner
      //display.printf("Temp = %0.20f \n Pressure = %0.2f\n Humidity = %0.2f \n",varTempC,varPressPA,varHumidRH);     
      //Serial.printf("Temp = %0.20f \n,Pressure = %0.2f\n,Humidity = %0.2f \n",varTempC,varPressPA,varHumidRH); 
      display.printf("Temp = %0.2f \n Pressure = %0.2f\n Humidity = %0.2f \n",varTempF,varPressPAinHG,varHumidRH);  
      Serial.printf("Temp = %0.2f \n,Pressure = %0.2f\n,Humidity = %0.2f \n",varTempF,varPressPAinHG,varHumidRH); 
      display.printf("moist= %i\n",moistureRead);
      display.printf("Air = %i\n",varAirQuality);
      display.printf("Dust = %f\n",concentration);
      display.printf(" Time is %s\n", currentTime );  
      display.display();
      delay(2000);
}

      //Moisture Setup
void getMoisture(){    // Draw 'stylized' characters
    moistureRead = analogRead(pinMoisture);  
    Serial.printf("pinMoisture Read %i\n",moistureRead);
    
    delay(2000);    
  
  }

      //print values to OLED

      //Date and Time
void sync_my_time () {
  Time.zone ( -7) ; // Set Time Zone to MST (UTC -7)
  Particle.syncTime () ;
  waitUntil ( Particle.syncTimeDone );
}

void getCurrentTime(){
   DateTime = Time.timeStr () ; // Get Current Time
   TimeOnly = DateTime.substring (11 ,19) ; // Extract the Time from the DateTime String

  // Convert String to char arrays - this is needed for formatted print
  DateTime.toCharArray ( currentDateTime ,25) ;
  TimeOnly.toCharArray ( currentTime ,9) ;

  // Print using formatted print
  Serial.printf (" Date and time is %s\n", currentDateTime );
  Serial.printf (" Time is %s\n", currentTime );
  } 

  //Air Quality Sensor 
void getAirQuality(){
     int quality = airSensor.slope();
    varAirQuality = airSensor.getValue();
  Serial.print("Sensor value: ");
  Serial.println(varAirQuality);
  
  if (quality == AirQualitySensor::FORCE_SIGNAL) {
    Serial.println("High pollution! Force signal active.");
  }
  else if (quality == AirQualitySensor::HIGH_POLLUTION) {
    Serial.println("High pollution!");
  }
  else if (quality == AirQualitySensor::LOW_POLLUTION) {
    Serial.println("Low pollution!");
  }
  else if (quality == AirQualitySensor::FRESH_AIR) {
    Serial.println("Fresh air.");
  }
  
  delay(1000);
  }

  //Publish Data
 void publishData(){
    //Publish temp data to Adafruit BME Data
    //Read value from sensors 
    if((millis()-lastTime > 30000)) {
        if(mqtt.Update()) {        
            feedvartemperature.publish(varTempF);
            feedvarhumidrh.publish(varHumidRH);
            feedvarpressurepainhg.publish(varPressPAinHG);
            feedvarmoistureread.publish(moistureRead);
            feedvarairquality.publish(varAirQuality);
            feedvardust.publish(concentration);
            Serial.printf("Publishing %i \n",varTempF); 
            Serial.printf("Publishing %i \n",varHumidRH);
            Serial.printf("Publishing %i \n",varPressPAinHG); 
            Serial.printf("Publishing %i \n",moistureRead);
            Serial.printf("Publishing %i \n",varAirQuality);
            Serial.printf("Publishing %i \n",varDust);
            
        } 
        lastTime = millis();
    } 

  }

  //Start Dust Data Coding
  void getDust() {
    duration = pulseIn(pinDust, LOW);
    lowpulseoccupancy = lowpulseoccupancy+duration;

    if((millis()-starttime) >= sampletime_ms)//if the sample time==30s
    {
    ratio = lowpulseoccupancy/(sampletime_ms*10.0);//Integer percentage 0=8gt;100
    concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62;//using spec sheet curve
    Serial.print("concentration=");
    Serial.print(concentration);
    Serial.println("pcs/0.01cf");
    Serial.println("\n");
    lowpulseoccupancy = 0;
    starttime = millis();
    
    }
  }

  

    

Credits

Constance

Constance

3 projects • 4 followers
I am completely new to coding/technology. I am enrolled in a 10 week IOT Bootcamp (http://deepdivecoding.com/iot).

Comments

Add projectSign up / Login