Version with MQ135 Air Quality sensor.
authorRoman Bazalevskiy <rvb@rvb.name>
Tue, 19 May 2015 13:50:33 +0000 (16:50 +0300)
committerRoman Bazalevskiy <rvb@rvb.name>
Tue, 19 May 2015 13:50:33 +0000 (16:50 +0300)
Weather_Station.ino [new file with mode: 0644]

diff --git a/Weather_Station.ino b/Weather_Station.ino
new file mode 100644 (file)
index 0000000..9358d3d
--- /dev/null
@@ -0,0 +1,272 @@
+/* SFE_BMP180 library example sketch
+
+This sketch shows how to use the SFE_BMP180 library to read the
+Bosch BMP180 barometric pressure sensor.
+https://www.sparkfun.com/products/11824
+
+Like most pressure sensors, the BMP180 measures absolute pressure.
+This is the actual ambient pressure seen by the device, which will
+vary with both altitude and weather.
+
+Before taking a pressure reading you must take a temparture reading.
+This is done with startTemperature() and getTemperature().
+The result is in degrees C.
+
+Once you have a temperature reading, you can take a pressure reading.
+This is done with startPressure() and getPressure().
+The result is in millibar (mb) aka hectopascals (hPa).
+
+If you'll be monitoring weather patterns, you will probably want to
+remove the effects of altitude. This will produce readings that can
+be compared to the published pressure readings from other locations.
+To do this, use the sealevel() function. You will need to provide
+the known altitude at which the pressure was measured.
+
+If you want to measure altitude, you will need to know the pressure
+at a baseline altitude. This can be average sealevel pressure, or
+a previous pressure reading at your altitude, in which case
+subsequent altitude readings will be + or - the initial baseline.
+This is done with the altitude() function.
+
+Hardware connections:
+
+- (GND) to GND
++ (VDD) to 3.3V
+
+(WARNING: do not connect + to 5V or the sensor will be damaged!)
+
+You will also need to connect the I2C pins (SCL and SDA) to your
+Arduino. The pins are different on different Arduinos:
+
+Any Arduino pins labeled:  SDA  SCL
+Uno, Redboard, Pro:        A4   A5
+Mega2560, Due:             20   21
+Leonardo:                   2    3
+
+Leave the IO (VDDIO) pin unconnected. This pin is for connecting
+the BMP180 to systems with lower logic levels such as 1.8V
+
+Have fun! -Your friends at SparkFun.
+
+The SFE_BMP180 library uses floating-point equations developed by the
+Weather Station Data Logger project: http://wmrx00.sourceforge.net/
+
+Our example code uses the "beerware" license. You can do anything
+you like with this code. No really, anything. If you find it useful,
+buy me a beer someday.
+
+V10 Mike Grusin, SparkFun Electronics 10/24/2013
+*/
+
+// Your sketch must #include this library, and the Wire library.
+// (Wire is a standard library included with Arduino.):
+
+#include <SFE_BMP180.h>
+#include <Wire.h>
+#include "DHT.h"
+
+// You will need to create an SFE_BMP180 object, here called "pressure":
+
+SFE_BMP180 pressure;
+
+// DHT object for humidity sensor
+DHT dht;
+
+#define CO2_PIN A1
+#define DHT_PIN 4
+#define GAS_PIN A0
+#define START_DELAY 20000
+#define DELAY 50000
+
+byte HasBaro;
+
+#define READ_SAMPLE_INTERVAL 50
+#define READ_SAMPLE_TIMES 5
+
+#define MQ135_RES 1000
+
+float MQRead(int mq_pin)
+{
+
+  int i;
+  float rs=0;
+  float rr;
+
+  for (i=0;i<READ_SAMPLE_TIMES;i++) {
+    rr = analogRead(mq_pin);
+    rs += rr;
+    delay(READ_SAMPLE_INTERVAL);
+  }
+  rs = rs/READ_SAMPLE_TIMES;
+  return rs;
+
+}
+
+/// Parameters to model temperature and humidity dependence
+
+#define CORA 0.00035
+#define CORB 0.02718
+#define CORC 1.39538
+#define CORD 0.0018
+
+float getMQ135CorrectionFactor(float t, float h) {
+  return CORA * t * t - CORB * t + CORC - (h-33.)*CORD;
+}
+
+#define RZERO 25300
+#define PARA 116.6020682
+#define PARB 2.769034857
+
+float getMQ135ppm(float Resistance) {
+  return PARA * pow((Resistance/RZERO), -PARB);  
+}
+
+void setup()
+{
+  delay(START_DELAY);
+
+  Serial1.begin(57600);
+  Serial1.println("START");
+
+  // Initialize the sensor (it is important to get calibration values stored on the device).
+
+  if (pressure.begin()) {
+    Serial1.println("BMP180 init success");
+    HasBaro = 1;
+  } else {
+    Serial1.println("BMP180 init fail\n\n");
+    HasBaro = 0;
+  }
+  
+  dht.setup(DHT_PIN);
+  
+  pinMode(GAS_PIN,INPUT);
+  pinMode(CO2_PIN,INPUT);
+  
+  digitalWrite(GAS_PIN, LOW);
+  digitalWrite(CO2_PIN, LOW);
+}
+
+void loop()
+{
+  char status;
+  double T,P;
+  double DHT_T,DHT_H;
+  int DHTStatus;
+  int Gas;
+
+  double LastTemp;
+  byte GotTemperature,GotPressure;
+
+  // Loop here getting pressure readings every 60 seconds.
+
+  GotTemperature = 0;
+  GotPressure = 0;
+
+  if (HasBaro) {
+    
+    status = pressure.startTemperature();
+    if (status != 0) {
+      // Wait for the measurement to complete:
+      delay(status);
+
+      // Retrieve the completed temperature measurement:
+      // Note that the measurement is stored in the variable T.
+      // Function returns 1 if successful, 0 if failure.
+
+      status = pressure.getTemperature(T);
+      if (status = !0) {
+        LastTemp=T;
+        GotTemperature=1;
+      } else {  
+        Serial1.println("ERROR:TYPE=BMP180,MESSAGE=FAILED MEASURE TEMPERATURE\n");
+      }  
+    } else {
+      Serial1.println("ERROR:TYPE=BMP180,MESSAGE=FAILED START TEMPERATURE MEASUREMENT\n");
+    }
+    
+    // Start a pressure measurement:
+    // The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
+    // If request is successful, the number of ms to wait is returned.
+    // If request is unsuccessful, 0 is returned.
+
+    status = pressure.startPressure(3);
+    if (status != 0) {
+      // Wait for the measurement to complete:
+      delay(status);
+
+      // Retrieve the completed pressure measurement:
+      // Note that the measurement is stored in the variable P.
+      // Note also that the function requires the previous temperature measurement (T).
+      // (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
+      // Function returns 1 if successful, 0 if failure.
+
+      status = pressure.getPressure(P,LastTemp);
+      if (status != 0) {
+          // Print out the measurement:
+          GotPressure=1;
+
+      } else {
+        Serial1.println("ERROR:TYPE=BMP180,MESSAGE=FAILED MEASURE PRESSURE\n");
+      }  
+    } else {
+      Serial1.println("ERROR:TYPE=BMP180,MESSAGE=FAILED START PRESSURE MEASUREMENT\n");
+    }  
+    if (GotPressure || GotTemperature) {
+      Serial1.print("SENSOR:TYPE=BMP180");
+      if (GotPressure) { Serial1.print(",PRESSURE="); Serial1.print(P); }
+      if (GotTemperature) { Serial1.print(",TEMPERATURE="); Serial1.print(T); }
+      Serial1.println();
+    }
+  }
+
+  delay(dht.getMinimumSamplingPeriod());
+
+  DHT_H = dht.getHumidity();
+  DHT_T = dht.getTemperature();
+
+  DHTStatus=dht.getStatus();
+  if (DHTStatus == 0) {
+    Serial1.print("SENSOR:TYPE=DHT22,TEMPERATURE=");
+    Serial1.print(DHT_T);
+    Serial1.print(",HUMIDITY=");
+    Serial1.println(DHT_H);
+  } else {
+    Serial1.print("ERROR:TYPE=DHT22,MESSAGE=");
+    Serial1.println(dht.getStatusString());
+  }
+  
+  Gas = MQRead(GAS_PIN);
+  
+  Serial1.print("SENSOR:TYPE=MQ4,VALUE=");
+  Serial1.println(Gas);
+
+  float MQ135_Resistance;
+  float CO2_raw;
+  float CO2_ppm;
+
+  float CO2_resistance;
+
+  CO2_raw = MQRead(CO2_PIN);
+  Serial1.print("DEBUG:RAW=");
+  Serial1.println(CO2_raw);
+
+  MQ135_Resistance=MQ135_RES*(1023./CO2_raw-1);
+  
+  Serial1.print("DEBUG:RESISTANCE=");
+  Serial1.println(MQ135_Resistance);
+  
+  MQ135_Resistance=MQ135_Resistance/getMQ135CorrectionFactor(DHT_T,DHT_H);
+  Serial1.print("DEBUG:CORR_RESISTANCE=");
+  Serial1.println(MQ135_Resistance);  
+
+  CO2_ppm = getMQ135ppm(MQ135_Resistance);  
+  
+  Serial1.print("SENSOR:TYPE=MQ135,VALUE=");
+  Serial1.println(CO2_ppm);
+  
+  delay(DELAY);  // Pause for 50 seconds.
+}
+