B H
Published

Self watering palnter

Never worry about forgetting to water your plants again.

Beginner10 hours57
Self watering palnter

Things used in this project

Hardware components

Argon
Particle Argon
×1
0.96" OLED 64x128 Display Module
ElectroPeak 0.96" OLED 64x128 Display Module
×1
Servo Module (Generic)
×1
SOIL MOISTURE SENSOR
×1
Grove - Dust Sensor(PPD42NS)
Seeed Grove - Dust Sensor(PPD42NS)
×1
Grove - Air quality sensor v1.3
Seeed Grove - Air quality sensor v1.3
×1
Through Hole Resistor, 2.21 kohm
Through Hole Resistor, 2.21 kohm
×1
Through Hole Resistor, 47 ohm
Through Hole Resistor, 47 ohm
×1
General Purpose Transistor NPN
General Purpose Transistor NPN
×1

Software apps and online services

Visual Studio 2017
Microsoft Visual Studio 2017

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Custom parts and enclosures

Enclosure

This is the enclosure for the hardware and wires

3d printed flower pot

internet dash board

This is the dashboard where you can monitor conditions, and manually water your plant

Code

Untitled file

C/C++
/*
 * Project L14_02
 * Description: moisture sensor
 * Author: Benjamin hansen  
 * Date: 08/10/2020
 */
#include <Adafruit_MQTT.h>

#include <Adafruit_MQTT/Adafruit_MQTT.h>
#include <Adafruit_MQTT/Adafruit_MQTT_SPARK.h> 
#include <Adafruit_MQTT/Adafruit_MQTT.h>

/************************* Adafruit.io Setup *********************************/ 
#define AIO_SERVER      "io.adafruit.com" 
#define AIO_SERVERPORT  1883                   // use 8883 for SSL 
#define AIO_USERNAME  "BenjaKH"
#define AIO_KEY       "aio_KKGV98C9rUd8ZHvj2OGgx3KihYMz"


