// 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 mq9_last_time;
unsigned long mq9_delay = 1000;
float mq9_R0 = 0.40;
uint8_t mq9_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("Init..."); // Print the String
pinMode(BUZZER, OUTPUT);
digitalWrite(BUZZER, LOW);
air.init(14);
dht.begin();
pinMode(dust_pin,INPUT);
now = millis();
dust_last_time = now;
mq9_last_time = now;
Serial.println("loop;uptime;temperature;humidity;air;dust;co_ch4_lpg");
}
void loop() {
float h = dht.readHumidity();
float t = dht.readTemperature();
counter = counter + 1;
now = millis();
Serial.write("loop=");
Serial.print(counter);
Serial.write(";up=");
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)
Serial.write(";temp=");
if (isnan(t)) {
SeeedGrayOled.setTextXY(0,0);
SeeedGrayOled.putString("T: ERROR ");
}
else {
Serial.print(t);
SeeedGrayOled.setTextXY(0,0);
SeeedGrayOled.putString("T: ");
SeeedGrayOled.setTextXY(0,3);
SeeedGrayOled.putFloat(t);
SeeedGrayOled.putString("*C");
}
Serial.write(";humi=");
if (isnan(h)) {
SeeedGrayOled.setTextXY(1,0);
SeeedGrayOled.putString("H: ERROR ");
}
else {
Serial.print(h);
SeeedGrayOled.setTextXY(1,0);
SeeedGrayOled.putString("H: ");
SeeedGrayOled.setTextXY(1,3);
SeeedGrayOled.putFloat(h);
SeeedGrayOled.putString("%");
}
/* Air Quality */
air_quality=air.slope();
Serial.write(";air=");
if (air_quality >= 0) {
Serial.print(air.first_vol,DEC);
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(";dust=");
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("Dust: ");
SeeedGrayOled.setTextXY(4,7);
SeeedGrayOled.putNumber(dust_concentration);
dust_lowpulseoccupancy = 0;
}
/* MQ9: CO CH4 LPG */
Serial.write(";fire=");
if ((now - mq9_last_time) >= mq9_delay) {
mq9_last_time = now;
int mq9_read = analogRead(mq9_pin);
float mq9_volt = (float)mq9_read / 1024 * 5.0;
float mq9_RS = (5.0 - mq9_volt) / mq9_volt; // omit *RL
/* Replace the name "R0" with the value of R0 in the demo of First Test */
float mq9_ratio = mq9_RS / mq9_R0; // mq9_ratio = RS/R0
float mq9_R0_ = mq9_RS / 9.9; // The ratio of RS/R0 is 9.9 in LPG gas from Graph (Found using WebPlotDigitizer)
Serial.print(mq9_R0_);
SeeedGrayOled.setTextXY(5,0);
SeeedGrayOled.putString("Feu: ");
SeeedGrayOled.setTextXY(5,5);
//SeeedGrayOled.putFloat(mq9_ratio);
//Serial.print(mq9_ratio);
SeeedGrayOled.putFloat(mq9_R0_);
}
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++;
}
}