From 4177ee347c6a063ac3e115d5419edfc2ae5d67fe Mon Sep 17 00:00:00 2001 From: Roman Bazalevskiy <rvb@rvb.name> Date: Tue, 19 May 2015 16:50:33 +0300 Subject: [PATCH 1/1] Version with MQ135 Air Quality sensor. --- Weather_Station.ino | 272 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 Weather_Station.ino diff --git a/Weather_Station.ino b/Weather_Station.ino new file mode 100644 index 0000000..9358d3d --- /dev/null +++ b/Weather_Station.ino @@ -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. +} + -- 2.34.1