// Licence: WTFPLv2
// Copyright 2015: Julien Moutinho
#include
#include "SeeedGrayOLED.h"
#include "AirQuality.h"
#include "Arduino.h"
#include "DHT.h"
unsigned long now;
unsigned long counter;
#define DHTPIN 2
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);
AirQuality air;
uint8_t air_pin = A0;
int air_quality = -1;
int dust_pin = 4;
unsigned long dust_duration;
unsigned long dust_last_time;
unsigned long dust_delay = 30000;
unsigned long dust_lowpulseoccupancy = 0;
float dust_concentration = 0;
float dust_ratio = 0;
/* MQ9: CO CH4 LPG */
unsigned long fire_last_time;
unsigned long fire_delay = 1000;
float fire_R0 = 0.40;
uint8_t fire_pin = A2;
#define BUZZER 10
void setup() {
Serial.begin(9600);
//while (!Serial) {
// ; // wait for serial port to connect. Needed for native USB port only
// }
Wire.begin(); // Initialize I2C
SeeedGrayOled.init(); // Initialize SEEED OLED display
SeeedGrayOled.clearDisplay(); // Clear the screen and set start position to top left corner
SeeedGrayOled.setNormalDisplay(); // Set display to normal mode (i.e non-inverse mode)
SeeedGrayOled.setVerticalMode();
//SeeedGrayOled.setPageMode(); // Set addressing mode to Page Mode
SeeedGrayOled.setTextXY(0,0); // Set the cursor to Xth Page, Yth Column
SeeedGrayOled.putString("Initializing"); // Print the String
pinMode(BUZZER, OUTPUT);
digitalWrite(BUZZER, LOW);
air.init(14);
dht.begin();
pinMode(dust_pin,INPUT);
now = millis();
dust_last_time = now;
fire_last_time = now;
Serial.println("counter;uptime;temperature;humidity;quality;dust;co-ch4-lpg");
}
void loop() {
float h = dht.readHumidity();
float t = dht.readTemperature();
counter = counter + 1;
now = millis();
Serial.print(counter);
Serial.write(';');
Serial.print(now);
/* DHT */
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(t) || isnan(h)) {
// Check if returns are valid,
// if they are NaN (not a number)
// then something went wrong!
SeeedGrayOled.setTextXY(0,0);
SeeedGrayOled.putString("T: ERROR ");
SeeedGrayOled.setTextXY(1,0);
SeeedGrayOled.putString("H: ERROR ");
Serial.write(';');
Serial.write(';');
}
else {
SeeedGrayOled.setTextXY(0,0);
SeeedGrayOled.putString("T: ");
SeeedGrayOled.setTextXY(0,3);
SeeedGrayOled.putFloat(t);
SeeedGrayOled.putString("*C");
Serial.write(';');
Serial.print(t);
SeeedGrayOled.setTextXY(1,0);
SeeedGrayOled.putString("H: ");
SeeedGrayOled.setTextXY(1,3);
SeeedGrayOled.putFloat(h);
SeeedGrayOled.putString("%");
Serial.write(';');
Serial.print(h);
}
/* Air Quality */
Serial.write(';');
Serial.print(air.first_vol,DEC);
// Checking Air Quality
air_quality=air.slope();
if (air_quality >= 0) {
if (air_quality <= 1)
// Air quality is bad.
// Let's revert display to make some light!
SeeedGrayOled.setInverseDisplay();
else
SeeedGrayOled.setNormalDisplay();
SeeedGrayOled.setTextXY(2,0);
SeeedGrayOled.putString("Air: ");
SeeedGrayOled.setTextXY(2,5);
SeeedGrayOled.putNumber(air.first_vol);
SeeedGrayOled.setTextXY(3,3);
if (air_quality==0)
SeeedGrayOled.putString("0/4 (x_x)");
else if (air_quality==1)
SeeedGrayOled.putString("1/4 (>_<)");
else if (air_quality==2)
SeeedGrayOled.putString("2/4 (=_=)");
else if (air_quality==3)
SeeedGrayOled.putString("3/4 (*_*)");
else
SeeedGrayOled.putString("4/4 (^_^)");
if (air_quality<1)
digitalWrite(BUZZER, HIGH);
else
digitalWrite(BUZZER, LOW);
}
/* Dust */
dust_duration = pulseIn(dust_pin, LOW);
dust_lowpulseoccupancy = dust_lowpulseoccupancy + dust_duration;
Serial.write(';');
if ((now - dust_last_time) >= dust_delay) {
dust_last_time = now;
dust_ratio = dust_lowpulseoccupancy / (dust_delay * 10.0); // Integer percentage 0=>100
dust_concentration = 1.1*pow(dust_ratio,3)
- 3.8*pow(dust_ratio,2)
+ 520*dust_ratio
+ 0.62; // Using spec sheet curve
/*
Serial.print(dust_lowpulseoccupancy);
Serial.write(';');
Serial.print(dust_ratio);
*/
Serial.print(dust_concentration);
SeeedGrayOled.setTextXY(4,0);
SeeedGrayOled.putString("Part.: ");
SeeedGrayOled.setTextXY(4,7);
SeeedGrayOled.putNumber(dust_concentration);
dust_lowpulseoccupancy = 0;
}
/* MQ9: CO CH4 LPG */
Serial.write(';');
if ((now - fire_last_time) >= fire_delay) {
fire_last_time = now;
float fire_read = analogRead(fire_pin);
float fire_volt = (float)fire_read / 1024 * 5.0;
float fire_RS = (5.0 - fire_volt) / fire_volt; // omit *RL
/* Replace the name "R0" with the value of R0 in the demo of First Test */
float fire_ratio = fire_RS / fire_R0; // fire_ratio = RS/R0
SeeedGrayOled.setTextXY(5,0);
SeeedGrayOled.putString("Feu: ");
SeeedGrayOled.setTextXY(5,5);
SeeedGrayOled.putFloat(fire_ratio);
Serial.print(fire_ratio);
}
Serial.println();
}
ISR(TIMER2_OVF_vect) {
if(air.counter==122) {
// NOTE: set 2 seconds as a detected duty
air.last_vol = air.first_vol;
air.first_vol = analogRead(air_pin);
air.counter = 0;
air.timer_index = 1;
//PORTB=PORTB^0x20;
}
else {
air.counter++;
}
}