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 fire_last_time;
32 unsigned long fire_delay = 1000;
34 uint8_t fire_pin = A2;
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("Initializing"); // Print the String
53 pinMode(BUZZER, OUTPUT);
54 digitalWrite(BUZZER, LOW);
58 pinMode(dust_pin,INPUT);
62 Serial.println("counter;uptime;temperature;humidity;quality;dust;co-ch4-lpg");
66 float h = dht.readHumidity();
67 float t = dht.readTemperature();
68 counter = counter + 1;
70 Serial.print(counter);
75 // Reading temperature or humidity takes about 250 milliseconds!
76 // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
77 if (isnan(t) || isnan(h)) {
78 // Check if returns are valid,
79 // if they are NaN (not a number)
80 // then something went wrong!
81 SeeedGrayOled.setTextXY(0,0);
82 SeeedGrayOled.putString("T: ERROR ");
83 SeeedGrayOled.setTextXY(1,0);
84 SeeedGrayOled.putString("H: ERROR ");
89 SeeedGrayOled.setTextXY(0,0);
90 SeeedGrayOled.putString("T: ");
91 SeeedGrayOled.setTextXY(0,3);
92 SeeedGrayOled.putFloat(t);
93 SeeedGrayOled.putString("*C");
97 SeeedGrayOled.setTextXY(1,0);
98 SeeedGrayOled.putString("H: ");
99 SeeedGrayOled.setTextXY(1,3);
100 SeeedGrayOled.putFloat(h);
101 SeeedGrayOled.putString("%");
108 Serial.print(air.first_vol,DEC);
109 // Checking Air Quality
110 air_quality=air.slope();
111 if (air_quality >= 0) {
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;
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("Part.: ");
161 SeeedGrayOled.setTextXY(4,7);
162 SeeedGrayOled.putNumber(dust_concentration);
163 dust_lowpulseoccupancy = 0;
166 /* MQ9: CO CH4 LPG */
168 if ((now - fire_last_time) >= fire_delay) {
169 fire_last_time = now;
170 float fire_read = analogRead(fire_pin);
171 float fire_volt = (float)fire_read / 1024 * 5.0;
172 float fire_RS = (5.0 - fire_volt) / fire_volt; // omit *RL
173 /* Replace the name "R0" with the value of R0 in the demo of First Test */
174 float fire_ratio = fire_RS / fire_R0; // fire_ratio = RS/R0
175 SeeedGrayOled.setTextXY(5,0);
176 SeeedGrayOled.putString("Feu: ");
177 SeeedGrayOled.setTextXY(5,5);
178 SeeedGrayOled.putFloat(fire_ratio);
179 Serial.print(fire_ratio);
185 ISR(TIMER2_OVF_vect) {
186 if(air.counter==122) {
187 // NOTE: set 2 seconds as a detected duty
188 air.last_vol = air.first_vol;
189 air.first_vol = analogRead(air_pin);