/*
* 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();
}
}
Comments