H2Whoa

This is H2whoa An indoor plant watering and room monitoring system. How I put it all together.

projectImage

Things used in this project

Hardware components

HARDWARE LIST
1 Particle Argon
1 DFRobot Gravity: Analog Capacitive Soil Moisture Sensor- Corrosion Resistant
1 Seeed Grove - Dust Sensor(PPD42NS)
1 Seeed Grove - Air quality sensor v1.3
1 Seeed Grove - Relay

Story

 

This is H2whoa

 

An indoor plant watering and room monitoring system.

 

Here's what I used to put it all together.

 

BME280

 

Reads humidity, pressure, and, temperature

 

Measurements are either triggered by the user manually or performed automatically in regular intervals

 

The BME can be used for:

 

skin detection

 

Home automation control

 

Indoor navigation like going from one floor to another

 

In my project I'll be using it to read temperature, humidity, and barometric pressure

 

In general, a rising barometer means improving weather

 

In general, a falling barometer means worsening weather

 

When atmospheric pressure drops suddenly, this usually indicates that a storm is on its way.

 

When atmospheric pressure remains steady, there will likely be no immediate change in the weather

 

Moisture sensor

 

Uses the capacitive method to measure the moisture in the soil

 

Made from non-corrosive materials and outputs an analog signal and based on that reading we can gauge our soil moisture level

 

Dust sensor

 

Gauges the dust levels through a process using heat and light

 

Gives a good indication of the air quality in an environment by measuring the dust concentration

 

The unit must be Kept it upright to operate efficiently

 

The Grove air quality sensor

 

Monitors for harmful gases such as carbon monoxide, alcohol, formaldehyde and so on

 

Although it doesn’t output the presence of WHICH pollutant has been detected, it registers a reading indicating the presence of 1, some, or all, the monitored gases.

 

Water pump and relay

 

-The pump used for watering our plant requires more power than the Argon can supply directly, so a relay to step up to the pump requirement is used

 

Just like humans, for plants to grow and thrive, the environment of which it lives will prove the quality of life.

 

With the data collected from the chosen environmental sensors in this project, I'm able to then represent accurate, useful, information that helps make informed decisions concerning the ideal environment for the plant life.````

 

How I chose to represent my data is through an easy to read online visual dashboard. It provides updated information down to the minute.

 

OLED

 

Grove - OLED Display - I2c

 

In addition to the online dashboard, I've installed a Grove OLED display with sensor readings

 

Initially I wanted to make each reading displayed differently just for the sake of diversity. By doing that, my dashboard looked "cool" but it took more effort to discern what I was actually looking at and what any of it meant. I revised it to be more natural, when we look at our car dashboards the temperature, speed, and other gauges are mostly circular, a low side, high side, and typically we desire to be in between those same with the dashboard I've created.

 

BaroqueBrother/H2_Whoa (github.com)

Schematics

H2Whoa Schematic

projectImage

H2Whoa Fritzing

projectImage

代码

H2Whoa

C/C++

CODE
/*
 * Project H2Whoa
 * Description:
 * Author:
 * Date:
 */
#include <SPI.h>
#include <Wire.h>

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

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

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

#include "Air_Quality_Sensor.h"


TCPClient TheClient;
Adafruit_MQTT_SPARK mqtt(&TheClient,AIO_SERVER,AIO_SERVERPORT,AIO_USERNAME,AIO_KEY);
Adafruit_MQTT_Publish bmeTemp = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Ambient Temperature");
Adafruit_MQTT_Publish bmeHumidity = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Humidity");
Adafruit_MQTT_Publish bmeAirPressure = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Air Pressure");
Adafruit_MQTT_Publish soilSaturation = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Soil Saturation");
Adafruit_MQTT_Publish dustParticulates = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Dust Particulates");
Adafruit_MQTT_Publish airQuality = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Air Quality");
Adafruit_MQTT_Subscribe waterMe = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/H20");


#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

Adafruit_BME280 bme;

bool status;
uint currentTime;
int onOrOff,ambientTemp;
const int relayPin = A5;
const int soilPin = A4;
const int dustPin = A3;
float soilReading;
float temperature;
float humidRH;
float pressPA;
float pressInhg;
uint last;
float inhg = .000295;
unsigned long duration;
unsigned long starttime;
unsigned long sampletime = 30000;
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;
AirQualitySensor sensor = (A2);
int quanAirValue;
int quality;
String DateTime, TimeOnly;




void setup() {
    Serial.begin(9600);
    if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c)){
      for(;;);
    }
    WiFi.connect();
    while(WiFi.connecting()){
      Serial.printf(".");
    }
    status = bme.begin(0x76);
    if (sensor.init()) {
      Serial.println("Sensor ready.");
  }
    else {
      Serial.println("Sensor ERROR!");
  }
    display.display();
    mqtt.subscribe(&waterMe);
    pinMode(relayPin,OUTPUT);
    pinMode(soilPin,INPUT);
    pinMode(dustPin, INPUT);
    Time.zone(-7);
    Particle.syncTime();
}

