// Include Particle Device OS APIs
// Project: SmartGrow Tower
// Author: Jeren Arellano Reeder
#include "Particle.h"
#include "Air_Quality_Sensor.h"
#include "Grove_Air_quality_Sensor.h"
#include <Adafruit_MQTT.h>
#include "Adafruit_MQTT/Adafruit_MQTT_SPARK.h"
#include "Adafruit_MQTT/Adafruit_MQTT.h"
#include "credentials.h"
#include "Adafruit_SSD1306.h"
#include "Adafruit_GFX.h"
#include "Adafruit_BME280.h"
//classes
AirQualitySensor sensor (A0);
TCPClient TheClient;
Adafruit_MQTT_SPARK mqtt(&TheClient,AIO_SERVER,AIO_SERVERPORT,AIO_USERNAME,AIO_KEY);
Adafruit_MQTT_Publish pubFeed = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/plantAQ");
Adafruit_MQTT_Publish pubFeed2 = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/plantmoisture");
Adafruit_MQTT_Publish pubFeed3 = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/planttemp");
Adafruit_MQTT_Publish pubFeed4 = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/planthumid");
Adafruit_MQTT_Publish pubFeed5 = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/plantpressure");
Adafruit_MQTT_Subscribe subFeed = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/WaterButton");
//bme
char number = 164;
Adafruit_BME280 bme;
int hexAddress = 0x76;
const int OLED_RESET=-1;
Adafruit_SSD1306 display1(OLED_RESET);
Adafruit_SSD1306 display2(OLED_RESET);
//relay
const int relayPin = D6;
int relayState;
unsigned int lastRelay;
unsigned int lastRelay2;
unsigned int lastPublish;
//stats
float temp, pres, humid, Fahrenheit, inHg;
bool status;
//strings floats ints
float subValue,pubValue,pubValue2,pubValue3,pubValue4,pubValue5,pubValue6,pubValue7;
String dateTime;
String timeOnly;
unsigned int last, lastTime;
const int moisturePin = A1;
float moistureValue;
//functions
void MQTT_connect();
bool MQTT_ping();
void OLED(void);
SYSTEM_MODE(AUTOMATIC);
SYSTEM_THREAD(ENABLED);
void setup() {
pinMode(relayPin,OUTPUT);
Time.zone(-6);
Particle.syncTime();
Serial.begin(9600);
waitFor(Serial.isConnected,10000);
//wifi
WiFi.on();
WiFi.connect();
while(WiFi.connecting()) {
Serial.printf(".");
}
Serial.printf("\n\n");
mqtt.subscribe(&subFeed);
while(!Serial);
//air sensor
Serial.println("Starting Sensor");
delay(10000);
if(sensor.init()){
Serial.println("Sensor is ready");
}
else{
Serial.println("Sensor Error");
}
status = bme.begin(hexAddress);
if (status == TRUE) {
Serial.printf("BME280 at address 0x%02X started successfully!\n",hexAddress);
//OLED
display1.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display2.begin(SSD1306_SWITCHCAPVCC, 0x3D);
display1.clearDisplay();
display2.clearDisplay();
display1.display();
display2.display();
delay(2000);
}
}
void loop() {
OLED();
//BME280
temp = bme.readTemperature();
pres = bme.readPressure();
humid = bme.readHumidity();
Fahrenheit = (temp * 9/5) + 32;
inHg = (pres * 0.00029529983071445);
Serial.printf("Pressure %f\nHumidity %f\nFahrenheit %f\n",inHg,humid,Fahrenheit);
delay(1000);
//AIR SENSOR
int quality = sensor.slope();
Serial.print("Air Quality: ");
Serial.println(sensor.getValue());
if (quality == AirQualitySensor::FORCE_SIGNAL){
Serial.println("VERY HIGH POLLUTION WARNING");
}
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);
{
lastTime = millis();
//MOISTURE SENSOR AND TIME
moistureValue = analogRead(moisturePin);
dateTime = Time.timeStr();
timeOnly = dateTime.substring(11,19);
if( millis () - lastTime >10000) {
lastTime = millis ();
Serial.printf ("Date/Time %s\n", dateTime.c_str () );
Serial.printf ("Time is %s\n", timeOnly.c_str () );
Serial.printf("Moisture Level is %0.2f",moistureValue);
}
}
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(100))) {
if (subscription == &subFeed) {
subValue = atof((char *)subFeed.lastread);
}
}
//RELAY EVERY 2 MINS
if (millis() - lastRelay > 120000) {
lastRelay = millis();
if (moistureValue > 2670) {
digitalWrite(relayPin, HIGH);
Serial.println("RELAY ON");
delay(500);
digitalWrite(relayPin, LOW);
Serial.println("RELAY OFF");
}
}
//ADAFRUIT WATERBUTTON
if (subValue == 1) {
digitalWrite(relayPin, HIGH);
Serial.println(" relayState = ON");
delay(500);
digitalWrite(relayPin, LOW);
Serial.println(" relayState = OFF");
}
if (subValue == 0) {
digitalWrite(relayPin, LOW);
Serial.println(" relayState = OFF");
}
if((millis()-lastPublish > 15000)) {
if(mqtt.Update()) {
pubValue = sensor.getValue();
pubValue2 = moistureValue;
pubValue3 = Fahrenheit;
pubValue4 = humid;
pubValue5 = inHg;
pubFeed.publish(pubValue);
pubFeed2.publish(pubValue2);
pubFeed3.publish(pubValue3);
pubFeed4.publish(pubValue4);
pubFeed5.publish(pubValue5);
Serial.printf("Publishing %0.2f \n",pubValue);
Serial.printf("Publishing %0.2f \n",pubValue2);
Serial.printf("Publishing %0.1f \n",pubValue3);
Serial.printf("Publishing %0.2f \n",pubValue4);
Serial.printf("Publishing %0.2f \n",pubValue5);
}
lastPublish = millis();
}
}
//CONNECTING
void MQTT_connect() {
int8_t ret;
if (mqtt.connected()) {
return;
}
Serial.print("Connecting to MQTT... ");
while ((ret = mqtt.connect()) != 0) {
Serial.printf("Error Code %s\n",mqtt.connectErrorString(ret));
Serial.printf("Retrying MQTT connection in 5 seconds...\n");
mqtt.disconnect();
delay(5000);
}
Serial.printf("MQTT Connected!\n");
}
bool MQTT_ping() {
static unsigned int last;
bool pingStatus;
if ((millis()-last)>120000) {
Serial.printf("Pinging MQTT \n");
pingStatus = mqtt.ping();
if(!pingStatus) {
Serial.printf("Disconnecting \n");
mqtt.disconnect();
}
last = millis();
}
return pingStatus;
}
//OLEDS
void OLED(void){
int quality = sensor.slope();
dateTime = Time.timeStr();
timeOnly = dateTime.substring(11,19);
//DISPLAYS
display1.display();
display1.clearDisplay();
display1.setTextSize(1);
display1.setTextColor(WHITE);
display1.setCursor(1,0);
display1.printf("MoistureMeter %0.2f\n %s\n",moistureValue, dateTime.c_str ());
display1.setTextSize(1);
display1.setTextColor(WHITE);
display1.setCursor(1,38);
display1.printf("Fahrenheit %0.1fF\nHumidity %0.1f\nPressure %0.1f\n",Fahrenheit,humid,inHg);;
display1.display();
display1.clearDisplay();
display2.display();
display2.clearDisplay();
display2.setTextSize(1);
display2.setTextColor(WHITE);
display2.setCursor(1,0);
display2.print("Sensor value:\n");
display2.println(sensor.getValue());
if (quality == AirQualitySensor::FORCE_SIGNAL){
display2.println("VERY HIGH POLLUTION WARNING\n");
}
else if(quality == AirQualitySensor::HIGH_POLLUTION){
display2.println("HIGH POLLUTION\n");
}
else if(quality == AirQualitySensor::LOW_POLLUTION){
display2.println("LOW POLLUTION\n");
}
else if(quality == AirQualitySensor::FRESH_AIR){
display2.println("FRESH AIR\n");
}
display2.display();
display2.clearDisplay();
delay(1000);
}
Comments