Сенсор углекислого газа MH-Z14/19 на последовательном интерфейсе.
[weathermon.git] / Weather_Station / Weather_Station.ino
1 /* SFE_BMP180 library example sketch
2
3 This sketch shows how to use the SFE_BMP180 library to read the
4 Bosch BMP180 barometric pressure sensor.
5 https://www.sparkfun.com/products/11824
6
7 Like most pressure sensors, the BMP180 measures absolute pressure.
8 This is the actual ambient pressure seen by the device, which will
9 vary with both altitude and weather.
10
11 Before taking a pressure reading you must take a temparture reading.
12 This is done with startTemperature() and getTemperature().
13 The result is in degrees C.
14
15 Once you have a temperature reading, you can take a pressure reading.
16 This is done with startPressure() and getPressure().
17 The result is in millibar (mb) aka hectopascals (hPa).
18
19 If you'll be monitoring weather patterns, you will probably want to
20 remove the effects of altitude. This will produce readings that can
21 be compared to the published pressure readings from other locations.
22 To do this, use the sealevel() function. You will need to provide
23 the known altitude at which the pressure was measured.
24
25 If you want to measure altitude, you will need to know the pressure
26 at a baseline altitude. This can be average sealevel pressure, or
27 a previous pressure reading at your altitude, in which case
28 subsequent altitude readings will be + or - the initial baseline.
29 This is done with the altitude() function.
30
31 Hardware connections:
32
33 - (GND) to GND
34 + (VDD) to 3.3V
35
36 (WARNING: do not connect + to 5V or the sensor will be damaged!)
37
38 You will also need to connect the I2C pins (SCL and SDA) to your
39 Arduino. The pins are different on different Arduinos:
40
41 Any Arduino pins labeled:  SDA  SCL
42 Uno, Redboard, Pro:        A4   A5
43 Mega2560, Due:             20   21
44 Leonardo:                   2    3
45
46 Leave the IO (VDDIO) pin unconnected. This pin is for connecting
47 the BMP180 to systems with lower logic levels such as 1.8V
48
49 Have fun! -Your friends at SparkFun.
50
51 The SFE_BMP180 library uses floating-point equations developed by the
52 Weather Station Data Logger project: http://wmrx00.sourceforge.net/
53
54 Our example code uses the "beerware" license. You can do anything
55 you like with this code. No really, anything. If you find it useful,
56 buy me a beer someday.
57
58 V10 Mike Grusin, SparkFun Electronics 10/24/2013
59 */
60
61 // Your sketch must #include this library, and the Wire library.
62 // (Wire is a standard library included with Arduino.):
63
64 #include <SFE_BMP180.h>
65 #include <Wire.h>
66 #include "DHT.h"
67
68 // You will need to create an SFE_BMP180 object, here called "pressure":
69
70 SFE_BMP180 pressure;
71
72 // DHT object for humidity sensor
73 DHT dht;
74
75 #define CO2_PIN A1
76 #define DHT_PIN 4
77 #define GAS_PIN A0
78 // #define MHZ14_PIN A2
79 #define START_DELAY 20000
80 #define DELAY 10000
81
82 byte HasBaro;
83
84 #define READ_SAMPLE_INTERVAL 50
85 #define READ_SAMPLE_TIMES 5
86
87 #include <SoftwareSerial.h>;
88
89 SoftwareSerial mySerial(8, 9); // 8 - к TX сенсора, 9 - к RX
90
91 byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79}; 
92 unsigned char response[9];
93
94 int MHZRead()
95 {
96   mySerial.write(cmd, 9);
97   memset(response, 0, 9);
98   mySerial.readBytes(response, 9);
99   int i;
100   byte crc = 0;
101   for (i = 1; i < 8; i++) crc+=response[i];
102   crc = 255 - crc;
103   crc++;
104
105   if ( !(response[0] == 0xFF && response[1] == 0x86 && response[8] == crc) ) {
106     return -1;
107   } else {
108     unsigned int responseHigh = (unsigned int) response[2];
109     unsigned int responseLow = (unsigned int) response[3];
110     unsigned int ppm = (256*responseHigh) + responseLow;
111     return ppm;
112   }
113 }
114
115 float MQRead(int mq_pin)
116 {
117
118   int i;
119   float rs=0;
120   float rr;
121
122   for (i=0;i<READ_SAMPLE_TIMES;i++) {
123     rr = analogRead(mq_pin);
124     rs += rr;
125     delay(READ_SAMPLE_INTERVAL);
126   }
127  
128   rs = rs/READ_SAMPLE_TIMES;
129   return rs;
130
131 }
132
133 /// Parameters to model temperature and humidity dependence
134
135
136 void setup()
137 {
138   delay(START_DELAY);
139
140   Serial.begin(115200);
141   Serial.println("START");
142   Serial1.begin(57600);
143   Serial1.println("START");
144   mySerial.begin(9600);
145
146   // Initialize the sensor (it is important to get calibration values stored on the device).
147
148   if (pressure.begin()) {
149     Serial.println("BMP180 init success");
150     Serial1.println("BMP180 init success");
151     HasBaro = 1;
152   } else {
153     Serial.println("BMP180 init fail\n\n");
154     Serial1.println("BMP180 init fail\n\n");
155     HasBaro = 0;
156   }
157   
158   dht.setup(DHT_PIN);
159   
160   pinMode(GAS_PIN,INPUT);
161   pinMode(CO2_PIN,INPUT);
162   
163   digitalWrite(GAS_PIN, LOW);
164   digitalWrite(CO2_PIN, LOW);
165 }
166
167 void loop()
168 {
169   char status;
170   double T,P;
171   double DHT_T,DHT_H;
172   int DHTStatus;
173   int Gas;
174   int CO2_raw;
175   int CO2_MHZ_raw;
176   float MHZ_ppm;
177
178   double LastTemp;
179   byte GotTemperature,GotPressure;
180
181   // Loop here getting pressure readings every 60 seconds.
182
183   GotTemperature = 0;
184   GotPressure = 0;
185
186   if (HasBaro) {
187     
188     status = pressure.startTemperature();
189     if (status != 0) {
190       // Wait for the measurement to complete:
191       delay(status);
192
193       // Retrieve the completed temperature measurement:
194       // Note that the measurement is stored in the variable T.
195       // Function returns 1 if successful, 0 if failure.
196
197       status = pressure.getTemperature(T);
198       if (status = !0) {
199         LastTemp=T;
200         GotTemperature=1;
201       } else {  
202         Serial.println("ERROR:TYPE=BMP180,MESSAGE=FAILED MEASURE TEMPERATURE\n");
203         Serial1.println("ERROR:TYPE=BMP180,MESSAGE=FAILED MEASURE TEMPERATURE\n");
204       }  
205     } else {
206       Serial.println("ERROR:TYPE=BMP180,MESSAGE=FAILED START TEMPERATURE MEASUREMENT\n");
207       Serial1.println("ERROR:TYPE=BMP180,MESSAGE=FAILED START TEMPERATURE MEASUREMENT\n");
208     }
209     
210     // Start a pressure measurement:
211     // The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
212     // If request is successful, the number of ms to wait is returned.
213     // If request is unsuccessful, 0 is returned.
214
215     status = pressure.startPressure(3);
216     if (status != 0) {
217       // Wait for the measurement to complete:
218       delay(status);
219
220       // Retrieve the completed pressure measurement:
221       // Note that the measurement is stored in the variable P.
222       // Note also that the function requires the previous temperature measurement (T).
223       // (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
224       // Function returns 1 if successful, 0 if failure.
225
226       status = pressure.getPressure(P,LastTemp);
227       if (status != 0) {
228           // Print out the measurement:
229           GotPressure=1;
230
231       } else {
232         Serial.println("ERROR:TYPE=BMP180,MESSAGE=FAILED MEASURE PRESSURE\n");
233         Serial1.println("ERROR:TYPE=BMP180,MESSAGE=FAILED MEASURE PRESSURE\n");
234       }  
235     } else {
236       Serial.println("ERROR:TYPE=BMP180,MESSAGE=FAILED START PRESSURE MEASUREMENT\n");
237       Serial1.println("ERROR:TYPE=BMP180,MESSAGE=FAILED START PRESSURE MEASUREMENT\n");
238     }  
239     if (GotPressure || GotTemperature) {
240       Serial.print("SENSOR:TYPE=BMP180");
241       Serial1.print("SENSOR:TYPE=BMP180");
242       if (GotPressure) { Serial.print(",PRESSURE="); Serial.print(P); Serial1.print(",PRESSURE="); Serial1.print(P); }
243       if (GotTemperature) { Serial.print(",TEMPERATURE="); Serial.print(T); Serial1.print(",TEMPERATURE="); Serial1.print(T); }
244       Serial.println(); Serial1.println();
245     }
246   }
247
248   delay(DELAY);
249
250   delay(dht.getMinimumSamplingPeriod());
251
252   DHT_H = dht.getHumidity();
253   DHT_T = dht.getTemperature();
254
255   DHTStatus=dht.getStatus();
256  
257   if (DHTStatus == 0) {
258     Serial.print("SENSOR:TYPE=DHT22,TEMPERATURE=");
259     Serial.print(DHT_T);
260     Serial.print(",HUMIDITY=");
261     Serial.println(DHT_H);
262     Serial1.print("SENSOR:TYPE=DHT22,TEMPERATURE=");
263     Serial1.print(DHT_T);
264     Serial1.print(",HUMIDITY=");
265     Serial1.println(DHT_H);
266   } else {
267     Serial.print("ERROR:TYPE=DHT22,MESSAGE=");
268     Serial.println(dht.getStatusString());
269     Serial1.print("ERROR:TYPE=DHT22,MESSAGE=");
270     Serial1.println(dht.getStatusString());
271   }
272   
273   delay(DELAY);
274   
275   Gas = MQRead(GAS_PIN);
276   
277   Serial.print("SENSOR:TYPE=MQ4,VALUE=");
278   Serial.println(Gas);
279   Serial1.print("SENSOR:TYPE=MQ4,VALUE=");
280   Serial1.println(Gas);
281
282   delay(DELAY);
283
284   CO2_raw = MQRead(CO2_PIN);
285   Serial.print("SENSOR:TYPE=MQ135,VALUE=");
286   Serial.println(CO2_raw);
287   Serial1.print("SENSOR:TYPE=MQ135,VALUE=");
288   Serial1.println(CO2_raw);
289
290   delay(DELAY);
291
292   MHZ_ppm=MHZRead();
293   if (MHZ_ppm<0) {
294     Serial.print("ERROR:TYPE=MHZ14,MESSAGE=CRC Error");
295     Serial.println(MHZ_ppm);
296     Serial1.print("ERROR:TYPE=MHZ14,MESSAGE=CRC Error");
297     Serial1.println(MHZ_ppm);
298   } else {
299     Serial.print("SENSOR:TYPE=MHZ14,PPM=");
300     Serial.println(MHZ_ppm);
301     Serial1.print("SENSOR:TYPE=MHZ14,PPM=");
302     Serial1.println(MHZ_ppm);
303   }
304
305   delay(DELAY);
306 }
307