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 hours354
Self Watering Flower Pot

Things used in this project

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
3 projects • 6 followers
I am completely new to coding/technology. I am enrolled in a 10 week IOT Bootcamp (http://deepdivecoding.com/iot).

Comments