1 // Licence: WTFPLv2 <http://www.wtfpl.net/txt/copying/>
 
   2 // Copyright 2015: Julien Moutinho <julm+air@autogeree.net>
 
   5 #include "SeeedGrayOLED.h"
 
   6 #include "AirQuality.h"
 
  11 unsigned long counter;
 
  14 //#define DHTTYPE DHT11 // DHT 11
 
  15 #define DHTTYPE DHT22 // DHT 22 (AM2302)
 
  16 DHT dht(DHTPIN, DHTTYPE);
 
  23 unsigned long dust_duration;
 
  24 unsigned long dust_last_time;
 
  25 unsigned long dust_delay = 30000;
 
  26 unsigned long dust_lowpulseoccupancy = 0;
 
  27 float         dust_concentration = 0;
 
  31 unsigned long mq9_last_time;
 
  32 unsigned long mq9_delay = 1000;
 
  41         //  ; // wait for serial port to connect. Needed for native USB port only
 
  44         Wire.begin();                       // Initialize I2C
 
  45         SeeedGrayOled.init();               // Initialize SEEED OLED display
 
  46         SeeedGrayOled.clearDisplay();       // Clear the screen and set start position to top left corner
 
  47         SeeedGrayOled.setNormalDisplay();   // Set display to normal mode (i.e non-inverse mode)
 
  48         SeeedGrayOled.setVerticalMode();
 
  49         //SeeedGrayOled.setPageMode();      // Set addressing mode to Page Mode
 
  50         SeeedGrayOled.setTextXY(0,0);       // Set the cursor to Xth Page, Yth Column
 
  51         SeeedGrayOled.putString("Init..."); // Print the String
 
  53         pinMode(BUZZER, OUTPUT);
 
  54         digitalWrite(BUZZER, LOW);
 
  58         pinMode(dust_pin,INPUT);
 
  62         Serial.println("loop;uptime;temperature;humidity;air;dust;co_ch4_lpg");
 
  66         float h = dht.readHumidity();
 
  67         float t = dht.readTemperature();
 
  68         counter = counter + 1;
 
  70         Serial.write("loop=");
 
  71         Serial.print(counter);
 
  76                 // Reading temperature or humidity takes about 250 milliseconds!
 
  77                 // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
 
  78                 Serial.write(";temp=");
 
  80                         SeeedGrayOled.setTextXY(0,0);
 
  81                         SeeedGrayOled.putString("T: ERROR    ");
 
  85                         SeeedGrayOled.setTextXY(0,0);
 
  86                         SeeedGrayOled.putString("T:          ");
 
  87                         SeeedGrayOled.setTextXY(0,3);
 
  88                         SeeedGrayOled.putFloat(t);
 
  89                         SeeedGrayOled.putString("*C");
 
  93                 Serial.write(";humi=");
 
  95                         SeeedGrayOled.setTextXY(1,0);
 
  96                         SeeedGrayOled.putString("H: ERROR    ");
 
 100                         SeeedGrayOled.setTextXY(1,0);
 
 101                         SeeedGrayOled.putString("H:          ");
 
 102                         SeeedGrayOled.setTextXY(1,3);
 
 103                         SeeedGrayOled.putFloat(h);
 
 104                         SeeedGrayOled.putString("%");
 
 108                 air_quality=air.slope();
 
 109                 Serial.write(";air=");
 
 110                 if (air_quality >= 0) {
 
 111                         Serial.print(air.first_vol,DEC);
 
 112                         if (air_quality <= 1)
 
 113                                 // Air quality is bad.
 
 114                                 // Let's revert display to make some light!
 
 115                                 SeeedGrayOled.setInverseDisplay();
 
 117                                 SeeedGrayOled.setNormalDisplay();
 
 119                         SeeedGrayOled.setTextXY(2,0);
 
 120                         SeeedGrayOled.putString("Air:        ");
 
 121                         SeeedGrayOled.setTextXY(2,5);
 
 122                         SeeedGrayOled.putNumber(air.first_vol);
 
 124                         SeeedGrayOled.setTextXY(3,3);
 
 126                         SeeedGrayOled.putString("0/4 (x_x)");
 
 127                         else if (air_quality==1)
 
 128                         SeeedGrayOled.putString("1/4 (>_<)");
 
 129                         else if (air_quality==2)
 
 130                         SeeedGrayOled.putString("2/4 (=_=)");
 
 131                         else if (air_quality==3)
 
 132                         SeeedGrayOled.putString("3/4 (*_*)");
 
 134                         SeeedGrayOled.putString("4/4 (^_^)");
 
 137                                 digitalWrite(BUZZER, HIGH);
 
 139                                 digitalWrite(BUZZER, LOW);
 
 143                 dust_duration = pulseIn(dust_pin, LOW);
 
 144                 dust_lowpulseoccupancy = dust_lowpulseoccupancy + dust_duration;
 
 145                 Serial.write(";dust=");
 
 146                 if ((now - dust_last_time) >= dust_delay) {
 
 147                         dust_last_time = now;
 
 148                         dust_ratio = dust_lowpulseoccupancy / (dust_delay * 10.0); // Integer percentage 0=>100
 
 149                         dust_concentration = 1.1*pow(dust_ratio,3)
 
 150                          - 3.8*pow(dust_ratio,2)
 
 152                          + 0.62; // Using spec sheet curve
 
 154                         Serial.print(dust_lowpulseoccupancy);
 
 156                         Serial.print(dust_ratio);
 
 158                         Serial.print(dust_concentration);
 
 159                         SeeedGrayOled.setTextXY(4,0);
 
 160                         SeeedGrayOled.putString("Dust:       ");
 
 161                         SeeedGrayOled.setTextXY(4,7);
 
 162                         SeeedGrayOled.putNumber(dust_concentration);
 
 163                         dust_lowpulseoccupancy = 0;
 
 166         /* MQ9: CO CH4 LPG */
 
 167                 Serial.write(";fire=");
 
 168                 if ((now - mq9_last_time) >= mq9_delay) {
 
 170                         int mq9_read = analogRead(mq9_pin);
 
 171                         float mq9_volt = (float)mq9_read / 1024 * 5.0;
 
 172                         float mq9_RS  = (5.0 - mq9_volt) / mq9_volt; // omit *RL
 
 173                         /* Replace the name "R0" with the value of R0 in the demo of First Test */
 
 174                         float mq9_ratio = mq9_RS / mq9_R0;  // mq9_ratio = RS/R0
 
 175                         float mq9_R0_ = mq9_RS / 9.9; // The ratio of RS/R0 is 9.9 in LPG gas from Graph (Found using WebPlotDigitizer)
 
 177                         Serial.print(mq9_R0_);
 
 178                         SeeedGrayOled.setTextXY(5,0);
 
 179                         SeeedGrayOled.putString("Feu:        ");
 
 180                         SeeedGrayOled.setTextXY(5,5);
 
 181                         //SeeedGrayOled.putFloat(mq9_ratio);
 
 182                         //Serial.print(mq9_ratio);
 
 183                         SeeedGrayOled.putFloat(mq9_R0_);
 
 189 ISR(TIMER2_OVF_vect) {
 
 190         if(air.counter==122) {
 
 191          // NOTE: set 2 seconds as a detected duty
 
 192                 air.last_vol    = air.first_vol;
 
 193                 air.first_vol   = analogRead(air_pin);