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"
10 // What pin the DHT is connected to.
12 // Uncomment whatever type you're using!
13 //#define DHTTYPE DHT11 // DHT 11
14 #define DHTTYPE DHT22 // DHT 22 (AM2302)
15 DHT dht(DHTPIN, DHTTYPE);
17 AirQuality airqualitysensor;
18 int current_quality = -1;
22 unsigned long duration;
23 unsigned long starttime;
24 unsigned long sampletime_ms = 30000;
25 unsigned long lowpulseoccupancy = 0;
26 unsigned long counter;
28 float concentration = 0;
33 // ; // wait for serial port to connect. Needed for native USB port only
36 Wire.begin(); // Initialize I2C
37 SeeedGrayOled.init(); // Initialize SEEED OLED display
38 SeeedGrayOled.clearDisplay(); // Clear the screen and set start position to top left corner
39 SeeedGrayOled.setNormalDisplay(); // Set display to normal mode (i.e non-inverse mode)
40 SeeedGrayOled.setVerticalMode();
41 //SeeedGrayOled.setPageMode(); // Set addressing mode to Page Mode
42 SeeedGrayOled.setTextXY(0,0); // Set the cursor to Xth Page, Yth Column
43 SeeedGrayOled.putString("Initializing"); // Print the String
45 pinMode(BUZZER, OUTPUT);
46 digitalWrite(BUZZER, LOW);
47 airqualitysensor.init(14);
50 pinMode(dust_pin,INPUT);
51 starttime = millis(); // Get the current time
52 Serial.println("counter;uptime;humidity;temperature;quality;particules");
56 // Reading temperature or humidity takes about 250 milliseconds!
57 // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
58 float h = dht.readHumidity();
59 float t = dht.readTemperature();
60 counter = counter + 1;
61 SeeedGrayOled.setTextXY(8,0);
62 // Check if returns are valid,
63 // if they are NaN (not a number)
64 // then something went wrong!
65 Serial.print(counter);
67 Serial.print(millis());
68 if (isnan(t) || isnan(h)) {
69 SeeedGrayOled.putString("DHT ERROR");
74 SeeedGrayOled.putString("Humidity:");
75 SeeedGrayOled.setTextXY(9,0);
76 SeeedGrayOled.putString(" ");
77 SeeedGrayOled.putFloat(h);
78 SeeedGrayOled.putString("%");
79 SeeedGrayOled.setTextXY(10,0);
80 SeeedGrayOled.putString("Temp.:");
81 SeeedGrayOled.setTextXY(11,0);
82 SeeedGrayOled.putString(" ");
83 SeeedGrayOled.putFloat(t);
84 SeeedGrayOled.putString("*C");
91 Serial.print(airqualitysensor.first_vol,DEC);
93 // Checking Air Quality
94 current_quality=airqualitysensor.slope();
95 if (current_quality >= 0) {
96 if (current_quality <= 1)
97 // Air quality is bad.
98 // Let's revert display to make some light!
99 SeeedGrayOled.setInverseDisplay();
101 SeeedGrayOled.setNormalDisplay();
103 SeeedGrayOled.setTextXY(2,0);
104 SeeedGrayOled.putString("Air Quality:"); // Print the String
105 SeeedGrayOled.setTextXY(3,3);
106 SeeedGrayOled.putNumber(airqualitysensor.first_vol); // Print the String
107 SeeedGrayOled.putString(" "); // Clear any old character
109 SeeedGrayOled.setTextXY(0,0);
110 if (current_quality==0)
111 SeeedGrayOled.putString("Emergency ");
112 else if (current_quality==1)
113 SeeedGrayOled.putString("Hi Pollution");
114 else if (current_quality==2)
115 SeeedGrayOled.putString("Low Polution");
116 else if (current_quality==3)
117 SeeedGrayOled.putString("Air OK :-) ");
119 if (current_quality<1)
120 digitalWrite(BUZZER, HIGH);
122 digitalWrite(BUZZER, LOW);
125 // Checking Dust Sensor
126 duration = pulseIn(dust_pin, LOW);
127 lowpulseoccupancy = lowpulseoccupancy+duration;
130 if ((millis()-starttime) > sampletime_ms) {
131 //if the sample time == 30s
132 ratio = lowpulseoccupancy / (sampletime_ms*10.0); // Integer percentage 0=>100
133 concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // Using spec sheet curve
135 Serial.print(lowpulseoccupancy);
139 Serial.print(concentration);
140 SeeedGrayOled.setTextXY(4,0);
141 SeeedGrayOled.putString("Particles:");
142 SeeedGrayOled.setTextXY(5,3);
143 SeeedGrayOled.putString(" ");
144 SeeedGrayOled.setTextXY(5,3);
145 SeeedGrayOled.putNumber(concentration);
146 lowpulseoccupancy = 0;
147 starttime = millis();
152 ISR(TIMER2_OVF_vect) {
153 if(airqualitysensor.counter==122) {
154 // set 2 seconds as a detected duty
155 airqualitysensor.last_vol=airqualitysensor.first_vol;
156 airqualitysensor.first_vol=analogRead(A0);
157 airqualitysensor.counter=0;
158 airqualitysensor.timer_index=1;
162 airqualitysensor.counter++;