/************ 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 GraftLineFeed = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/graftineFeed"); 
Adafruit_MQTT_Publish AtmosphericPressureFeed = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Atmospheric_Pressure_Feed");
Adafruit_MQTT_Publish HumidityFeed = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Humidity_Feed");
Adafruit_MQTT_Publish TematureFeed = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Temature_Feed");
Adafruit_MQTT_Publish MoistureFeed = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Moisture_Feed");
Adafruit_MQTT_Publish AirQualitySensorFeed = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Air_Quality_Sensor_Feed");
Adafruit_MQTT_Publish DustSensorFeed = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Dust_Sensor_Feed");
// Adafruit_MQTT_Publish variable1 = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/variable1"); //this is the feed template
Adafruit_MQTT_Subscribe WaterPlantButton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/WaterPlantButton");

#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Air_Quality_Sensor.h>
#include <math.h>

#define BME_SCK D4
#define BME_MISO D3
#define BME_MOSI D2
#define BME_CS D5
#define SEALEVELPRESSURE_HPA (1013.25)
#define OLED_RESET D4

Adafruit_SSD1306 display(OLED_RESET);
Adafruit_BME280 bme;

String DateTime, TimeOnly;

AirQualitySensor airSensor(A2);

unsigned long last;
int mValue, count, currentTime, lastSecond, variable1, lastTime, quality;
const int MoistureSensor = A1;
int Pump = D6;
unsigned long delayTime;
float humidRH, pressPA, tempC, tempF, hpa, inHg;
float value;
//dust sensor variables
int dustSensor = A0;
unsigned long duration;
unsigned long starttime;
unsigned long sampletime_ms = 500;
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;

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

  int quality = airSensor.slope();

  mqtt.subscribe(&WaterPlantButton);
  pinMode(dustSensor,INPUT);
  pinMode(MoistureSensor, INPUT);
  pinMode(Pump, OUTPUT);
  sync_my_time();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
  display.display(); // show splashscreen
  delay(2000);
  display.clearDisplay(); 
  Serial.print("Hello");
  BMEsetup();
  initAirSensor();
}

void loop() {
  currentTime = millis();
  DateTime = Time.timeStr();
  TimeOnly = DateTime.substring(11, 19);
  if((currentTime - lastSecond) >1000){
    printValues();
    displayValues();
    lastSecond = millis();
    }
  BMEloop();
  mValueFunction();
  MQTT_connect();
  variable1 = rand() % 100;
  MQTTping();
  adafruitPublishing();
  WaterPlantButtonFunction();
  ifSoilDryWater();
  dustSensorLoop();
}

void sync_my_time() {
  String DateTime, TimeOnly;
  Time.zone (-6); 
  Particle.syncTime();
  waitUntil(Particle.syncTimeDone);
}

void BMEsetup(){
      while (!Serial); // time to get serial running
    Serial.println(F("BME280 test"));
    unsigned status;
    // default settings
    // (you can also pass in a Wire library object like &Wire2)
    status = bme.begin();
    if (!status)
    {
        Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
        Serial.print("SensorID was: 0x");
        Serial.println(bme.sensorID(), 16);
        Serial.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
        Serial.print("   ID of 0x56-0x58 represents a BMP 280,\n");
        Serial.print("        ID of 0x60 represents a BME 280.\n");
        Serial.print("        ID of 0x61 represents a BME 680.\n");
        while (1)
            ;
    }
}

void printValues(){

    Serial.println(TimeOnly);

    Serial.print("Temperature = ");
    Serial.print(bme.readTemperature());
    Serial.println(" *C");

    Serial.print("Pressure = ");

    Serial.print(bme.readPressure() / 100.0F);
    Serial.println(" hPa");

    Serial.print("Approx. Altitude = ");
    Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    Serial.println(" m");

    Serial.print("Humidity = ");
    Serial.print(bme.readHumidity());
    Serial.println(" %");

    Serial.print("Moisture level= ");
    Serial.print(mValue);
    Serial.println(" ");

    AirSensorPrint();

    Serial.print("Dust particle Ratio is ");
    Serial.print(concentration);
    Serial.println(" ");

    Serial.println();
}
float CtoF(float IN) {
  return (IN * 1.8) + 32;
}

float PressCon(float P){
  return (0.03 * P);
}
void displayValues(void) {
  static int t = 0;
  // delay(2000);
  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.println(TimeOnly);
  display.setCursor(0,16);
  if (t == 0){
    display.printf("Atomspheric pressure is %0.2f inches mercury. \n \n", inHg);
  }
  if (t == 1){
    display.printf("Humidity is %0.2f percent. \n \n", humidRH);
  }
  if (t == 2){
    display.printf("Temperature right now is %0.2f , F. \n \n", tempF);
  }
  if (t == 3){
    display.printf("Moisure value is %i. \n \n", mValue);
  }
  if (t == 4){
    AirSensorDisplay();
  }
  if (t == 5){
    display.printf("The Particual ratio is %i, \n \n", concentration);
  }
  display.display();
    t++;
    if (t > 5){
    t = 0; 
  }
}
void BMEloop(){
  pressPA = bme.readPressure() / 100.0F;
  inHg = PressCon(pressPA);
  humidRH = bme.readHumidity();
  tempC = bme.readTemperature();
  tempF = CtoF(tempC); 
}
// 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 adafruitPublishing(){
    if((millis()-lastTime > 120000)) {
    if(mqtt.Update()) {
      AtmosphericPressureFeed.publish(inHg);
      Serial.printf("Publishing %0.2f \n", inHg); 
       HumidityFeed.publish(humidRH);
       TematureFeed.publish(tempF);
       MoistureFeed.publish(mValue);
       AirQualitySensorFeed.publish(airSensor.getValue());
       DustSensorFeed.publish(concentration);
             } 
    lastTime = millis();
  }
}
void MQTTping(){
  if ((millis()-last)>120000) {
      Serial.printf("Pinging MQTT \n");
      if(! mqtt.ping()) {
        Serial.printf("Disconnecting \n");
        mqtt.disconnect();
      }
      last = millis();
  }
}
void waterPlant(){
  Serial.println("Plant is being watered");
  digitalWrite(Pump, HIGH);
  delay(1000);
  digitalWrite(Pump, LOW);
  delay(1000);
}
void WaterPlantButtonFunction(){
  Adafruit_MQTT_Subscribe *subscription; 
  while ((subscription = mqtt.readSubscription(10000))) {
    if (subscription == &WaterPlantButton) {
      value = atof((char *)WaterPlantButton.lastread);
      if (value == 1){
      waterPlant();
      }
    }
  }
}
void ifSoilDryWater(){
  if (mValue > 2500){
    waterPlant();
  }
}
void mValueFunction(){
  mValue = analogRead(MoistureSensor);
}
void initAirSensor(){

  
  Serial.println("Waiting sensor to init...");
  delay(20000);
  
  if (airSensor.init()) {
    Serial.println("Sensor ready.");
  }
  else {
    Serial.println("Sensor ERROR!");
  }
}
void AirSensorPrint(){
  Serial.print("Air quality value: ");
  Serial.println(airSensor.getValue());
  
  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.");
  }
}
void AirSensorDisplay(){
  display.print("Air quality value: ");
  display.println(airSensor.getValue());
  
  if (quality == AirQualitySensor::FORCE_SIGNAL) {
    display.println("High pollution! Force signal active.");
  }
  else if (quality == AirQualitySensor::HIGH_POLLUTION) {
    display.println("High pollution!");
  }
  else if (quality == AirQualitySensor::LOW_POLLUTION) {
    display.println("Low pollution!");
  }
  else if (quality == AirQualitySensor::FRESH_AIR) {
    display.println("Fresh air.");
  }
}
void dustSensorLoop(){

PlantWatering

Credits

B H

B H

1 project • 3 followers

Comments

Add projectSign up / Login