]> Git — Sourcephile - julm/air-duino.git/blob - send.ino
add MQ9 R0 collect
[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 mq9_last_time;
32 unsigned long mq9_delay = 1000;
33 float mq9_R0 = 0.40;
34 uint8_t mq9_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("Init..."); // 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 mq9_last_time = now;
62 Serial.println("loop;uptime;temperature;humidity;air;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.write("loop=");
71 Serial.print(counter);
72 Serial.write(";up=");
73 Serial.print(now);
74
75 /* DHT */
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=");
79 if (isnan(t)) {
80 SeeedGrayOled.setTextXY(0,0);
81 SeeedGrayOled.putString("T: ERROR ");
82 }
83 else {
84 Serial.print(t);
85 SeeedGrayOled.setTextXY(0,0);
86 SeeedGrayOled.putString("T: ");
87 SeeedGrayOled.setTextXY(0,3);
88 SeeedGrayOled.putFloat(t);
89 SeeedGrayOled.putString("*C");
90
91 }
92
93 Serial.write(";humi=");
94 if (isnan(h)) {
95 SeeedGrayOled.setTextXY(1,0);
96 SeeedGrayOled.putString("H: ERROR ");
97 }
98 else {
99 Serial.print(h);
100 SeeedGrayOled.setTextXY(1,0);
101 SeeedGrayOled.putString("H: ");
102 SeeedGrayOled.setTextXY(1,3);
103 SeeedGrayOled.putFloat(h);
104 SeeedGrayOled.putString("%");
105 }
106
107 /* Air Quality */
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();
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(";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)
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("Dust: ");
161 SeeedGrayOled.setTextXY(4,7);
162 SeeedGrayOled.putNumber(dust_concentration);
163 dust_lowpulseoccupancy = 0;
164 }
165
166 /* MQ9: CO CH4 LPG */
167 Serial.write(";fire=");
168 if ((now - mq9_last_time) >= mq9_delay) {
169 mq9_last_time = now;
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)
176
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_);
184 }
185
186 Serial.println();
187 }
188
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);
194 air.counter = 0;
195 air.timer_index = 1;
196 //PORTB=PORTB^0x20;
197 }
198 else {
199 air.counter++;
200 }
201 }