]> Git — Sourcephile - julm/air-duino.git/blob - send.ino
add MQ9 sensor
[julm/air-duino.git] / send.ino
1 // Licence: WTFPLv2 <http://www.wtfpl.net/txt/copying/>
2 // Copyright 2015: Julien Moutinho <julm+air@autogeree.net>
3
4 #include <Wire.h>
5 #include "SeeedGrayOLED.h"
6 #include "AirQuality.h"
7 #include "Arduino.h"
8 #include "DHT.h"
9
10 unsigned long now;
11 unsigned long counter;
12
13 #define DHTPIN 2
14 //#define DHTTYPE DHT11 // DHT 11
15 #define DHTTYPE DHT22 // DHT 22 (AM2302)
16 DHT dht(DHTPIN, DHTTYPE);
17
18 AirQuality air;
19 uint8_t air_pin = A0;
20 int air_quality = -1;
21
22 int dust_pin = 4;
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;
28 float dust_ratio = 0;
29
30 /* MQ9: CO CH4 LPG */
31 unsigned long fire_last_time;
32 unsigned long fire_delay = 1000;
33 float fire_R0 = 0.40;
34 uint8_t fire_pin = A2;
35
36 #define BUZZER 10
37
38 void setup() {
39 Serial.begin(9600);
40 //while (!Serial) {
41 // ; // wait for serial port to connect. Needed for native USB port only
42 // }
43
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
52
53 pinMode(BUZZER, OUTPUT);
54 digitalWrite(BUZZER, LOW);
55 air.init(14);
56 dht.begin();
57
58 pinMode(dust_pin,INPUT);
59 now = millis();
60 dust_last_time = now;
61 fire_last_time = now;
62 Serial.println("counter;uptime;temperature;humidity;quality;dust;co-ch4-lpg");
63 }
64
65 void loop() {
66 float h = dht.readHumidity();
67 float t = dht.readTemperature();
68 counter = counter + 1;
69 now = millis();
70 Serial.print(counter);
71 Serial.write(';');
72 Serial.print(now);
73
74 /* DHT */
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 ");
85 Serial.write(';');
86 Serial.write(';');
87 }
88 else {
89 SeeedGrayOled.setTextXY(0,0);
90 SeeedGrayOled.putString("T: ");
91 SeeedGrayOled.setTextXY(0,3);
92 SeeedGrayOled.putFloat(t);
93 SeeedGrayOled.putString("*C");
94 Serial.write(';');
95 Serial.print(t);
96
97 SeeedGrayOled.setTextXY(1,0);
98 SeeedGrayOled.putString("H: ");
99 SeeedGrayOled.setTextXY(1,3);
100 SeeedGrayOled.putFloat(h);
101 SeeedGrayOled.putString("%");
102 Serial.write(';');
103 Serial.print(h);
104 }
105
106 /* Air Quality */
107 Serial.write(';');
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();
116 else
117 SeeedGrayOled.setNormalDisplay();
118
119 SeeedGrayOled.setTextXY(2,0);
120 SeeedGrayOled.putString("Air: ");
121 SeeedGrayOled.setTextXY(2,5);
122 SeeedGrayOled.putNumber(air.first_vol);
123
124 SeeedGrayOled.setTextXY(3,3);
125 if (air_quality==0)
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 (*_*)");
133 else
134 SeeedGrayOled.putString("4/4 (^_^)");
135
136 if (air_quality<1)
137 digitalWrite(BUZZER, HIGH);
138 else
139 digitalWrite(BUZZER, LOW);
140 }
141
142 /* Dust */
143 dust_duration = pulseIn(dust_pin, LOW);
144 dust_lowpulseoccupancy = dust_lowpulseoccupancy + dust_duration;
145 Serial.write(';');
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)
151 + 520*dust_ratio
152 + 0.62; // Using spec sheet curve
153 /*
154 Serial.print(dust_lowpulseoccupancy);
155 Serial.write(';');
156 Serial.print(dust_ratio);
157 */
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;
164 }
165
166 /* MQ9: CO CH4 LPG */
167 Serial.write(';');
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);
180 }
181
182 Serial.println();
183 }
184
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);
190 air.counter = 0;
191 air.timer_index = 1;
192 //PORTB=PORTB^0x20;
193 }
194 else {
195 air.counter++;
196 }
197 }