// 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++; } }