/*
* Project L14_04_PlantWater
* Description: Smart Plant Watering System
* Author: Christian Chavez
* Date: 11-09-2020
*/
#include <Adafruit_MQTT.h>
#include "Adafruit_MQTT/Adafruit_MQTT.h"
#include "Adafruit_MQTT/Adafruit_MQTT_SPARK.h"
#include "Adafruit_MQTT/Adafruit_MQTT.h"
#include "credentials.h"
#include <Adafruit_BME280.h>
#include <Adafruit_SSD1306.h>
#include "Air_Quality_Sensor.h"
#define OLED_RESET D4
Adafruit_SSD1306 display(OLED_RESET);
Adafruit_BME280 bme;
AirQualitySensor sensor(A4);
TCPClient TheClient;
Adafruit_MQTT_SPARK mqtt(&TheClient,AIO_SERVER,AIO_SERVERPORT,AIO_USERNAME,AIO_KEY);
Adafruit_MQTT_Subscribe buttonState = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/buttonOnOff");
Adafruit_MQTT_Publish soilRead = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Soil Moisture");
Adafruit_MQTT_Publish tempRead = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Temperature Reading");
Adafruit_MQTT_Publish pressureRead = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Pressure Reading");
Adafruit_MQTT_Publish humidityRead = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Humidity Reading");
Adafruit_MQTT_Publish airRead = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Air Quality Reading");
Adafruit_MQTT_Publish dustRead = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Dust Reading");
float temp;
float pressure;
float humidity;
unsigned long last;
unsigned long lastTime;
unsigned long pumpLastTime;
unsigned long dustStartTime;
unsigned long duration;
int capRead; //stores capacitive soil sensor reading
int value; //stores value subcribed from adafruit.io
int airQuality; //stores value from Air Quality Sensor
int slopeQuality;
char dangerReading;
int dust;
float lowPulseOccupancy;
float concentration = 0;
float realConcentration;
float ratio;
const int ledPin = D7; //pin to turn on Particle led
const int soilPin = A1;
const int dustPin = A3;
const int airPin = A4;
const int pumpPin = A5;
void setup() {
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.display();
delay(2000);
bme.begin(0x76);
if (sensor.init()) {
Serial.printf("Sensor ready.");
} else {
Serial.printf("Sensor ERROR!");
}
mqtt.subscribe(&buttonState);
pinMode(soilPin, INPUT);
pinMode(pumpPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(airPin, INPUT);
pinMode(dustPin, INPUT);
dustStartTime = millis();
}
void loop() {
duration = pulseIn(dustPin, LOW);
lowPulseOccupancy = lowPulseOccupancy + duration;
if ((millis()-dustStartTime) >= 30000){
ratio = lowPulseOccupancy/(30000*10.0);
concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62;
if(concentration > 1){
realConcentration = concentration;
}
Serial.printf("Concentration = %f pcs/0.01cf",realConcentration);
lowPulseOccupancy = 0;
dustStartTime = millis();
}
int slopeQuality = sensor.slope();
if (slopeQuality == AirQualitySensor::FORCE_SIGNAL) {
Serial.println("High pollution! Force signal active.");
}
else if (slopeQuality == AirQualitySensor::HIGH_POLLUTION) {
Serial.println("High pollution!");
}
else if (slopeQuality == AirQualitySensor::LOW_POLLUTION) {
Serial.println("Low pollution!");
}
else if (slopeQuality == AirQualitySensor::FRESH_AIR) {
Serial.println("Fresh air.");
}
display.clearDisplay();
display.setRotation(2);
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
temp = ((bme.readTemperature()*9/5)+32);
pressure = ((bme.readPressure()/100)*0.03);
humidity = bme.readHumidity();
airQuality = sensor.getValue();
display.printf("Soil: %i\nTemp: %.2f%c\nPressure: %.2f\nHumidity: %.2f%c\nAir Quality: %i\nDust: %.2f\n",capRead,temp,(char)247,pressure,humidity,(char)37,airQuality,realConcentration);
display.display();
MQTT_connect();
if ((millis()-last)>5000) {
Serial.printf("Pinging MQTT \n");
if(! mqtt.ping()) {
Serial.printf("Disconnecting \n");
mqtt.disconnect();
}
last = millis();
}
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(10000))) {
if (subscription == &buttonState) {
value = atof((char *)buttonState.lastread);
if(value == 1){
digitalWrite(ledPin, HIGH);
digitalWrite(pumpPin, HIGH);
}
else{
digitalWrite(ledPin, LOW);
digitalWrite(pumpPin, LOW);
}
}
}
if((millis()-lastTime > 30000)) {
if(mqtt.Update()) {
analogWrite(pumpPin, HIGH);
capRead = analogRead(soilPin);
soilRead.publish(capRead);
tempRead.publish(temp);
pressureRead.publish(pressure);
humidityRead.publish(humidity);
airRead.publish(airQuality);
dustRead.publish(concentration);
Serial.printf("Soil Read: %i Temp: %f Pressure: %f Humidity %f Air Quality: %i Dust: %f\n",capRead,temp,pressure,humidity, airQuality, concentration);
}
lastTime = millis();
}
if((millis()-pumpLastTime > 60000)) { //automatic plant watering
if(capRead > 1600){
digitalWrite(pumpPin, HIGH);
digitalWrite(ledPin, HIGH);
Serial.printf("Watering plant\n");
delay(1000);
digitalWrite(pumpPin, LOW);
digitalWrite(ledPin, LOW);
Serial.printf("Stop Watering plant\n");
}
pumpLastTime = millis();
}
}
void MQTT_connect() {
int8_t ret;
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!");
}
Comments