void loop() {
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  displayOLED();
  MQTT_connect();
  if ((millis()-last)>120000) {
    Serial.printf("Pinging MQTT \n");
    if(! mqtt.ping()) {
      Serial.printf("Disconnecting \n");
      mqtt.disconnect();
      }
      last = millis();
  }
  currentTime = millis();
    if((currentTime - last) > 1800000) {
        readSoil();
        if(mqtt.Update()){
            soilSaturation.publish(soilReading);
        }
        last = millis();
    }
    currentTime = millis();
    if((currentTime - last) > 30000) {
        readTempF();
        readHumidity();
        readPressureInhg();
        readDust();
        readAirQuality();
        if(mqtt.Update()){
            bmeTemp.publish(temperature);
            bmeHumidity.publish(humidRH);
            bmeAirPressure.publish(pressInhg);
            dustParticulates.publish(concentration);
            airQuality.publish(quanAirValue);
          
        }
        last = millis();
    }
    

    Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(1000))) {
    if (subscription == &waterMe) {
      onOrOff = atoi((char *)waterMe.lastread);
      if((currentTime - last) > 500) {
        digitalWrite(relayPin, HIGH);
  }
      else {
        digitalWrite(relayPin, LOW);
  }
      last = millis();
          Serial.printf("Received %i from Adafruit.io feed H20 \n",onOrOff);
          
    }
  }
  if(onOrOff){
      digitalWrite(relayPin,HIGH);
    }
    else{
    digitalWrite(relayPin,LOW);
    }
  
}
float readTempF(){ // print temp every 60 seconds 
    float tempC;
    tempC = bme.readTemperature();
    temperature = map(tempC, 0.0, 100.0, 32.0, 212.0);
    return(temperature);
}
float readHumidity() {
  humidRH = bme.readHumidity();
  return(humidRH);
}
float readPressureInhg() {
  pressPA = bme.readPressure();
  pressInhg = pressPA * inhg;
  return (pressInhg);
}
float readSoil(){
  soilReading = analogRead(soilPin);
  if(soilReading >= 3000.0){
    if((currentTime - last) > 500) {
    digitalWrite(relayPin, HIGH);
  }
  else {
    digitalWrite(relayPin, LOW);
  }
  last = millis();
  }
  Serial.printf("Soil Saturation %.01f \n", soilReading);
  return (pressInhg);

}
float readDust(){
  duration = pulseIn(dustPin,LOW);
  lowpulseoccupancy = lowpulseoccupancy+duration;
    ratio = lowpulseoccupancy/(sampletime*10.0);
    concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62;
    Serial.printf("Dust Concentration %.01f \n",concentration);
    lowpulseoccupancy = 0;
    starttime = millis();
  return(concentration);
}
int readAirQuality(){
  quanAirValue = sensor.getValue();
  quality = sensor.slope();
  Serial.printf("Air Quality %i \n", quanAirValue);
  
  if (quality == AirQualitySensor::FORCE_SIGNAL) {
    Serial.printf("High pollution! Force signal active \n");
  }
  else if (quality == AirQualitySensor::HIGH_POLLUTION) {
    Serial.printf("High pollution \n");
  }
  else if (quality == AirQualitySensor::LOW_POLLUTION) {
    Serial.printf("Low pollution \n");
  }
  else if (quality == AirQualitySensor::FRESH_AIR) {
    Serial.printf("Fresh air \n");
  }
return (quanAirValue);

}

void displayOLED(void){
  display.clearDisplay();
  display.printf("Temperature %.01f \n",temperature);
  display.printf("Humidity %.01f \n",humidRH);
  display.printf("Air Pressure %.01f \n",pressInhg);
  display.printf("Soil Moisture %.01f \n",soilReading);
  display.printf("Dust Concentration %.01f \n",concentration);
  if (quality == AirQualitySensor::FORCE_SIGNAL) {
    display.printf("High pollution! Force signal active \n");
  }
  else if (quality == AirQualitySensor::HIGH_POLLUTION) {
    display.printf("High pollution \n");
  }
  else if (quality == AirQualitySensor::LOW_POLLUTION) {
    display.printf("Low pollution \n");
  }
  else if (quality == AirQualitySensor::FRESH_AIR) {
    display.printf("Fresh air \n");
  }
  DateTime = Time.timeStr();
  TimeOnly = DateTime.substring(11,19);
  display.printf("%s, %s\n",DateTime.c_str(),TimeOnly.c_str());
  display.display();
}

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.printf("%s\n",(char *)mqtt.connectErrorString(ret));
       Serial.printf("Retrying MQTT connection in 5 seconds..\n");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
  }
  Serial.printf("MQTT Connected!\n");
}

The article was first published in hackster, November 11, 2021

cr: https://www.hackster.io/edward-ishman/h2whoa-130895

author: Edward Ishman

License
All Rights
Reserved
licensBg
0